Have you ever wanted to run a program remotely across a network without needing to install or configure anything on the remote machine you wish to access?
If the answer is yes then you’ll be pleased to know there is a way to accomplish this in a Windows environment using a very clever little command-line program named ‘PsExec’.
In this article, I explain what PsExec is, how to use it, and how it works under the covers.
What is PsExec?
PsExec is a command-line utility which can be used to execute programs remotely on other Windows machines to which you have network access. PsExec redirects the console output of remotely executed programs to the client machine such that they appear to be running locally.
PsExec is part of a family of command-line tools called ‘PsTools’, developed by Mark Russinovich who is currently the CTO of Microsoft Azure. The tools were created while Mark was the Chief Software Architect at Winternals Software and they were part of a project named ‘Sysinternals’.
In the following two sections, I explain how to install PsExec and walk through the basics of using it to execute a program on another machine.
The usual approach for getting access to PsExec is to first of all download it onto your machine (I discuss an alternative at the end of this section).
On the Microsoft Docs SysInternals page click on the ‘Download PsTools’ link which will download a zip file containing all of the available PsTools, including PsExec.
Extract the contents of the zip file to a folder on your local machine.
Now launch your terminal of choice and change your working directory to the location of the folder containing the PsTools which you extracted from the zip file. You can also add the PsTools folder to your ‘Path’ Environment Variable so that you can use PsExec from your terminal without having to change directory.
Tip: If you wish to quickly launch the standard Windows Console host (Command Prompt) in the current directory via File Explorer, simply type ‘cmd’ within the File Explorer location bar and press the Enter/Return key.
Before moving on, note that it is also possible to run PsExec and any of the other PsTools directly, without the need to manually download them, by entering the following into File Explorer.
Now that PsExec is available on your local machine, execute the following command within your terminal (make sure your current working directory is set to the folder containing PsExec).
By default, whenever you execute PsExec without specifying any command-line arguments, PsExec will display help information.
I have included the terminal output below for reference.
PsExec v2.2 - Execute processes remotely Copyright (C) 2001-2016 Mark Russinovich Sysinternals - www.sysinternals.com PsExec executes a program on a remote system, where remotely executed console applications execute interactively. Usage: psexec [\\computer[,computer2[,...] | @file]][-u user [-p psswd][-n s][-r servicename][-h][-l][-s|-e][-x][-i [session]][-c [-f|-v]][-w directory][-d][-<priority>][-a n,n,...] cmd [arguments] -a Separate processors on which the application can run with commas where 1 is the lowest numbered CPU. For example, to run the application on CPU 2 and CPU 4, enter: "-a 2,4" -c Copy the specified program to the remote system for execution. If you omit this option the application must be in the system path on the remote system. -d Don't wait for process to terminate (non-interactive). -e Does not load the specified account's profile. -f Copy the specified program even if the file already exists on the remote system. -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. -l Run process as limited user (strips the Administrators group and allows only privileges assigned to the Users group). On Windows Vista the process runs with Low Integrity. -n Specifies timeout in seconds connecting to remote computers. -p Specifies optional password for user name. If you omit this you will be prompted to enter a hidden password. -r Specifies the name of the remote service to create or interact. with. -s Run the remote process in the System account. -u Specifies optional user name for login to remote computer. -v Copy the specified file only if it has a higher version number or is newer on than the one on the remote system. -w Set the working directory of the process (relative to remote computer). -x Display the UI on the Winlogon secure desktop (local system only). -arm Specifies the remote computer is of ARM architecture. -priority Specifies -low, -belownormal, -abovenormal, -high or -realtime to run the process at a different priority. Use -background to run at low memory and I/O priority on Vista. computer Direct PsExec to run the application on the remote computer or computers specified. If you omit the computer name PsExec runs the application on the local system, and if you specify a wildcard (\\*), PsExec runs the command on all computers in the current domain. @file PsExec will execute the command on each of the computers listed in the file. cmd Name of application to execute. arguments Arguments to pass (note that file paths must be absolute paths on the target system). -accepteula This flag suppresses the display of the license dialog. -nobanner Do not display the startup banner and copyright message. You can enclose applications that have spaces in their name with quotation marks e.g. psexec \\marklap "c:\long name app.exe". Input is only passed to the remote system when you press the enter key, and typing Ctrl-C terminates the remote process. If you omit a user name the process will run in the context of your account on the remote system, but will not have access to network resources (because it is impersonating). Specify a valid user name in the Domain\User syntax if the remote process requires access to network resources or to run in a different account. Note that the password and command is encrypted in transit to the remote system. Error codes returned by PsExec are specific to the applications you execute, not PsExec.
As you can see, there are a host of available options.
Now let’s try out some remote commands.
Execute the following command. Replace ‘computername’ with the name of the remote computer you wish to execute the command on and replace ‘username’ with the username to authenticate with.
psexec \\computername -u username -d -i notepad
Note that you will be prompted for a password. Enter the password for the remote computer and press the Enter/Return key.
The above command launches Notepad on the remote computer interactively (as it is a GUI application) using the -i argument and doesn’t wait for Notepad to close before returning using the -d argument. If you don’t specify the -d argument you can use the Ctrl + C keyboard shortcut to terminate the remote process.
Whenever PsExec begins executing a remote command you will see text similar to the following displayed in your terminal.
Starting PSEXESVC service on computername...
Note that the purpose of the PsExecSvc service will be explained in the next section.
After the remote command finishes, text similar to the following will be displayed.
notepad started on computername with process ID 1234.
The Notepad example works by only specifying ‘notepad’ as the application name because the Notepad program lives in the %systemdrive%\Windows\System32 folder. You can launch other programs remotely by specifying the full path to the program, as per the example below.
psexec \\computername -u username -d "C:\Program Files\7-Zip\7z.exe"
If you need to pass arguments to the remote program you are executing, simply add the arguments to the end of the overall command, as follows.
psexec \\computername -u username -d "C:\Program Files\7-Zip\7z.exe" i -so
One of the most powerful features of PsExec is its ability to redirect the output of remotely executed processes back to the caller. A good example of this is the ‘ipconfig’ conmmand which displays information regarding the Windows IP Configuration.
psexec \\computername -u username ipconfig
After executing the above command you will see the output returned from the remote computer, followed by the exit code.
Having the ability to run command-line programs on remote systems and receive the output is very powerful and essentially allows you to ‘remote-enable’ any command-line program as you see fit.
You can also launch an interactive Command Prompt on the remote system as follows.
psexec \\computername -u username cmd
You can then issue whatever additional commands you need to without concerning yourself further with the syntax of PsExec.
The above examples are a good starting point for understanding how to use PsExec and there are many more interesting options to explore.
For example, using the -c argument you can copy a program to execute to the remote computer. Whenever PsExec finishes running the program which was copied it will automatically remove the program from the remote computer. Neat!
How it works
Whenever a remote command is initiated, PsExec copies a Windows Service program named ‘PsExecSvc’ (cleverly contained within its own executable image) to the remote machine.
PsExec then uses the SCM (Service Control Manager) on the remote machine (which has a remote interface) to start the service on the remote machine.
When started, the PsExecSvc service opens a named pipe which is used for communication between the machines and redirects any console output back to PsExec.
If the -d (don’t wait) parameter has been specified, the PsExecSvc service stops immediately after starting the remote process, otherwise, the service stays running until the process has completed and then returns the exit code to the client machine which issued the remote command.
In order for PsExec to work, file and printer sharing must be enabled on both the local and remote machine. PsExec uses the built-in Admin$ (Remote Admin) hidden share on the remote computer to copy and execute its payload, enabling remote communications.
You can see where the Admin$ share is defined by issuing the following command from the ‘Run’ dialog (WIN + R) and then pressing the Enter/Return key.
This will open the ‘Shared Folders’ window which displays all folders which are shared by the system, whether built-in or user-defined. After the window appears click on the ‘Shares’ folder. The ‘Folder Path’ column indicates that the Admin$ share maps to the %systemdrive%\Windows directory.
Although of course, PsExec itself is not a virus, it has been used by viruses to propagate malicious programs across networks. As a result, PsExec can be reported as a virus by some anti-virus programs.
Of course, viruses are merely using PsExec as a convenient way to do some things that they could implement themselves with a bit of time and effort.
Much of the security concerns around the usage of PsExec are mitigated by the fact that administrative account credentials are required in order for PsExec to have the rights required to access the $Admin share and therefore to copy and execute its payload.
Both the command text and the user credentials are encrypted in transit to the remote machine.
If incorrect credentials are specified you will receive an error similar to the following.
Couldn't access computername:
Access is denied.
If the Admin$ share has been disabled on the remote machine, then you will receive an error similar to the following.
Couldn't access computername:
The network path was not found.
If you having difficulties executing a process on a remote computer using PsExec, first of all, verify that the credentials you have specified are correct.
Next, make sure that the default Admin$ share is enabled on the remote computer.
You should also check that file and printer sharing is enabled on both the remote computer and on your local machine.
In summary, we have learned what PsExec is and how easy it is to install and use.
We’ve also delved into how PsExec works behind the scenes and have considered the security implications.
PsExec offers a lot of options for remotely executing programs and it can be a very useful tool in the arsenal of a Windows system administrator.
I would encourage you to check out the other Sysinternals tools if you have an interest in how Windows works under the covers. There are quite a few gems in there which can help you with troubleshooting system issues, identifying security holes and automating tasks on Windows machines.