100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Batch

Calling PowerShell from Batch

Learn how to invoke PowerShell commands and scripts from a batch file, pass parameters, capture output, and manage execution policy and security implications.

AutomationIntermediate8 min readJul 10, 2026
Analogies

Why Call PowerShell from a Batch File

Batch files and PowerShell are not mutually exclusive; a very common real-world pattern is a thin .bat wrapper that handles simple orchestration (checking for admin rights, setting environment variables, being double-clickable without an execution-policy prompt) while delegating any task requiring structured data, .NET objects, or modern cmdlets to an embedded PowerShell call. This lets teams keep a familiar batch entry point, useful for legacy deployment tooling or login scripts, while still leveraging PowerShell's richer capabilities such as Get-Service, Invoke-WebRequest, or Active Directory cmdlets for the parts of the job batch simply cannot do well.

🏏

Cricket analogy: Using batch as a wrapper around PowerShell is like a T20 captain opening with a specialist pinch-hitter for the first few overs before bringing on the team's premier all-rounder to handle the technical middle overs.

Invoking PowerShell Commands and Scripts

From a batch file, powershell.exe -NoProfile -Command "Get-Service -Name Spooler | Select-Object Status" runs an inline command, while powershell.exe -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\Deploy.ps1" runs a full .ps1 script file. -NoProfile skips loading the user's PowerShell profile for faster, more predictable startup in automation contexts, and -ExecutionPolicy Bypass overrides the machine's default script-execution restriction for that single invocation only, without permanently changing the system policy. On modern Windows, pwsh.exe (PowerShell 7+) can be called instead of the legacy powershell.exe (Windows PowerShell 5.1) if the cross-platform, actively developed version is installed and required.

🏏

Cricket analogy: The -Command flag for a quick inline instruction is like a captain shouting a single fielding adjustment mid-over rather than calling a full team huddle for a complete tactical briefing.

batch
@echo off
rem Call a PowerShell one-liner and capture a single value into a batch variable
for /f "usebackq delims=" %%S in (`powershell -NoProfile -Command "(Get-Service -Name Spooler).Status"`) do (
    set "SpoolerStatus=%%S"
)
echo Spooler service status: %SpoolerStatus%

rem Run a full PowerShell script and pass it parameters
powershell -NoProfile -ExecutionPolicy Bypass -File "C:\Scripts\Deploy.ps1" -Environment "Production" -Version "2.4.1"
if %errorlevel% neq 0 (
    echo Deployment script failed with exit code %errorlevel%
    exit /b %errorlevel%
)
echo Deployment completed successfully.

Passing Parameters and Capturing Output

Batch variables are passed to a PowerShell script as ordinary command-line parameters after -File, matched against a param() block defined at the top of the .ps1 file, e.g. param([string]$Environment, [string]$Version). To capture PowerShell's output back into batch, wrap the invocation in a for /f loop using backticks, which reads each line of stdout into a loop variable, exactly as you would capture output from any other console command. For exit-code propagation, a PowerShell script should call exit with an explicit integer (exit 1 on failure), which then surfaces to the batch caller as the normal %errorlevel%, since PowerShell's own $LASTEXITCODE only matters within PowerShell itself and must be explicitly turned into a process exit code to be visible to cmd.exe.

🏏

Cricket analogy: Matching batch arguments to a param() block is like a scorer entering the correct batter's name against the correct column in a pre-formatted scoresheet, position matters.

Execution Policy and Security Implications

PowerShell's execution policy (Restricted, AllSigned, RemoteSigned, Unrestricted) is a safety rail, not a security boundary; it exists to prevent accidental execution of scripts, not to stop a determined attacker, since it can always be overridden per-invocation with -ExecutionPolicy Bypass as shown above, or bypassed entirely by piping script content directly into powershell -Command. Because -ExecutionPolicy Bypass is so commonly used in legitimate automation, it is also a well-known pattern abused by malicious batch files that download and execute a remote payload with a single line, so security teams and antivirus/EDR products specifically watch for the combination of powershell.exe with -enc (encoded command), -windowstyle hidden, and Bypass appearing together.

🏏

Cricket analogy: Execution policy as a safety rail rather than a real barrier is like a boundary rope marking the edge of the field, it guides normal play but doesn't physically stop a determined six from clearing it.

Because -ExecutionPolicy Bypass combined with -WindowStyle Hidden and a base64-encoded -EncodedCommand is one of the most common patterns seen in malware droppers, any batch file you author that legitimately needs Bypass should keep the invocation fully visible (no -WindowStyle Hidden, no -enc obfuscation) and should be code-reviewed. If you find this exact combination in a script you did not write, treat it as a red flag and investigate before running it.

  • A batch wrapper calling PowerShell combines batch's simple invocation with PowerShell's richer cmdlet and object capabilities.
  • powershell -Command runs an inline expression; powershell -File runs a full .ps1 script with parameters.
  • -NoProfile speeds up and stabilizes automated PowerShell invocations by skipping profile scripts.
  • for /f with backticks captures PowerShell's stdout output back into batch variables.
  • PowerShell scripts must explicitly call exit <code> for the result to surface as the batch caller's %errorlevel%.
  • Execution policy is a safety rail against accidental execution, not a real security boundary, since Bypass overrides it per call.
  • The combination of -EncodedCommand, -WindowStyle Hidden, and Bypass is a well-known malware pattern that security tools monitor for.

Practice what you learned

Was this page helpful?

Topics covered

#Batch#WindowsBatchScriptingStudyNotes#MicrosoftTechnologies#CallingPowerShellFromBatch#Calling#PowerShell#Call#File#StudyNotes#SkillVeris