When attempting to execute Windows Update operations through PowerShell remoting, many administrators encounter permission-related errors like:
Exception calling "Download" with "0" argument(s): "Exception from HRESULT: 0x80240044"
Exception calling "CreateUpdateDownloader" with "0" argument(s): "Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"
The Windows Update Agent (WUA) API requires elevated privileges to perform most operations. This explains why:
- The script works when run locally in an elevated PowerShell session
- Fails when run locally without admin rights
- Fails during remote sessions via Enter-PSSession
The most reliable method to run elevated commands remotely is using CredSSP authentication:
# On the client machine (where you initiate the connection)
Enable-WSManCredSSP -Role Client -DelegateComputer *
# On the server machine (target machine)
Enable-WSManCredSSP -Role Server
# Establish the remote session with explicit credentials
$cred = Get-Credential
$session = New-PSSession -ComputerName SERVERNAME -Authentication CredSSP -Credential $cred
# Execute your script in elevated context
Invoke-Command -Session $session -ScriptBlock {
Start-Process powershell -ArgumentList "-NoProfile -Command &{ $using:scriptContent }" -Verb RunAs
}
Another method is to create a scheduled task remotely that runs with highest privileges:
$action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -File C:\scripts\windowsupdate.ps1"
$principal = New-ScheduledTaskPrincipal -UserId "NT AUTHORITY\SYSTEM" -LogonType ServiceAccount -RunLevel Highest
Register-ScheduledTask -Action $action -Principal $principal -TaskName "ElevatedWindowsUpdate" -Description "Runs Windows Update with elevated privileges"
Start-ScheduledTask -TaskName "ElevatedWindowsUpdate"
When using CredSSP:
- Only enable for specific servers when needed
- Always disable after completing administrative tasks
- Use in trusted network environments only
To disable CredSSP later:
Disable-WSManCredSSP -Role Client
Disable-WSManCredSSP -Role Server
Here's a full implementation of a remote Windows Update script with elevation:
# WindowsUpdateRemoter.ps1
param(
[Parameter(Mandatory=$true)]
[string]$ComputerName,
[Parameter(Mandatory=$true)]
[pscredential]$Credential
)
try {
# Configure CredSSP if not already enabled
if (-not (Get-WSManCredSSP).Contains("The machine is not configured")) {
Enable-WSManCredSSP -Role Client -DelegateComputer $ComputerName -Force
}
# Create remote session
$sessionParams = @{
ComputerName = $ComputerName
Authentication = 'CredSSP'
Credential = $Credential
ErrorAction = 'Stop'
}
$session = New-PSSession @sessionParams
# Execute Windows Update operations with elevation
$updateScript = {
$updateSession = New-Object -ComObject Microsoft.Update.Session
$updateSearcher = $updateSession.CreateUpdateSearcher()
$searchResult = $updateSearcher.Search("IsInstalled=0 and Type='Software'")
if ($searchResult.Updates.Count -gt 0) {
$updatesToInstall = New-Object -ComObject Microsoft.Update.UpdateColl
foreach ($update in $searchResult.Updates) {
$updatesToInstall.Add($update) | Out-Null
}
$installer = $updateSession.CreateUpdateInstaller()
$installer.Updates = $updatesToInstall
$installationResult = $installer.Install()
return $installationResult.ResultCode
}
return "NoUpdatesFound"
}
$result = Invoke-Command -Session $session -ScriptBlock {
Start-Process powershell -ArgumentList "-NoProfile -Command &{ $using:updateScript }" -Verb RunAs -Wait
}
return $result
}
finally {
if ($session) { Remove-PSSession $session }
Disable-WSManCredSSP -Role Client
}
When working with Windows Update automation through PowerShell remoting, I kept hitting a frustrating wall: the Windows Update Agent (WUA) API requires elevated privileges, but standard remote sessions don't provide this by default. Here's what I discovered about running elevated operations through Enter-PSSession.
The error messages tell the story clearly:
Exception calling "CreateUpdateDownloader" with "0" argument(s):
"Access is denied. (Exception from HRESULT: 0x80070005 (E_ACCESSDENIED))"
This occurs because the COM objects used by Windows Update (like Microsoft.Update.Session) require administrative privileges, similar to how the GUI Windows Update applet behaves.
1. Scheduled Tasks Approach
The most robust method I've found uses scheduled tasks to trigger elevated execution:
$scriptBlock = {
$session = New-Object -ComObject Microsoft.Update.Session
$searcher = $session.CreateUpdateSearcher()
# Rest of your update script
}
$action = New-ScheduledTaskAction -Execute "powershell.exe"
-Argument "-NoProfile -ExecutionPolicy Bypass -Command $scriptBlock"
$trigger = New-ScheduledTaskTrigger -Once -At (Get-Date)
Register-ScheduledTask -TaskName "ElevatedUpdate"
-Action $action -Trigger $trigger -RunLevel Highest
Start-ScheduledTask -TaskName "ElevatedUpdate"
2. CredSSP Authentication
For domain environments, CredSSP allows credential delegation:
# On client:
Enable-WSManCredSSP -Role Client -DelegateComputer remotePC
# On server:
Enable-WSManCredSSP -Role Server
# Then connect:
$cred = Get-Credential
Enter-PSSession -ComputerName remotePC -Credential $cred -Authentication CredSSP
3. Remote Registry + RunAs Technique
A more complex but effective hybrid approach:
# Create the script on remote machine
$updateScript = @'
Start-Process powershell.exe -Verb RunAs -ArgumentList @"
-Command "
$session = New-Object -ComObject Microsoft.Update.Session;
# Your update commands here
"
"@
'@
# Deploy and execute
Invoke-Command -ComputerName remotePC -ScriptBlock {
param($script)
$script | Out-File C:\temp\update.ps1
& C:\temp\update.ps1
} -ArgumentList $updateScript
Each method has security implications:
- Scheduled tasks leave credentials in the task history
- CredSSP opens potential credential relay vulnerabilities
- Remote registry requires careful permission management
Always consider using Just Enough Administration (JEA) endpoints when possible to limit privileges.
For modern systems, the PSWindowsUpdate module simplifies this:
Install-Module PSWindowsUpdate -Force
Get-WUInstall -AcceptAll -AutoReboot -Verbose
The module handles elevation internally when properly configured through JEA or constrained endpoints.