Skip to main content

migrating-powershell-sdk

Migrates the legacy System.Management.Automation (PowerShell SDK) references from obsolete .NET Framework (Windows PowerShell 5.1) to modern .NET (PowerShell 7+). Replaces Windows PowerShell Reference Assemblies or GAC references with the cross-platform System.Management.Automation NuGet package. Use ONLY when the legacy Windows PowerShell SDK has been flagged as obsolete or deprecated and must be replaced — not for version-bump scenarios where existing PowerShell packages are still supported. Scope is binary cmdlet projects: this skill retargets a compiled project and does NOT edit PowerShell script files. Loose .ps1/.psm1 scripts, and the 5.1-to-7 script breaks they contain, belong to the powershell-51-to-7-upgrade scenario instead. Triggers for "migrate PowerShell SDK", "upgrade cmdlet project", "PowerShellStandard.Library", project files (.csproj, .vbproj, .fsproj) with PowerShell references, and .psd1 module manifests that ship alongside such a project.

Source facts

Repository
microsoft/upgrade-agent-plugins
Last source activity
September 15, 2026 at 22:49
Detected SKILL.md language
English
Stars
41
Forks
9

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
migrating-powershell-sdk
description
Migrates the legacy System.Management.Automation (PowerShell SDK) references from obsolete .NET Framework (Windows PowerShell 5.1) to modern .NET (PowerShell 7+). Replaces Windows PowerShell Reference Assemblies or GAC references with the cross-platform System.Management.Automation NuGet package. Use ONLY when the legacy Windows PowerShell SDK has been flagged as obsolete or deprecated and must be replaced — not for version-bump scenarios where existing PowerShell packages are still supported. Scope is binary cmdlet projects: this skill retargets a compiled project and does NOT edit PowerShell script files. Loose .ps1/.psm1 scripts, and the 5.1-to-7 script breaks they contain, belong to the powershell-51-to-7-upgrade scenario instead. Triggers for "migrate PowerShell SDK", "upgrade cmdlet project", "PowerShellStandard.Library", project files (.csproj, .vbproj, .fsproj) with PowerShell references, and .psd1 module manifests that ship alongside such a project.
metadata
{"discovery":"lazy","traits":".NET|CSharp|VisualBasic|DotNetCore"}
# System.Management.Automation Migration ## Overview Migrate PowerShell cmdlet projects from .NET Framework (Windows PowerShell 5.1) to modern .NET (.NET 6+). The core change is replacing the Windows PowerShell reference assembly with the cross-platform `System.Management.Automation` NuGet package. Most code remains unchanged because the SDK types (`PSCmdlet`, `Cmdlet`, `PSObject`, attributes) are identical across both packages. **Scope.** This skill retargets the *project*. It does not read or edit `.ps1`/`.psm1` files, so it will not find the script-level 5.1 → 7 breaks — removed cmdlets, snap-ins, WMI, encoding defaults. If the repository also carries loose PowerShell scripts that must run on PowerShell 7, those are the `powershell-51-to-7-upgrade` scenario's work, not this skill's. ## Package Reference Changes ### Old References (Remove) ```xml <!-- GAC/file reference --> <Reference Include="System.Management.Automation" /> <!-- Windows PowerShell ref assemblies NuGet --> <PackageReference Include="Microsoft.PowerShell.5.ReferenceAssemblies" Version="1.1.0" /> ``` ### New Reference (Add) ```xml <!-- Cross-platform NuGet package; use version matching target framework --> <PackageReference Include="System.Management.Automation" Version="{version-for-target-framework}" /> <!-- OR for dual-targeting Windows PowerShell 5.1 + PowerShell 7 --> <PackageReference Include="PowerShellStandard.Library" Version="{stable-version}" /> ``` ### Choosing the Right Package | Package | When to Use | |---------|-------------| | `System.Management.Automation` | Targeting a specific PowerShell 7.x version. Provides full API surface. | | `PowerShellStandard.Library` | Must support both Windows PowerShell 5.1 and PowerShell 7+ from a single binary. Targets `netstandard2.0`. | Use tools or [PowerShell releases](https://github.com/PowerShell/PowerShell/releases) to find the latest stable package version for the target framework. ## Workflow ``` Migration Progress: - [ ] Step 1: Detect PowerShell SDK usage - [ ] Step 2: Determine target framework and package version - [ ] Step 3: Update project file references - [ ] Step 4: Handle API differences - [ ] Step 5: Update module manifest - [ ] Step 6: Build and verify ``` ### Step 1: Detect PowerShell SDK Usage Scan the project for: - `using System.Management.Automation;` statements - Types inheriting from `Cmdlet` or `PSCmdlet` - `[Cmdlet(...)]` attributes - Reference type: GAC reference, `Microsoft.PowerShell.5.ReferenceAssemblies` NuGet, or direct file reference If the project already uses the cross-platform NuGet package, no migration is needed. ### Step 2: Determine Target Framework and Package Version 1. Check if the user specified a target framework (e.g., "migrate to net10.0") 2. Otherwise, read `<TargetFramework>` or `<TargetFrameworks>` from the project file or `Directory.Build.props` 3. Look up the best `System.Management.Automation` package version for that framework 4. If the project must support both Windows PowerShell 5.1 and PowerShell 7+, choose `PowerShellStandard.Library` instead — it targets `netstandard2.0` so a single binary works in both hosts ### Step 3: Update Project File References Remove old references and add the new package reference (see "Package Reference Changes" above). ### Step 4: Handle API Differences Most SDK types are identical, but these APIs changed: | Windows PowerShell | PowerShell 7+ | Action | |-------------------|---------------|--------| | `PSSnapIn` classes | Not supported | Convert to module manifests (`.psd1`). Snap-ins were deprecated because modules provide better isolation and discoverability. | | `PSHost.NotifyBeginApplication` | May not be implemented | Guard with try/catch or remove the call | | WinRM remoting APIs | Limited on non-Windows | Use SSH remoting for cross-platform scenarios | ### Step 5: Update Module Manifest (If Applicable) If the project produces a PowerShell module, update the `.psd1`: ```powershell @{ PowerShellVersion = '7.0' CompatiblePSEditions = @('Core') ProcessorArchitecture = 'None' } ``` ### Step 6: Build and Verify 1. Build the module: ``` dotnet build ``` 2. Import and check cmdlet registration: ```powershell Import-Module ./bin/Debug/{target-framework}/MyModule.dll Get-Command -Module MyModule ``` 3. Run cmdlet smoke tests to verify parameter binding and pipeline operations ## Troubleshooting ### Cmdlets Not Found After Import Ensure the assembly contains `[Cmdlet]` attributes and the namespace is correctly exported in the module manifest. ### Type Conflicts with Other Modules Another loaded module may bundle a different `System.Management.Automation` version. Use assembly load contexts or module isolation boundaries to resolve. ### Missing APIs at Runtime Some Windows PowerShell APIs have no PowerShell 7 equivalent. Check the [PowerShell 7 SDK docs](https://learn.microsoft.com/en-us/powershell/scripting/dev-cross-plat/choosing-the-right-nuget-package) for alternatives. ### Snap-in Code PowerShell 7 does not support snap-ins. Remove `PSSnapIn`-derived classes and replace with: - Module manifests (`.psd1`) for metadata - `RequiredModules` in the manifest for dependency management
View on GitHub