Run a command as a different user in Powershell

There are three main ways to run a command as a different user in Powershell, besides the classing Right click shift. This article will show you how to do that, within the same Powershell session.
By the same Powershell session, I mean something like this:

  • You’re logged on as ITDroplets\UserA.
  • You have a powershell script/console running as UserA.
  • Within that powershell script/console, you want to run a command as ITDroplets\UserB.

In the Options below, I will consider the above example and I will run “Get-Process Explorer” as UserB. This is very handy when running elevated commands, for instance when UserA is a standard user account and UserB has local admin rights. Of course, Get-Process Explorer doesn’t really need elevation ­čÖé
Remember that the examples are super concentrated, which means I didn’t add any check to see if the command ran successfully etc. They’re there as pure examples, you can then shape them to fit your needs.

Option 1 –┬áSystem.Diagnostics.ProcessStartInfo

Option 1 is the one that seems to be working better than others. It’s similar to Option 2 as it also starts a new process, but handles the output way better than Option 2. It basically starts a new process as UserB and then grab the output, stored in $GetProcessResult. The comments should explain everything on what the script is doing.

Option 2 – Start-Process

Very similar to Option 1, this way to┬árun a command as a different user in Powershell has one flow: it’s not possible to grab the output from Start-Process, unless it’s redirected to a file! So that means we need to store the output somewhere and then grab it back. Thankfully, the file is created as UserA, which means we can target UserA’s %temp% folder to store it.┬á The above script will also delete it afterwards and at the beginning of it, should the file already exist for some reason.

Option 3 – Start-Job

This one’s my favorite to run a command as a different user in Powershell, however it does have an issue and you may receive the error below in case you’ve got a mapped drive on UserA’s profile: An error occurred while starting the background process. Error reported: The directory name is invalid.

So, there are a couple of ways to fix this but unfortunately, I don’t like them and I don’t think the’re good solutions.

Solution 1

The first solution would be changin the “Start In” setting in the Powershell shortcut (in Windows 10 it’s located here: %appdata%\Microsoft\Windows\Start Menu\Programs\Windows PowerShell). You must change %HOMEDRIVE%%HOMEPATH% to something like %WinDir% for example. If you don’t want o edit the original shortcut, you can just clone it and edit the cloned one.

Once done, you can just double click on it as UserA and you should be good. This won’t require admin rights, but it requires a restart of the console if you have it opened!

Solution 2

This one is a bit of an overkill if you ask me and it does require UserA to have local admin rights, or at least write access to %windir%\System32\WindowsPowerShell\v1.0. So basically you want to create a file named profile.ps1 and add something like this in it: Set-Location -Path $($env:windir)
This has to be done before running the script as UserB so that when the script tries to start the job as a different user, it’ll be able to launch the script as it’ll load the right location. If you want to script this, I would do something like this:

So basically, the script checks if the file already exists, if it does, it renames it, creates a new one which includes $ProfilePS1’s content, finally runs Option 3’s script, deletes profile.ps1 and reverts back to the old one (if existed). If UAC is enabled, you must make sure you’re running this as Administrator!

Unfortunately, using Set-Location in the current session before hand, won’t work.

Leave a Reply

Your email address will not be published. Required fields are marked *