Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Windows] Add test to validate windows updates installation #4489

Merged
merged 4 commits into from
Nov 16, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions images/win/scripts/ImageHelpers/ImageHelpers.psm1
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,5 @@ Export-ModuleMember -Function @(
'Get-AndroidPackagesByVersion'
'Get-VisualStudioInstance'
'Get-VisualStudioComponents'
'Get-WindowsUpdatesHistory'
)
44 changes: 44 additions & 0 deletions images/win/scripts/ImageHelpers/InstallHelpers.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -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 ( $event.Id ) {
19 {
$status = "Successful"
$title = $event.Properties[0].Value
$allEvents[$title] = ""
break
}
20 {
$status = "Failure"
$title = $event.Properties[1].Value
$allEvents[$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
}
}
}
33 changes: 31 additions & 2 deletions images/win/scripts/Installers/Install-WindowsUpdates.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,34 @@
## Should be run at end, just before SoftwareReport and Finalize-VM.ps1.
################################################################################

Write-Host "Run windows updates"
Get-WUInstall -MicrosoftUpdate -AcceptAll -Install -IgnoreUserInput -IgnoreReboot
function Install-WindowsUpdates {
Write-Host "Starting wuauserv"
Start-Service -Name wuauserv -PassThru | Out-Host

Write-Host "Getting list of available windows updates"
Get-WindowsUpdate -MicrosoftUpdate -OutVariable updates | Out-Host

if ( -not $updates ) {
Write-Host "There are no windows updates to install"
return
}

Write-Host "Installing windows updates"
Get-WindowsUpdate -MicrosoftUpdate -AcceptAll -Install -IgnoreUserInput -IgnoreReboot | 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)
# 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)"
exit 1
}
}

Install-WindowsUpdates

# Create complete windows update file
New-Item -Path $env:windir -Name WindowsUpdateDone.txt -ItemType File | Out-Null
22 changes: 22 additions & 0 deletions images/win/scripts/Tests/WindowsFeatures.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -56,3 +56,25 @@ Describe "Test Signed Drivers" -Skip:(Test-IsWin16) {
"$(bcdedit)" | Should -Match "testsigning\s+Yes"
}
}

Describe "Windows Updates" {
It "WindowsUpdateDone.txt should exist" {
"$env:windir\WindowsUpdateDone.txt" | Should -Exist
}

$testCases = Get-WindowsUpdatesHistory | Sort-Object Title | ForEach-Object {
@{
Title = $_.Title
Status = $_.Status
}
}

It "<Title>" -TestCases $testCases {
$expect = "Successful"
if ( $Title -match "Microsoft Defender Antivirus" ) {
$expect = "Successful", "Failure"
}

$Status | Should -BeIn $expect
}
}
28 changes: 12 additions & 16 deletions images/win/windows2019.json
Original file line number Diff line number Diff line change
Expand Up @@ -143,21 +143,6 @@
},
{
"type": "powershell",
"scripts": [
"{{ template_dir }}/scripts/Installers/Install-WindowsUpdates.ps1"
],
"elevated_user": "{{user `install_user`}}",
"elevated_password": "{{user `install_password`}}"
},
{
"type": "windows-restart",
"check_registry": true,
"restart_check_command": "powershell -command \"& {if ((-not (Get-Process TiWorker.exe -ErrorAction SilentlyContinue)) -and (-not [System.Environment]::HasShutdownStarted) ) { Write-Output 'Restart complete' }}\"",
"restart_timeout": "30m"
},
{
"type": "powershell",
"pause_before": "2m",
"scripts": [
"{{ template_dir }}/scripts/Installers/Install-VCRedist.ps1",
"{{ template_dir }}/scripts/Installers/Install-Docker.ps1",
Expand Down Expand Up @@ -270,12 +255,23 @@
"{{ template_dir }}/scripts/Installers/Enable-DeveloperMode.ps1"
]
},
{
"type": "powershell",
"scripts": [
"{{ template_dir }}/scripts/Installers/Install-WindowsUpdates.ps1"
],
"elevated_user": "{{user `install_user`}}",
"elevated_password": "{{user `install_password`}}"
},
{
"type": "windows-restart",
"restart_timeout": "10m"
"check_registry": true,
"restart_check_command": "powershell -command \"& {if ((-not (Get-Process TiWorker.exe -ErrorAction SilentlyContinue)) -and (-not [System.Environment]::HasShutdownStarted) ) { Write-Output 'Restart complete' }}\"",
"restart_timeout": "30m"
},
{
"type": "powershell",
"pause_before": "2m",
"scripts": [
"{{ template_dir }}/scripts/Tests/RunAll-Tests.ps1"
]
Expand Down