Build PsExec commands to run programs on remote Windows machines.
PsExec runs a program on another Windows computer as if you had walked over and typed it there. This builder assembles the command from the target, the program you want to run, and the handful of switches that actually change behaviour. It produces text only — the page has no access to your network and cannot connect to anything.
The shape of every PsExec command is the same:
psexec \\PC01 -accepteula cmd
Target first, switches next, then the program and its arguments last. Anything after the program name belongs to the remote program, not to PsExec, which is the single most common syntax mistake.
Two facts that matter more than any flag.
First, PsExec is a Microsoft Sysinternals utility, not a Windows component. It is not present on a stock installation. You download it as part of the Sysinternals Suite (or PSTools) and run it from wherever you unzipped it. The first run shows a licence dialog, which is why the builder always includes -accepteula — without it, a script that calls PsExec on a machine where it has not run before will hang on a dialog nobody is watching.
Second, PsExec is one of the most heavily flagged legitimate tools in existence. Ransomware crews and intrusion operators use it for lateral movement constantly, so endpoint detection products, SIEM rules and managed SOC playbooks treat its use as a signal. Expect any of the following:
PSEXESVC service is installed — a service installation writes System event ID 7045, which is a standard hunting rule.None of that means you should not use it. It means you should tell whoever runs detection before you do, on machines you administer, and it means that if PowerShell Remoting is available it is usually the lower-friction option. Use PsExec when you need what it uniquely gives you: SYSTEM context, an interactive process on someone’s visible desktop, or access to a machine where WinRM is not configured.
Understanding the mechanism explains every error message you will hit. PsExec connects to the target’s hidden administrative share, copies a small service executable there, installs and starts it as a Windows service, and then relays input and output over named pipes across that same SMB connection. When the remote program exits, the service is stopped and removed and the exit code is returned to you.
Which means all of the following must be true:
ADMIN$ and IPC$ are present by default on domain-joined machines but are often disabled by hardening baselines.LocalAccountTokenFilterPolicy registry value on the target — which weakens a deliberate protection, so weigh it rather than applying it reflexively.| Switch | What it does | When you actually need it |
|---|---|---|
\\host | The target computer, by name or IP. The builder adds the leading backslashes for you if you leave them off | Always. Omit it and PsExec runs locally instead |
-accepteula | Suppresses the first-run licence dialog | Always, in anything automated. The builder includes it unconditionally |
-u DOMAIN\user | Connect as a different account | When your current logon is not an administrator on the target, or you are crossing a trust boundary |
-s | Run the remote process as the LocalSystem account | Anything that needs full machine privilege: service repair, registry work under HKLM, tools that refuse to run as an ordinary admin |
-i | Run in the interactive desktop session so the logged-on user can see it | Any program with a window. Without -i a GUI application starts invisibly and hangs there forever |
-c | Copy the specified program to the remote machine before running it | Running a tool that is not installed on the target — the point being you do not have to stage it first |
-d | Do not wait for the remote process to finish | Long-running jobs, and anything you are firing at many machines in sequence |
Notably absent: -p. The builder deliberately never writes a password onto the command line. If you supply a username, PsExec prompts for the password instead, which keeps it out of your shell history, out of process-creation event logs, and out of the command line that any other process on your machine can read. That is worth the extra keypress every time.
Other real PsExec switches the builder does not produce — add them by hand if you need them — include -h for the account’s elevated token, -e to skip loading the profile, -w to set the working directory, -f and -v to control overwriting with -c, -low and -high for priority, and @file to run against a list of computers.
psexec \\PC01 -accepteula cmd. You get a prompt that behaves like a local one. Type exit to close it cleanly — killing the window can leave the service behind.-s. This is how you reach places even an administrator prompt cannot, and it is also exactly the pattern that lights up detection, so use it deliberately.-i is mandatory. Without it, the process runs in session 0 where nobody can see or dismiss it.-s -i together. Common for running a repair tool on a user’s desktop while they watch.-c with the full local path to the executable. PsExec copies it, runs it, and removes it afterwards.-d so your console returns immediately. You lose the remote exit code and the output, so use it for things whose result you will check another way.| What you see | What it usually means |
|---|---|
| Couldn’t access <host>: Access is denied | Not an administrator on the target, or remote UAC filtering blocking a local account |
| The network path was not found | Host unreachable, name not resolving, or TCP 445 blocked by a firewall |
| The system cannot find the file specified | The program does not exist on the target. Either give a path that exists there, or use -c |
| Access is denied when copying PSEXESVC | The ADMIN$ share is disabled or unreachable |
| The command completes but nothing visibly happens | A GUI program launched without -i, running invisibly in session 0 |
| PsExec hangs with no output | The remote program is waiting for input, or the licence dialog appeared — hence -accepteula |
| The binary vanished from your Downloads folder | Antivirus quarantined it. Expected, not a corrupted download |
If PsExec is interrupted badly, the PSEXESVC service can be left installed on the target. sc \\PC01 query psexesvc tells you, and sc \\PC01 delete psexesvc removes it.
PowerShell Remoting — Invoke-Command and Enter-PSSession over WinRM — is the modern answer for most remote execution. It is built in, authenticates and encrypts by default, returns objects rather than screen-scraped text, and does not install a service on the target, so it draws far less attention from detection tooling. Where PsExec still wins is running as SYSTEM, putting a process on the interactive desktop, staging a binary with -c, and reaching machines where WinRM was never enabled — which, in the field, is a great many of them.
Use it on machines you are authorised to administer, tell your security team when you do, and never leave a password on the command line.
PsExec accepts a file of computer names in place of the target: psexec @hosts.txt -accepteula ipconfig /all, with one name or IP per line. The builder does not produce that form — it writes a single target — but the command it gives you is the template, and swapping \PC01 for @hosts.txt is the only change needed.
A few realities of running at scale. PsExec works through the list sequentially, so an unreachable machine costs you its full timeout before the run moves on; a stale list is the usual reason a fleet-wide command appears to hang. Adding -d stops PsExec waiting for each remote process to finish, which is much faster but discards both the output and the exit code, so only use it for actions you can verify another way. And every machine in the list gets a service installed and removed, which means every machine in the list generates the detection signal described above — running against fifty hosts at once is a reliable way to trigger an incident response.
If you find yourself doing this regularly, Invoke-Command -ComputerName (Get-Content hosts.txt) -ScriptBlock { ... } runs in parallel, returns structured results tagged with the machine each came from, and installs nothing. That is the better tool for fleet work; keep PsExec for the individual machine that needs SYSTEM, a visible desktop, or a binary staged onto it.
PsExec is a Sysinternals tool that runs programs and commands on remote Windows machines without installing anything on them. Admins use it to open a remote command shell, run diagnostics, or apply a quick fix across computers, with the output shown on their own console.
Leave the -p switch off the command line. When you specify a user with -u but no -p, PsExec securely prompts you for the password at runtime instead of storing it in your shell history or logs, which is the recommended practice.
PsExec is a legitimate admin tool, but attackers and malware frequently abuse it for lateral movement across a network. Because of that reputation, EDR and antivirus products often flag or block it. Use it only on machines you manage, and expect to allow-list it in your security tooling.
The -s flag runs the remote command under the local SYSTEM account, the highest-privilege built-in account on the machine. It bypasses user-level restrictions, so use it only when a task genuinely requires SYSTEM rights, such as certain service or registry operations.