In an effort to reduce our required outage time for patching, I’ve created a worklet that sets a few registry keys on Windows systems to enable Windows Update to download (but not install) any newly relevant patches. This should significantly improve our ability to execute patching windows quickly, especially for systems at remote locations or with restricted bandwidth.
Note: only the ‘NoAutoUpdate’ and ‘AUOptions’ keys are actually required to enable this behavior. There are two other keys we have included to better manage this process for our needs.
(Special shoutout to @Josh-W for some assistance/finishing touches!)
Evaluation Code:
# Check registry key/value to enable Automatic Downloading of all relevant patches - DOES NOT INSTALL
#############################################
$regPathAU = 'HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate\AU'
$regPathWindowsUpdate = 'HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate'
$regPropertyAUOptions = 'AUOptions'
$desiredValueAUOptions = '3'
$regPropertyNAU = 'NoAutoUpdate'
$desiredValueNAU = '1'
$regPropertyAIMU = 'AutoInstallMinorUpdates'
$desiredValueAIMU = '0'
$regPropertyENA = 'ElevateNonAdmins'
$desiredValueENA = '0' # ElevateNonAdmins = 0 - Only users in the Administrators user group can approve or disapprove updates
$response = ''
$registryFlag = $true #indicates registry keys are set correctly
#############################################
# Retrieve current values for comparison
$currentValueAUOptions = (Get-ItemProperty -Path $regPathAU -Name $regPropertyAUOptions -ErrorAction SilentlyContinue).$regPropertyAUOptions
$currentValueNAU = (Get-ItemProperty -Path $regPathAU -Name $regPropertyNAU -ErrorAction SilentlyContinue).$regPropertyNAU
$currentValueAIMU = (Get-ItemProperty -Path $regPathAU -Name $regPropertyAIMU -ErrorAction SilentlyContinue).$regPropertyAIMU
$currentValueENA = (Get-ItemProperty -Path $regPathWindowsUpdate -Name $regPropertyENA -ErrorAction SilentlyContinue).$regPropertyENA
# Compare current with desired and exit accordingly.
# 0 for Compliant, 1 for Non-Compliant
if ($currentValueAUOptions -eq $desiredValueAUOptions) {
if ($currentValueNAU -eq $desiredValueNAU) {
if ($currentValueAIMU -eq $desiredValueAIMU) {
if ($currentValueENA -eq $desiredValueENA) {
} else { $registryFlag = $false } #registry key is not set
} else { $registryFlag = $false } #registry key is not set
} else { $registryFlag = $false } #registry key is not set
} else { $registryFlag = $false } #registry key is not set
if (!$registryFlag) {
$response = 'A registry key is missing'
Write-Output $response
Exit 1
} else {
$response = 'All registry keys for Automox patching are set as expected'
Write-Output $response
Exit 0
}
Remediation Code:
# Define Registry paths, key(s) and variables
#############################################
# paths
$regPathAU = 'HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate\AU'
$regPathWindowsUpdate = 'HKLM:\Software\Policies\Microsoft\Windows\WindowsUpdate'
# key(s)/variables
$regPropertyENA = 'ElevateNonAdmins'
$desiredValueENA = '0' # ElevateNonAdmins = 0 - Only users in the Administrators user group can approve or disapprove updates
$response = ''
#############################################
#Test WU path, if path exists then create key, else create path then create key
if (Test-Path -Path $regPathWindowsUpdate) {
Set-ItemProperty -Path $regPathWindowsUpdate -Name $regPropertyENA -Type DWord -Value $desiredValueENA -ErrorAction Stop
$response = 'WU - ElevateNonAdmins key created.'
Write-Output $response
} else {
New-Item -Path $regPathWindowsUpdate -Force
$response = 'Created Windows Update registry path.'
Write-Output $response
Set-ItemProperty -Path $regPathWindowsUpdate -Name $regPropertyENA -Type DWord -Value $desiredValueENA -ErrorAction Stop
$response = 'WU - ElevateNonAdmins key created.'
Write-Output $response
}
# Test AU path, if path exists then create keys, else create path then create keys
# NoAutoUpdate - 1 = enable Automatic Updates
# AUOptions - 3 = Automatically download and notify of installation
# AutoInstallMinorUpdates - 0 = Treat minor updates like other updates
if (Test-Path -Path $regPathAU) {
'Name,Value,Type
NoAutoUpdate,1,DWORD
AUOptions,3,DWORD
AutoInstallMinorUpdates,0,DWORD' |
ConvertFrom-Csv |
Set-ItemProperty -Path $regPathAU -Name { $_.Name }
$response = 'AU Registry keys created.'
Write-Output $response
} else {
New-Item -Path $regPathAU -Force
$response = 'Created AU registry path.'
Write-Output $response
'Name,Value,Type
NoAutoUpdate,1,DWORD
AUOptions,3,DWORD
AutoInstallMinorUpdates,0,DWORD' |
ConvertFrom-Csv |
Set-ItemProperty -Path $regPathAU -Name { $_.Name }
$response = 'AU Registry keys created.'
Write-Output $response
}