diff --git a/images/win/scripts/ImageHelpers/ImageHelpers.psm1 b/images/win/scripts/ImageHelpers/ImageHelpers.psm1 index 5eed2299056f..03e0307426bc 100644 --- a/images/win/scripts/ImageHelpers/ImageHelpers.psm1 +++ b/images/win/scripts/ImageHelpers/ImageHelpers.psm1 @@ -41,4 +41,5 @@ Export-ModuleMember -Function @( 'Get-AndroidPackagesByVersion' 'Get-VisualStudioInstance' 'Get-VisualStudioComponents' + 'Get-WindowsUpdatesHistory' ) diff --git a/images/win/scripts/ImageHelpers/InstallHelpers.ps1 b/images/win/scripts/ImageHelpers/InstallHelpers.ps1 index e05e44e9ff44..0d4b84adbe99 100644 --- a/images/win/scripts/ImageHelpers/InstallHelpers.ps1 +++ b/images/win/scripts/ImageHelpers/InstallHelpers.ps1 @@ -489,3 +489,47 @@ function Get-AndroidPackagesByVersion { $packagesByVersion = $packagesByName | Where-Object { ($_.Split($Delimiter)[$Index] -as $Type) -ge $MinimumVersion } return $packagesByVersion | Sort-Object { $_.Split($Delimiter)[$Index] -as $Type} -Unique } + +function Get-WindowsUpdatesHistory { + $allEvents = @{} + # 19 - Installation Successful: Windows successfully installed the following update + # 20 - Installation Failure: Windows failed to install the following update with error + # 43 - Installation Started: Windows has started installing the following update + $filter = @{ + LogName = "System" + Id = 19, 20, 43 + ProviderName = "Microsoft-Windows-WindowsUpdateClient" + } + $events = Get-WinEvent -FilterHashtable $filter -ErrorAction SilentlyContinue | Sort-Object Id + + foreach ( $event in $events ) { + switch ( $evnt.Id ) { + 19 { + $status = "Successful" + $title = $event.Properties[0].Value + $allEvents.Add($title, "") + break + } + 20 { + $status = "Failure" + $title = $event.Properties[1].Value + $allEvents.Add($title, "") + break + } + 43 { + $status = "InProgress" + $title = $event.Properties[0].Value + break + } + } + + if ( $status -eq "InProgress" -and $allEvents.ContainsKey($title) ) { + continue + } + + [PSCustomObject]@{ + Status = $status + Title = $title + } + } +} \ No newline at end of file diff --git a/images/win/scripts/Installers/Install-WindowsUpdates.ps1 b/images/win/scripts/Installers/Install-WindowsUpdates.ps1 index b2035ae8988a..bcdfc21a691a 100644 --- a/images/win/scripts/Installers/Install-WindowsUpdates.ps1 +++ b/images/win/scripts/Installers/Install-WindowsUpdates.ps1 @@ -17,13 +17,13 @@ function Install-WindowsUpdates { } Write-Host "Installing windows updates" - Get-WindowsUpdate -MicrosoftUpdate -AcceptAll -Install -IgnoreUserInput -IgnoreReboot | Out-Host + Get-WindowsUpdate -MicrosoftUpdate -AcceptAll -Install -IgnoreUserInput -IgnoreReboot -OutVariable current | Out-Host Write-Host "Validating windows updates installation and skip Microsoft Defender Antivirus" # Azure service can automatic updates AV engine(Microsoft.Azure.Security.AntimalwareSignature.AntimalwareConfiguration) - # Operationname = Installation and Restul=Succeeded/InProgress - $wuHistory = Get-WUHistory | Where-Object { $_.OperationName -eq "Installation" -and $_.Result -in ("Succeeded", "InProgress") } - $wuFail = $updates[0] | Where-Object Title -notmatch "Microsoft Defender Antivirus" | Where-Object KB -notin $wuHistory.KB + # Get-WUHistory doesn't support Windows Server 2022 + $wuHistory = Get-WindowsUpdatesHistory | Where-Object { $_.Status -in ("Successful", "InProgress") } + $wuFail = $updates[0] | Where-Object Title -notmatch "Microsoft Defender Antivirus" | Where-Object { -not ($wuHistory.Title -match $_.KB) } if ( $wuFail ) { Write-Host "Windows updates failed to install: $($wuFail.KB)" diff --git a/images/win/scripts/Tests/WindowsFeatures.Tests.ps1 b/images/win/scripts/Tests/WindowsFeatures.Tests.ps1 index 4f16f573d922..7c754967c005 100644 --- a/images/win/scripts/Tests/WindowsFeatures.Tests.ps1 +++ b/images/win/scripts/Tests/WindowsFeatures.Tests.ps1 @@ -62,16 +62,19 @@ Describe "Windows Updates" { "$env:windir\WindowsUpdateDone.txt" | Should -Exist } - $testCases = Get-WUHistory | Where-Object Title -notmatch "Microsoft Defender Antivirus" | ForEach-Object { + $testCases = Get-WindowsUpdatesHistory | Sort-Object Title | ForEach-Object { @{ Title = $_.Title - Result = $_.Result - OperationName = $_.OperationName + Status = $_.Status } } It "