How to Configure WSUS on Windows Server 2012 R2
Windows Server Update Services (WSUS) provides centralised management of Microsoft update distribution within an organisation. Rather than each server and workstation downloading updates individually from Microsoft Update servers, WSUS downloads updates once to a central server and then distributes them to managed endpoints on your schedule. This reduces internet bandwidth consumption, gives administrators control over which updates are approved and when they are deployed, and provides compliance reporting across the entire managed fleet.
This guide covers installing WSUS, configuring synchronisation, creating computer groups, approving updates, setting up Group Policy for client assignment, and maintaining the WSUS database.
Prerequisites
- Windows Server 2012 R2 with at least 10 GB of free space for the WSUS database and update storage (much more in production — plan for 30–100+ GB depending on products and languages).
- SQL Server 2012+ or Windows Internal Database (WID) for the WSUS database. WID is adequate for up to ~500 clients.
- Internet access from the WSUS server to Microsoft Update (or a parent WSUS server in a hierarchical deployment).
- Domain Administrator account for Group Policy configuration.
Step 1: Install WSUS
# Install WSUS with Windows Internal Database (for up to ~500 clients)
Install-WindowsFeature -Name UpdateServices, UpdateServices-UI `
-IncludeManagementTools
# Install WSUS with SQL Server backend (for larger environments)
Install-WindowsFeature -Name UpdateServices, UpdateServices-DB, UpdateServices-UI `
-IncludeManagementTools
# Verify installation
Get-WindowsFeature -Name UpdateServices* |
Where-Object { $_.InstallState -eq "Installed" } |
Select-Object Name, DisplayName
Step 2: Post-Installation Configuration
After installation, you must run the WSUS post-install configuration to specify the content storage directory and database connection before the service can start properly.
# Create the update content directory on a dedicated volume
New-Item -Path "E:WSUS" -ItemType Directory
# Run the WSUS post-install configuration
# -SqlInstanceName "MICROSOFT##WID" uses Windows Internal Database
& "C:Program FilesUpdate ServicesToolswsusutil.exe" postinstall `
CONTENT_DIR=E:WSUS
# For SQL Server backend:
& "C:Program FilesUpdate ServicesToolswsusutil.exe" postinstall `
SQL_INSTANCE_NAME="WSUS-SRVSQLEXPRESS" `
CONTENT_DIR=E:WSUS
# Start the WSUS service
Start-Service -Name WsusService, W3SVC
# Verify services are running
Get-Service -Name WsusService, W3SVC | Select-Object Name, Status
Step 3: Configure WSUS Synchronisation
Configure which Microsoft products, update classifications, and languages to synchronise. Be selective — synchronising everything significantly increases storage requirements and bandwidth consumption.
# Get the WSUS server object
[void][reflection.assembly]::LoadWithPartialName("Microsoft.UpdateServices.Administration")
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::GetUpdateServer("localhost", $false, 8530)
$config = $wsus.GetConfiguration()
# Set the upstream sync source (sync from Microsoft Update directly)
$config.SyncFromMicrosoftUpdate = $true
$config.Save()
# Configure products to synchronise
$wsus.GetSubscription() | ForEach-Object {
$_.StartSynchronizationForCategoryOnly()
}
# Use wsusutil or the WSUS console to set products and classifications
# (PowerShell direct product selection is verbose — the console or wsusutil is more practical)
# Configure automatic sync schedule (daily at 03:00 AM)
$subscription = $wsus.GetSubscription()
$subscription.SynchronizeAutomatically = $true
$subscription.SynchronizeAutomaticallyTimeOfDay = [timespan]"03:00:00"
$subscription.NumberOfSynchronizationsPerDay = 1
$subscription.Save()
# Trigger an immediate synchronisation
$subscription.StartSynchronization()
Step 4: Create Computer Groups
Computer groups allow you to approve updates for specific groups of computers on different schedules — for example, approve updates to test servers first, validate, then approve for production servers.
# Create computer groups in WSUS
$wsus.CreateComputerTargetGroup("Test-Servers")
$wsus.CreateComputerTargetGroup("Production-Servers")
$wsus.CreateComputerTargetGroup("Workstations")
# List all computer groups
$wsus.GetComputerTargetGroups() | Select-Object Name, Id
# Get count of computers in each group
$wsus.GetComputerTargetGroups() | ForEach-Object {
[PSCustomObject]@{
GroupName = $_.Name
ComputerCount = $_.GetComputerTargets().Count
}
}
Step 5: Configure Group Policy for WSUS Client Assignment
Configure Group Policy to point all managed computers to the WSUS server for update detection and assign them to the correct WSUS computer group.
# The following settings are configured in Group Policy Management:
# Computer Configuration -> Policies -> Administrative Templates ->
# Windows Components -> Windows Update
# Key GPO settings:
# "Configure Automatic Updates" = Enabled
# Option: 4 - Auto download and schedule the install
# Schedule: Every day at 03:00 (or your preferred time)
# "Specify intranet Microsoft update service location" = Enabled
# Intranet update service: http://WSUS-SERVER:8530
# Intranet statistics server: http://WSUS-SERVER:8530
# "Enable client-side targeting" = Enabled
# Target group name: Production-Servers (matches WSUS group name)
# Verify GPO is applied on a client
gpresult /r | findstr /i "Windows Update"
# Check WSUS client registry settings on a managed computer
reg query "HKLMSOFTWAREPoliciesMicrosoftWindowsWindowsUpdate" /s
# Force client to register with WSUS
wuauclt /resetauthorization /detectnow
# Or with PowerShell (Windows Update Agent):
(New-Object -ComObject Microsoft.Update.AutoUpdate).DetectNow()
Step 6: Approve Updates
Updates do not deploy automatically unless you approve them. Use a staged approval process: approve for test groups first, validate, then approve for production.
# Get unapproved security updates for Windows Server 2012 R2
$security = $wsus.SearchUpdates("Security Update") |
Where-Object { $_.ApprovalSummary.NotApproved -gt 0 }
Write-Host "Found $($security.Count) unapproved security updates"
# Approve all critical and security updates for the Test-Servers group
$testGroup = $wsus.GetComputerTargetGroups() | Where-Object { $_.Name -eq "Test-Servers" }
$wsus.GetUpdates() |
Where-Object {
$_.UpdateClassificationTitle -in "Critical Updates","Security Updates" -and
$_.ApprovalSummary.NotApproved -gt 0
} |
ForEach-Object {
$_.Approve([Microsoft.UpdateServices.Administration.UpdateApprovalAction]::Install, $testGroup)
}
# View approved updates
$wsus.GetUpdates() |
Where-Object { $_.ApprovalSummary.Approved -gt 0 } |
Select-Object -First 20 |
Select-Object Title, UpdateClassificationTitle, CreationDate
Step 7: WSUS Maintenance and Troubleshooting
# Run the WSUS Server Cleanup Wizard to remove obsolete updates and free disk space
Invoke-WsusServerCleanup `
-CleanupObsoleteComputers `
-CleanupObsoleteUpdates `
-CleanupUnneededContentFiles `
-CompressUpdates `
-DeclineExpiredUpdates `
-DeclineSupersededUpdates
# Run this monthly — WSUS databases grow large without regular cleanup
# Check WSUS synchronisation status
$wsus.GetSubscription().GetSynchronizationHistory(0, 10) |
Select-Object StartTime, EndTime, Result, Error | Format-Table
# Check synchronisation event log
Get-EventLog -LogName Application -Source "Windows Server Update Services" -Newest 20
# Re-index the WSUS database (improves performance — run monthly)
# Connect to the WID database:
# Server: \.pipeMICROSOFT##WIDtsqlquery
# Run the WsusDBMaintenance.sql script from WSUS toolkit
# Check WSUS console URL
Start-Process "http://localhost:8530/ApiRemoting30/WebService.asmx"
# Verify clients are checking in
$wsus.GetComputerTargets() |
Sort-Object LastSyncTime -Descending |
Select-Object -First 10 |
Select-Object FullDomainName, LastSyncTime, LastSyncResult, IPAddress
Generating Compliance Reports
# Generate a summary compliance report
$updateScope = New-Object Microsoft.UpdateServices.Administration.UpdateScope
$computerScope = New-Object Microsoft.UpdateServices.Administration.ComputerTargetScope
$computerScope.IncludedInstallationStates = `
[Microsoft.UpdateServices.Administration.UpdateInstallationStates]::NotInstalled
$wsus.GetSummariesPerComputerTarget($updateScope, $computerScope) |
Select-Object Computer, NotInstalledCount, InstalledPendingRebootCount |
Format-Table
# Export compliance data to CSV
$wsus.GetComputerTargets() | ForEach-Object {
[PSCustomObject]@{
Computer = $_.FullDomainName
OS = $_.OSDescription
LastSync = $_.LastSyncTime
LastSyncResult = $_.LastSyncResult
}
} | Export-Csv -Path "C:ReportsWSUS-Compliance.csv" -NoTypeInformation
Summary
WSUS on Windows Server 2012 R2 is a proven, cost-effective way to manage update distribution across a Windows environment. The key operational practices are: synchronise only the products and classifications you actually use to control storage growth, use computer groups to stage update approvals (test first, then production), run the Server Cleanup Wizard monthly to prevent the database and content store from consuming excessive disk space, re-index the WSUS WID database regularly to maintain query performance, and use the WSUS compliance reports to identify computers with outstanding critical and security updates so you can prioritise remediation. Pair WSUS with Group Policy for automatic client assignment and ensure clients are checking in regularly by monitoring the LastSyncTime for each managed computer.