Monthly Archive

Categories

WSUS

Applying updates through WSUS

I like to keep the virtual machines in my test lab up to date so have a WSUS server to download and manage updates. The difficulty is applying the updates. With Windows 2012 R2 I used a module that would contact the WSUS server and apply the updates – the was especially useful on server core installations.

I found with Windows 2016 that this COM based module wasn’t reliable so after a bit of investigation discovered that there are some CIM classes that you can use to discover and apply available updates and see what updates have been applied.

 

All I need is a simple set of code so wrote a bare bones module that offers three functions:

#Scan for available updates
function Get-AvailableUpdate {
[CmdletBinding()]
param()
$ci = New-CimInstance -Namespace root/Microsoft/Windows/WindowsUpdate -ClassName MSFT_WUOperationsSession
$result = $ci | Invoke-CimMethod -MethodName ScanForUpdates -Arguments @{SearchCriteria="IsInstalled=0";OnlineScan=$true}
$result.Updates
}

#Install all available updates
function Install-AvailableUpdate {
[CmdletBinding()]
param()
$ci = New-CimInstance -Namespace root/Microsoft/Windows/WindowsUpdate -ClassName MSFT_WUOperationsSession
Invoke-CimMethod -InputObject $ci -MethodName ApplyApplicableUpdates
}

#list installed updates
function Get-InstalledUpdate {
[CmdletBinding()]
param()
$ci = New-CimInstance -Namespace root/Microsoft/Windows/WindowsUpdate -ClassName MSFT_WUOperationsSession
$result = $ci | Invoke-CimMethod -MethodName ScanForUpdates -Arguments @{SearchCriteria="IsInstalled=1";OnlineScan=$true}
$result.Updates
}

 

Testing so far seems to be good. As this is just for me I’m bothering with adding error testing or other production ready stuff. This works and I’ll fix problems as they occur

Quick test for updates that aren’t installed

I want a quick test to determine if any of the updates I’d approved hadn’t been installed on all of the relevant machines.

 

Get-WsusUpdate -Approval Approved | where InstalledOrNotApplicablePercentage -ne 100

 

Get the list of approved updates and filter on the InstalledOrNotApplicablePercentage

 

If anything does show up you can dig further to determine what hasn’t installed where

Quick update check

Want to check on any updates that haven’t been fully applied in your environment.

 

Run this on your WSUS server (2012 R2)

£> Get-WsusUpdate -Classification All -Status Any -Approval AnyExceptDeclined |
where InstalledOrNotApplicablePercentage -ne 100

 

You can modify the filters:

 

Classification = one of All, Critical, Security, WSUS

 

Status = one of NoStatus, InstalledOrNotApplicable, InstalledOrNotApplicableOrNoStatus, Failed, Needed, FailedOrNeeded, Any

 

Approval = one of Approved, Unapproved, AnyExceptDeclined, Declined

Starting VMs based on WSUS state

I use WSUS in my lab to update machines – means I only have to download updates once. The issue is that I have to start the VMs so they can communicate with the WSUS server. WSUS will start to flag warnings if machines haven’t contacted the WSUS server for more than that length of time.

 

Putting that together I can use the UpdateServices (WSUS) module and the Hyper-V module to start machines that have been turn off more than 7 days.

 

$date = (Get-Date).AddDays(-7)
Get-WsusComputer -NameIncludes 'W12R2' |
where LastReportedStatusTime -lt $date |
foreach {
  $psitem.FullDomainName
  $name = ($psitem.FullDomainName -split "\.")[0]

  $vm = Get-VM -Name $name -ComputerName server02
 
  if ($vm.State -eq 'Off') {

    Start-VM -Name $name -ComputerName server02
 
    Start-Sleep -Seconds 30
  }
}

 

Set a date 7 days in the past.

 

Use get-WsusComputer to pull the machine names. I filter on W12R2 (all my machine names contain an abbreviated OS type) and check the last status report time.

 

Any machines that haven’t reported – the VM data is retrieved and if the machine isn’t running it’s started. Machines take about 25-30 seconds to boot on my lab so a sleep of 30 seconds means I’m not starting them all at once.

Starting virtual machines for WSUS

My test environment usually has a dozen or so machines at any one time. Some of these are short lived and used for a particular piece of testing – others are kept for  years. I decided that I wanted to keep up to date on the patching of these virtual machines so installed WSUS on a Windows 2012 box.

One issue is that if a VM isn’t started for 10 days WSUS starts complaining that it hasn’t been contacted and if you run the WSUS clean up wizard the non-reporting servers may be removed. Checking the WSUS console for which machines haven’t sync’d recently is a chore.

In Windows 2012 both WSUS and Hyper-V come with a PowerShell module. This means I can do this:

$date = (Get-Date).AddDays(-10)            
Get-WsusComputer -ToLastSyncTime $date |            
sort  LastSyncTime |            
select -First 4 |            
foreach {             
 $computer = ($_.FullDomainName -split "\.")[0]            
 Start-VM -Name $computer -ComputerName Server02 -Passthru            
}

I’m using the WSUS server as my admin box but if you were accessing a remote WSUS machine change the code to

Get-WsusServer -Name w12sus -PortNumber 8530 | Get-WsusComputer –ToLastSyncTime $date |

I sorted the computers WSUS knows about by date – picked the last 4 to sync so I didn’t overwhelm the Hyper-V host and started them up. Only trick is to get the computer name out of the FullDomainName property.