Automating tasks that require administrator privileges on Windows presents a common challenge: how do you handle the UAC (User Account Control) prompt in a non-interactive script, such as in a CI/CD pipeline or a scheduled task? Attempting to bypass UAC is a major security risk and is not recommended.
Instead, you should use tools and methods that are designed for non-interactive elevation. This guide will cover the two best approaches: using the open-source gsudo tool for scripted elevation and the built-in Windows Task Scheduler.
The Challenge: Non-Interactive UAC
The UAC prompt is a security feature that requires explicit user consent for elevation. This is why you cannot simply “click yes” in an automated script. Any attempt to programmatically bypass the UAC prompt is a security vulnerability and should be avoided.
The correct approach is to use a mechanism that runs the script in an already elevated context, thus avoiding the need for a UAC prompt altogether.
Method 1: Using gsudo for Scripted Elevation
gsudo is a powerful sudo equivalent for Windows that is designed with automation in mind. While it cannot bypass the initial UAC prompt, it provides several mechanisms to run commands with elevated privileges in a non-interactive way, assuming the necessary credentials or context is provided.
Important Security Note: For automation, you should never hardcode passwords in your scripts. The examples below assume you are using a secure method to manage your credentials, such as a secrets management system (e.g., Azure Key Vault, HashiCorp Vault) or the Windows Credential Manager.
How gsudo Handles Non-Interactive Elevation
gsudo can run a command as another user with elevated privileges if you provide the credentials.
# --- THIS IS AN INSECURE EXAMPLE FOR DEMONSTRATION ONLY ---
# Do not hardcode passwords in your scripts.
# The password for the admin user
$password = "YourAdminPassword"
# The command to run
$command = 'powershell -Command "whoami /groups | findstr ''High Mandatory''"'
# Use gsudo to run the command as the admin user
echo $password | gsudo -u MyAdminUser $commandIn a real automation scenario, you would retrieve the password from a secure vault and pipe it to gsudo.
A Reusable Function for gsudo Automation
Here is a more robust PowerShell function that takes a PSCredential object, making it more secure and reusable.
function Invoke-GsudoCommand {
param (
[Parameter(Mandatory = $true)]
[string]$Command,
[Parameter(Mandatory = $true)]
[pscredential]$Credential
)
# This is the tricky part: we need to get the password as plain text for the gsudo command line
$ptr = [System.Runtime.InteropServices.Marshal]::SecureStringToCoTaskMemUnicode($Credential.Password)
try {
$plainPass = [System.Runtime.InteropServices.Marshal]::PtrToStringUni($ptr)
# Build the arguments for gsudo
$gsudoArgs = "-u $($Credential.UserName)", $Command
# 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 "MyAdminUser"
Invoke-GsudoCommand -Command 'powershell -Command "Get-Service -Name sshd"' -Credential $credMethod 2: Using Windows Task Scheduler (The Most Secure Way)
For regularly scheduled tasks, the Windows Task Scheduler is the most secure and reliable method for running scripts with elevated privileges.
When you create a scheduled task, you can configure it to run under a specific user account and check the “Run with highest privileges” option. When the task runs, the Task Scheduler service (which already runs in an elevated context) launches your script with a high-integrity token, completely bypassing the need for a UAC prompt.
How to Create an Elevated Scheduled Task
- Open Task Scheduler.
- Click Create Task…
- On the General tab:
- Give the task a name (e.g., “My Admin Script”).
- Under “Security options”, click Change User or Group… and select the user account that will run the task (e.g.,
SYSTEMor a dedicated service account). - Check the box for “Run with highest privileges”.
- On the Triggers tab, define when you want the task to run (e.g., daily, at startup).
- On the Actions tab, create a new action:
- Action:
Start a program - Program/script:
powershell.exe - Add arguments (optional):
-File "C:\Scripts\MyScript.ps1"
- Action:
Now, when the task runs, it will execute your PowerShell script with full administrative privileges, without any user interaction.
Conclusion: Which Method Should You Choose?
-
Use
gsudowhen:- You need to trigger an elevated task on-demand from within another script (e.g., in a CI/CD pipeline).
- You are building a complex automation workflow that requires dynamic elevation.
- You have a secure way to manage and supply the necessary credentials to your script.
-
Use the Task Scheduler when:
- Your task needs to run on a regular schedule.
- You want the most secure, built-in method for non-interactive elevation.
- Your script can be run as a self-contained unit without needing to be triggered by another process.
By avoiding insecure practices like trying to bypass UAC and instead using tools that are designed for non-interactive elevation, you can build powerful, reliable, and secure automation for your Windows environment.