Handling Removed PSSnapins (PowerShell 7.x)
PowerShell snap-ins do not exist in PowerShell 7 — there is no
Add-PSSnapin. A snap-in is a binary DLL loaded into the Windows PowerShell 5.1
(.NET Framework) runtime; it cannot load into the PS7 (.NET) runtime. This is an
architectural change per snap-in, not a rewrite of syntax.
Decision tree
For each Add-PSSnapin X:
Is there a mapping for X? If the finding's rule id is specific to the snap-in rather than the generic
snapin, the answer is already known — an organisation contributed it (see Organisation knowledge inscanning-powershell-compatibility). Use the named module, or the named alternative when the map records that no module exists. Do not re-derive it; the person who wrote that row knows the estate better thanGet-Module -ListAvailabledoes, and a probe on the migrating machine only proves what is installed here.A generic
snapinfinding means no mapping was contributed. Continue below, and say so — an unmapped in-house snap-in is a question for the user, not something to guess at.Is there a module replacement? Many snap-ins were superseded by modules that DO load in PS7. Check
Get-Module -ListAvailable. If so, replace:Add-PSSnapin SomeSnapin → Import-Module SomeModuleIs the snap-in Windows PowerShell-only with no PS7 module? Use one of, best first:
- Implicit remoting into a Windows PowerShell / product endpoint:
This is the robust path for product shells (Exchange, etc.).$s = New-PSSession -ComputerName Host -ConfigurationName SomeEndpoint Import-PSSession -Session $s -Module SomeModule - Windows PowerShell compatibility layer — last resort:
It proxies into a hiddenImport-Module SomeModule -UseWindowsPowerShellpowershell.exe(5.1) child process, so the script still requires Windows PowerShell locally and is still Windows-only. Record it as deferred, not remediated. Serialized objects lose live methods.
- Implicit remoting into a Windows PowerShell / product endpoint:
No replacement and no endpoint? The functionality must be re-implemented (e.g. call the product's REST/API directly) or the script stays on Windows PowerShell 5.1. Flag it explicitly.
Record what you learn
When you resolve an unmapped snap-in — by asking the user, or by finding the
replacement module — that answer is worth more than the one fix it unblocks.
Offer to record it as a row in a ## Snapin Module Map contribution skill under
.github/skills/, so every later scan of this estate names the replacement
instead of reporting a bare blocker. See Organisation knowledge in
scanning-powershell-compatibility for the format.
Object fidelity caveat
Both the compat layer and implicit remoting return deserialized objects
(Deserialized.* types) — properties survive, methods do not. Rewrite code
that calls methods on returned objects to use cmdlets/parameters instead.
Exchange
The Exchange management snap-in (Microsoft.Exchange.Management.PowerShell.*) is
the most common case and has its own path — see
migrating-exchange-management-shell.
Validation
- Rung 2 confirms no
Add-PSSnapinremains. - Rung 3 (
Get-Command) confirms the cmdlets resolve via the chosen path. - Rung 4c: product cmdlets that mutate state need a live endpoint —
prove the command surface matches, else
manual-signoff.