Skip to content

Commit df27520

Browse files
authored
[Windows] Add test to validate windows updates installation (#4489)
* Add test to validate windows updates installation * Add function Get-WindowsUpdatesHistory
1 parent 1b583e0 commit df27520

File tree

5 files changed

+110
-18
lines changed

5 files changed

+110
-18
lines changed

images/win/scripts/ImageHelpers/ImageHelpers.psm1

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,5 @@ Export-ModuleMember -Function @(
4343
'Get-AndroidPackagesByVersion'
4444
'Get-VisualStudioInstance'
4545
'Get-VisualStudioComponents'
46+
'Get-WindowsUpdatesHistory'
4647
)

images/win/scripts/ImageHelpers/InstallHelpers.ps1

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,3 +489,47 @@ function Get-AndroidPackagesByVersion {
489489
$packagesByVersion = $packagesByName | Where-Object { ($_.Split($Delimiter)[$Index] -as $Type) -ge $MinimumVersion }
490490
return $packagesByVersion | Sort-Object { $_.Split($Delimiter)[$Index] -as $Type} -Unique
491491
}
492+
493+
function Get-WindowsUpdatesHistory {
494+
$allEvents = @{}
495+
# 19 - Installation Successful: Windows successfully installed the following update
496+
# 20 - Installation Failure: Windows failed to install the following update with error
497+
# 43 - Installation Started: Windows has started installing the following update
498+
$filter = @{
499+
LogName = "System"
500+
Id = 19, 20, 43
501+
ProviderName = "Microsoft-Windows-WindowsUpdateClient"
502+
}
503+
$events = Get-WinEvent -FilterHashtable $filter -ErrorAction SilentlyContinue | Sort-Object Id
504+
505+
foreach ( $event in $events ) {
506+
switch ( $event.Id ) {
507+
19 {
508+
$status = "Successful"
509+
$title = $event.Properties[0].Value
510+
$allEvents[$title] = ""
511+
break
512+
}
513+
20 {
514+
$status = "Failure"
515+
$title = $event.Properties[1].Value
516+
$allEvents[$title] = ""
517+
break
518+
}
519+
43 {
520+
$status = "InProgress"
521+
$title = $event.Properties[0].Value
522+
break
523+
}
524+
}
525+
526+
if ( $status -eq "InProgress" -and $allEvents.ContainsKey($title) ) {
527+
continue
528+
}
529+
530+
[PSCustomObject]@{
531+
Status = $status
532+
Title = $title
533+
}
534+
}
535+
}

images/win/scripts/Installers/Install-WindowsUpdates.ps1

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,34 @@
44
## Should be run at end, just before SoftwareReport and Finalize-VM.ps1.
55
################################################################################
66

7-
Write-Host "Run windows updates"
8-
Get-WUInstall -MicrosoftUpdate -AcceptAll -Install -IgnoreUserInput -IgnoreReboot
7+
function Install-WindowsUpdates {
8+
Write-Host "Starting wuauserv"
9+
Start-Service -Name wuauserv -PassThru | Out-Host
10+
11+
Write-Host "Getting list of available windows updates"
12+
Get-WindowsUpdate -MicrosoftUpdate -OutVariable updates | Out-Host
13+
14+
if ( -not $updates ) {
15+
Write-Host "There are no windows updates to install"
16+
return
17+
}
18+
19+
Write-Host "Installing windows updates"
20+
Get-WindowsUpdate -MicrosoftUpdate -AcceptAll -Install -IgnoreUserInput -IgnoreReboot | Out-Host
21+
22+
Write-Host "Validating windows updates installation and skip Microsoft Defender Antivirus"
23+
# Azure service can automatic updates AV engine(Microsoft.Azure.Security.AntimalwareSignature.AntimalwareConfiguration)
24+
# Get-WUHistory doesn't support Windows Server 2022
25+
$wuHistory = Get-WindowsUpdatesHistory | Where-Object { $_.Status -in ("Successful", "InProgress") }
26+
$wuFail = $updates[0] | Where-Object Title -notmatch "Microsoft Defender Antivirus" | Where-Object { -not ($wuHistory.Title -match $_.KB) }
27+
28+
if ( $wuFail ) {
29+
Write-Host "Windows updates failed to install: $($wuFail.KB)"
30+
exit 1
31+
}
32+
}
33+
34+
Install-WindowsUpdates
35+
36+
# Create complete windows update file
37+
New-Item -Path $env:windir -Name WindowsUpdateDone.txt -ItemType File | Out-Null

images/win/scripts/Tests/WindowsFeatures.Tests.ps1

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,3 +56,25 @@ Describe "Test Signed Drivers" -Skip:(Test-IsWin16) {
5656
"$(bcdedit)" | Should -Match "testsigning\s+Yes"
5757
}
5858
}
59+
60+
Describe "Windows Updates" {
61+
It "WindowsUpdateDone.txt should exist" {
62+
"$env:windir\WindowsUpdateDone.txt" | Should -Exist
63+
}
64+
65+
$testCases = Get-WindowsUpdatesHistory | Sort-Object Title | ForEach-Object {
66+
@{
67+
Title = $_.Title
68+
Status = $_.Status
69+
}
70+
}
71+
72+
It "<Title>" -TestCases $testCases {
73+
$expect = "Successful"
74+
if ( $Title -match "Microsoft Defender Antivirus" ) {
75+
$expect = "Successful", "Failure"
76+
}
77+
78+
$Status | Should -BeIn $expect
79+
}
80+
}

images/win/windows2019.json

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -143,21 +143,6 @@
143143
},
144144
{
145145
"type": "powershell",
146-
"scripts": [
147-
"{{ template_dir }}/scripts/Installers/Install-WindowsUpdates.ps1"
148-
],
149-
"elevated_user": "{{user `install_user`}}",
150-
"elevated_password": "{{user `install_password`}}"
151-
},
152-
{
153-
"type": "windows-restart",
154-
"check_registry": true,
155-
"restart_check_command": "powershell -command \"& {if ((-not (Get-Process TiWorker.exe -ErrorAction SilentlyContinue)) -and (-not [System.Environment]::HasShutdownStarted) ) { Write-Output 'Restart complete' }}\"",
156-
"restart_timeout": "30m"
157-
},
158-
{
159-
"type": "powershell",
160-
"pause_before": "2m",
161146
"scripts": [
162147
"{{ template_dir }}/scripts/Installers/Install-VCRedist.ps1",
163148
"{{ template_dir }}/scripts/Installers/Install-Docker.ps1",
@@ -271,12 +256,23 @@
271256
"{{ template_dir }}/scripts/Installers/Install-LLVM.ps1"
272257
]
273258
},
259+
{
260+
"type": "powershell",
261+
"scripts": [
262+
"{{ template_dir }}/scripts/Installers/Install-WindowsUpdates.ps1"
263+
],
264+
"elevated_user": "{{user `install_user`}}",
265+
"elevated_password": "{{user `install_password`}}"
266+
},
274267
{
275268
"type": "windows-restart",
276-
"restart_timeout": "10m"
269+
"check_registry": true,
270+
"restart_check_command": "powershell -command \"& {if ((-not (Get-Process TiWorker.exe -ErrorAction SilentlyContinue)) -and (-not [System.Environment]::HasShutdownStarted) ) { Write-Output 'Restart complete' }}\"",
271+
"restart_timeout": "30m"
277272
},
278273
{
279274
"type": "powershell",
275+
"pause_before": "2m",
280276
"scripts": [
281277
"{{ template_dir }}/scripts/Tests/RunAll-Tests.ps1"
282278
]

0 commit comments

Comments
 (0)