← Back to Guides Homepage

Automate Windows Server Updates with PowerShell

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.

Part 1: Initial Setup and Directory Creation

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.

1. Create the Folders

Navigate to your C: drive and create the following structure:

Open the PowerShell ISE as an Administrator and save a new blank script named patch.ps1 into your newly created folder.

Part 2: Installing the PSWindowsUpdate Module

We will utilize the PSWindowsUpdate module from the PowerShell Gallery. This module provides the cmdlets necessary to manage updates via CLI.

1. Install Module Script

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

2. Troubleshooting: Force TLS 1.2

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

Part 3: Writing the Update and Logging Logic

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.

1. Define Log File

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

2. Run the Update Command

We use Get-WindowsUpdate with specific parameters:

# 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.

Part 4: Scheduling the Script

We can script the creation of the Scheduled Task directly within PowerShell so that we don't have to use the GUI.

1. Define Action and Trigger

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

2. Register the Task

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"

Part 5: Verification

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.

← Back to Guides Homepage