How to Run EXE Files using PowerShell
The message is clear: PowerShell is taking over the scripting world within the Windows OS. Until now, many different scripting languages have been used, with batch scripting being the most popular, and later replaced by VBScript.
Even the MSI technology uses VBScript and understands how to define custom actions in it. Since VBScript is now considered deprecated, many companies are switching to PowerShell.
Apart from the MSI itself, PowerShell has become the most popular scripting language outside of the MSI area. Because of the large collection of cmdlets available, people use PowerShell to configure almost everything within the OS.
We’ve talked a lot about PowerShell on our blog, and you have many articles to help you, including this one on how to convert a PowerShell Script into an EXE. But today, we want to shift direction and focus, specifically, on how to run an EXE from a PowerShell script.
Common Methods to Run EXE Files in PowerShell

PowerShell includes many ways to invoke executables, each with its unique behavior and advantages, so let's look into multiple options:
1. Direct Invocation

You can simply invoke the EXE by using the following command:
.\myapp.exe
This is a simple and intuitive method that also inherits the current environment. However, as a downside, the output goes directly to the console, so if you want any logs, you will need to run additional commands.
2. Using Start-Process

Start-Process is a standard PowerShell cmdlet that you can use to launch applications, run scripts or executables with specific arguments, elevate privileges, and control window behavior.
Using this cmdlet is quite simple:
Start-Process -FilePath "myapp.exe" -ArgumentList "-arg1 value1" -Wait -NoNewWindow
This cmdlet is ideal for GUI apps or background tasks. Additionally, Start-Process supports async execution. The downside is that technically, Start-Process does not capture the output unless it is redirected.
One small pro tip I would offer is to use the -Wait parameter when scripting installations or tasks that must be completed before continuing, and then combine it with the -PassThru argument to monitor or kill the process later.
3. Using Invoke-Expression

Invoke-Expression is one of PowerShell’s most unpredictable and somewhat risky cmdlets.
It allows you to evaluate and execute a string as PowerShell code, which can be powerful but should be used with caution. Essentially, Invoke-Expression executes a string as if it were typed directly into the PowerShell console.
It’s basically a method for dynamically creating and executing code:
Invoke-Expression -Command '"C:\Path\To\App.exe"'
If the executable requires arguments, include them in the string:
Invoke-Expression -Command '"C:\Path\To\App.exe" /silent /install'
Invoke-Expression is risky because it executes arbitrary strings as PowerShell code, which opens the door to serious security vulnerabilities if not handled properly.
If you build a command string from user input or external sources and pass it to Invoke-Expression, that’s how malicious actors can inject harmful commands. Also, it can bypass script signing, execution policies, and other security mechanisms by dynamically evaluating strings, making it more difficult to audit or control.
4. Using & (Call Operator)

The “&” operator is great for dynamic paths and supports arguments, but it does require some careful quoting:
$exe = "C:\Tools\deploy.exe" & $exe "/silent" "/log:deploy.log"
In general, these are the most commonly used methods for running an EXE, with the “Start-Process” command being the most popular.
Subscribe to our blog to receive monthly articles and webinar invites.No spam — just pure, valuable content for IT professionals
Running EXE Files Placed Near Your Script

Usually, the EXE files are bundled with the PowerShell script that will be executed. To avoid hardcoded paths, it is recommended to locate the execution directory dynamically.
With PowerShell, this is easy. To get the current script directory, which is the folder that contains the current script (even if the script is invoked from another directory):
$scriptDir = Split-Path -Parent $MyInvocation.MyCommand.Definition
Once we have the variable with the current script directory, all we need to do is implement it in the main run sequence:
$exePath = Join-Path $scriptDir "myapp.exe" & $exePath -arg1 value1
This is how you avoid hardcoded paths, and it also helps with packaged deployments or relative executions in CI/CD pipelines.
Tips and Best Practices

There are some tips we can certainly offer:
- First, always make sure to avoid hardcoded paths and use the “$MyInvocation.MyCommand.Definition” as shown above.
- Regarding running an EXE, we prefer the “Start-Process” cmdlet because it offers benefits, and most EXEs now have a GUI and an async behavior.
- Avoid “Invoke-Expression” at all costs unless it is necessary and backed up by strong security.
- One last tip would be to capture exit codes with $LASTEXITCODE:
& $exePath
if ($LASTEXITCODE -ne 0) {
Write-Error "Execution failed with code $LASTEXITCODE"
}Final Takeaways

- PowerShell has become the leading scripting language within Windows OS, replacing methods such as VBScript and batch due to its versatility, organization, and extensive cmdlet library.
- There are several methods to execute EXE files. Yet Start-Process is the most frequently used due to its ability to manage arguments, asynchronous execution, privilege elevation, and controlled processing.
- The immediate invocation and the call operator are effective for execution. Still, they do not include logging, so you'd need extra measures if you want to manage the output or any errors.
- Invoke-Expression is a functional feature, but due to its security vulnerabilities, it should be avoided at all costs unless no better alternative is on hand.
- Stay away from hardcoded paths, exit code capturing, and script-aware variables, which are just a few examples of things you should not do to keep your deployment scripts portable, reliable, and future-proof.
Conclusion

PowerShell gives you flexible, secure, and scriptable ways to run executables — whether you're deploying software, automating tasks, or building endpoint workflows.
By leveraging dynamic path resolution and choosing the right invocation method, you can build robust scripts that work across environments and use cases.
Subscribe to our blog to receive monthly articles and webinar invites.No spam — just pure, valuable content for IT professionals
