<# Hydrate HKLM\SOFTWARE\Microsoft\PolicyManager\default\Update with keys + metadata from the inbox WindowsUpdate.admx • auto-compiles DMWmiBridgeProv.mof if Update/Update02 class is missing • writes Behavior / mergealgorithm / policytype / GPBlocking* / ranges – Behavior is only added when the key did not exist before #> # ------------------------------------------------------------------ config $admxPath = "$env:SystemRoot\PolicyDefinitions\WindowsUpdate.admx" $ns = 'root\cimv2\mdm\dmmap' $mofFile = "$env:windir\System32\wbem\DMWmiBridgeProv.mof" $mofExe = "$env:windir\System32\wbem\mofcomp.exe" $rootKey = 'HKLM:\SOFTWARE\Microsoft\PolicyManager\default\Update' $behDef = 0x1200 # default Behavior Microsoft adds to Update policies $mergeAlg = 3 $policyTy = 4 # ------------------------------------------------------------------------ function Ensure-Class { param([string]$name) if (Get-CimClass -Namespace $ns -ClassName $name -EA 0) { return $true } Write-Host "$name missing – compiling MOF..." & $mofExe "`"$mofFile`"" | Out-Null; Start-Sleep 1 return (Get-CimClass -Namespace $ns -ClassName $name -EA 0) } # pick Update vs Update02 $class = (Get-CimClass -Namespace $ns | Where CimClassName -like 'MDM_Policy_Config01_Update*' | Select -First 1 -Expand CimClassName) if (-not $class) { throw 'Update class not found in WMI.' } if (-not (Ensure-Class $class)) { throw "$class still missing after mofcomp." } # ---- parse WindowsUpdate.admx ------------------------------------------- if (-not (Test-Path $admxPath)) { throw "ADMX not found: $admxPath" } [xml]$admx = Get-Content -Raw -Path $admxPath $meta = @{} # valueName -> @{ keyPath; valName; low; high } $admx.policyDefinitions.policies.policy | Where-Object { $_.key -like 'Software\Policies\Microsoft\Windows\WindowsUpdate*' } | ForEach-Object { # helper to record one valueName + range function Add-Meta($node,$keyPath) { if (-not $node.valueName) { return } $lo = 0; $hi = 0 $loAttr = $node.GetAttribute('minValue') $hiAttr = $node.GetAttribute('maxValue') if ($loAttr) { $lo = [int]$loAttr } if ($hiAttr) { $hi = [int]$hiAttr } $meta[$node.valueName] = @{ key=$keyPath; val=$node.valueName; low=$lo; high=$hi } } # container switch Add-Meta $_ $_.key # child elements foreach ($el in $_.elements.ChildNodes) { Add-Meta $el $_.key } } # ---- ensure base registry node ------------------------------------------ if (-not (Test-Path $rootKey)) { New-Item $rootKey -Force | Out-Null } # ---- hydrate registry ---------------------------------------------------- (Get-CimClass -Namespace $ns -ClassName $class).CimClassProperties |Where-Object { $_.Name -notin 'InstanceID','ParentID' } |ForEach-Object { $reg = Join-Path $rootKey $_.Name $newKey = $false if (-not (Test-Path $reg)) { New-Item $reg | Out-Null; $newKey = $true } # add core fields – Behavior only on first creation if ($newKey) { New-ItemProperty -Path $reg -Name Behavior -Type DWord -Value $behDef -Force | Out-Null } if (-not (Get-ItemProperty $reg -Name mergealgorithm -EA 0)) { New-ItemProperty -Path $reg -Name mergealgorithm -Type DWord -Value $mergeAlg -Force | Out-Null } if (-not (Get-ItemProperty $reg -Name policytype -EA 0)) { New-ItemProperty -Path $reg -Name policytype -Type DWord -Value $policyTy -Force | Out-Null } # metadata from ADMX table if ($meta.ContainsKey($_.Name)) { $m = $meta[$_.Name] New-ItemProperty -Path $reg -Name GPBlockingRegKeyPath -Type String -Value $m.key -Force | Out-Null New-ItemProperty -Path $reg -Name GPBlockingRegValueName -Type String -Value $m.val -Force | Out-Null New-ItemProperty -Path $reg -Name lowrange -Type DWord -Value $m.low -Force | Out-Null New-ItemProperty -Path $reg -Name highrange -Type DWord -Value $m.high -Force | Out-Null } else { # fallback if ADMX had no explicit entry if (-not (Get-ItemProperty $reg -Name GPBlockingRegKeyPath -EA 0)) { New-ItemProperty -Path $reg -Name GPBlockingRegKeyPath -Type String ` -Value 'Software\Policies\Microsoft\Windows\WindowsUpdate' -Force | Out-Null New-ItemProperty -Path $reg -Name GPBlockingRegValueName -Type String -Value $_.Name -Force | Out-Null New-ItemProperty -Path $reg -Name lowrange -Type DWord -Value 0 -Force | Out-Null New-ItemProperty -Path $reg -Name highrange -Type DWord -Value 0 -Force | Out-Null } } # guarantee a value field exists if (-not (Get-ItemProperty $reg -Name value -EA 0)) { New-ItemProperty -Path $reg -Name value -Type DWord -Value 0 -Force | Out-Null } } Write-Host "`nUpdate category hydrated — $((Get-ChildItem $rootKey).Count) keys present."