Here is a quick example for using PowerShell to make changes in offline registry in a ConfigMgr task sequence. If using a different deployment solution simply replace the logic to locate the offline image.
# Figure out if we can use the task sequence object
try {
$TSEnv = New-Object -ComObject Microsoft.SMS.TSEnvironment -ErrorAction Stop
}
catch [System.Exception] {
Write-Warning -Message "Unable to create Microsoft.SMS.TSEnvironment object, aborting..."
Break
}
$LogPath = $TSEnv.Value("_SMSTSLogPath")
$Logfile = "$LogPath\DisableWindowsUpdates.log"
# Delete any existing logfile if it exists
If (Test-Path $Logfile){Remove-Item $Logfile -Force -ErrorAction SilentlyContinue -Confirm:$false}
Function Write-Log{
param (
[Parameter(Mandatory = $true)]
[string]$Message
)
$TimeGenerated = $(Get-Date -UFormat "%D %T")
$Line = "$TimeGenerated : $Message"
Add-Content -Value $Line -Path $LogFile -Encoding Ascii
}
# Load the offline registry hive from the OS volume
$OSDTargetSystemDrive = $TSEnv.Value("OSDTargetSystemDrive")
$HivePath = "$OSDTargetSystemDrive\Windows\System32\config\SOFTWARE"
Write-Log -Message "About to load registry hive: $HivePath "
reg load "HKLM\NewOS" $HivePath
Start-Sleep -Seconds 5
# Updating offline registry to disable Windows updates
Write-Log -Message "Updating registry to disable Windows updates"
$RegistryKey = "HKLM:\NewOS\Policies\Microsoft\Windows\WindowsUpdate\AU"
Write-Log -Message "Creating registry key: $RegistryKey"
$Result = New-Item -Path $RegistryKey -ItemType Directory -Force
$Result.Handle.Close()
$RegistryValue = "NoAutoUpdate"
$RegistryValueType = "DWord"
$RegistryValueData = 1
# 0 = Updates Enabled
# 1 = Updates Disabled
Write-Log -Message "Creating registry value: $RegistryValue, value type: $RegistryValueType, value data: $RegistryValueData"
$Result = New-ItemProperty -Path $RegistryKey -Name $RegistryValue -PropertyType $RegistryValueType -Value $RegistryValueData -Force
# Cleanup (to prevent access denied issue unloading the registry hive)
Remove-Variable Result
Get-Variable Registry* | Remove-Variable
[gc]::collect()
Start-Sleep -Seconds 5
# Unload the registry hive
Write-Log -Message "Unloading the registry hive"
Set-Location X:\
reg unload "HKLM\NewOS"

thank you
Hi Johan, I like this approach and may begin using it as opposed to individual registry change steps, but why not use a function so you can use it for multiple registry changes and you wouldn't have to redefine the variables each time? Would this be possible?
Yes, this can absolutely be transferred to a function. I just haven't done it 🙂
Great article Johan, I have done something similar in September to accommodate a regsitry addition in the user's RunOnce section. It was tricky but our solutions are close 🙂
I can share the code if you want.
Thank you, and yes please, share the code 🙂
I did shared 🙂 Any comments welcome!
I really appreciate the expertise that this simple post provided… I have been trying unsuccessfully for about a week to figure out why PowerShell did not seem to be able to unload the hive (I could spot exactly what the problem was but couldn't identify why the process was still being held hostage)… Thank you, Johan! As usual, your experience in these matters is PRICELESS!