Self elevate as administrator powershell script with parameters passed.

Hi,
I have a powershell script whcih self elevates as administrator. It checks the script is launched in administrator or non administrator and then changes and runs as administrator. But I am using a try catch in my script. I am not sure how to pass the arguments on to that script. Below is the script, if I save the script as test.ps1 and run it, it checks and elevates properly.

BUT... if I run the script with argument which I have used in try ... catch i.e test.ps1 -r it is not passing the "-r". I need to pass the argument -r if needed. Can someone help to modify it which will run as expected.
Start-Sleep -seconds 5


# Get the ID and security principal of the current user account
 $myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
 $myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
  
 # Get the security principal for the Administrator role
 $adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
  
 # Check to see if we are currently running "as Administrator"
 if ($myWindowsPrincipal.IsInRole($adminRole))
    {
    # We are running "as Administrator" - so change the title and background color to indicate this
    $Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)"
    $Host.UI.RawUI.BackgroundColor = "DarkBlue"
    clear-host
    }
 else
    {
    # We are not running "as Administrator" - so relaunch as administrator
    
    # Create a new process object that starts PowerShell
    $newProcess = new-object System.Diagnostics.ProcessStartInfo "PowerShell";
    
    # Specify the current script path and name as a parameter
    $newProcess.Arguments = $myInvocation.MyCommand.Definition;
    Write-Host $newProcess.Arguments
    pause
    
    # Indicate that the process should be elevated
    $newProcess.Verb = "runas";
    pause
    
    # Start the new process
    [System.Diagnostics.Process]::Start($newProcess);
    
    # Exit from the current, unelevated, process
    exit
    }




try {
if($args[0] = "-r")
{
Write-Host "Hello"
pause
}
}
catch {
Write-Host "No Hello"
pause
}


# Stop-Transcript

Open in new window

ID_LostStudentAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

footechCommented:
The try/catch doesn't really factor into the problem.

# Get the ID and security principal of the current user account
$myWindowsID=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$myWindowsPrincipal=new-object System.Security.Principal.WindowsPrincipal($myWindowsID)
   
# Get the security principal for the Administrator role
$adminRole=[System.Security.Principal.WindowsBuiltInRole]::Administrator
   
# Check to see if we are currently running "as Administrator"
if ($myWindowsPrincipal.IsInRole($adminRole))
{
    # We are running "as Administrator" - so change the title and background color to indicate this
    $Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)"
    $Host.UI.RawUI.BackgroundColor = "DarkBlue"
    clear-host
}
else
{
    # We are not running "as Administrator" - so relaunch as administrator

    $scriptPath = $MyInvocation.MyCommand.Path
    [string[]]$argList = @('-NoExit','-File', $scriptPath)
    $argList += $MyInvocation.BoundParameters.GetEnumerator() | Foreach {"-$($_.Key)", "$($_.Value)"}
    $argList += $MyInvocation.UnboundArguments
    Start-Process PowerShell.exe -Verb Runas -WorkingDirectory $pwd -ArgumentList $argList
}

try {
 if($args[0] = "-r")
 {
 Write-Host "Hello"
 pause
 }
 }
 catch {
 Write-Host "No Hello"
 pause
 }

Open in new window

Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
A shorter way to check for elevation is
(whoami /all | select-String S-1-16-12288) –ne $null

Open in new window

which is true for elevated shells.
footechCommented:
While #a41334865 does provide an alternative to checking whether a script is being run as admin, there was no question about that and the OP's code already did that.
The code posted in #a41265848 correctly passes the argument to the new session as requested (tested), and so that post should be accepted as answer.
Simplify Active Directory Administration

Administration of Active Directory does not have to be hard.  Too often what should be a simple task is made more difficult than it needs to be.The solution?  Hyena from SystemTools Software.  With ease-of-use as well as powerful importing and bulk updating capabilities.

Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
No doubt my comment was no answer at all. But the suggested code is incomplete and not correct:
1. The -noexit seems to be unwanted (unless for debugging).
2. There is no exit from the (unelevated) script, so it will run twice - elevated and non-elevated.
3. The check for the parameter in the script is wrong: if($args[0] = "-r") needs to be if($args[0] -eq "-r").
4. The try/catch is wrong, as stated correctly by footech, and should just be an IF.

Also, how the commandline is rebuilt looks cumbersome.

Putting that together with my suggestion (should be easy to replace with the original "elevated" test, if unwanted):
# Check to see if we are currently running "as Administrator"
if ((whoami /all | select-String S-1-16-12288) –ne $null)
{
    # We are running "as Administrator" - so change the title and background color to indicate this
    $Host.UI.RawUI.WindowTitle = $myInvocation.MyCommand.Definition + "(Elevated)"
    $Host.UI.RawUI.BackgroundColor = "DarkBlue"
    clear-host
}
else
{
    # We are not running "as Administrator" - so relaunch as administrator
    Start-Process PowerShell.exe -Verb Runas -WorkingDirectory $pwd -ArgumentList ("-NoLogo -File "+$MyInvocation.Line)
    exit
}

if($args[0] -eq "-r")
{
    Write-Host "Hello"
}
else
{
    Write-Host "No Hello"
}
pause

Open in new window

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
footechCommented:
1.  I might say it'd depend on the script, but I left it because it clearly shows the newly elevated session.
2.  Left in more as debugging, but you're correct that it'd be better left out in a script that did more substantive action.
3.  It's amazing that this still slips past me sometimes.  Nice catch.
4.  Funny enough, it does actually work.  Which is probably why I never corrected it.

Cumbersome?  Maybe, but I liked how it's done.  :)

In any case, what I posted already passes the arguments on to the elevated session, which was the point of the question.
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
If we consider only the part of passing the commandline parameters, then yes, it works and is sufficient as answer (if we add the exit, which is part of the original script).

The try never will work. No matter what parameters you provide, it will output "Hello".
footechCommented:
I know it's not doing exactly what's intended (more coincidence than anything), but it will output "No Hello".
console outputadmin-test.ps1.txt
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
"No Hello" only results from not using any parameter. If you provide e.g. -z, it will still be "Hello".
That is because $args[0] errors out if there is no parameter, and so will trigger an exception to catch.
footechCommented:
Yep, as I said, coincidence.  I've never made the claim that it was correct in any way, just that it gave the expected output in a limited test.
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
I have to object. As soon as there is a correct solution posted, you cannot just accept errornous suggestions (alone). The change as posted might have fatal consequences, as it runs the code to execute twice.
And you accepted a comment which is no solution at all.
footechCommented:
In #a41265848 I considered not having the exit command a very minor point, as it helped to show that both the new process and old were doing the same thing, and the code after line 25 to be of little consequence since it would certainly be changed to do something  besides a throwaway action.  But I won't argue the point any further.

It seems now the only acceptable course is to split the points between #a41265848 and #a41499530
Though I'm not sure how I feel about awarding points to a post made after a question was re-opened.
Qlemo"Batchelor", Developer and EE Topic AdvisorCommented:
Again - old and new code do not the same. And "minor" depends on what the code performs as final action - in this example it is minor, but what if there is code really doing something?
footechCommented:
I think most answers here deal with what's posted in front of them, rather than eventualities, unless that's what the asker's question is about.

Again - old and new code do not the same.
I don't know what that means.
footechCommented:
I've already made my recommendations.  See #a41506171
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.