Last active
November 27, 2024 22:13
-
-
Save realchrisolin/c99181584ecfde199a584782bd38f9c7 to your computer and use it in GitHub Desktop.
unattended Windows Update scripts compatible with Windows Provisioning Packages
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# example WCD customizations.xml demonstrating how to use | |
<WindowsCustomizations> | |
<Settings xmlns="urn:schemas-microsoft-com:windows-provisioning"> | |
<Customizations> | |
<Common> | |
<ProvisioningCommands> | |
<PrimaryContext> | |
<Command> | |
<CommandConfig Name="ps_WindowsUpdates"> | |
<CommandFile>C:\path\to\ScheduleWindowsUpdatesTask.ps1</CommandFile> | |
<CommandLine>powershell.exe -ExecutionPolicy RemoteSigned -File ScheduleWindowsUpdatesTask.ps1</CommandLine> | |
<DependencyPackages> | |
<Dependency Name="RunWindowsUpdates">C:\path\to\RunWindowsUpdates.ps1</Dependency> | |
</DependencyPackages> | |
</CommandConfig> | |
</Command> | |
</PrimaryContext> | |
</ProvisioningCommands> | |
</Common> | |
</Customizations> | |
</Settings> | |
</WindowsCustomizations> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# utility script to fetch Windows Updates -- must be run as administrator | |
# Set execution policy to RemoteSigned for the current process | |
Set-ExecutionPolicy RemoteSigned -Scope Process -Force | |
# Install NuGet package provider | |
Install-PackageProvider NuGet -Force | |
# Install PSWindowsUpdate module | |
Install-Module PSWindowsUpdate -Force | |
# Import PSWindowsUpdate module | |
Import-Module PSWindowsUpdate -Force | |
# Install Windows updates, accepting all and ignoring reboot | |
Install-WindowsUpdate -AcceptAll -IgnoreReboot |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$dest_dir = "C:\temp" | |
if (-not (Test-Path $dest_dir)) { | |
ni $dest_dir -ItemType Directory -Force | Out-Null | |
} | |
Start-Transcript -Path "C:\temp\ScheduleWindowsUpdates.log" | |
Write-Host "created temp directory and copying scripts to an absolute path that will persist" | |
$scriptToSchedule = "RunWindowsUpdates.ps1" | |
$parentDirectory = (Get-Item -Path ".\..").FullName | |
$scriptFileLocation = Get-ChildItem -Path $parentDirectory -Recurse -Filter $scriptToSchedule | |
if ($scriptFileLocation) { | |
Copy-Item -Path $scriptFileLocation.FullName -Destination "$($dest_dir)\$($scriptToSchedule)" -Force | |
} else { | |
Write-Host "$scriptToSchedule not found" | |
} | |
$full_dest = "$($dest_dir)\$($scriptToSchedule)" | |
$command = "powershell.exe -ExecutionPolicy Unrestricted -File $full_dest | |
cmd.exe /c reg add "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\RunOnce" /v "FetchWindowsUpdates" /t REG_SZ /d "$command" /f |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
The files in this gist are largely for my own reference so I can recycle the logic used in these scripts unrelated to Windows Updates. | |
The workflow of this script and the problem it solves is relatively simple, but the technical overhead makes it seem more intimidating than it really is. | |
To be brief, ProvisioningCommand files added to .ppkg provisioning packages are copied to a pseudorandom directory under C:\Windows or C:\ProgramData (I forget which offhand) during the unattended OOBE setup process and are run as defaultuser0, which causes numerous technical complications that I won't get into in this readme. | |
It's a bit of a sledgehammer approach, but I've successfully worked around these issues by using the "schedule" script to automatically copy the requisite scripts to an absolute path (C:\temp by default) during unattended OOBE setup and run them accordingly. "Scheduling" the "run" script uses HKLM RunOnce registry key, which will cause the run script to execute the next time a local admin account logs in, which pairs well with HKLM\Software\Microsoft\Windows NT\CurrentVersion\Winlogon key and relevant AutoAdminLogon/DefaultUsername values under it so the local admin account logs in automatically after provisioning (you will probably need to research these values and manually add them) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment