How to Run PowerShell Remotely with Admin Privileges for Windows Update Scripts


2 views

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.