59 How to view windows update (WSUS) summary report of left systems
In the below PowerShell script:-
- Name and save the script as “Get-Windows_Update_failed_left_system.PS1”.
- Run the script from the PowerShell console.
- The output will be displayed on the PowerShell console.
Note:
Only change the path that is highlighted below in bold with your folder path.
In case of any hurdle, please Contact Us
<#
.SYNOPSIS
Gets Patching Summary Report and Detail Report for a specific month's security patches for all servers or a particular group.
.DESCRIPTION
Summary Report contains the status(such as installed, failed, needed and pending reboot) for approved security patches of the month. It shows the machine counts of each status for each KB.
Detail Report lists all the machines that are needed/failed on the KBs of the month.
.NOTES
Author: InfotechFusion
Last update: 10/2021
Script required PowerShell Module "PoshWSUS" to work. The module is imported from fileshare. For more info about the module: https://www.powershellgallery.com/packages/PoshWSUS
.EXAMPLE
Get-WSUSReport -Month 2019-09
The above script gets the Patching Summary Report and Detail Report. They are saved to .\WSUSReport\2019-09\ for patches of Sep.2019 as no Group is specified.
***Report only includes servers that sync with WSUS in the last 7 days(defalut value) if the LastSyncDay variable is not specified.
.EXAMPLE
Get-WSUSReport -Month 2019-09 -$LastSyncDay 3
The above script gets the Patching Summary Report and Detail Report. They are saved to .\WSUSReport\2019-09\ for patches of Sep.2019 as no Group is specified.
***Report only includes servers that sync with WSUS in the last 3 days.
.EXAMPLE
Get-WSUSReport -Month 2019-09 -Group Production
The above script gets the Patching Summary Report and Detail Report. They are saved to .\WSUSReport\2019-09\Production as group "production" is specified. There are two more group options, "DMZ" and "Development"
***LastSyncTime cannot be used while group is specified.
#>
[CmdletBinding()]
Param
(
[parameter(Position=0, Mandatory=$true)]
[string]$Month,
[parameter(Position=1, Mandatory=$false)]
[ValidateSet('Production', 'DMZ', 'Development','Lab','AllServers')]
[string]$Group,
[parameter(Position=1, Mandatory=$false)]
[int]$LastSyncDay
)
#Define Variables
$Server = 'windowsupdate.Infotechfusion.com'
$path = ".\WSUSReports\$month"
$ExcludeState = "NotApplicable" ,"Installed", "Unknown"
$KBs = @()
# $LastSyncTime default is 7 days if $LastSyncDay is not specified
if($LastSyncDay){$LastSyncTime = (Get-Date).AddDays(-($LastSyncDay))}
else{$LastSyncTime = (Get-Date).AddDays(-7)}
#$Month = "2019-09"
#Group = "Production"
#Import module and connect to WSUS
Import-Module C:\ps\PoshWSUS
$null = Connect-PSWSUSServer -WsusServer $Server -Port 8530
#check if the pathe exist, if not create it
if (Test-Path 'WSUSReports')
{ if (Test-Path ".\WSUSReports\$month"){}
else{$null = New-Item -ItemType directory ".\WSUSReports\$month"}
}
else
{$null = New-Item -ItemType directory '.\WSUSReports'; $null = New-Item -ItemType directory ".\WSUSReports\$month"}
#get all approved security patches for servers
Write-Progress "Getting Approved Security Patches"
$ApprovedPatches = Get-PSWSUSUpdate -Update $month | where {$_.IsApproved -eq "True" -and $_.UpdateClassificationTitle -like "*Security*"}
################################### Patching Summary Report ##################################
Write-Progress "Getting Patching Stats Summary"
If($Group)
{
#create subfolder for the group
$path = ".\WSUSReports\$month\$Group"
if (!(Test-Path $path)){$null = New-Item -ItemType directory $path}
if($group -eq "lab"){$TargetGroup = "Laboratory"}
else{$TargetGroup = "Servers-$Group"}
$Patches = $ApprovedPatches | Get-PSWSUSUpdateSummaryPerGroup -GroupName $TargetGroup
}
else
{
$Group = "AllServers"
#For AllServer, Report only includes servers that are synced with WSUS in the last X days, X defined as $LastSyncTime
$Patches = $ApprovedPatches | Get-PSWSUSUpdateSummary -ComputerScope (New-PSWSUSComputerScope -FromLastSyncTime $LastSyncTime)
}
Write-Progress "Exporting Monthly Patching Summary Report"
# Write-host "Reports are saved to $path"
$Patches | Select UpdateTitle,UpdateKB,Installed,Needed,Failed,PendingReboot | sort UpdateTitle| Export-Csv -NoTypeInformation "$path\$month-PatchingReport-Summary-$Group-$((get-date).toString('yyyy-MM-dd')).csv"
################################### Patching Report for Individual KB ##########################
#getting all KBs with at least one needed or failed
Foreach($patch in $Patches)
{
If($patch.Failed -ne "0" -or $patch.needed -ne "0")
{
$KBs += $patch.UpdateKB
}
}
$KBs = $KBs | sort -Unique
Write-Progress "Exporting Computer list of each needed KB"
Foreach ($KB in $KBs)
{
If($Group -eq "AllServers")
{
#For AllServer, Report only includes servers that are synced with WSUS in the last X days, X defined as $LastSyncTime
$KBReport = Get-PSWSUSClientPerUpdate -Update $KB -ComputerScope (New-PSWSUSComputerScope -IncludeSubGroups -ExcludedInstallationState $ExcludeState -FromLastSyncTime $LastSyncTime ) | where {$_.UpdateTitle -like "*Server*"}`
}
else
{
$KBReport = Get-PSWSUSClientPerUpdate -Update $KB -GroupName $TargetGroup | where {$_.UpdateInstallationState -ne "NotApplicable " -and $_.UpdateInstallationState -ne "installed" -and $_.UpdateInstallationState -ne "Unknown"}
}
$KBReport |select Computername, UpdateKB,UpdateInstallationState,UpdateTitle | sort Computername| Export-Csv -NoTypeInformation "$path\$month-PatchingReport-Detail-$Group-$((get-date).toString('yyyy-MM-dd')).csv" -Append
#$KBReport | select Computername, UpdateKB,UpdateInstallationState,UpdateTitle | sort Computername| Export-Csv -NoTypeInformation "$path\KB$KB-$group-$((get-date).toString('yyyy-MM-dd')).csv"
}
$output = Import-Csv "$path\$month-PatchingReport-Detail-$Group-$((get-date).toString('yyyy-MM-dd')).csv"
$num = ($output.computername | sort -Unique).count
write-host "Computers missing $month 's updates : $num "
if($group -eq 'Development')
{
$output.computername | ? {$_ -notlike "*RWC1BINF*"}| sort name |Sort -Unique | Out-File Patching-$Group-VMs.txt
}
else
{
$output.computername | sort name |Sort -Unique | Out-File Patching-$Group-VMs.txt
}