Link to home
Start Free TrialLog in
Avatar of Leo
LeoFlag for Australia

asked on

Computers reporting Windows patches applied

Hi,

Is there a PowerShell script or free tool, which can report on weekly basis the status of windows patches, in a way that it reports on how many updates has been applied to individual server, and when its was last patched?

Thanks.
Avatar of Mal Osborne
Mal Osborne
Flag of Australia image

You COULD look at installing WSUS. This is a role on Server 2008 and 2012, which maintains a central repository of patches, and allows machines to do updates from that. It is a bit of work to get going, but quite good once it is. It will certainly provide the functionality you are after.
Avatar of Leo

ASKER

We have WSUS,

Does WSUS reports for what patches has been applied for individual servers, when they were last patched?
Certainly can give you a list of all patches applied, just double click on a computer object in the WSUS console, and set the "Status" to "Installed/Not Applicable". You can see the time last checked in, but not sure if the last patching event is visible.
Avatar of Leo

ASKER

we have over 100 servers, I know on wsus I can click on every server and it will show which patches has been applied.
I am looking for automation where a tool or script will report on how many patches has been installed on each server and when it was last patched.
The script is available to pull all computers in given scope from AD and check for their patch level

Check below link
http://www.powershelladmin.com/wiki/Check_when_servers_were_last_patched_with_Windows_Update_via_COM_or_WSUS
Avatar of Leo

ASKER

I am getting this message on that link when I try to open it up.

"Sorry! This site is experiencing technical difficulties."

Are you able to open up that link?

thanks.
Until yesterday link was opening

I don't know suddenly some issues today saying that database error

Will update once link is UP
The link is up.
Avatar of Leo

ASKER

thanks,

Which fields I need to change in this script to make it work?

Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'

[reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") | Out-Null

# This requires an elevated console/host.
$Wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer()

# Create a computer scope that includes all computers that have at least one
# update reported to the WSUS server as in the installed state.
$ComputerScope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope
$ComputerScope.IncludedInstallationStates = [Microsoft.UpdateServices.Administration.UpdateInstallationStates]::Installed

# Create an update scope that includes updates that are installed.
$UpdateScope = New-Object Microsoft.UpdateServices.Administration.UpdateScope
$UpdateScope.IncludedInstallationStates = [Microsoft.UpdateServices.Administration.UpdateInstallationStates]::Installed

$Computers = $Wsus.GetComputerTargets($ComputerScope)

# Data hashtable, indexed by the computers' "FullDomainName" property.
$LastUpdateData = @{}

foreach ($Computer in $Computers) {
   
    #$ComputerName = $Computer.FullDomainName # -replace '\..+' # strip off domain, if present
    $LastUpdateData.($Computer.FullDomainName) = New-Object PSObject    
   
    $InstalledUpdates = $Computer.GetUpdateInstallationInfoPerUpdate($UpdateScope)
   
    # The updates apparently are sorted in the order they were installed,
    # so here I rely on this logic and store the arrival date and title
    # of the last installed update in the hashtable object.
    $InstalledUpdates | Select-Object -Last 1 | Foreach-Object {
       
        $Update = $_.GetUpdate()
       
        Add-Member -MemberType NoteProperty -Name 'ArrivalDate' -Value $Update.ArrivalDate -InputObject $LastUpdateData.($Computer.FullDomainName)
        Add-Member -MemberType NoteProperty -Name 'Title' -Value $Update.Title -InputObject $LastUpdateData.($Computer.FullDomainName)
       
    }
   
}

$LastUpdateData.GetEnumerator() | Sort-Object -Property @{Ascending=$true;e={$_.Value.ArrivalDate}},@{Ascending=$true;e={$_.Name}} |
    Select-Object -Property @{n='Host';e={$_.Name}},@{n='Arrival Date';e={$_.Value.ArrivalDate}},@{n='Title';e={$_.Value.Title}} |
    ConvertTo-Csv -NoTypeInformation | Set-Content Last-WSUS-Updates.csv

@"

Total computers found with at least one update installed: $($LastUpdateData.Keys.Count)
Output file: Last-WSUS-Updates.csv
"@

notepad Last-WSUS-Updates.csv
ASKER CERTIFIED SOLUTION
Avatar of David Johnson, CD
David Johnson, CD
Flag of Canada image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Leo

ASKER

Thanks David, so I will saving the script as .ps1? and changing notepad Last-WSUS-Updates.csv to C:\temp\lastupdate.csv?

Any other changes?
yes save it as a .ps1 and you can change the line that opens notepad to be whatever you want