Two shells, two models
cmd.exe is the classic Windows command processor: commands return text, pipelines are byte streams, and .bat/.cmd files use batch control flow (if, for, call, errorlevel). Windows PowerShell 5.1 and PowerShell 7+ (pwsh) sit on .NET: cmdlets emit objects, the pipeline binds properties, and scripts use rich types, modules, remoting, and structured error records.
When CMD still wins
Use CMD for minimal environments, legacy instructions, quick dir/ping/ipconfig sequences, and third-party tooling that shells out to cmd semantics. Recovery and imaging environments may expose CMD first. Batch is still common in long-lived logon scripts where organizations have not migrated.
When PowerShell wins
Use PowerShell when you need filterable output (Where-Object, Select-Object), JSON/CSV export, remoting (Invoke-Command), Desired State Configuration, Azure or Microsoft Graph modules, and repeatable network diagnostics with Get-Net* and Test-NetConnection. Cross-platform automation targets pwsh on Linux and macOS with cmdlet availability checks.
Common misconceptions
ExecutionPolicy is not a security boundary like AppLocker or WDAC—it is a script-snippet gate that can be overridden in several ways. Treat signing and admin tiering as real controls. PowerShell is not “slower” for interactive work when you avoid loading heavy profiles—use -NoProfile in CI.
Practical coexistence
Windows Terminal can host CMD, PowerShell 5.1, and pwsh tabs side by side. Learn enough CMD to read older runbooks; default new automation to PowerShell 7 where your modules support it.
Related: CMD commands every user should know, What PowerShell is used for, PowerShell networking, PowerShell vs CMD.