Script to Report on Software Update Group compliance

This script will collect the status of the last created Software Update Group and send it as a mail to the specified recipient(s).

All you have to do is to change the variables under #Mail and #Variables to match your domain settings.

After that you can set up a scheduled task that runs this script with the frequency that you want.

Import-Module '\\sccmserver\d$\Program Files\Microsoft Configuration Manager\AdminConsole\bin\ConfigurationManager.psd1'

#Mail
$smtpServer = "smtprelay.customer.com"
$mailinfo_from = "server1@customer.com"
$mailinfo_to = "initials@company.com"
$mailinfo_cc = ""
$subject = "Windows 10 Patch Compliance - "

#Variables
$tableheading = "Windows 10 Patch Compliance - "
$logoURL = "<Img src='https://www.url.com/picture.gif' style='float:left' width='99' height='75' hspace=10>"
[string]$SavePath = "c:\temp\Compliance Reports"
$year = (Get-Date).year
$month = Get-Date -Format MM
$SiteCode = "SiteCode"


$ReportTitle = "System Report"
[string]$reportVersion = "1.0"


$head = @"
<style>
TABLE {border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;margin-left:50px}
TH {border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color: #8c0000;}
TD {border-width: 1px;padding: 3px;border-style: solid;border-color: black;}
.odd  { background-color:#ffffff; }
.even { background-color:#dddddd; }
</style>
<Title>$ReportTitle</Title>
"@


#Access the SCCM Site
Set-Location $SiteCode:

#Finding the latest created Software Update Group

$SUG = Get-CMSoftwareUpdateGroup | Sort-Object { $_.datecreated } -Descending | Select -First 1

$updategroupname = $SUG.LocalizedDisplayName

#Getting all updates on that Software update Group

$Updates = (Get-CMSoftwareUpdate -UpdateGroupName $updategroupname) | Select-Object Vendor, ArticleID, BulletinID, @{E = { $_.LocalizedDisplayName }; L = "Titel" }, @{E = { $_.NumPresent }; L = "Installed" }, @{E = { $_.NumMissing }; L = "Required" }, @{E = { $_.NumNotApplicable }; L = "Not Required" } , @{E = { $_.NumUnknown }; L = "Unknown" }, @{E = { $_.NumTotal }; L = "Total" }, @{E = { [math]::Round((($_.NumPresent / ($_.NumPresent + $_.NumMissing)) * 100), 2) }; L = "% Compliant" }, @{E = { [math]::Round((($_.NumMissing / ($_.NumPresent + $_.NumMissing)) * 100), 2) }; L = "% Not Compliant" }, @{E = { [math]::Round((($_.NumUnknown / $_.NumTotal) * 100), 2) }; L = "% Unknown" }

#Write results depending on parameter set
$footer = "Report ran from {3} initiated by {1}\{2}" -f (Get-Date), $env:USERDOMAIN, $env:USERNAME, $env:COMPUTERNAME

#Prepare HTML code
$fragments = @()

#Insert a graphic header
$fragments += "$logoURL<br><br>"

$fragments += $Updates | ConvertTo-HTML -Fragment -PreContent "<H2>$tableheading $updategroupname</H2>"


write $fragments | clip
$outFile = ConvertTo-Html -Head $head -Title $ReportTitle -PreContent ($fragments | out-String) -PostContent "<br><I>$footer</I>"


#Checks savepath and export file.
IF ((test-path $SavePath) -eq $False) { md $SavePath }
$ExportFile = "$SavePath\Win 10 Compliance-$updategroupname.csv"
IF (Test-Path $ExportFile) { Remove-Item $ExportFile }


$Updates | export-csv $ExportFile -Append -Force -NoTypeInformation

$body = "" + $OutFile

Send-MailMessage -SmtpServer $smtpServer -From $mailinfo_from -To $mailinfo_to -Subject "$subject $updategroupname" -Body $body -BodyAsHtml -Attachments $ExportFile