Sounds simple? Unfortunately not! To set the scene I had a simple powershell menu that I needed to then run another script, run it as a different user and as administrator. Interestingly after scouring the internet i could do these things but separately, not together. Finally i worked out how to achieve running a script from another as different user and elevated!
Finding out user information
First here’s some useful code to output which user is running the shell and if the shell is elevated to admin:
$runninguser = [Security.Principal.WindowsIdentity]::GetCurrent().Name
write-host “Running as $runninguser”
$isadmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] “Administrator”)
write-host “Running as admin: $isadmin”
Running a script from a script as a different user and elevated
Initially i tried invoke-command however that bought up the “double hop” authentication problem and i was reluctant to start setting credssp on machines not to mention i actually wanted to run it locally on the same server so the commands failed. Therefore i quickly realised using start-process was the answer. Now, something interesting about start-process, there are different parameters that can not be used together! For example you can not use both -credential and -verb together, which was exactly what i needed to do. So after much head scratching i realised that what is needed is to run the start-process once for the other user then once again within the first to achieve the admin elevation. To add complexity i also wanted it to run a script with arguments! Here’s what i ended up with:
$script = ” c:\somescript.ps1″ #Very important do not remove the space!
$scriptWithArgs = ” $script, $arg1, $arg2″
Start-Process powershell -wait -Credential $ANOtherAccount -ArgumentList “-command &{Start-Process powershell -argumentlist `"$scriptWithArgs
`” -verb runas -wait}”
Unfortunately this does produce 2 new powershell windows, there isnt really a way around this, the -credential command requires a new window for a new token however it could be possible to add the -NoNewWindow parameter to the second start-process however for my purpose i was fine with 2 windows!
Dealing with UAC Prompts
Just an aside, another issue I came across was UAC prompts. Whilst it not best practice we wanted this to run seamlessly and it had a number of further scripts to run so rather than a user needing to approve the prompt 20 times i opted to temporarily disable the UAC prompts on the system using the registry:
#Temporarily disable UAC prompts
New-ItemProperty -Path “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System” -Name “ConsentPromptBehaviorAdmin” -Value “0” -PropertyType DWORD -Force | Out-Null
Do your thing.
#Re-enable UAC prompts
New-ItemProperty -Path “HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System” -Name “ConsentPromptBehaviorAdmin” -Value “2” -PropertyType DWORD -Force | Out-Null
I hope this helps someone!