This document defines the compatibility target for the managed C# module engine. It is not a promise to clone every historical behavior from PowerShellGet or PSResourceGet. The goal is a clean managed implementation that covers the common module lifecycle workflows and keeps escape hatches where provider support is incomplete.
For the command-by-command stable PSResourceGet 1.2.0 comparison, including intentional differences and non-module gaps, see PSResourceGet Parity. Final security, benchmark, and packaged-artifact evidence is tracked in Managed Module Release Readiness. This document remains the module-specific compatibility contract.
Baseline references:
- PowerShellGet v2 command reference
- PSResourceGet command reference
- Install-Module
- Find-Module
- Publish-Module
- Install-PSResource
| Existing workflow | Managed command | Status | Notes |
|---|---|---|---|
Find-Module |
Find-ManagedModule |
Supported | Searches direct repository sources or saved profiles. Wildcard names are supported. |
Save-Module |
Save-ManagedModule |
Supported | Saves module package content and dependency closure to a path. |
Install-Module |
Install-ManagedModule |
Supported | Installs side-by-side versions into CurrentUser, AllUsers, or a custom module root. |
Update-Module |
Update-ManagedModule |
Supported | Plans updates from installed inventory, receipt evidence, and repository metadata. |
Publish-Module |
Publish-ManagedModule |
Supported | Packs and publishes modules to local folder or NuGet v3-compatible feeds. |
Find-PSResource |
Find-ManagedModule |
Supported for modules | Supports module name/wildcard, version expression, tag, prerelease, all-version, type, and dependency search. Package-content command and DSC-resource search are explicit gaps. |
Get-InstalledPSResource |
Get-ManagedModule |
Supported for modules | Returns typed installed rows by name, version, prerelease, scope, or explicit module path. |
Save-PSResource |
Save-ManagedModule |
Supported for modules | Supports typed find input, current-directory default, unpacked or nupkg output, PSGet XML metadata, dependencies, and version policy. |
Install-PSResource |
Install-ManagedModule |
Supported for modules | Supports typed find input, version ranges, prerelease, scope, required-resource batches, dependency closure, and safety policy. |
Update-PSResource |
Update-ManagedModule |
Supported for modules | Supports named and installed-estate update workflows with version, scope, dependency, and safety policy. |
Uninstall-PSResource |
Uninstall-ManagedModule |
Supported for modules | Supports typed installed input, version ranges, scope/path selection, dependency safety, loaded-module safety, planning, WhatIf, and confirmation. |
Publish-PSResource |
Publish-ManagedModule |
Supported for modules | Packs module folders or publishes existing nupkg files. Microsoft Artifact Registry ModulePrefix transport remains an explicit gap. |
Compress-PSResource |
Compress-ManagedResource |
Supported for modules | Creates a module nupkg without publishing. Script compression remains an explicit non-module gap. |
Get-ManagedModuleis the PowerShell-native installed inventory surface. Use-AsInventorywhen an advanced ModuleState inventory object is needed for planning or support bundles.Repair-ManagedModuleis the day-to-day stale/drift/family/source maintenance surface. Use-Planfor preview. ModuleState remains the internal planning engine, not a compatibility promise for unreleased public cmdlet names.Register-ManagedModuleRepository,Get-ManagedModuleRepository,Set-ManagedModuleRepository,Reset-ManagedModuleRepository,Import-ManagedModuleRepository, andUnregister-ManagedModuleRepositoryown the managed profile lifecycle.Initialize-ManagedModuleRepositoryremains the readiness/bootstrap workflow. Managed lifecycle commands can also use direct-Repositoryvalues.- There are no separate private install/update wrappers. The reusable module path is
Find-ManagedModule,Get-ManagedModule,Save-ManagedModule,Install-ManagedModule,Update-ManagedModule,Uninstall-ManagedModule,Repair-ManagedModule, andPublish-ManagedModule. - Public and private command aliases are allowed only when they point to the same managed command implementation. New command families need a distinct operator purpose.
The managed commands keep the common module lifecycle shape familiar while moving repository access, dependency resolution, package extraction, receipts, and publish packing into the C# engine.
Find-ManagedModule -Name Company.Tools -Repository 'https://packages.company.test/nuget/v3/index.json'
Find-ManagedModule -Name Company.* -ProfileName CompanyModules -AllVersions
Find-ManagedModule -Name Company.Tools -Version '[1.2.0,2.0.0)' -ProfileName CompanyModules.\Benchmarks\ManagedModules\Compare-ManagedModuleEngines.ps1 -ModuleName Company.Tools -Operation Find -Engine ManagedSave-ManagedModule -Name Company.Tools -Path C:\OfflineModules -Repository PSGallery
Save-ManagedModule -Name Company.Tools -RequiredVersion 1.2.0 -Path C:\OfflineModules -ProfileName CompanyModules
Find-ManagedModule -Name Company.Tools -Version 1.2.0 -ProfileName CompanyModules |
Save-ManagedModule -Path C:\OfflineModules -IncludeXmlInstall-ManagedModule -Name Company.Tools -Scope CurrentUser -Repository PSGallery
Install-ManagedModule -Name Company.Tools -RequiredVersion 1.2.0 -ProfileName CompanyModules -AcceptLicense
Find-ManagedModule -Name Company.Tools -Version 1.2.0 -ProfileName CompanyModules |
Install-ManagedModule -Scope CurrentUser
Install-ManagedModule -RequiredResource @{
'Company.Tools' = @{
Version = '1.2.0'
Repository = 'PSGallery'
Prerelease = $false
Reinstall = $true
AcceptLicense = $true
}
}
Install-ManagedModule -RequiredResourceFile .\required-resources.psd1 -Path C:\OfflineModulesDefault install is latest-first for broad requests. When the caller does not pin an exact version, Install-ManagedModule resolves the repository-selected version first, then compares that selected version with the target module root. If the repository has a newer version than the locally installed copy, the newer version is installed side-by-side. If the selected version is already installed, the command performs a cheap installed-manifest dependency health check. Missing or unsatisfied manifest RequiredModules are repaired automatically without forcing a healthy root-module reinstall.
Exact-version installs keep the fast local no-op path. -Version, -RequiredVersion, or an exact -VersionPolicy can skip repository work when the selected installed version is already healthy. Use -Force only when the selected root module version itself should be replaced.
Update-ManagedModule -Repository PSGallery
Update-ManagedModule -Name Company.Tools -Repository PSGallery
Update-ManagedModule -Name Company.Tools -VersionPolicy '>=1.2.0 <2.0.0' -ProfileName CompanyModulesWhen -ExpectedPackageSha256 is used with pipeline names, the command buffers the complete pipeline and requires exactly one distinct package target before starting any update. A multi-target hash request fails atomically rather than updating an early pipeline item first.
Repair-ManagedModule -Latest -Repository PSGallery -Plan -ShowSummary
Repair-ManagedModule -Family Graph -Repository PSGallery -Plan -ShowSummary
Repair-ManagedModule -MaintenanceReceiptPath .\module-maintenance.json -Repository CompanyModules -Plan
Repair-ManagedModule -Name Company.Tools,Company.Web -InstallMissing -Latest -Repository PSGallery -Plan -ShowSummary
Repair-ManagedModule -RequiredResourceFile .\required-resources.psd1 -Latest -Repository PSGallery -Plan -ShowSummary
Repair-ManagedModule -ModulePath $ps5Root,$ps7Root -Latest -Cleanup OldVersions -Repository PSGallery -Plan
Repair-ManagedModule -UserProfilePath C:\Users\Alice,C:\Users\Service.PowerShell -Name Company.* -Latest -Repository CompanyModules -PlanRepair plans include manifest dependency health. An installed module whose own version is otherwise fine can still receive an install-repair action when its manifest RequiredModules are missing or outside the declared version policy. External runtime dependencies declared through PrivateData.PSData.ExternalModuleDependencies are not treated as managed install dependencies.
Use -InstallMissing with literal -Name values when a named baseline should also seed modules that are not installed yet. Required-resource repair is the richer form for repeatable baselines with per-module options; it treats the resource map as desired module state. Missing modules are planned as managed installs, installed modules can be updated when -Latest or a version policy requires it, and cleanup remains explicit through -Cleanup OldVersions.
Repair preserves physical estate identity across module root, PowerShell edition, scope, and local user profile. Use -UserProfilePath for explicit profile homes or -IncludeAllUserProfiles for existing standard roots below the local profile container. A Unix root session retains /root and scans /home instead of treating filesystem root as the profile container. Use explicit -ModulePath for redirected, service-account, mounted, or otherwise nonstandard server roots. Inaccessible optional PSModulePath, discovered profile, and discovered module-root entries are warnings; inaccessible explicitly requested roots remain blocking errors. -ModuleRoot narrows selection and delivery to one physical target. A single explicit profile supplies its platform-standard current-edition CurrentUser root for missing-module delivery even when the module root has not been created yet, but it never redirects a command-level or per-resource AllUsers request into that profile. Other missing modules are applicable only when -ModuleRoot is explicit or exactly one scanned root is eligible; ambiguous or scope-incompatible destinations block apply.
Supplied -Inventory and -InventoryPath artifacts remain useful as baseline evidence, but they do not hide an explicit destination: -ModuleRoot, -UserProfilePath, and maintenance-receipt roots are scanned and merged into the working inventory, then retained for post-apply convergence checks. A successful live scan replaces artifact rows and diagnostics for that root, including when the root is now empty. A receipt-only root may be created by delivery and is visible to the final convergence scan. A no-action apply also performs a live convergence scan instead of declaring success from artifact evidence alone.
-Cleanup OldVersions is executable, not plan-only. Delivery completes first, repair inventories the same estate again, and cleanup is replanned from that current state so a newly installed latest version can make its former fallback eligible for removal in the same run. An explicit -Force still reinstalls a satisfied selected version before that refreshed cleanup. Cleanup does not mutate any path when the refreshed plan contains errors. Every removal names one exact installed directory, and the complete selected batch is planned, confirmed, and dependency-preflighted before deletion begins. Selected dependents are removed before their selected dependencies, so mutually related stale versions do not become action-order dependent. The managed uninstall engine merges current-runspace loaded-module evidence even when -IncludeLoaded was omitted; global targets validate each scanned same-edition profile with only that profile's visible roots rather than pooling unrelated users, unknown-edition custom roots are included conservatively, and profile targets validate that profile plus AllUsers roots. Anonymous roots inherited together from the current process's PSModulePath form one dependency-visibility context; unattributed roots supplied explicitly remain separate conservative contexts. A dependency root that was available during planning must remain enumerable through destructive preflight or cleanup fails closed without mutation. Exact-path, ShouldProcess, WhatIf, and confirmation safety remain active. Declined actions are reported as skipped and cannot produce ExecutionSucceeded or Converged. Repair stops cleanup after an operational failure, inventories the same roots one final time, and returns ExecutionSucceeded, Converged, and post-apply inventory, plan, and test evidence.
Repair operates on the local machine/session. This makes the same command suitable for workstations, build agents, service accounts, and servers with multiple PowerShell editions or user profiles, but it is not remote fleet orchestration. Use PowerShell remoting or the existing configuration-management system to invoke the local contract on each server.
Get-ManagedModule -Name Microsoft.Graph.* -IncludeLoaded -ShowSummary
Get-ManagedModule -Path C:\OfflineModules -AsInventoryTyped installed rows retain structured edition, scope, profile, and availability provenance for the roots scanned with their inventory. Piping exact rows to Uninstall-ManagedModule therefore validates each applicable visibility context without letting another user's or edition's copy satisfy an unrelated dependent. Roots successfully scanned by inventory must remain available through planning and destructive preflight. Multiple piped rows are collected into one cross-root dependency preflight and removed in dependent-first order.
Get-ManagedModule -Name Company.Tools -Version 1.2.0 |
Uninstall-ManagedModule -WhatIf
Uninstall-ManagedModule -Name Company.Tools -Version '[1.0.0,2.0.0)' -PlanPublish-ManagedModule -Path C:\Source\Company.Tools -Repository C:\Packages
Publish-ManagedModule -Path C:\Source\Company.Tools -ProfileName CompanyModules -ApiKeyFilePath C:\Secrets\company-feed-key.txt
Publish-ManagedModule -NupkgPath C:\Packages\Company.Tools.1.2.0.nupkg -ProfileName CompanyModules -ApiKeyFilePath C:\Secrets\company-feed-key.txtManaged repository profiles are first-class inputs to the lifecycle commands:
Register-ManagedModuleRepository -Name CompanyModules -Uri 'https://packages.company.test/nuget/v3/index.json' -Trusted
Initialize-ManagedModuleRepository -ProfileName CompanyModules -InstallPrerequisites
Install-ManagedModule -ProfileName CompanyModules -Name Company.Tools
Update-ManagedModule -ProfileName CompanyModules -Name Company.ToolsUse Repair-ManagedModule as the operator entrypoint when the question is not just "install this module", but "keep this machine's module estate under control":
Repair-ManagedModule -Latest -Repository PSGallery -ShowSummaryFor automation and support bundles, keep the steps inspectable through managed-family objects:
$inventory = Get-ManagedModule -IncludeLoaded -AsInventory -ShowSummary
$preview = Repair-ManagedModule -Inventory $inventory -Latest -Repository PSGallery -Plan -ShowSummary
$preview.Plan | Format-List
$preview.Test | Format-List
Repair-ManagedModule -Inventory $inventory -Latest -Repository PSGallery -ShowSummary| Capability | Managed support | Compatible inputs |
|---|---|---|
| Module identity | Supported | -Name, wildcard names where search semantics apply |
| Repository source | Supported | -Repository, -RepositoryName, -ProfileName |
| Credentials | Supported | -Credential, credential user/secret/file inputs where exposed |
| Proxy | Supported | -Proxy, -ProxyCredential on managed repository cmdlets |
| Version selection | Supported | -RequiredVersion, -Version, -MinimumVersion, -MaximumVersion, -VersionPolicy |
| Typed pipeline input | Supported | Find-ManagedModule output to install/save; Get-ManagedModule output to uninstall |
| Prerelease | Supported | -Prerelease, -AllowPrerelease alias where useful |
| Scope | Supported | CurrentUser, AllUsers, Custom module root |
| Dependency handling | Supported | Dependency closure, skip dependency check, package dependency mirroring during managed publish |
| Required resource batch install and repair | Supported for module resources | -RequiredResource, -RequiredResourceFile, and PSResourceGet-style nested hashtable values with Name, Version, Repository, AcceptLicense, Prerelease, Scope, Quiet, Reinstall, TrustRepository, AllowClobber, NoClobber, and SkipDependencyCheck keys |
| Save compatibility formats | Supported | current-directory default, -AsNupkg, and -IncludeXml for unpacked module saves |
| Existing package publish | Supported | Publish-ManagedModule -NupkgPath publishes without repacking |
| Trust/integrity | Supported | Trusted repository requirement, allowed author policy, expected package SHA256 |
| WhatIf/Confirm | Supported | Mutating cmdlets use PowerShell ShouldProcess |
| Summaries | Supported | Spectre.Console summaries remain host-side; result objects are still pipeline-friendly |
Compatibility aliases are exposed only when the old name maps to the same managed behavior. -RequiredVersion, -AllowPrerelease, -Source, -RepositoryUri, -Path, -DestinationPath, -SkipDependenciesCheck, -ModulePath, and -NuGetApiKey are safe aliases because they do not change the safety model.
PSResourceGet operator spellings are accepted where they map to the same managed behavior without changing automation output. Install-ManagedModule -Reinstall is equivalent to the managed reinstall behavior behind -Force for the selected version. Install-ManagedModule -NoClobber is accepted as an explicit spelling for the managed default that rejects command export conflicts. Install-ManagedModule, Save-ManagedModule, and Update-ManagedModule accept -Quiet to suppress optional host summaries and progress-style output without suppressing pipeline result objects.
-TrustRepository is not exposed as an alias. In PowerShellGet and PSResourceGet it is commonly used to skip an untrusted-repository prompt for that invocation. The managed engine does not prompt inside the reusable core; it uses repository profile trust evidence and the explicit -RequireTrustedRepository policy. A direct alias would invert the meaning and could make automation less safe.
Install-ManagedModule -RequiredResource and -RequiredResourceFile accept the PSResourceGet per-resource keys TrustRepository and Quiet so existing resource maps do not fail validation. Repository trust still follows the managed safety model above, and quiet output remains controlled by the managed cmdlet/output path rather than by a per-resource option.
-SkipPublisherCheck is not exposed as an alias or no-op switch. Managed install, save, update, and repair currently use source trust, allowed-author policy, expected package SHA256, license acceptance, clobber checks, and optional -AuthenticodeCheck. Cloning PowerShellGet publisher-check behavior needs a separate signed fixture and catalog evidence before it becomes a public compatibility switch.
The managed engine started as a module lifecycle engine. It supports module find, installed inventory, save, install, update, uninstall, publish, compression, and estate repair. Script packages now have first-class save/install support through the managed script resource surface. It does not currently claim support for the remaining PSResourceGet resource kinds or provider bootstrap behaviors. Those gaps are tracked by PSResourceGet Parity, which keeps script/resource support isolated from the module hot path:
- script find/update/publish/uninstall/compress workflows
- DSC resources as a separate resource-kind search/install surface
- command-name search across package contents
- role capability search
- provider-specific bootstrap, registration, credential-provider installation, or repository plugin behavior
Those scenarios should continue through native provider commands until they have a managed model, tests, and benchmark evidence. They are intentionally documented gaps, not silently supported module-engine behavior.
This checklist is the guardrail for replacing common PowerShellGet and PSResourceGet usage without surprises. Matching a parameter name is not enough; each item needs behavior proof, tests, and benchmark evidence when it can affect speed.
-
Install-ManagedModulesupports commonInstall-Moduleflows:-Name,-Repository,-RequiredVersion,-MinimumVersion,-MaximumVersion,-Scope,-Force,-AllowClobber,-AcceptLicense,-Credential,-WhatIf, and-Confirm. -
Install-ManagedModuleresolves repository-selected latest versions for broad requests before treating a local install as satisfying the operation, matching PSResourceGet-style latest-first expectations without giving up exact-version no-op speed. -
Install-ManagedModulerepairs missing or unsatisfied manifest dependencies when the selected installed version is already present and broken, without requiring-Force. -
Update-ManagedModulesupports named updates and no-name estate updates from selected module roots, matching the commonUpdate-Moduleoperator habit. -
Save-ManagedModulesupports typed find input, dependency closure, current-directory or explicit path, version policies,-AsNupkg,-IncludeXml, license acceptance, forced replacement, and import-validation benchmark proof. -
Find-ManagedModulesupports repository/profile lookup, wildcard module names, exact/wildcard/range-Version, all versions, tags, prerelease inclusion, dependency expansion, and fast latest-version lookup. -
Get-ManagedModuletyped rows pipe toUninstall-ManagedModulefor exact installed-path removal with dependency and loaded-module safety. -
Publish-ManagedModulesupports module-folder packing and existing-NupkgPathpublishing with API key or credential paths through the managed publisher. - PSResourceGet-style semantic version ranges are supported by find/uninstall
-Versionand install/save/update version-policy inputs. - PSResourceGet-style
-TrustRepositorybehavior maps to trusted repository profiles and-RequireTrustedRepositorypolicy instead of hidden prompts. - Public
-Proxyand-ProxyCredentialparameters are exposed on managed find/install/save/update/publish repository cmdlets and flow into the managed repository client. -
Install-ManagedModulesupports PSResourceGet-style module batch installs through-RequiredResourceand-RequiredResourceFile, including nested resource option hashtables and version range strings. - Define exact public semantics for
-Forceon install/save/update, including exact-version reinstall, no-op plans, rollback-protected replacement, downgrade blocking, and no implied cleanup. - Define exact public semantics for
-Forcein repair and maintenance flows, including receipt repair and cleanup interactions. - Define exact public semantics for
-AllowClobberversus PSResourceGet-NoClobber, including exported command conflicts in the selected target root. - Define exact public semantics for
-AcceptLicense, including dependency packages and unattended estate updates. - Define exact public semantics for
-SkipPublisherCheckcompatibility. Managed install/update currently uses trust, author, source, package hash, and optional Authenticode policies instead of cloning PowerShellGet's publisher-check switch; no public switch is exposed until true publisher-check semantics exist. - Match stable PSResourceGet 1.2.0
-AuthenticodeCheckbehavior for install/save/update on Windows by validating extracted signable files, including signed.catfiles, with native WinTrust before promotion. - Expose semantically equivalent migration aliases such as
-RequiredVersion,-AllowPrerelease,-Source,-RepositoryUri,-Path,-DestinationPath,-SkipDependenciesCheck,-ModulePath, and-NuGetApiKeywhere they map cleanly to managed cmdlet behavior. - Decide whether to add explicit
-TrustRepositoryand-SkipPublisherCheckcompatibility parameters. They are not aliases because repository trust and publisher checks are different safety concepts in the managed engine; use-RequireTrustedRepositoryand-AuthenticodeCheck/integrity policies instead. - Document unsupported non-module resource use cases explicitly: remaining script lifecycle gaps, DSC resources as resource kinds, role capability search, command-name search, and provider-specific bootstrap behavior.
- Add initial managed script resource save/install support with PSScriptInfo validation and local-feed proof.
- Add repair/maintenance benchmark lanes for stale versions, source drift, scope drift, and family coherence.
- Add repair/maintenance coverage for current-runspace loaded-module safety, exact-path cleanup execution, post-delivery cleanup replanning, cross-root dependency blocking, stale-estate revalidation, artifact-plus-destination inventory, multiple editions/profiles/physical roots, and post-apply convergence.
- Add install/save/update no-op and force benchmark lanes so existing-target behavior is measured across managed, PowerShellGet, PSResourceGet, and the install-only speed gate where an equivalent operation exists.
The managed engine owns typed domain models for:
- Repositories: source, name, kind, trust, priority, and profile-derived evidence.
- Packages: identity, nuspec metadata, manifest metadata, dependency metadata, hashes, file counts, and byte counts.
- Versions: semantic comparison, prerelease labels, PowerShellGet-style bounds, and NuGet/PSResourceGet-style ranges.
- Plans and actions: install, save, update, publish, managed delivery, repair, and skip reasons.
- Receipts: successful delivery evidence under the installed module version directory.
- Benchmark evidence: engine, operation, timing, package counts, bytes, import validation, publish status, and report paths. Benchmark tooling lives under
Benchmarks, not in the shipped cmdlet surface.
Cmdlets should map parameters into these models and write result objects. They should not own repository protocol logic, archive extraction, dependency solving, package creation, or repair decisions.
| Provider/source | Support level | Notes |
|---|---|---|
| PowerShell Gallery | Supported | Canonical PSGallery read operations use the NuGet v2 API for find/save/install/update because that endpoint is the reliable public module feed surface; managed publish and generic NuGet feeds still use NuGet v3 service metadata where required. |
| Generic NuGet v3 feed | Supported | Find, save, install, update, and publish with API key or basic credential where the feed supports it. |
| Local folder feed | Supported | Used for deterministic tests, offline bundles, local publish, and benchmark smoke proof. |
| Azure Artifacts | Partial | Profiles and direct v3 feed URLs work. Credential-provider bootstrapping remains a compatibility/profile concern. |
| JFrog/Artifactory | Partial | NuGet v3 endpoints and static credentials work. Runtime OIDC exchange remains outside the managed publish path. |
| ProGet/Nexus-compatible NuGet feeds | Expected | Treat as generic NuGet v3 until live validation proves feed-specific behavior. |
| GitHub Packages NuGet feeds | Expected | Treat as generic NuGet v3 until live validation proves authentication and publish behavior. |
- Repository trust is explicit. A trusted profile or caller policy can allow unattended install/update;
RequireTrustedRepositoryblocks untrusted sources. - Credentials are resolved before managed repository access. The core engine receives credential values or no credential; it does not call external credential helpers.
- Retries, timeouts, cancellation, proxy behavior, endpoint selection, and HTTP error messages belong in the managed repository client. The public PowerShell Gallery default resolves read operations through its NuGet v2 endpoint to avoid slow or blocked v3 service-index probes.
- Side-by-side versions are valid when version policies ask for exact or compatible copies. Forced replacement stages first and rolls back on promotion failure.
- Broad install requests select from the repository first, then decide whether the selected version is already installed. This means
Install-ManagedModule -Name Microsoft.Graphcan install2.38.0side-by-side when2.37.0is present and2.38.0is the repository-selected version. - When the selected installed version is already present, install checks the installed manifest dependency graph and repairs missing or unsatisfied managed dependencies unless dependency checks are explicitly skipped.
- Downgrades require a dedicated explicit downgrade policy;
-Forcealone is not a downgrade request. - Loaded modules can block unsafe updates unless the caller explicitly allows that risk.
- Cross-scope repairs must target the requested scope and must not treat a satisfying copy in another scope as equivalent.
- Prerelease labels are semantic-version labels. Stable versions do not satisfy prerelease-only requests unless the policy allows that outcome.
-Force is intentionally narrow in the managed engine:
Install-ManagedModule -ForceandSave-ManagedModule -Forcereplace the exact selected module version when that version already exists in the target root.- Without
-Force, installing or saving an exact version that already exists is a no-op plan and does not write files. -Forceis not required for dependency repair. If the repository-selected installed version is present but its managed manifest dependencies are missing or unsatisfied, install repairs those dependencies while leaving the healthy root module in place.Update-ManagedModule -Forcereinstalls the selected target version when the selected target is already the installed version.Update-ManagedModule -Forcedoes not silently downgrade a newer installed version to an older selected version. Downgrade behavior needs a separate explicit policy so stale-version repair and operator mistakes do not collapse into the same switch.Repair-ManagedModule -Forcemarks managed/private install, update, and save delivery as forced. In-Planmode this is visible on the action and prepared command evidence, but no mutation occurs.Repair-ManagedModulecan plan a non-forced install repair for an installed module whose manifest dependency graph is broken. The repair action targets the installed root module version so the managed installer can restore the dependency closure without replacing the healthy root module unless-Forceis supplied.-Forcedoes not imply destructive old-version cleanup. Cleanup remains a separate maintenance/repair decision.Publish-ManagedModule -Forcebypasses managed preflight duplicate/version guards where the target repository supports replacement or accepts the pushed package. It does not guarantee that a remote feed will overwrite an existing package.
Managed install, save, and update are no-clobber by default. Before a staged package is promoted, the managed engine reads manifest-declared FunctionsToExport, CmdletsToExport, and AliasesToExport values and checks them against other installed modules in the selected target root. If another module exports the same function, cmdlet, or alias, the operation fails before writing the final module version.
-AllowClobber is the explicit opt-in that permits those exported command conflicts. -NoClobber is also accepted for PSResourceGet migration and makes the default policy explicit; specifying both switches is rejected.
Same-name modules are skipped during conflict checks so side-by-side versions and exact-version reinstalls do not self-conflict. Wildcard exports such as FunctionsToExport = '*' are not treated as concrete conflicts because they cannot be reliably enumerated from the manifest alone. The check is target-root based; cross-scope conflicts remain a repair/maintenance policy concern rather than an install-time block across every module path on the machine.
Managed install, save, update, and repair delivery never prompt for license acceptance. If the selected package or any dependency package declares requireLicenseAcceptance=true, the operation fails unless the caller passes -AcceptLicense.
-AcceptLicense applies to the whole dependency closure for that operation. This is intentional for unattended estate maintenance: either the operator or automation policy accepts the package licenses up front, or no package that requires acceptance is promoted. A license-required dependency blocks the parent package before the parent is promoted.
Plan operations do not accept licenses or write license receipts. They only describe the intended action. The caller must pass -AcceptLicense again when invoking the mutating install, save, update, or ModuleState apply operation.
-AuthenticodeCheck is an explicit opt-in on managed install, save, and update. When supplied, the managed engine extracts the package to a staging directory and validates signable files with native Windows WinTrust before dependency delivery and before the staged module is promoted to the target root. Unsigned or invalid signable files block the operation before the final module version is written.
The initial managed gate covers common signable module artifacts such as .ps1, .psm1, .psd1, .ps1xml, .pssc, .psrc, .mof, .dll, .exe, and .cat. Dependency installs inherit the same check. Plan output records that Authenticode validation would be required, but plan mode does not download or validate signatures.
This check is currently Windows-only. Calling it on non-Windows hosts fails closed instead of warning and continuing without validation, which is an intentional managed safety difference. The stable PSResourceGet 1.2.0 implementation also validates the Authenticode status of each selected file, including .cat files; it does not validate catalog contents through Test-FileCatalog. The managed behavior therefore meets the stable module-parity baseline. Deeper catalog-content policy and additional timestamp or short-lived-certificate fixtures remain useful security hardening, but they are not missing PSResourceGet 1.2.0 module functionality.
Compatibility transport stays available as a temporary fallback. The managed engine is the preferred path when source evidence and provider support allow it; compatibility is still selected when a provider gap or missing repository-source signal would make the managed decision unsafe.
The managed path can be treated as the default for supported module workflows after all of these are true:
- Managed find/inventory/save/install/update/uninstall/publish/compress passes the applicable local-folder, installed-root, and public-feed proof on Windows PowerShell 5.1 and PowerShell 7+.
- Benchmarks cover cold cache, warm cache, heavy extraction, dependency closure, no-op update, private feed metadata, and publish comparison.
- Common PowerShellGet and PSResourceGet module workflows have documented managed equivalents.
Repair-ManagedModulemaintains the same estate through managed transport with receipts and inspectable repair plans.- Provider gaps are documented as explicit partial support instead of hidden fallbacks.
Current status: these gates have local evidence on both Windows PowerShell 5.1 and PowerShell 7+. Auto transport prefers managed delivery for local paths, direct repository URIs, and registered/profile repositories that resolve to source endpoints. Compatibility transport remains available for provider-specific bootstrap gaps, non-module resource kinds, and unresolved repository names; those decisions are surfaced in typed result objects and summaries instead of being hidden.