I have a Powershell script with parameters that I'd like to be able to self-elevate.
[CmdletBinding()]
param (
[Parameter(ParameterSetName="cp")]
[Switch]
$copy = $false,
[Parameter(ParameterSetName="mv")]
[Switch]
$move = $false
)
# Elevate if required
if (-not ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] 'Administrator')) {
if ([int](Get-CimInstance -Class Win32_OperatingSystem | Select-Object -ExpandProperty BuildNumber) -ge 6000) {
$Cmd = (
'-File',
"`"$($MyInvocation.MyCommand.Path)`"",
$MyInvocation.BoundParameters
)
$ProcArgs = @{
FilePath = 'PowerShell.exe'
Verb = 'RunAs'
ArgumentList = $Cmd
}
Start-Process @ProcArgs
Exit
}
}
Set-Location -LiteralPath $PSScriptRoot
Write-Host "$copy"
Pause
If I comment out the param
block and run script.ps1 -copy
, an elevated Powershell window opens and prints out Press enter to continue
, i.e. it works.
If I comment out the if
statement, the current window outputs True
, i.e. it also works.
If I run the whole thing though, the elevated windows opens for a split second, then closes ignoring Pause
with no output anywhere.
I want the elevated window to open and print out True
.
CodePudding user response:
I tested this on Linux and worked for me but couldn't test on Windows, I don't see other way around having to manipulate the $PSBoundParameters
into strings to pass the arguments on -ArgumentList
.
Below code is meant to be exclusively for testing, hence why I've removed the if
conditions.
[CmdletBinding()]
param (
[Parameter(ParameterSetName="cp")]
[Switch]$copy,
[Parameter(ParameterSetName="mv")]
[Switch]$move
)
$argument = @(
"-File $PSCommandPath"
"-$($PSBoundParameters.Keys)"
)
$ProcArgs = @{
FilePath = 'powershell.exe'
Verb = 'RunAs'
ArgumentList = $argument
}
Start-Process @ProcArgs
"Started new Process with the argument: -$($PSBoundParameters.Keys)"
[System.Console]::ReadKey()
Exit