I have the following script to check if it's running as admin. If not, it launches a new window with the admin token and runs the script again in the admin window. The part I am unable to figure out, is how to pass the parameters originally sent to the script over to the newly launched script
[CmdletBinding()]
param (
$Test1
)
$myWindowsID = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($myWindowsID)
$adminRole = [System.Security.Principal.WindowsBuiltInRole]::Administrator
if (-not $myWindowsPrincipal.IsInRole($adminRole)) {
switch ($PSVersionTable.PSVersion.Major) {
5 {
Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"{
Set-Location -Path $pwd
& '$PSCommandPath'
}`""
}
Default {
Start-Process PWSH -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"{
Set-Location -Path $pwd
& '$PSCommandPath'
}`""
}
}
exit
}
Write-Host $Test1
Write-Host "elevated"
(Get-Item -Path .\).FullName
Start-Sleep -Seconds 10
Let's call the above script test.ps1. In a PowerShell window, I would call it as follows:
PS C:\>& .\test.ps1 -Test1 'SampleScript'
Since I'm passing a string at the time of calling the script, I would like this same string to be passed to the Administrative PowerShell that gets opened. So far, any attempts to pass the parameters have failed.
If possible, it needs to be versatile in that it passes all parameters that a script may have. The example above only has one parameter, but ideally even if the script has two or more all will get passed over to the admin window.
This should work for passing the bound parameters to the elevated script, might not be 100% robust but using an example of parameters (added a second $Test2
param for the example):
PS ..\pwsh> .\test.ps1 -Test1 123 -Test2 'a string with spaces'
Will output:
Elevated
D:\User\Documents\pwsh
Key Value
--- -----
Test1 123
Test2 a string with spaces
This is the code for constructing the arguments by enumerating $PSBoundParameters
. Note that -NoExit
was added for debugging purposes, should be removed later on.
using namespace System.Management.Automation.Language
[CmdletBinding()]
param (
$Test1,
$Test2
)
$isAdmin = [System.Security.Principal.WindowsPrincipal]::new(
[System.Security.Principal.WindowsIdentity]::GetCurrent()).
IsInRole('Administrators')
if (-not $isAdmin) {
$pwsh = (Get-Process -Id $PID).Path
# NOTE:
# the use of `[CodeGeneration]::EscapeSingleQuotedStringContent(...)` is required to properly escape
# possible single quotes `'` in arguments or the path itself
$boundParams = $PSBoundParameters.GetEnumerator() |
ForEach-Object { "-$($_.Key)", "'$([CodeGeneration]::EscapeSingleQuotedStringContent($_.Value))'" }
$command = "
Set-Location -Path '$([CodeGeneration]::EscapeSingleQuotedStringContent($pwd))'
& '$([CodeGeneration]::EscapeSingleQuotedStringContent($PSCommandPath))' $boundParams
"
$arg = '-NoProfile -ExecutionPolicy Bypass -NoExit -Command "{0}"' -f $command
Start-Process $pwsh -Verb RunAs $arg
return
}
Write-Host 'Elevated'
(Get-Item -Path .\).FullName
$PSBoundParameters | Out-Host