Run a .cmd file through PowerShell
Categories:
Executing .cmd Files from PowerShell: A Comprehensive Guide

Learn various methods to run legacy .cmd batch files within PowerShell, understanding their nuances and best practices for seamless integration.
PowerShell is a powerful, modern scripting environment for Windows, but often you'll encounter legacy batch scripts (.cmd
or .bat
) that you need to execute. Directly running a .cmd
file from PowerShell isn't always as straightforward as typing its name. This article explores the different ways to invoke .cmd
files, explaining the underlying mechanisms and providing practical examples to help you integrate your old scripts into new PowerShell workflows.
Understanding the Challenge
When you type a command like my_script.cmd
directly into PowerShell, PowerShell tries to interpret it. Since .cmd
files are designed for cmd.exe
, PowerShell's default behavior might not execute them as expected. This often leads to errors or the script not running at all. The key is to tell PowerShell to hand off the execution to cmd.exe
.
flowchart TD A[PowerShell Invocation] --> B{Is it a native PowerShell command?} B -->|Yes| C[Execute directly in PowerShell] B -->|No| D{Is it an executable (.exe)?} D -->|Yes| E[Execute directly] D -->|No| F{Is it a script (.ps1, .cmd, .bat)?} F -->|Yes| G{Check file extension and PATHEXT} G -->|PowerShell Script| C G -->|CMD/BAT Script| H["Requires explicit cmd.exe invocation"] H --> I[Execute via `cmd.exe /c`]
PowerShell Command Execution Flow
Method 1: Using cmd.exe /c
The most robust and recommended way to run a .cmd
file from PowerShell is to explicitly invoke cmd.exe
and pass the .cmd
file as an argument using the /c
switch. The /c
switch tells cmd.exe
to execute the command string and then terminate.
cmd.exe /c "C:\Path\To\Your\script.cmd"
# Or, if the script is in the current directory:
cmd.exe /c ".\script.cmd"
# Passing arguments to the .cmd script:
cmd.exe /c "C:\Path\To\Your\script.cmd" Arg1 "Argument with spaces"
Executing a .cmd file using cmd.exe /c
.cmd
file or ensure it's in the current directory. If the path contains spaces, enclose the entire path in double quotes.Method 2: Using the Call Operator &
The call operator (&
) in PowerShell allows you to run commands, scripts, or executables that are stored in a string or a variable. While it can sometimes work for .cmd
files, it's less reliable than cmd.exe /c
because PowerShell still tries to interpret the command before passing it. However, for simple .cmd
files without complex internal logic, it might suffice.
& "C:\Path\To\Your\script.cmd"
# Or, if the script is in the current directory:
& ".\script.cmd"
# Passing arguments:
& "C:\Path\To\Your\script.cmd" Arg1 "Argument with spaces"
Executing a .cmd file using the call operator &
&
for .cmd
files can sometimes lead to unexpected behavior, especially with environment variables or complex batch commands. cmd.exe /c
is generally safer and more consistent.Method 3: Using Start-Process
Start-Process
is a PowerShell cmdlet designed to start new processes. It's useful when you want to run the .cmd
file in a new window, or if you need more control over the process's execution, such as waiting for it to complete or capturing its output.
# Run in a new window, without waiting:
Start-Process -FilePath "C:\Path\To\Your\script.cmd"
# Run and wait for the process to complete:
Start-Process -FilePath "C:\Path\To\Your\script.cmd" -Wait
# Run and pass arguments:
Start-Process -FilePath "C:\Path\To\Your\script.cmd" -ArgumentList "Arg1", "Argument with spaces"
# Run hidden and wait:
Start-Process -FilePath "C:\Path\To\Your\script.cmd" -WindowStyle Hidden -Wait
Executing a .cmd file using Start-Process
Start-Process
with .cmd
files, PowerShell automatically uses cmd.exe
as the default handler, so you don't need to explicitly specify cmd.exe /c
.Capturing Output and Exit Codes
When running .cmd
files, especially in automated scripts, you often need to capture their output (stdout/stderr) and check their exit code to determine success or failure. This is crucial for error handling and logging.
# Using cmd.exe /c to capture output and exit code
$command = "C:\Path\To\Your\script.cmd Arg1"
$output = cmd.exe /c $command
$exitCode = $LASTEXITCODE
Write-Host "Output:"
$output
Write-Host "Exit Code: $exitCode"
# Using Start-Process to capture output (requires redirection)
# This is more complex as Start-Process runs in a separate process
# For simple output capture, cmd.exe /c is often easier.
# Example: Redirecting output to a file
Start-Process -FilePath "C:\Path\To\Your\script.cmd" -ArgumentList "Arg1" -RedirectStandardOutput "output.txt" -Wait
$fileContent = Get-Content "output.txt"
Write-Host "File Content: $fileContent"
Capturing output and exit codes from .cmd execution
$LASTEXITCODE
automatic variable in PowerShell holds the exit code of the last native command executed. This is extremely useful for checking the success or failure of your .cmd
scripts.