nullzilla

Monitor - Windows Update

Feb 11th, 2021 (edited)
3,560
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. # Windows Update Monitor
  2. Import-Module $env:SyncroModule -DisableNameChecking
  3. <# Todo: properly handle less common Win10 editions LTSB/LTSC & ESU
  4.          https://learn.microsoft.com/en-us/windows/release-health/release-information
  5. Changes: - Split out $Win11MaxAge into editions
  6.          - Handle last version of Windows 10 correctly (22H2 is 36 months)
  7.          - Refactor code to be less redundant
  8.          - Change alert message to use regular version instead of converted to numerical form
  9.          - Properly handle 11 Enterprise/Edu/IoT Enterprise
  10. #>
  11.  
  12. # Maximum age of builds you want to support in months
  13. [int]$Win10MaxAge = "18" # EOS for Home/Pro is 18 months except for 22H2 which we account for later
  14. [int]$Win11HomeProMaxAge = "24" # EOS for Home/Pro is 24 months
  15. [int]$Win11EntEduIoTMaxAge = "36" # EOS for Enterprise/Education/IoT Enterprise is 36 months
  16.  
  17. # Number of days to consider an update recent
  18. $Recent = '50'
  19.  
  20. # UTC Time Offset: check yours at https://www.timeanddate.com/time/difference/timezone/utc
  21. $Offset = '-6'
  22.  
  23. # Check Windows version age
  24. $OSname = Get-CimInstance Win32_OperatingSystem | Select-Object -ExpandProperty Caption
  25. if ((Get-CimInstance Win32_OperatingSystem).Version -gt '10' -and $OSname -notlike '*Server*') {
  26.     # Grab version (19041 and older do not have DisplayVersion so we grab ReleaseID)
  27.     if ((Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").DisplayVersion) {
  28.         $Version = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").DisplayVersion
  29.     } else {
  30.         $Version = (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion").ReleaseId
  31.     }
  32.     if ($OSname -match 'Windows 10') {
  33.         # Adjustment for last version of Windows 10
  34.         if ($Version -eq '22H2') {
  35.             $MaxAge = 36
  36.         } else { $MaxAge = $Win10MaxAge }
  37.     }
  38.     if ($OSname -match 'Windows 11 Home' -or $OSname -match 'Windows 11 Pro') {
  39.         $MaxAge = $Win11HomeProMaxAge
  40.     }
  41.     if ($OSname -match 'Windows 11 Enterprise' -or $OSname -match 'Windows 11 Education' -or $OSname -match 'Windows 11 IoT Enterprise') {
  42.         $MaxAge = $Win11EntEduIoTMaxAge
  43.     }
  44.     # Convert current date to comparable format and subtract $MaxAge
  45.     $CurrentDate = (Get-Date).AddMonths(-$MaxAge).ToString("yyMM")    
  46.     # Convert $Version to numerical format and subtract $CurrentDate
  47.     $VersionNumerical = ($Version).replace('H1', '05').replace('H2', '10')
  48.     $Diff = $VersionNumerical - $CurrentDate
  49.     if ($Diff -lt '0') {
  50.         Write-Host "$OSname $Version is over $MaxAge months old, needs upgrading"`n
  51.         Rmm-Alert -Category "Monitor - Windows Update" -Body "$OSname $Version is over $MaxAge months old, needs upgrading"
  52.         exit 1
  53.     } else {
  54.         Write-Host "$OSname $Version is less than the max age of $MaxAge months"`n
  55.         Close-Rmm-Alert -Category "Monitor - Windows Update"
  56.     }
  57. } else {
  58.     Write-Host "Unsupported OS: $OSname`nThis script only supports Windows 10 & 11, exiting..."
  59. }
  60.  
  61. # Check for disabled services
  62. $DisabledServices = Get-Service WUAUServ, BITS, CryptSvc, RPCSS, EventLog | Where-Object -Property 'StartType' -eq 'Disabled'
  63. if ($DisabledServices) {
  64.     "Disabled Services:"
  65.     $DisabledServices
  66.     Rmm-Alert -Category "Monitor - Windows Update" -Body "Disabled Services: $DisabledService"
  67.     exit 1
  68. } else {
  69.     Close-Rmm-Alert -Category "Monitor - Windows Update"
  70. }
  71.  
  72. # If the Microsoft Update service is not enabled, enable it.
  73. $UpdateService = New-Object -ComObject Microsoft.Update.ServiceManager
  74. $MicrosoftUpdateService = $UpdateService.Services | Where-Object { $_.ServiceId -eq '7971f918-a847-4430-9279-4a52d1efe18d' }
  75. if (!$MicrosoftUpdateService) {
  76.     $UpdateService.AddService2('7971f918-a847-4430-9279-4a52d1efe18d', 7, '')
  77. }
  78.  
  79. # Check if recent updates are installed
  80. $WindowsUpdateObject = New-Object -ComObject Microsoft.Update.AutoUpdate
  81.  
  82. $SearchSuccessDate = $WindowsUpdateObject.Results | Select-Object LastSearchSuccessDate
  83. $SSDLastDate = ([datetime]$SearchSuccessDate.LastSearchSuccessDate).AddHours($Offset)
  84. $SSDDays = (New-TimeSpan -Start $SSDLastDate -End (Get-Date) | Select-Object Days).Days
  85. Write-Host 'Last Search Success:' $SSDLastDate "($SSDDays days ago)"`n
  86.  
  87. $InstallSuccessDate = $windowsUpdateObject.Results | Select-Object LastInstallationSuccessDate
  88. $ISDLastDate = ([datetime]$InstallSuccessDate.LastInstallationSuccessDate).AddHours($Offset)
  89. $ISDDays = (New-TimeSpan -Start $ISDLastDate -End (Get-Date) | Select-Object Days).Days
  90. Write-Host 'Last Installation Success:' $ISDLastDate "($ISDDays days ago)"`n
  91.  
  92. $Searcher = (New-Object -ComObject 'Microsoft.Update.Session').CreateUpdateSearcher()
  93. $HistoryCount = $Searcher.GetTotalHistoryCount()
  94.  
  95. if ($HistoryCount -gt 0) {
  96.     $xx = $Searcher.QueryHistory(0, $HistoryCount) | Where-Object { $_.Operation -like 1 -and $_.ResultCode -match '[123]' } | Select-Object Title
  97. }
  98.  
  99. $LastMonth = (Get-Date).AddMonths(-1).ToString("yyyy-MM")
  100. $ThisMonth = (Get-Date).ToString("yyyy-MM")
  101. $xx = $xx | Where-Object { $_ -match "($LastMonth|$ThisMonth) (Security Monthly Quality Rollup for Windows|Cumulative Update for Windows)" -or $_ -match "Feature update" }
  102. if (!$xx -and $ISDDays -gt $Recent) {
  103.     Write-Output "WARNING - No recent rollup/cumulative/feature update detected"
  104.     Write-Output "Last updates:"
  105.     $xx | Select-Object -ExpandProperty Title -First 1
  106.     Rmm-Alert -Category "Monitor - Windows Update" -Body "WARNING - No recent rollup/cumulative/feature update detected"
  107.     exit 1
  108. } else {
  109.     Write-Output "Recent rollup or cumulative update detected:"
  110.     $xx | Select-Object -ExpandProperty Title -First 1
  111.     Close-Rmm-Alert -Category "Monitor - Windows Update"
  112. }
  113.  
Advertisement
Add Comment
Please, Sign In to add comment