Home > Software engineering >  Elevate a script with parameters
Elevate a script with parameters

Time:12-23

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
  • Related