Manage Windows Update installations using Windows PowerShell

In most domains Windows Update are controlled by Group Policy and Windows Server Update Services (WSUS). For client computers, its common to download and install updates automatically. For servers, we want to control the installation of Windows Updates inside a scheduled maintenance window, and hence the Windows Update settings are configured not to automatically install updates.

If there are a few servers to manage, it wont be that time consuming to log on to each server with Remote Desktop and do the Windows Update installations manually. In larger environments however, this wont be an option, it must be automated in some way. While enterprise environments typically invest in a commercial product like BigFix for patch management, this might be overkill or too expensive for environments smaller than an enterprise.

To manage Windows Update in an automated way we can access the Windows Update Agent API using a COM-object called Microsoft.Update.Session. Using the New-Object cmdlet in Windows PowerShell, its easy to work with this COM-object. Based on this COM-object and portions of James ONeills functions for managing Windows Update, Ive written a PowerShell-script called Invoke-WindowsUpdate.

This script is intended to be used to download and install Windows Updates on servers. It runs like expected when invoked from a local computer, however, invoking the script using PowerShell Remoting like I was planning turned out to be problematic: Invoke-Command -ComputerName ServerA -FilePath 'C:ps-scriptsWindows UpdateInvoke-WindowsUpdate.ps1'

This will return the following error message:
Exception calling "CreateUpdateDownloader" with "0" argument(s): "Access is denied. (Exception from HRESULT: 0x80070005 E_ACCESSDENIED))"

This issue doesnt seem to be related to PowerShell, as there are several others reporting the same problem in other languages like VBScript.

The common workaround is to schedule the script to run as a scheduled task running as SYSTEM. Ive chosen to use this approach and to use PowerShell Remoting to invoke the scheduled task to run the script. An example:

$servers = Get-Content 'C:ps-scriptsWindows UpdateBulkA.txt'
foreach ($server in $servers) {
Invoke-Command -Computer $server -ScriptBlock {schtasks /run /tn "PowerShell - download and install Windows Updates"}

To create the scheduled task I would recommend you to use Group Policy Preferences.
A few sample screenshots from my lab setup:





Although its possible to invoke the script on all servers in the domain at once using i.e. the Active Directory-module for PowerShell to get the server names, I would recommend to break down the installations in several bulks. This way you can control that all domain controllers doesnt go offline at the same time and so on.

As you can see in the script its also possible to enable reporting to e-mail or file (HTML) to a central location, in addition to control whether the servers should reboot if required.
Planned improvements include nicer reports, Windows Update settings in the reports and if possible make the script work without having to use scheduled tasks. Suggestions for other improvements are always welcome.

Backing up Group Policy Objects using Windows PowerShell

A best practice in domain environments are backing up the Group Policy Objects regularly. Even though a GPO may be restored by restoring a system state backup from a domain controller to an alternate location, and then copy the contents from the deleted GPO to a new GPO to restore the settings, this may be a hazzle since its not pretty straightforward. It also requires you to restart the domain controller affected in Directory Services Restore Mode.
PowerShell MVP Don Jones has written a good article on this topic, available here.

For those of you who may not want to do GPO restore the hard way, or buy a commercial third party product, I would encourage you to schedule regular GPO backups using the Windows PowerShell Group Policy-module available in Windows Server 2008 R2, as well as RSAT in Windows 7.
To accomplish this, I
ve written a small script which backs up all modified GPO`s in the specified timespan. I would generally recommend to have the script run once a day, thereby setting the timespan-variable to the last 24 hours. The script are called Backup-ModifiedGPOs.ps1, and available from here.

All Group Policy Objects modified in the specified timespan are backup up to the specified backup path.
Also, an HTML-report are created for each GPO-backup, with the unique backup GUID as part of the filename. This way you can easily see what settings each backup contains.

When restoring a GPO, you must first note the GUID of the backup you want to restore. Then you can restore the GPO by using the Restore-GPO cmdlet in the Group Policy-module. Sample usage:


Administrators who feels more comfortable working with the GUI, may use the Group Policy Management Console to do the restore.

The following procedure from the Group Policy Planning and Deployment Guide on Microsoft TechNet describes how to accomplish the restore operation from the GUI:

To view the list of GPO backups

  1. In the GPMC console tree, expand the forest or domain that contains the GPOs that you want to back up.
  2. Right-click Group Policy Objects, and the click Manage Backups.
  3. In the Manage Backups dialog box, enter the path to the location where you stored the GPO backups that you want to view. Alternatively, you can click Browse, locate the folder that contains the GPO backups, and then click OK.
  4. To specify that only the most recent version of the GPOs be displayed in the Backed up GPOs list, select the Show only the latest version of each GPO check box. Click Close.

Using the GPMC to restore GPOs

You can also restore GPOs. This operation restores a backed-up GPO to the same domain from which it was backed up. You cannot restore a GPO from a backup into a domain that is different from the GPO’s original domain.

To restore a previous version of an existing GPO

  1. In the GPMC console tree, expand Group Policy Objects in the forest or domain that contains the GPOs that you want to restore.
  2. Right-click the GPO that you want to restore to a previous version, and then click Restore from Backup.
  3. When the Restore Group Policy Object Wizard opens, follow the instructions in the wizard, and then click Finish.
  4. After the restore operation completes, a summary will state whether the restore succeeded. Click OK.

To restore a deleted GPO

  1. In the GPMC console tree, expand the forest or domain that contains the GPO that you want to restore.
  2. Right-click Group Policy Objects, and then click Manage Backups.
  3. In the Manage Backups dialog box, click Browse, and then locate the file that contains your backed-up GPOs.
  4. In the Backed up GPOs list, click the GPO that you want to restore, and then click Restore.
  5. When you are prompted to confirm the restore operation, click OK.
  6. After the restore operation completes, a summary will state whether the restore succeeded. Click OK. Click Close.

Important: Since Group Policy links are stored on the Organizational Unit objects in Active Directory, this information are not backup up and also not restore. However, the HTML backup-reports contains this information, so you may manually re-link the GPO to the correct OU(s).

Also note that WMI filters and IPSec policies are not backed up by the backup feature in the Group Policy Management Console. For more information on how to manage these items, see the before mentioned Group Policy Planning and Deployment Guide.


Enable and configure Windows PowerShell Remoting using Group Policy

As you may know, Windows PowerShell 2.0 introduced a new remoting feature, allowing for remote management of computers.

While this feature can be enabled manually (or scripted) with the PowerShell 2.0 cmdlet Enable-PSRemoting, I would recommend using Group Policy whenever possible. This guide will show you how this can be accomplished for Windows Vista, Windows Server 2008 and above. For Windows XP and Windows Server 2003, running Enable-PSRemoting in a PowerShell startup script would be the best approach.

Windows PowerShell 2.0 and WinRM 2.0 shipped with Windows 7 and Windows Server 2008 R2. To take advantage of Windows PowerShell Remoting, both of these are required on the downlevel operating systems Windows XP, Windows Server 2003, Windows Vista and Windows Server 2008. Both Windows PowerShell 2.0 and WinRM 2.0 are available for download here, as part of the Windows Management Framework (Windows PowerShell 2.0, WinRM 2.0, and BITS 4.0). To deploy this update to downlevel operating systems I would recommend to use WSUS, which are described in detail in this blog post by Kurt Roggen.

Group Policy Configuration

Open the Group Policy Management Console from a domain-joined Windows 7 or Windows Server 2008 R2 computer.

Create or use an existing Group Policy Object, open it, and navigate to Computer Configuration->Policies->Administrative templates->Windows Components

Here you will find the available Group Policy settings for Windows PowerShell, WinRM and Windows Remote Shell:


To enable PowerShell Remoting, the only setting we need to configure are found under “WinRM Service”, named “Allow automatic configuration of listeners”:


Enable this policy, and configure the IPv4 and IPv6 addresses to listen on. To configure WinRM to listen on all addresses, simply use *.

In addition, the WinRM service are by default not started on Windows client operating systems. To configure the WinRM service to start automatically, navigate to Computer ConfigurationPoliciesWindows SettingsSecurity SettingsSystem ServicesWindows Remote Management, doubleclick on Windows Remote Management and configure the service startup mode to “Automatic”:

No other settings need to be configured, however, Ive provided screenshots of the other settings so you can see whats available:





There is one more thing to configure though; the Windows Firewall.

You need to create a new Inbound Rule under Computer Configuration->Policies->Windows Settings->Windows Firewall with Advanced Security->Windows Firewall with Advanced Security->Inbound Rules:


The WinRM port numbers are predefined as “Windows Remote Management”:


With WinRM 2.0, the default http listener port changed from TCP 80 to TCP 5985. The old port number are a part of the predefined scope for compatibility reasons, and may be excluded if you dont have any legacy WinRM 1.1 listeners.



When the rule are created, you may choose to make further restrictions, i.e. to only allow the IP addresses of your management subnet, or perhaps some specific user groups:


Now that the firewall rule are configured, we are done with the minimal configuration to enable PowerShell Remoting using Group Policy.


On a computer affected by the newly configured Group Policy Object, run gpupdate and see if the settings were applied:


As you can see, the listener indicates “Source*”GPO”, meaning it was configured from a Group Policy Object.

When the GPO have been applied to all the affected computers you are ready to test the configuration.

Here is a sample usage of PowerShell Remoting combined with the Active Directory-module for Windows PowerShell:


The example are saving all computer objects in the Domain Controller Organization Unit in a variable. Then, a foreach-loop are invoking a scriptblock, returning the status of the Netlogon-service on all of the Domain Controllers.


Weve now had a look on how to enable and configure PowerShell Remoting using Group Policy.
There are an incredible number of opportunities opening up with the new Remoting feature in Windows PowerShell 2.0. For a complete walkthrough on how you can use this new feature, I would like to recommend the excellent Administrator’s Guide to Windows PowerShell Remoting written by Dr. Tobias Weltner, Aleksandar Nikolic and Richard Giles.

Automate Group Policy Preferences printer-management using Windows PowerShell

Ive written a couple of blog posts earlier on Group Policy Preferences and printer deployment using Group Policy.

Using Group Policy Preferences is a very flexible way to deploy printer connections. This is also very manageable in smaller environments. What if you got hundreds, or even thousands of printer connections you need to deploy? Do you want to sit down and make several thousands of mouse clicks to accomplish the task? There are better alternatives!

Based on SDM Softwares Group Policy Automation Engine, Ive created a script module to handle this. The script module are available from this link.

Save the script module as a psm1-file in the following directory: %userprofile%DocumentsWindowsPowerShellModulesGPPreferencesPrinters
You need to manually create the 3 subfolders under %userprofile%Documents if they doesn
t exist.

When done, start Windows PowerShell and type the following command:


You should now see the GPPreferencesPrinters module.
Import the module with the Import-Module cmdlet:


As you can see there are two functions in addition to SDM Software`s cmdlet: Add-GPPreferencesPrinter and Get-GPPreferencesPrinter.

Example 1:


Example 2:

If you got the printers listed in an Excel spreadsheet, save the document in csv-format:


The csv-file may be used like this to import the printer connections:



Additional functions and parameters will later be added to the script module, i.e. Remove-GPPreferencesPrinter and Item-Level Targeting. Note that example usage for Item-Level Targeting are provided in the Group Policy Automation Engine User Manual.

Single Sign-On to Remote Desktop Services


Single sign-on is an authentication method that allows users with a domain account to log on once to a client computer by using a password, and then gain access to remote servers without being asked for their credentials again. See more details here for Windows Server 2008 and here for Windows Server 2008 R2.

On the client-side SSO are currently available for Windows XP with SP3, Windows Vista and Windows 7.


Configure SSO on the server-side

To configure SSO on the server-side (Windows Server 2008 Terminal Services or Windows Server 2008 R2 Remote Desktop Services), set the option “Security layer” to either “Negotiate” or “SSL (TLS 1.0)”:


Best practice would be to configure this in a common GPO for all Remote Desktop Services servers in the domain:


This setting resides under Computer Configuration->Policies->Administrative templates->Windows Components->Terminal Services->Terminal Server->Security.


Configure SSO on the client-side

Using a common GPO would also be the best practice to deploy the client settings needed for SSO to work.
The “Allow Delegating Default Credentials” resides under Computer Configuration->Policies->System->Credentials Delegation:



Enable “Allow Delegating Default Credentials”, press the “Show”-button and either specify the domain pre-fixed with * to allow delegation to all servers in the domain, or specify specific servers:


Next, create a RDP-file and deploy this file to the client computers.
Before deploying the file, open it in a text editor, e.g. Notepad, and add the following line: enablecredsspsupport:i:1
This will enable SSO for the RDP-file.

I would also recommend to sign the RDP-file with a Code Signing certificate. This can be accomplished using the utility rdpsign.exe:


Sample signing:


When a RDP-file are signed, the following will be added to the bottom of the file:


For Windows Vista and Windows 7 clients, the configuration would now be completed when the RDP-file are deployed.


For Windows XP clients the following would be necessary in addition to the steps above:
-Service Pack 3 needs to be installed
-At least version 6.0 of the Remote Desktop Client
-Turn on the CredSSP Security Provider

The steps to turn on the CredSSP Security Provider are described in this kb-article.

I would recommend deploying these registry settings using Group Policy Preferences:


Also the RDP-file may be deployed in the same way:


I`ve covered the usage of Group Policy Preferences in a previous post.

Also, SSO can be combined with Remote Desktop Services Web Access. The Remote Desktop Services Team has posted an excellent post describing how to set up SSO in RDS Web Access.

Deploying printers using Group Policy

Traditionally printer connections have been deployed to users with scripting, like batch (net use) and Kixtart (AddPrinterConnection).

I would now like to show how printer connections can be deployed using Group Policy. Today we have 2 possible solutions for natively deploy printers using Group Policy without the need for any scripting:

1) Group Policy Preferences – available in Windows Server 2008 and later

2) Print Management – available in Windows Server 2003 R2 and later

Using Group Policy Preferences to deploy printers are described in an earlier blog post, available here. Therefore, I wont explain any further details regarding this.

I will focus on the Print Management which has a powerful “Deploy with Group Policy” feature.

Configure printer deployment on

print servers

To use the “Deploy with Group Policy” feature, you need to install the “Print Management Component” feature from “Add/Remove Windows Components” in Windows Server 2003 R2. In Windows Server 2008/2008 R2 you need to install the “Print Server”-role from the “Add Roles Wizard”.

When installed, youll find “Print Management” under “Administrative tools” on the Start menu:


The following screenshots are taken from Windows Server 2008 R2.

When you open the Print Management Console you will see an overview of Custom Filters, Print Server and Deployed Printers:


You may add additional filters and print servers to the console, which you can read more about in the links in the bottom of this post. For now, well focus on the printer deployment part.

Right-click the printer you want to deploy, and select “Deploy with Group Policy”:


Select “Browse” to choose a Group Policy Object where the printer connection will be deployed. Select “per user” and/or “per machine” and press “Add”. Then click “OK”:


You should now receive a message stating that the deployment operation was successful. Click “OK”:


The printer will now be deployed to client computers.


Behind the scenes

To understand how the print deployment feature works, well activate the “Advanced Features” option on the “View”-menu in “Active Directory Users and Computers”:


Open the “Group Policy Management Console”, go to the Group Policy Object you deployed the printer to, and select “Details”:


Note the “Unique ID” (GUID).

Back in ADUC, expand “System” and then “Policies”:


This is where the actual Group Policy Objects in Active Directory are stored, in addition to \domain.localsysvolpolicies.

Find and expand the Group Policy Object you deployed the printer to. You will now see “PushedPrinterConnections” under the “Machine” and “User” nodes:


When looking at “PushedPrinterConnections” under the “User” node, we see an entry of type “msPrint-ConnectionPolicy”:


When we go into “Properties” on the “msPrint-ConnectionPolicy” and go to “Attribute Editor”, we can see that this represents the printer connection we added:


Deployment to client computers

Client computers running Windows Vista and later have native support for the new printer connection policies, and will work “out-of-the-box” when printer connections are added to a Group Policy.

Client computers running Windows 2000 and Windows XP doesnt support the the new printer connection policies natively. To resolve this, there are a utility called “pushprinterconnections.exe” which must be added to a logonscript in Group Policy. This utility will check the computer and user Group Policy Objects and add any printer connections defined.

This utility have 1 parameter: –log. This is useful when troubleshooting problems, and I would recommend you to use this parameter. As you can see, the utility should not be run manually from the command line:


Here is an example of the utility added to a logon-script in a Group Policy Object:


The log-files are named “ppcUser.log” and “ppcComputer.log”. These are located in the %temp% directory:


Here is an example output of the logfile:


In Windows 2000 and Windows XP, no other feedback than these log-files are provided.

In Windows Vista/Windows Server 2008 and later, the following feedback are shown during logon:


In addition, any failures are logged to the “Application”-log with Source “SpoolerSpoolss”.

Special considerations

Windows 2000 supports only “per machine” deployments when using the pushprinterconnections.exe utility.

The pushprinterconnections.exe utility wont catch “per user” connection policies when using “User Group Policy loopback processing”. You must link the GPO containing the “per user” connection policies to an Organizational Unit where the users reside.

Use ACL`s  on the printer objects on the print servers to publish the printers based on group membership. By using this approach, all printer connections may be defined in the same Group Policy Object.

My recommendations

As I said in the introduction to this post, printer connections have traditionally been deployed to users with scripting. Since there are native ways to accomplish this using Group Policy, this would be my recommendation.

Considerations for using the “Deploy with Group Policy” feature in the print server role:

-the print administrator would have an overview over all printers which are deployed with the Print Management Group Policy feature in the Print Management console
-printers can be administered in an individual GPO like GP Preferences with the Print Management console. To do so, open Group Policy Editor, expand Computer Configuration/User Configuration->Policies->Windows Settings->Deployed Printers
-it requires that pushprinterconnections.exe are run on Windows XP and Windows Server 2003 clients
-it is available with Windows XP/Windows Server 2003 R2 and later (backwards compatible to Windows 2000 Professional/2000 Server)
-it requires Windows Server 2003 Client Access Licenses (CALs)

Considerations for using Group Policy Preferences:

-it can handle more different printer types (local, TCP/IP, and shared instead of only “shared”)
-it has several additional options (deleting all existing connections, setting default printer, etc.)
-it can save a lot of GPOs because you can have many printer objects in one GPO and use “Item Level Targeting” to address each printer individually (e.g. clients in a specific IP-range, per group or even per user)
-it is easy to automate the process of adding printer objects to a GPO using Windows PowerShell, since the GP Preferences settings are store in XML-files
-it requires that Group Policy Client Side Extenstions are deployed on Windows XP and Windows Server 2003 clients
-it is available with Windows Vista/Windows Server 2008 and later (backwards compatible to Windows XP/2003 Server)
-it requires Windows Server 2008 Client Access Licenses (CALs)


Resource links

Step-by-Step Guide for Print Management
(Applies To: Windows Server 2003 R2)

Print Management Step-by-Step Guide
Applies To: Windows Server 2008

Print Management
(Applies To: Windows 7, Windows Server 2008 R2, Windows Vista)

Deploy the PushPrinterConnections.exe Utility

How to install an Excel Add-in with PowerShell

Recently I had the need to automate the process of installing Excel Add-ins in a terminalserver (or more correctly Remote Desktop Services environment since this was Windows Server 2008 R2) environment.

Since Excel Add-ins are per-user based, this was in the first place a manual setting. Of course we wanted to automate this process, so I researched a bit on the internet and found mostly VBScripts. Ive used this KB-article as a template.

Although this worked very well, Im trying to leverage the use of PowerShell as much as possible. Many would say that VBScripts load much faster, and are more effecient as logonscripts.
Even though PowerShell v1 was a bit slow due to the lack of assemblies not being ngened, as described on the PowerShell Teams Blog, this bug is fixed in v2 and I`m quite happy with the loading time now.

I basicly re-wrote the sample VBScript in the KB-article, the result are uploaded to and available from here.

I used an if-statement to check if the Add-in are already installed, to avoid installing it on every logon.

When tested and ready for production, the script may be distributed as a traditional logonscript, or alternatively with Group Policy:


Troubleshooting Group Policy made easier

In Windows Vista/Server 2008 and newer operation systems from Microsoft the userenv.log file which was logging Group Policy processing information in Windows 2000/XP are replaced by a new event log named Group Policy. You can find it in the Event Viewer when you browse to Applications and Services Logs/Microsoft/Windows/GroupPolicy.


The event categories found in the Group Policy event log:


This really makes Group Policy troubleshooting much easier!

In addition to checking out the Group Policy event log on the client, I would also recommend the use of the Group Policy Modeling (simulating what is supposed to happen) and Group Policy Results (connecting to the client to see what did happen) wizards when troubleshooting Group Policy:


Group Policy Preferences


GP Preferences was released with Windows Vista and Windows Server 2008. It gives much more flexibility in addition to Group Policy Settings (administrative templates), and in some environments it may completely replace logon scripts.



GP Preferences Overview

To work with Windows XP and Windows Server 2003 there must be installed client-side extensions. The most common and practical way to deploy these would be to approve them in WSUS.

If setup and managed from Windows Vista or Windows Server 2008, GP Preferences may also be implemented in a Active Directory domain in Windows Server 2003 mode. This is described in more detail here.

Group Policy preference client-side extension can be downloaded here.

Group Policy Preferences overview whitepaper can be downloaded here.


Preferences vs. Settings (from the whitepaper)

Group Policy Preferences

Group Policy Settings


· Preferences are not enforced

· User interface is not disabled

· Can be refreshed or applied once

· Settings are enforced

· User interface is disabled

· Settings are refreshed


· Easily create preference items for registry settings, files, and so on

· Import individual registry settings or entire registry branches from a local or a remote computer

· Adding policy settings requires application support and creating administrative templates

· Cannot create policy settings to manage files, folders, and so on

Local Policy

· Not available in local Group Policy

· Available in local Group Policy


· Supports non-Group Policy-aware applications

· Requires Group Policy-aware applications


· Original settings are overwritten

· Removing the preference item does not restore the original setting

· Original settings are not changed

· Stored in registry Policy branches

· Removing the policy setting restores the original settings

Targeting and Filtering

· Targeting is granular, with a user interface for each type of targeting item

· Supports targeting at the individual preference item level

· Filtering is based on Windows Management Instrumentation (WMI) and requires writing WMI queries

· Supports filtering at a GPO level

User Interface

· Provides a familiar, easy-to-use interface for configuring most settings

· Provides an alternative user interface for most policy settings

Also, see this blog post from the Group Policy team regarding GP Preferences vs GP Settings.


Example usage

Drive mapping


Printer mapping


Power Options



Group Policy Resources 

Group Policy Team Blog

GPOGuy – whitepapers, blog, free tools and some excellent video trainings

GPanswers – newsletters, book resources, community forum and more.