2

I know this looks like a duplicate question, but I've tried the solutions and they haven't worked for me.

We need to run a script with our domain accounts but also execute it elevated. This isn't an issue on most devices, since the shortcut runs as admin and prompts us for a credential. However, if the user is a local admin, we are not prompted for a credential (just a yes/no UAC prompt).

I'm confused why this is not working:

# Get identity of script user
$identity = [Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()

# Elevate the script if not already
if ($identity.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
    Write-Host -F Green 'ELEVATED'
} else {
    Start-Process PowerShell -Verb RunAs "-NoProfile -ExecutionPolicy Bypass -Command `"& '$PSCommandPath'`""
    Exit
}

# Ensure the script has domain privileges
if ($identity.IsInRole('[domain]\[admin group]')) {
    Write-Host -F Green 'DOMAIN ADMIN'
} else {
    Start-Process PowerShell -Verb RunAsUser "-NoProfile -ExecutionPolicy Bypass -Command `"& '$PSCommandPath'`""
    Pause # required, otherwise the Exit below closes the UAC prompt
    Exit
}
Pause

When the self-elevated script runs as user and domain credentials are entered, it loses elevation... i.e. when Start-Process -Verb RunAsUser powershell is run from an elevated PowerShell, it is not itself elevated.

I also tried the following:

Start-Process powershell -verb RunAs -argumentlist "Start-Process powershell.exe -Verb RunAsUser `"& path\to\script.ps1`""

Which fails because the domain admin does not have access to the script directory... unless they're elevated.

Vomit IT - Chunky Mess Style
  • 40,038
  • 27
  • 84
  • 117
Kevin Higby
  • 111
  • 1
  • 1
  • 5
  • See the solution I provided that has a way to get this to work without needing to mess with security of the shares and such. Had a typo in my previous comment so I removed it and added this new one so it's more clear. – Vomit IT - Chunky Mess Style Feb 03 '21 at 17:04

4 Answers4

5

Are you automating something or just running a script occasionally? Is the script directory local or on the network?

As you've noticed, starting a new instance of powershell with runas won't change the user, and runasuser won't elevate the process. You'll need to do them both in the opposite order. If you are logged in as the local admin, start Powershell with RunAsUser, or through:

  • Shift+Right-click > Run as different user > Domain admin

Then do your runas to elevate from there (as the domain admin):

Start-Process PowerShell -Verb RunAs

You can check what user you're currently running as with whoami. the result should be your domain account, even when elevated.

OR

if you are managing a PC remotely and using powershell already, connect using powershell instead as the session will always be elevated:

Enter-PSSession MyPCName -credential (get-credential -username domain\MyAdmin)
# remote session:
[MyPCName]: PS C:\WINDOWS\system32>

I also have to recommend never using the local admin account if possible.

Cpt.Whale
  • 4,501
  • 2
  • 13
  • 25
  • Looks like running as a different user then self-elevating is the way to go. I will have to find a workaround to the domain admins not having access to the script directory. I'm not sure why it's there and not on the network... – Kevin Higby Jan 21 '21 at 19:36
0

An alternate tool is the free sysinternals tool PsExec.

The command would look like:

psexec -u domain\user -h -i command [arguments]

The parameters are:

  • -i : Run the program so that it interacts with the desktop of the specified session on the remote system. If no session is specified the process runs in the console session.
  • -h : If the target system is Vista or higher, has the process run with the account's elevated token, if available.

An unsafe practice is also to specify the password:

-p : Specifies optional password for user name. If you omit this you will be prompted to enter a hidden password.

harrymc
  • 455,459
  • 31
  • 526
  • 924
0

A simple solution is to first copy the script from the location which requires the domain credential that you are already logged on as to the local filesystem of the machine which you need to execute it from elevated. Then execute the script elevated from that local copy instead.

Execute the Start-Process Powershell a little differently than you were executing it for it to take the action of the script logic while running elevated too. Add the ExecutionPolicy Bypass -NoProfile -File parameters and run the script after that for it to work.

Note: Both of the below example PowerShell solutions use the root of the "C" drive at C:\ of the local filesystem, but you can adjust that accordingly to accommodate.

PowerShell (Solution 1)

Copy-Item "path\to\script.ps1" -Destination "C:\" -Force;
Start-Process Powershell -Argumentlist '-ExecutionPolicy Bypass -NoProfile -File "C:\script.ps1"' -Verb RunAs;

If you need to authenticate with a domain credential to access the script path location initially you can use invoke-command with the -credential parameter to perform the copy operation. Then you can execute the local filesystem copied script elevated that way.

PowerShell (Solution 2)

$cred = Get-Credential "domain\username";
Invoke-Command -ScriptBlock {
    Copy-Item "path\to\script.ps1" -Destination "C:\" -Force;
    } -Credential $cred;

Start-Process Powershell -Argumentlist '-ExecutionPolicy Bypass -NoProfile -File "C:\script.ps1"' -Verb RunAs;

Supporting Resources

Vomit IT - Chunky Mess Style
  • 40,038
  • 27
  • 84
  • 117
-2

In my understanding, in generally, the executing user and privilege of the current process can not be altered during the process is executing, but they are set at the process startup timing by operating system kernel.
So you should separate the code block which you want to run as elevated, and run it with RunAs (or its valiations).
If altering privilege within a process is possible, it will become very dangerous security hole of the operating system.

In addition, local privilege (local administrator) and domain privilege ([domain]\[admin group]) are separately defined.
If you want to permit DomainA\User01 both local administrator AND DomainA\AdminGroup, you have to do both:

  • grant DomainA\User01 into local computer security group local administrator , AND
  • grant DomainA\User01 into domain security group DomainA\AdminGroup

and then execute the script with RunAs.

  • 2
    This answer reads more like a comment than an actual answer that explains how to accomplish what the author wants. You should provide explicit examples. You can [edit] your answer and improve it. – Ramhound Jan 22 '21 at 01:06