Les Cunliffe - Fotolia
Roll your own Windows patching tool with PowerShell
This tutorial based on PowerShell helps administrators build an automated routine that audits Windows machines, then applies missing patches to lighten this management task.
It's a necessary but loathsome activity for just about every systems administrator: Windows patching.
Windows systems get patched via Microsoft Update. There are many Windows patching tools that help with this procedure.
Windows Server Update Services (WSUS) is free, but lacks some tooling for administrators who might want to fine-tune the process. System Center Configuration Manager enables administrators to build highly customized patching rollouts, but it requires some time to learn -- and it can be a sizeable expense for some organizations. Regardless of your choice, each uses the built-in Windows Update Agent to connect to Microsoft to obtain new updates.
If a commercial Windows patching tool is too costly and the limitations of a free tool are too constraining, there is the option to create your own automated procedure. There are several advantages to this approach. The main perk is the flexibility to build a Windows patching system that matches the organization's needs. But this method requires specific expertise and will take a significant amount of work to build.
To start construction of a Windows patching tool, it helps to think about the details behind the process before writing a single line of code; for example:
- How do you target the systems that need patches?
- What source do you use for the patches?
- Which patches do you apply?
- How do you deliver the patches and install them?
There are several ways to handle these tasks, but in this article, we will address those areas in this fashion:
- Targeting: via Active Directory organizational unit (OU);
- Patch source: Microsoft Update;
- Patch type: all critical patches; and
- Delivery: use PowerShell to remotely invoke the Windows Update Agent.
The administrator can configure all the options at the time of patching, except perhaps the patch source. The Windows Update Agent uses the registry -- possibly through a group policy object -- to determine if the updates will come from Microsoft Update or a local WSUS server. A Windows patching tool built on PowerShell will use the source set in the Windows Update agent.
To start, we will use a prebuilt PowerShell module I developed called WindowsUpdate. Download and install the module. To see a list of available commands, enter:
Get-Command -Module WindowsUpdate
Next, query a list of computers to update. For this article, we'll use a single Active Directory OU, but the source can be anything from a database, CSV file or an Excel spreadsheet, for example. We'll use the Active Directory module included with Microsoft's Remote System Administration Tools package.
After installing that module, we can query AD computers with the Get-AdComputer cmdlet. To find all computers in a single OU, use the SearchScope and SearchBase parameters. With the command below, we can find computers in the Servers OU from the domain mylab.local and return their names:
$computerToPatch = Get-AdComputer -SearchScope Base -SearchBase 'OU=Servers,DC=mylab,DC=local' | Select-Object -ExpandProperty Name
Next, let's target a machine. When I use a new tool, I usually retrieve the existing state of the machine first. I perform a Get operation as a test for the tool and assess the current patch state. The command below queries the first computer in our variable and finds all the available updates that are not installed. By default, it just checks for missing updates:
Get-WindowsUpdate -ComputerName $computersToPatch[0]
Once you've seen the output and you're comfortable with the patches the tool will install, use the Install-WindowsUpdate command to force the Windows Update agent on the remote computer to download and install the missing updates.
Install-WindowsUpdate -ComputerName $computersToPatch[0] -ForceReboot
Notice we've chosen to force a reboot on the machine if needed. By default, Install-WindowsUpdate does not attempt to reboot the computer if an update requires it.
We can take things a step further and install updates on all the target computers. In PowerShell, we can use a ForEach loop to iterate through each computer name in the $computersToPatch array and run Install-WindowsUpdate against each one.
foreach ($computer in $computersToPatch) {
Install-WindowsUpdate -ComputerName $computer -ForceReboot
}
The loop goes through each computer in the Servers OU, checks each for missing patches, installs them and reboots the machine to complete the update process.
This basic demonstration shows what's possible with a free PowerShell tool. Open up the code for these commands and give them a closer look to see where a few modifications might work better with your environment.