Elevating Powershell to admin and keeping passed arguments

Viewed 344

This was an unsuccessful attempt by me to explain the issue, please scroll down to see a hopefully better explanation


So I'm trying to have my script self-elevate itself to use admin rights.

I think I tried every fix possible on how to elevate a PS session to admin rights but it seems that none can make my arguments stick after the PS session re-opens. I'm assuming it's me who misunderstands how to do this properly.

I have a script that has only one parameter that can be passed to it. Here is the relevant block of code that includes the parameter in the script and the function that I call to elevate to admin permissions:

param (
    [Parameter(Mandatory=$false)][bool]$Param1= $false
)


function openWithPriv {
    if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
        Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$pwd'; & '$PSCommandPath';`";`"$args`"";
        exit;
    }
}

When I run my script and add my parameter, it just skips that function all together. For example: .\script.ps1 -Param1 $true runs the script in its' entirety but when it reaches my function, it just goes to the Default switch:

function runParam1 {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$false)][bool]$Param1= $false
    )
    switch ($Param1) {
        $true { 
            Write-Host "script works" 
         }
        Default {
            Write-Host "script didn't run" -ForegroundColor Red
        }
    }
}

By the way, here is how I call all of the functions in my script, maybe I'm doing something wrong here as well?

#Run all functions
try {
    openWithPriv
    runParam1 -Param1 $Param1
    someFunction1
    someFunction2
}
catch {
    Write-Host "Unknown error" -ForegroundColor Red -ErrorAction SilentlyContinue
    Read-Host -Prompt "Press any key to continue"
}

What am I missing? Any help to fix this would be great :)


This is another attempt to explain, with the full script

So here is my script:

param (
    [Parameter(Mandatory=$false)][bool]$param1 = $false
)

function openWithPriv {
    if (!([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
        Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"cd '$($PWD.Path)'; & '$PSCommandPath';`";`"$args`"";
        exit;
    }
}

function func1 {

    try {
        Write-Host "executing function number 1" -BackgroundColor Blue
    
    }
    catch {
        Write-Host "Unknown error in func1" -ForegroundColor Red -ErrorAction SilentlyContinue
    }
}

function func2 {
    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$false)][bool]$param1 = $false
    )
    switch ($param1) {
        $true { 
            Write-Host "Executing function 2 because param1 was passed"
         }
        Default {
            Write-Host "Skipping func2 because param1 is false" -ForegroundColor Yellow
        }
    }
}

function func3{
    try {
        Write-Host "Executing function 3"
    }
    catch {
        Write-Host "Error, couldn't execute func3" -ForegroundColor Red -ErrorAction SilentlyContinue
    }
}

#Run all functions
try {
    openWithPriv
    func1
    func2 -param1 $param1
    func3
    Read-Host "Script finishd without an issue, press any key to exit"
}
catch {
    Write-Host "Unknown error somewhere in the script" -ForegroundColor Red -ErrorAction SilentlyContinue
    Read-Host -Prompt "Press any key to continue"
}

The issue:

When I execute the script and give it the parameter, nothing happens, it just skips that function and goes to the default switch which is to just prompt the user that the function was skipped.

Example

When I run .\test.ps1, this is the output:

enter image description here

When I run .\test.ps1 -param1 $true

This is the output:

enter image description here

The output should include this text Executing function 2 because param1 was passed as it's shown in func2.

Bottom line

As you can see, because I elevate the script to use admin rights the parameter I'm passing is "lost" when it reaches that function.

Hope this was a bit more clear :)

1 Answers

OK I think you loos the param1 when you start an other process. The $Args are not present and not passed to the script. I splited the code a little to make it clearer

Start-Process PowerShell -Verb RunAs "
    -NoProfile -ExecutionPolicy Bypass -Command `"
        cd '$pwd';
        & '$PSCommandPath';
        `";`"     # this is just the string ";"
        $args     # these $args are written after the script is executed
    `"
";

Instead you need to pass the $param1 to the script:

Start-Process PowerShell -Verb RunAs "
    -NoProfile -ExecutionPolicy Bypass -Command `"
        cd '$pwd';
        & '$PSCommandPath' -param1 $param1
    `"
";

However since $param1 is [bool] and will only accept [bool] you get an error because you are in a string and $param1 will automically be cast to [string] = True instead of $true. To prevent this use 1 and 0 instead:

if ($param1){
    $Arg = 1
}else{
    $Arg = 0
}
...
    Start-Process PowerShell -Verb RunAs "-NoProfile -Noexit -ExecutionPolicy Bypass -Command `"cd '$($PWD.Path)'; & '$PSCommandPath' -param1 $Arg`"";

This could be shortened to:

$Arg = [int]$param1
Related