Credential Elevation in Invoke-Command – The Full Truth

When using PowerShell’s Invoke-Command for remote administration, understanding how credential elevation works is crucial. Many misconceptions exist, especially regarding a non-existent -RunAsAdministrator flag or UAC prompts. This post clarifies the real mechanics behind running commands as an administrator remotely.


🔍 Quick Summary

Question Answer
Does Invoke-Command have a -RunAsAdministrator flag? ❌ No, this flag does not exist.
How does elevation actually work? ✅ Elevation is entirely determined by the -Credential parameter you pass and the nature of the remote process.

1. How Invoke-Command Handles Credentials and Elevation

Invoke-Command operates by establishing a remote session (typically via WinRM) using the credentials you provide. The elevation of the commands executed within that session depends directly on the privileges of the user account associated with those credentials.

Step-by-step Process:

  1. Connection: PowerShell connects via WinRM to the remote host.
  2. Authentication: It authenticates using the username and password from the PSCredential object ($cred) you supply.
  3. Session Context: The remote session starts under the security context of that authenticated user.
  4. Execution: All code within the -ScriptBlock runs with that user’s security token.

💡 The Core Principle: Elevation is not a separate flag; it’s determined by whether the user account provided in the -Credential parameter is a member of the local Administrators group on the remote machine.


2. Elevation Rules (Administrator vs. Non-Administrator)

The behavior of Invoke-Command regarding elevation is consistent with how Windows handles process integrity levels.

Credential Type Remote Privileges UAC Behavior
Standard user Limited token (low integrity) No administrative rights.
Local / Domain admin Full admin token (high integrity) Elevated automatically if UAC allows, or if the process is headless.
Admin + UAC enabled Split token (medium integrity) Needs explicit elevation only if an interactive UI (like a UAC prompt) is triggered.

3. The Key Rule: No UI = No UAC Prompt

User Account Control (UAC) is designed to protect interactive user sessions. When a process attempts to perform an administrative action that would normally trigger a UAC prompt, it does so because it’s trying to interact with the desktop or display a UI.

Crucially, remote Invoke-Command sessions are typically headless (non-interactive) and do not display a UI. Therefore, if the process running on the remote machine does not attempt to display a graphical interface or interact with the user’s desktop, it will often run with full administrative privileges without triggering a UAC prompt, provided the supplied credentials are for an administrator account.

Scenario Result
Run setup.exe /configure with Display Level="Full" UI appears → triggers UAC prompt (if run interactively).
Run setup.exe /configure with Display Level="None" No UI → runs silently with full elevation (if admin credentials are used).

Even if you use admin credentials, Windows will present a UAC prompt if your remote process attempts to show a user interface. This is why silent installers are critical for remote automation.


4. Real-World Example: Installing Office Remotely

Let’s consider a common scenario: silently installing Microsoft Office on a remote machine.

# 1. Define the remote computer and get administrator credentials
$computerName = "PC01"
$adminCred = Get-Credential "DOMAIN\adminuser" # Enter admin username and password

# 2. Use Invoke-Command to execute the installation script block remotely
Invoke-Command -ComputerName $computerName -Credential $adminCred -ScriptBlock {
    # This script block runs on PC01 with the privileges of DOMAIN\adminuser

    $officeInstallerDir = 'C:\Temp\Office'
    $officeSharePath = '\\SERVER\OfficeShare' # UNC path to your Office installation files

    # Create a local directory for the installer files
    New-Item -Path $officeInstallerDir -ItemType Directory -Force | Out-Null

    # Copy Office installation files from a network share to the local machine
    Copy-Item -Path "$officeSharePath\*" -Destination $officeInstallerDir -Recurse -Force

    # Execute the Office setup command using cmd.exe
    # The 9-msOffice.cmd script will handle the actual setup.exe call
    & cmd /c "$officeInstallerDir\9-msOffice.cmd"
}

Content of 9-msOffice.cmd (on the remote machine, copied from the share):

@echo off
cd /d "%~dp0"
setup.exe /configure "%~dp0install-Office-2021-KMS.xml" > "%~dp0install.log" 2>&1
exit /b %ERRORLEVEL%

Content of install-Office-2021-KMS.xml (on the remote machine, copied from the share):

<Configuration>
  <Add OfficeClientEdition="32" Channel="PerpetualVL2021">
    <Product ID="ProPlus2021Volume">
      <Language ID="en-us" />
      <ExcludeApp ID="Access" />
      <ExcludeApp ID="Groove" />
      <ExcludeApp ID="OneNote" />
      <ExcludeApp ID="OneDrive" />
      <ExcludeApp ID="Teams" />
      <ExcludeApp ID="Bing" />
      <ExcludeApp ID="Lync" />
      <ExcludeApp ID="Outlook" />
      <ExcludeApp ID="Publisher" />
    </Product>
  </Add>
  <RemoveMSI All="True" />
  <Updates Enabled="TRUE" Channel="PerpetualVL2021" />
  <Display Level="None" AcceptEULA="TRUE" />
  <Property Name="AUTOACTIVATE" Value="1" />
</Configuration>

✅ Result:

  • The remote script runs as DOMAIN\adminuser.
  • The session is fully elevated (high integrity).
  • No UAC popup occurs because the setup.exe is configured to run silently (<Display Level="None" />).
  • No SmartScreen interruptions.
  • The silent installation progress is logged to install.log.

5. How to Verify Elevation on the Remote Host

To confirm that your remote session is indeed running with elevated privileges, you can include a check within your -ScriptBlock:

Invoke-Command -ComputerName $computerName -Credential $adminCred -ScriptBlock {
    $isElevated = ([Security.Principal.WindowsPrincipal] \
        [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
        [Security.Principal.WindowsBuiltinRole]::Administrator)

    Write-Output "Elevated: $isElevated"
    whoami /groups | Select-String "High Mandatory" # Look for "High Mandatory Level"
}

Output if elevated:

Elevated: True
... 
Group Name: Mandatory Label\High Mandatory Level
...

6. Common Misconceptions

  • “I need -RunAsAdministrator: ❌ This flag does not exist for Invoke-Command.
  • “Admin user = always elevated”: ❌ Not true. If a process tries to display UI, UAC may still restrict it, even for an admin.
  • “Silent installs need extra flags”: ❌ For most MSI/EXE installers, the silent switch (e.g., /quiet, /qn, or <Display Level="None" /> for ODT) is sufficient.
  • “Invoke-Command bypasses UAC”: ❌ Invoke-Command doesn’t bypass UAC; it operates in a headless context where UAC typically doesn’t interfere with administrative actions, provided the credentials are for an administrator and no UI is displayed.

7. Best Practices for Remote Elevated Execution

✅ Do:

  • Always use an administrator credential with the -Credential parameter.
  • Ensure any installers or scripts executed remotely are configured for silent/headless operation (e.g., <Display Level="None" /> for Office ODT, /quiet for MSIs).
  • Copy installation files locally to the remote machine before running them to avoid network path issues or double-hop authentication problems.
  • Use & cmd /c "..." or Start-Process -Wait for executing traditional command-line tools or batch files from within PowerShell’s ScriptBlock.
  • Verify elevation using [Security.Principal.WindowsPrincipal]::IsInRole() or whoami /groups.

🚫 Don’t:

  • Attempt to use a non-existent -RunAsAdministrator flag.
  • Assume elevation without verifying it.
  • Launch graphical user interface (GUI) installers remotely, as they will trigger UAC and fail without user interaction.
  • Run installers directly from UNC paths (\\SERVER\Share) if they require elevation, as this can lead to double-hop authentication issues.

8. TL;DR – Always Works One-Liner Example

# Define credentials (will prompt for password)
$adminCred = Get-Credential "DOMAIN\adminuser"

# Define remote computer name
$targetComputer = "PC01"

# Execute the remote script block
Invoke-Command -ComputerName $targetComputer -Credential $adminCred -ScriptBlock {
    # Define local directory for installer files
    $localInstallerPath = 'C:\job\update-mps\msOffice'
    
    # Create the directory if it doesn't exist
    New-Item -Path $localInstallerPath -ItemType Directory -Force | Out-Null
    
    # Copy installer files from a network share (replace with your actual share)
    Copy-Item -Path '\\SERVER\OfficeShare\*' -Destination $localInstallerPath -Recurse -Force
    
    # Execute the batch script for silent Office installation
    & cmd /c "$localInstallerPath\9-msOffice.cmd"
}
  • Elevation: Achieved because DOMAIN\adminuser is an administrator on PC01.
  • No popup: Because the Office installer is configured for silent mode (<Display Level="None" />).
  • No invalid flags: PowerShell correctly handles the security tokens.

🧩 Summary Table

Concept Description
Elevation mechanism Via the -Credential parameter, not a separate flag.
Works remotely Yes, through WinRM (or SSH with Invoke-SSHCommand).
UAC behavior Only prompts when a UI is displayed; headless remote sessions typically bypass it.
Silent installer requirement Installers must be configured for silent mode (e.g., <Display Level="None" />).
Check elevation Use [Security.Principal.WindowsPrincipal]::IsInRole() or whoami /groups.

✅ Final Takeaway

Invoke-Command does not elevate by magic. It simply runs under the credentials you supply. If that user is an administrator on the remote machine, and the process runs headless (without a UI), the session is fully elevated.

No hacks. No prompts. No myths. Just providing the correct credentials and ensuring silent execution leads to true, seamless remote elevation.