On a Windows machine, `powershell.exe` reports version 5.1 while `pwsh` reports 7.x. Are these the same PowerShell after an upgrade, and what does `$PSVersionTable.PSEdition` tell you about each?
answer
- two installs, not one upgrade
- different executable at the prompt
- one runtime is Windows-only
- .NET Framework versus modern .NET
- Desktop edition versus Core edition
basics
~20 sThey are two separate products installed side by side. Windows PowerShell 5.1 (powershell.exe) runs on .NET Framework and reports PSEdition Desktop; PowerShell 7 (pwsh) is a separate cross-platform install on modern .NET and reports Core.
solid answer
~40 sInstalling PowerShell 7 does not upgrade Windows PowerShell — it puts a second product on the box. Windows PowerShell 5.1 is a Windows component, lives in `System32\WindowsPowerShell\v1.0`, is launched as `powershell.exe`, runs on .NET Framework 4.x, and `$PSVersionTable.PSEdition` returns `Desktop`. PowerShell 7 installs under `C:\Program Files\PowerShell\7`, is launched as `pwsh`, runs on modern cross-platform .NET, and reports `Core`. They keep separate profiles (`Documents\PowerShell` versus `Documents\WindowsPowerShell`), separate user module directories, and separate PSReadLine versions, so a module or profile tweak made in one is not automatically visible in the other. The practical consequence in an interview: never say "PowerShell 7" when a scheduled task, a build agent or a legacy tool is actually invoking `powershell.exe`, because the edition decides which cmdlets and which .NET surface you get.
code
powershell · 9 lines# Runs in both engines: which product am I actually in?
$PSVersionTable.PSVersion # 5.1.x under powershell.exe, 7.x under pwsh
$PSVersionTable.PSEdition # 'Desktop' under Windows PowerShell, 'Core' under PowerShell 7
if ($PSVersionTable.PSEdition -eq 'Desktop') {
Write-Host 'Windows PowerShell 5.1 on .NET Framework'
} else {
Write-Host "PowerShell $($PSVersionTable.PSVersion) on modern .NET, platform $($PSVersionTable.Platform)"
}go deeper
Know that powershell.exe and pwsh start different programs, and that $PSVersionTable tells you which one you are in. Say plainly that installing PowerShell 7 leaves Windows PowerShell 5.1 in place.
Explain the runtime split: 5.1 on .NET Framework reporting edition Desktop, 7 on modern cross-platform .NET reporting Core, with separate install paths, profiles and module directories. Name a feature that exists only in 7.
Show you design for it: pin the engine in scheduled tasks, CI steps and installers, use #requires -Version, and treat a script that works in pwsh but is launched by powershell.exe as a deployment defect rather than a coding one.
Own the migration position for a fleet — which workloads move to pwsh, which stay on 5.1 because of Windows-only modules, and how you stop the estate drifting into an untracked mix of two engines with two module inventories.
## Two products, not one upgrade Microsoft ships two things whose names both contain "PowerShell". **Windows PowerShell** is a component *of Windows*. Its last version is 5.1, it is installed with the OS at `%SystemRoot%\System32\WindowsPowerShell\v1.0`, and its executable is `powershell.exe`. It is built on .NET Framework 4.x — the Windows-only, in-box runtime. It is serviced for security and reliability, but it does not receive new features. **PowerShell** (6.0, then 7.x — the "Core" edition) is a separate, downloadable product built on modern cross-platform .NET. Its executable is `pwsh` (`pwsh.exe` on Windows), and on Windows it installs under `C:\Program Files\PowerShell\7`. It also runs on Linux and macOS, which is the whole reason the split exists: .NET Framework never left Windows, so a portable PowerShell required a different runtime and therefore a different product. Installing PowerShell 7 does **not** replace or remove Windows PowerShell 5.1. Both remain on the machine, both stay on PATH, and each has its own Start-menu entry. That is deliberate: countless scheduled tasks, installers, CI steps and third-party tools hardcode `powershell.exe`, and silently changing what that name runs would break them. ## What `$PSVersionTable` actually reports `$PSVersionTable` is an automatic variable — a read-only hashtable describing the running engine. Two keys matter here: ```powershell $PSVersionTable.PSVersion # 5.1.x under powershell.exe; 7.x under pwsh $PSVersionTable.PSEdition # 'Desktop' under Windows PowerShell; 'Core' under PowerShell 6/7 ``` `PSEdition` names the runtime family, not the version number. `Desktop` means the engine is on .NET Framework; `Core` means it is on the modern .NET. PowerShell 6 and PowerShell 7 both report `Core`, so `PSEdition` alone does not tell you 6 from 7 — read `PSVersion.Major` for that. The table's contents differ by edition too. Windows PowerShell 5.1 carries `CLRVersion` and `BuildVersion`; PowerShell 6+ drops those and adds `Platform` (`Win32NT` or `Unix`), `OS` (a descriptive OS string) and `GitCommitId`. Testing for a key that only one edition has is itself a workable, if crude, probe. ## The version test that people get wrong The safe branch uses something both editions define: ```powershell if ($PSVersionTable.PSEdition -eq 'Desktop') { ... } # or: $PSVersionTable.PSVersion.Major -lt 6 ``` The unsafe branch uses `$IsWindows`. That automatic variable was introduced in PowerShell 6, so under 5.1 it is simply undefined — it evaluates to `$null`, which is falsy, and your "Windows" branch silently never runs on the most Windows machine you own. Any compatibility check has to be written in a dialect *both* engines speak. ## What else is separate * **Profiles.** PowerShell 7 on Windows uses `$HOME\Documents\PowerShell\` (on Linux/macOS, `~/.config/powershell/`); Windows PowerShell uses `$HOME\Documents\WindowsPowerShell\`. `$PROFILE` resolves per engine, so a prompt customisation added in one shell does not appear in the other. * **Modules.** Each edition has its own user module directory. On Windows, PowerShell 7 does append the Windows PowerShell system module path to `PSModulePath` so many in-box modules can still be imported, but a module you installed for 5.1 into the user scope is not automatically on 7's path. * **Removed features.** PowerShell 6 dropped workflows, PowerShell snap-ins, the WMI cmdlets (`Get-WmiObject` and friends) and the `-ComputerName` parameter on many cmdlets. `Get-Service`, `Get-WinEvent` and the registry provider still exist on Windows but have no meaning on Linux or macOS. * **Remoting endpoints.** Enabling remoting for PowerShell 7 registers its own WinRM session configuration; connecting to the default endpoint still lands you in 5.1. ## Why this shows up in interviews Because the failure mode is invisible. A script tested interactively in `pwsh` is later launched by a scheduled task, a Jenkins step or an MSI custom action that says `powershell.exe -File script.ps1`, and it fails on syntax or cmdlets that exist only in 7 (ternary `?:`, pipeline chain operators `&&`/`||`, `ForEach-Object -Parallel`). The correct instinct is to state the target engine explicitly — invoke `pwsh` by name, put `#requires -Version 7.0` at the top of the script, and treat "which edition runs this" as part of the deployment contract rather than an accident of PATH.
- If one script has to run under both engines, how do you branch on the edition safely?Test something both editions define: `$PSVersionTable.PSEdition -eq 'Desktop'` or `$PSVersionTable.PSVersion.Major -lt 6`. Do not branch on `$IsWindows` — it was added in PowerShell 6, so under 5.1 it is undefined, evaluates to `$null`, and the Windows branch never executes. Better still, declare the requirement with `#requires -Version 7.0` and fail loudly instead of degrading.
- Do the two engines share profiles and modules on the same Windows machine?No. PowerShell 7 uses `Documents\PowerShell` for profiles and its own user module directory; Windows PowerShell uses `Documents\WindowsPowerShell`. `$PROFILE` resolves per engine. On Windows, PowerShell 7 does append the Windows PowerShell system module path to `PSModulePath`, so many in-box modules remain importable, but anything you installed per-user for one edition is not automatically visible to the other.
- Is Windows PowerShell 5.1 being removed from Windows?No. It ships as a Windows component and is serviced for security and reliability, but it receives no new features — 5.1 is the final version. All development happens in PowerShell 7. Plan migrations toward `pwsh`, but expect `powershell.exe` to keep existing on Windows machines, which is exactly why scripts must state which engine they need.
saying these in an interview costs you the question
- Says PowerShell 7 is just an update to 5.1
- Claims installing pwsh removes or replaces powershell.exe
- Thinks PSEdition reports the version number
- Uses $IsWindows as an edition check
- Assumes any 5.1 module loads unchanged in 7