Automating administrative tasks on Windows often requires running scripts with elevated privileges. When you can’t have a UAC prompt interrupting your workflow, you need a reliable, non-interactive way to elevate. Two powerful and modern approaches to this problem are gsudo for local elevation and Invoke-SSHCommand for remote execution.
This guide provides a deep dive into both tools, comparing their strengths and weaknesses to help you decide which one is the right fit for your automation needs, whether you’re managing a local machine or a fleet of remote servers.
Part 1: Local Elevation with gsudo
gsudo is a free, open-source sudo equivalent for Windows. It allows a script or user to elevate their privileges in the current console or run a new command as an administrator, often without a UAC prompt if the credentials are correct or cached.
How to Install gsudo
You can install gsudo easily with winget or by downloading the MSI.
# Install using winget (recommended)
winget install gerardog.gsudo
# Or, download the MSI and install it silently
# msiexec /i gsudo.x.x.x.msi /quietNon-Interactive Elevation with gsudo
The real power of gsudo for automation is its ability to run commands non-interactively, using provided credentials to bypass the UAC prompt.
Here’s how to run a command as a specific admin user without any user interaction:
# Define the credentials for the local admin user
$cred = [pscredential]::new("$env:COMPUTERNAME\localadmin", ('myP@ssw0rd' | ConvertTo-SecureString -AsPlainText -Force))
# This part is tricky: we need to get the password as plain text for the gsudo command line
$ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($cred.Password)
$plainPass = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr)
[System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($ptr) # Clear the password from memory
# Define the command to run
$cmdToRun = 'cmd /c "c:\job\update-mps\msOffice\9-msOffice.cmd"'
# Execute the command with gsudo
& gsudo runas "/user:$($cred.UserName)" "/password:$plainPass" $cmdToRunThis approach is perfect for scheduled tasks, CI/CD pipelines, or any other scenario where a script needs to elevate itself locally without user intervention.
Reusable Function: Invoke-GsudoCommand
To make this even easier, you can use a reusable PowerShell function that handles the credential conversion securely.
function Invoke-GsudoCommand {
param (
[Parameter(Mandatory = $true)]
[string]$CmdToRun,
[Parameter(Mandatory = $true)]
[pscredential]$Credential
)
$ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($Credential.Password)
try {
$plainPass = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr)
# Build the arguments for gsudo
$gsudoArgs = "runas", "/user:$($Credential.UserName)", "/password:$plainPass", $CmdToRun
# Pipe the password to gsudo
echo $plainPass | gsudo @gsudoArgs
}
finally {
# Always clear the plain text password from memory
if ($ptr -ne [System.IntPtr]::Zero) {
[System.Runtime.InteropServices.Marshal]::ZeroFreeCoTaskMemUnicode($ptr)
}
}
}
# --- How to Use ---
# In a real script, you would get the credential from a secure source
$cred = Get-Credential "$env:COMPUTERNAME\localadmin"
Invoke-GsudoCommand -CmdToRun 'powershell -Command "Get-Service -Name sshd"' -Credential $credPart 2: Remote Execution with Invoke-SSHCommand
When you need to run administrative tasks on a remote Windows machine, Invoke-SSHCommand (from the Posh-SSH module) is an excellent choice. It uses the standard SSH protocol, which is secure, reliable, and often already allowed through firewalls.
How to Set Up
- Install
Posh-SSHModule:Install-Module -Name Posh-SSH -Scope CurrentUser - Enable OpenSSH Server on the remote machine: On the remote Windows server, install and enable the OpenSSH Server feature.
Running a Remote Command
The script below connects to a remote host via SSH and executes a PowerShell script as an administrator.
# Define the credentials for an admin user on the remote host
$cred = [pscredential]::new("$hostName\localadmin", ('myP@ssw0rd' | ConvertTo-SecureString -AsPlainText -Force))
# Create an SSH session
$session = New-SSHSession -ComputerName $hostName -Credential $cred -AcceptKey
# Invoke the command on the remote host
Invoke-SSHCommand -SSHSession $session -Command 'powershell -NoProfile -File "C:\job\update-mps\msOffice\9-msOffice.ps1"'
# Clean up the session
Remove-SSHSession -SSHSession $sessionBecause the SSH session is headless, no UAC prompt is ever displayed. If the user you connect with is an administrator, the command will run with full administrative privileges.
Part 3: Comparison and Recommendations
| Feature | Invoke-SSHCommand (Posh-SSH) |
gsudo |
|---|---|---|
| Target | Remote host (via SSH) | Local host only |
| Elevation Method | Uses the privileges of the SSH user account | Elevates the current process or runs a new one as admin |
| Requires Server? | ✅ Yes (OpenSSH Server) | ❌ No |
| Network Protocol | TCP/22 (encrypted) | None (local process) |
| UAC Prompt | None (headless) | Yes, unless credentials are provided or cached |
| Best For | Remote automation, managing a fleet of servers | Local elevation, scheduled tasks, CI/CD agents |
Which Tool Should You Choose?
| Scenario | Recommended Tool | Why |
|---|---|---|
| Automating tasks on remote servers | Invoke-SSHCommand |
Secure, reliable, and uses a standard protocol. |
| A script needs to elevate itself on a local machine | gsudo |
Fast, simple, and designed for local elevation. |
| Running a scheduled task as an admin | gsudo |
Perfect for non-interactive local elevation. |
| Working in an air-gapped or offline environment | gsudo |
Works without any network connectivity. |
| You need to avoid UAC prompts entirely | Both, when used correctly | Invoke-SSHCommand is naturally headless; gsudo can be with provided credentials. |
Conclusion
Both gsudo and Invoke-SSHCommand are excellent, modern solutions for automating administrative tasks on Windows without interactive UAC prompts. The choice between them is simple:
- For local elevation, use
gsudo. It is the perfect tool for scripts that need to run as an administrator on the machine they are executed on. - For remote execution, use
Invoke-SSHCommand. It provides a secure and reliable way to manage remote machines over a standard, firewall-friendly protocol.
By understanding the strengths of each tool, you can build robust, non-interactive automation workflows for any scenario, whether it’s on a single machine or across your entire infrastructure.