Windows Server Update Services (WSUS) administrators often need to compare update approval statuses across different computer groups. The native WSUS console provides basic reporting, but lacks the ability to:
- Show differential approvals between groups
- Export tabular data for automated processing
- Filter updates approved for Group A but not Group B
This PowerShell script connects to the WSUS server and generates a comprehensive report showing update approval status across all computer groups:
# WSUS Group Approval Comparison Script
[void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer()
# Get all updates and groups
$updates = $wsus.GetUpdates()
$groups = $wsus.GetComputerTargetGroups()
# Create approval matrix
$report = @()
foreach ($update in $updates) {
$row = New-Object PSObject -Property @{
UpdateID = $update.Id.UpdateId
Title = $update.Title
}
foreach ($group in $groups) {
$approval = $update.GetUpdateApproval($group)
$row | Add-Member -NotePropertyName $group.Name -NotePropertyValue $approval.Action
}
$report += $row
}
# Export to CSV
$report | Export-Csv -Path "WSUS_Approval_Matrix.csv" -NoTypeInformation
To specifically find updates approved for GroupA but not GroupB:
# Filter the matrix for GroupA-approved but GroupB-not-approved updates
$filtered = $report | Where-Object {
$_.GroupA -eq "Install" -and
($_.GroupB -ne "Install" -or !$_.GroupB)
}
$filtered | Format-Table -AutoSize
For more sophisticated reporting needs, consider these enhancements:
# Add KB article information to the report
foreach ($row in $report) {
$kb = ($row.Title -split "$")[-1] -replace "$",""
$row | Add-Member -NotePropertyName "KB" -NotePropertyValue $kb
}
# Include update classification
$report | ForEach-Object {
$update = $wsus.GetUpdate([guid]$_.UpdateID)
$_ | Add-Member -NotePropertyName "Classification" -NotePropertyValue $update.UpdateClassificationTitle
}
# Create HTML report
$html = $report | ConvertTo-Html -Property Title,KB,Classification,GroupA,GroupB,GroupC
$html | Out-File "WSUS_Group_Approvals.html"
For regular reporting, schedule this script to run weekly and email the results:
# Schedule with Task Scheduler
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File C:\Scripts\WSUS_Group_Approvals.ps1"
$trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Monday -At 2am
Register-ScheduledTask -TaskName "WSUS Group Approval Report" -Action $action -Trigger $trigger
# Email the report (requires Send-MailMessage configuration)
Send-MailMessage -From "wsus@domain.com" -To "admin@domain.com" -Subject "Weekly WSUS Approval Report" -Body "Attached" -Attachments "WSUS_Approval_Matrix.csv" -SmtpServer "mail.domain.com"
When managing Windows Server Update Services (WSUS), administrators often need to compare update approval statuses across different computer groups. The native WSUS console doesn't provide a straightforward way to generate reports showing which updates are approved for one group but not others.
We can leverage the WSUS API through PowerShell to extract this information. The script will:
- Connect to the WSUS server
- Retrieve all computer groups
- Compare update approvals between specified groups
- Generate a comprehensive report
Before running the script, ensure you have:
# Install WSUS Administration Tools if not present
Install-WindowsFeature -Name UpdateServices-API
Here's the complete solution to generate the report:
# Import WSUS assembly
[reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration") | Out-Null
# Connect to WSUS server
$wsusServer = "YourWSUSServer"
$wsusPort = 8530
$useSSL = $false
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer($wsusServer, $useSSL, $wsusPort)
# Define target groups
$primaryGroupName = "GroupA"
$compareGroups = @("GroupB", "GroupC")
# Get update scope
$updateScope = New-Object Microsoft.UpdateServices.Administration.UpdateScope
# Get computer groups
$primaryGroup = $wsus.GetComputerTargetGroups() | Where-Object { $_.Name -eq $primaryGroupName }
$compareGroupsObj = $wsus.GetComputerTargetGroups() | Where-Object { $compareGroups -contains $_.Name }
# Initialize report collection
$report = @()
# Process all updates
$wsus.GetUpdates($updateScope) | ForEach-Object {
$update = $_
$primaryApproval = $update.GetUpdateApprovals($primaryGroup.Id)
if ($primaryApproval) {
$row = [PSCustomObject]@{
UpdateTitle = $update.Title
UpdateID = $update.Id.UpdateId
PrimaryGroupApproved = $true
}
foreach ($group in $compareGroupsObj) {
$approval = $update.GetUpdateApprovals($group.Id)
$row | Add-Member -NotePropertyName "$($group.Name)Approved" -NotePropertyValue ($approval -ne $null)
}
$report += $row
}
}
# Filter for updates approved in primary group but not in others
$filteredReport = $report | Where-Object {
$needsAttention = $false
foreach ($group in $compareGroups) {
$property = "${group}Approved"
if (-not $_.$property) {
$needsAttention = $true
break
}
}
$needsAttention
}
# Export to CSV
$filteredReport | Export-Csv -Path "WSUS_Group_Approval_Report.csv" -NoTypeInformation
You can modify the script to produce different report formats:
# HTML Report Example
$htmlReport = $filteredReport | ConvertTo-Html -Property UpdateTitle, UpdateID, *Approved
$htmlReport | Out-File "WSUS_Report.html"
For more complex filtering, you can add criteria like update classification or product:
# Filter by security updates only
$securityUpdates = $wsus.GetUpdates($updateScope) | Where-Object {
$_.UpdateClassificationTitle -match "Security"
}
Create a scheduled task to run the script weekly:
$trigger = New-JobTrigger -Weekly -DaysOfWeek Monday -At 3am
Register-ScheduledJob -Name "WeeklyWSUSReport" -FilePath "C:\Scripts\WSUS_Group_Report.ps1" -Trigger $trigger