← All scripts

Windows configuration

Check Automatic Updates + Active Hours

Reports whether automatic updates are running and what active hours are set.

Download .ps181 lines · PowerShell

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