← Back to Guides Homepage

Automate Windows Server Patching with PSWindowsUpdate

This guide demonstrates how to create a complete script using the **PSWindowsUpdate** PowerShell module to automatically download, install, and schedule Windows and Microsoft updates, complete with logging and troubleshooting tips.

Part 1: Setup and Module Installation

We will start by creating the necessary folder structure on the Windows Server (e.g., Windows Server 2025 Evaluation Edition) and installing the core module.

1. Creating the Project and Log Folders

Open PowerShell ISC as Administrator. Create a main directory for the project and separate folders for scripts and logs:

  1. Navigate to the C: drive.
  2. Create the main folder, which shares its name with the module: PS-Windows-Update.
  3. Inside, create subfolders: Logs and Scripts.

Save your main script (e.g., patch.ps1) in the Scripts folder.

2. Installing the PSWindowsUpdate Module

The first part of your script should handle the installation and dependencies:

# Install module and dependencies
Install-Module -Name PSWindowsUpdate -Force

Running this command will install the module and prompt you to accept the PSGallery repository. Accept these prompts to proceed.

Troubleshooting Tip: Forcing TLS 1.2

If you encounter issues during installation, it is often due to the PowerShell session not using a high enough TLS version. Run the following command in your session to enforce TLS 1.2:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Part 2: Defining the Update and Logging Script

This block of code handles logging the start/end time and running the actual update process.

1. Defining Log File and Start Time

The log file is defined using the current date, and a custom timestamp is added to ensure the log is never empty, even if no updates are found:

# Define Log Path using current date
$LogFile = "C:\PS-Windows-Update\Logs\$(Get-Date -Format yyyy-MM-dd)-Log.txt"

# Log script start with timestamp
"Script Started: $(Get-Date)" | Out-File $LogFile -Append

2. Running the Updates

The Get-WindowsUpdate command is used with flags to include Microsoft updates (e.g., for SQL Server or PowerShell) and to automate the process:

# Run the update command
Get-WindowsUpdate -MicrosoftUpdate -AcceptAll -AutoReboot | Out-File $LogFile -Append

The -Append flag ensures the update results are added below the "Script Started" line in the log file.

3. Defining Script End Time

Finally, log the completion timestamp:

# Log script finish with timestamp
"Script Finished Successfully: $(Get-Date)" | Out-File $LogFile -Append

Part 3: Scheduling the Script with PowerShell

Instead of manually configuring the Windows Task Scheduler GUI, we can create the scheduled task directly within PowerShell.

1. Define Action and Trigger

Define the action (what to execute) and the trigger (when to execute) for the task:

# Define the action: Execute PowerShell with arguments
$Action = New-ScheduledTaskAction -Execute 'PowerShell.exe' -Argument '-NoProfile -ExecutionPolicy Bypass -File C:\PS-Windows-Update\Scripts\patch.ps1'

# Define the trigger: Example runs every 4th Sunday at 3:00 AM
$Trigger = New-ScheduledTaskTrigger -Weekly -DaysOfWeek Sunday -At '3:00AM' -RepetitionInterval (New-TimeSpan -Days 28)

2. Register the Task

Register the scheduled task using the defined action and trigger, running with the highest privileges:

# Register the task
Register-ScheduledTask -TaskName "My PS Windows Update" -Action $Action -Trigger $Trigger -User "System" -RunLevel Highest

Verifying the Task

Verify that the task is active and configured correctly by opening the Windows Task Scheduler GUI (it will be visible under the name "My PS Windows Update").

Summary: Testing and Conclusion

The script is now ready to be run manually or scheduled. A final test shows that the log folder is successfully populated with the date-stamped log file, containing the "Script Started," update details, and "Script Finished Successfully" timestamps, ensuring accurate tracking of patch status.

← Back to Guides Homepage