In this guide, you will learn how to create a robust script to automatically download and install Windows and Microsoft updates using PowerShell. We will cover directory setup, module installation, logging, and scheduling the task on Windows Server 2025.
Before writing the script, we need to organize our environment. We will create a specific folder structure to house the script and the logs it generates.
Navigate to your C: drive and create the following structure:
C:\PSWindowsUpdateC:\PSWindowsUpdate\logsC:\PSWindowsUpdate\script (or place the script in the root of the main folder)Open the PowerShell ISE as an Administrator and save a new blank script named patch.ps1 into your newly created folder.
We will utilize the PSWindowsUpdate module from the PowerShell Gallery. This module provides the cmdlets necessary to manage updates via CLI.
Add the following lines to the top of your script to install the module and necessary dependencies (like NuGet). If prompted during execution, accept the installation.
# Install Module and Dependencies
Install-Module -Name PSWindowsUpdate -Force
A common issue when connecting to the PowerShell Gallery on servers is an outdated TLS version. If you encounter errors, add this line immediately after the install command to force the session to use TLS 1.2:
# Set TLS to 1.2 for PSGallery connection issues
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Now we will write the core logic. This section defines where the logs go, stamps the start time, runs the update, and stamps the finish time.
We create a dynamic log file name based on the current date so that every run has its own entry or is easily identifiable.
# Define Log File
$LogFile = "C:\PSWindowsUpdate\logs\$(Get-Date -Format 'yyyy-MM-dd').log"
# Log Start Time
"Script Started: $(Get-Date)" | Out-File $LogFile -Append
We use Get-WindowsUpdate with specific parameters:
-MicrosoftUpdate: Checks for other Microsoft product updates (e.g., SQL, Exchange) in addition to Windows.-AcceptAll: Automatically accepts installation agreements.-AutoReboot: Reboots the server automatically if required by the update.| Out-File...: Pipes the results directly to our log file.# Install Updates and Log Result
Get-WindowsUpdate -MicrosoftUpdate -AcceptAll -AutoReboot | Out-File $LogFile -Append
# Log Finish Time
"Script Finished: $(Get-Date)" | Out-File $LogFile -Append
At this stage, you can select these lines in the ISE and press F8 (Run Selection) to test them. If updates are available, the task manager will show the "Windows Modules Installer Worker" consuming resources.
We can script the creation of the Scheduled Task directly within PowerShell so that we don't have to use the GUI.
We define an action to run PowerShell, bypass execution policies, and load our file. We then create a trigger (e.g., weekly, every 4 weeks at 3:00 AM).
# Create Scheduled Task Action
$Action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File C:\PSWindowsUpdate\patch.ps1"
# Create Trigger (Every 4 weeks on Sunday at 3:00 AM)
$Trigger = New-ScheduledTaskTrigger -Weekly -WeeksInterval 4 -At 3am
Finally, we register the task to run as the "SYSTEM" user to ensure it has the highest privileges.
# Register the Task
Register-ScheduledTask -TaskName "PSWindowsUpdate" -Action $Action -Trigger $Trigger -User "SYSTEM"
Once you have run the scheduling code, open the Windows Task Scheduler to confirm the task "PSWindowsUpdate" exists. You can manually run the task to test the entire flow.
Check the C:\PSWindowsUpdate\logs folder. You should see a text file generated containing the start time, the details of any updates installed, and the finish time.