Fixing Windows-Only Modules (PowerShell 7.x)
Several in-box Windows modules ship only with Windows PowerShell 5.1 (they target .NET Framework) and are not loaded natively by PowerShell 7. These are Manual-severity: they usually keep working through a shim, but you must choose and verify the shim per module.
Common ones: ActiveDirectory, ServerManager, Hyper-V, FailoverClusters,
BitLocker, NetSecurity, Dism, Storage, ScheduledTasks,
WebAdministration.
Options (in order of preference)
Native import — the only option that actually completes the upgrade. Many of these are CDXML/CIM-based and DO load in PS7 on a Windows box with the RSAT/feature installed. Try a plain import first:
Import-Module ActiveDirectory # works on PS7 with RSAT-AD-PowerShell installedA module built for PS7. Some Windows PowerShell modules have a supported successor that targets PS7 directly —
WebAdministration(IIS) →IISAdministrationis the common one. Prefer the successor over any shim.Implicit remoting to a server that has the module:
$s = New-PSSession -ComputerName Host Invoke-Command $s { Import-Module FailoverClusters } Import-PSSession $s -Module FailoverClusters -AllowClobberThe dependency moves to a managed remote endpoint rather than to a local 5.1 install, which is why it ranks above the compatibility layer.
Windows PowerShell compatibility layer — last resort only.
Import-Module Hyper-V -UseWindowsPowerShellThis starts a hidden Windows PowerShell 5.1 child process (
powershell.exe) and proxies the module's commands into it. The module is not ported and the 5.1 requirement is not removed — it is hidden. Use it only when 1-3 are genuinely unavailable, and record the result as deferred, never as remediated. Returned objects are deserialized: properties survive, methods do not, so audit every downstream.Method()call.
Notes
- The compatibility layer only exists on Windows — none of this makes the script cross-platform. Record the target as Windows-bound.
- Installing the proper RSAT/optional feature and importing natively is worth real effort: it is the difference between a completed migration and a script that still needs Windows PowerShell 5.1 on every machine that runs it.
- If most of the estate can only be landed on option 4, report that as the finding. "Blockers cleared via the compatibility layer" is not a successful upgrade.
Validation
- Rung 3 (
Get-Command <cmd> -ErrorAction Stop) is the key gate here — record whether each command resolves natively or only via -UseWindowsPowerShell. - Rung 4: read-only queries → 4b diff; state-changing cmdlets (AD writes, cluster
failover, Hyper-V start/stop) →
manual-signoffunless run in a sandbox.