Windows configuration
Check Automatic Updates + Active Hours
Reports whether automatic updates are running and what active hours are set.
Replace generic placeholder values (tenant, domain, secrets) for your own environment before running. Read it first and test safely.
# Checks:
# - Windows Update service state + startup type
# - Automatic Updates policy/state (AUOptions and NoAutoUpdate)
# - Active Hours (start/end) and whether they are enabled
# Outputs a single object and a simple Enabled/Disabled verdict
$ErrorActionPreference = "SilentlyContinue"
# --- Windows Update service ---
$svc = Get-Service -Name "wuauserv"
$svcCim = Get-CimInstance Win32_Service -Filter "Name='wuauserv'"
# --- Automatic Updates config ---
$auPath = "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update"
$au = Get-ItemProperty -Path $auPath
$polWUPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate"
$polAUPath = "HKLM:\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU"
$polWU = Get-ItemProperty -Path $polWUPath
$polAU = Get-ItemProperty -Path $polAUPath
# --- Active Hours ---
$uxPath = "HKLM:\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings"
$ux = Get-ItemProperty -Path $uxPath
# ActiveHoursStart/End are typically integers 0-23 (24h clock)
$activeStart = $ux.ActiveHoursStart
$activeEnd = $ux.ActiveHoursEnd
# Some builds include an "IsActiveHoursEnabled" style flag (name varies); try common ones
$activeHoursEnabled =
if ($null -ne $ux.IsActiveHoursEnabled) { [bool]$ux.IsActiveHoursEnabled }
elseif ($null -ne $ux.ActiveHoursEnabled) { [bool]$ux.ActiveHoursEnabled }
else { $null }
# --- Determine "Automatic Updates enabled" ---
# Policy NoAutoUpdate = 1 means disabled.
$noAutoUpdate = $null
if ($null -ne $polAU.NoAutoUpdate) { $noAutoUpdate = [int]$polAU.NoAutoUpdate }
elseif ($null -ne $au.NoAutoUpdate) { $noAutoUpdate = [int]$au.NoAutoUpdate }
# AUOptions (2-5) indicates how updates are configured when enabled.
$auOptions = $null
if ($null -ne $polAU.AUOptions) { $auOptions = [int]$polAU.AUOptions }
elseif ($null -ne $au.AUOptions) { $auOptions = [int]$au.AUOptions }
$auOptionsMeaning = switch ($auOptions) {
2 { "Notify for download and auto install" }
3 { "Auto download and notify for install" }
4 { "Auto download and schedule install" }
5 { "Allow local admin to choose setting" }
default { $null }
}
# Basic verdict:
# - Service not disabled AND
# - NoAutoUpdate is not 1 AND
# - AUOptions exists and is not 0
$serviceOk = $svc -and $svcCim -and ($svcCim.StartMode -ne "Disabled")
$policyOk = ($noAutoUpdate -ne 1)
$configOk = ($null -ne $auOptions -and $auOptions -ge 2 -and $auOptions -le 5)
$automaticUpdatesEnabled = ($serviceOk -and $policyOk -and $configOk)
# --- Output ---
$result = [pscustomobject]@{
AutomaticUpdatesEnabled = $automaticUpdatesEnabled
WindowsUpdateServiceStatus = $svc.Status
WindowsUpdateServiceStartupType = $svcCim.StartMode
NoAutoUpdate = $noAutoUpdate
AUOptions = $auOptions
AUOptionsMeaning = $auOptionsMeaning
ActiveHoursEnabled = $activeHoursEnabled
ActiveHoursStartHour24 = $activeStart
ActiveHoursEndHour24 = $activeEnd
}
$result | Format-List