Windows PowerShell vs CMD comes down to one difference: CMD passes plain text between commands, while PowerShell passes .NET objects you can filter, sort and format. For anything beyond a quick one-liner, PowerShell is the better choice.
CMD (cmd.exe, the Command Prompt) is still around for batch files and old habits. Below I compare the two side by side with commands I ran in PowerShell 7.6, Windows PowerShell 5.1 and CMD on Windows 11.
PowerShell vs CMD at a glance
| CMD | PowerShell | |
|---|---|---|
| Output | Plain text | .NET objects |
| Commands | Built-in commands and .exe tools | Cmdlets, functions and .exe tools |
| Scripts | .bat and .cmd | .ps1 |
| Environment variables | %PATH% | $env:PATH |
| Last exit code | %ERRORLEVEL% | $LASTEXITCODE |
| Remote management | Separate tools | Built in (Invoke-Command) |
| Runs on | Windows only | Windows; PowerShell 7 also on macOS and Linux |
Both shells run regular programs like ipconfig, ping and robocopy the same way. The real gap is what happens to the output.
Text vs objects: the key difference
Ask both shells for a folder listing and look at what comes back. CMD gives you strings, and PowerShell gives you file and folder objects:
$fromCmd = cmd.exe /c "dir /b C:\psfaqs\Compare"
$fromPs = Get-ChildItem -Path C:\psfaqs\Compare
"CMD returns: $($fromCmd[0].GetType().Name) -> '$($fromCmd[0])'"
"PowerShell returns: $($fromPs[0].GetType().Name) -> Name, Length, LastWriteTime and more"
Output:
CMD returns: String -> 'logs'
PowerShell returns: DirectoryInfo -> Name, Length, LastWriteTime and more

With text, you’d have to cut columns out of each line to get a file size. With objects, the size is already a number in the Length property.
Filter and sort without parsing text
Here I list every file over 10 KB, largest first. In CMD this needs a FOR loop and string parsing. In PowerShell it’s one pipeline:
Get-ChildItem -Path C:\psfaqs\Compare -File -Recurse |
Where-Object Length -GT 10KB |
Sort-Object -Property Length -Descending |
ForEach-Object { '{0,-11} {1,8:N0} KB' -f $_.Name, ($_.Length / 1KB) }
Output:
app.log 244 KB
report.csv 47 KB

Sorting files by date uses the same idea with LastWriteTime instead of Length.
Familiar CMD commands in PowerShell
PowerShell includes aliases, so dir, cd, copy and del still work. Each one points to a cmdlet:
Get-Alias -Name dir, cd, copy, del, type, cls, md |
ForEach-Object { '{0,-5} -> {1}' -f $_.Name, $_.Definition }
Output:
dir -> Get-ChildItem
cd -> Set-Location
copy -> Copy-Item
del -> Remove-Item
type -> Get-Content
cls -> Clear-Host
md -> mkdir
The catch is that aliases take PowerShell parameters, not CMD switches. dir /s fails, because PowerShell reads /s as a path:
try { dir /s C:\psfaqs\Compare -ErrorAction Stop | Out-Null; 'dir /s worked' }
catch { "dir /s: Failed. $($_.Exception.Message)" }
"Get-ChildItem -Recurse found $((Get-ChildItem -Path C:\psfaqs\Compare -Recurse -File).Count) files"
Output:
dir /s: Failed. Cannot find path 'C:\s' because it does not exist.
Get-ChildItem -Recurse found 3 files

Use -Recurse instead of /s, -Force instead of /a and -Name instead of /b.
Environment variables and exit codes
Both shells read the same environment variables, just with different syntax:
"CMD syntax: $(cmd.exe /c 'echo %OS%')"
"PowerShell syntax: $env:OS"
Output:
CMD syntax: Windows_NT
PowerShell syntax: Windows_NT
Exit codes work the same way too. CMD stores the last one in %ERRORLEVEL%, and PowerShell puts a program’s exit code in $LASTEXITCODE:
cmd.exe /c "exit 3"
"Exit code from CMD: $LASTEXITCODE"
cmd.exe /c "dir C:\psfaqs\Compare >nul"
"After a successful command: $LASTEXITCODE"
Output:
Exit code from CMD: 3
After a successful command: 0
Setting environment variables in PowerShell covers changing them for the session, the user or the machine.
Run CMD commands from PowerShell
Built-in CMD commands such as dir, echo and mklink live inside cmd.exe, so call them with cmd /c. Running a .bat file from PowerShell starts cmd.exe for you:
cmd /c "dir /s /b C:\Reports"
.\Build.bat
cmd /c mklink /J C:\Data\Current C:\Data\2026-09
For programs with tricky arguments, the stop-parsing token --% passes the rest of the line as is. Microsoft explains it in about_Parsing.
When to use CMD and when to use PowerShell
Use PowerShell for new scripts, admin tasks, working with files and services, Active Directory, Microsoft 365 and Azure. Its objects, error handling and remoting make scripts shorter and safer.
Use CMD when you run or maintain existing .bat files, or in recovery and setup environments where PowerShell isn’t available. Microsoft documents every CMD command in the Windows commands reference.
Windows PowerShell 5.1 or PowerShell 7?
Windows PowerShell 5.1 ships with Windows. PowerShell 7 is the newer, cross-platform version you install separately, and it runs side by side with 5.1. Microsoft’s What is PowerShell? overview covers both.
Frequently Asked Questions
What is the difference between PowerShell and CMD?
CMD passes plain text between commands. PowerShell passes .NET objects, so you can filter, sort and format results without parsing text.
Can PowerShell run CMD commands?
Yes. Programs like ipconfig and ping run directly. Built-in CMD commands and switches need cmd /c, for example cmd /c "dir /s /b".
Is PowerShell replacing CMD?
PowerShell is the recommended shell for automation, but cmd.exe still ships with Windows for batch files and compatibility.
Why does dir /s not work in PowerShell?
In PowerShell, dir is an alias for Get-ChildItem, which doesn’t use CMD switches. Use Get-ChildItem -Recurse instead.
Can I run a .bat file in PowerShell?
Yes. Type its path, such as .\Build.bat, and PowerShell runs it with cmd.exe.
Where to go next with PowerShell:
- Check your PowerShell version
- Update PowerShell on Windows 11
- Run a script from the command line
- Set the execution policy
Bijay Kumar is an esteemed author and the mind behind PowerShellFAQs.com, where he shares his extensive knowledge and expertise in PowerShell, with a particular focus on SharePoint projects. Recognized for his contributions to the tech community, Bijay has been honored with the prestigious Microsoft MVP award. With over 15 years of experience in the software industry, he has a rich professional background, having worked with industry giants such as HP and TCS. His insights and guidance have made him a respected figure in the world of software development and administration. Read more.