-
Notifications
You must be signed in to change notification settings - Fork 132
Enable discovery of compatible Windows PowerShell modules in PSCore6 #130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Enable discovery of compatible Windows PowerShell modules in PSCore6 #130
Conversation
> The module '{0}' could not be imported as it is not declared as compatible. Use `-SkipCompatibilityCheck` switch to override this check. | ||
|
||
`Import-Module` will support `-SkipCompatibilityCheck` switch to try and import the module regardless of `CompatiblePSEditions`. | ||
Since module auto-discovery does not expose cmdlets from modules not declared as compatible, explicit `Import-Module` with |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As much as I hate to suggest an automatic preference variable, one likely needs to be added to allow auto-discovery to import "incompatible" modules.
Since PowerShell Core shipped without this being enforced, code has been written for Core which is absolutely compatible, but lacks CompatiblePSEditions
. Additionally, plenty of modules originally written to target Windows PowerShell "just work" in PowerShell Core those modules may no longer be maintained or are maintained by a 3rd party who may not have updating their module manifest anywhere in their priority stack. That code may also be under license which forbids the user from making modifications as a work-around.
Given that there is plenty of compatible code this change will make "incompatible" simply because it lacks CompatiblePSEditions
in the manifest, there should be a way for users to enable auto-discovery to bypass compatibility checks that does not require adding a ton of Import-Module -SkipCompatibilityCheck
calls.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, this setting is needed. But maybe it should be a more permanent one, for example in powershell.config.json
.
Also, there can be a cmdlet, something like Set-ExecutionPolicy
. Say, Set-ModuleAutoDiscoveryPolicy
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It needs to be toggleable at run time and possibly even scoped, so I disagree with putting it in powershell.config.json
. I don't think it is permanent global state. It may only be needed in a single script of many that runs on a system. To me, that json file should have very very very compelling reasons to be expanded until there is a proper definition of everything that can and should go in it. and even then, it should be avoided unless it is a permanent global setting.
Set-ModuleAutoDiscoveryPolicy
and Get-ModuleAutoDiscoveryPolicy
would be a decent alternative to an automatic preference variable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps I need to have a more explicit statement, but the intent is that the enforcement of CompatiblePSEditions
is only for the System32 path.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah.. yes after reading it your this more clearly stated I can see that now, definitely did not read like that was the case before that though. All good then. If the intent is only to CompatiblePSEditions on the system32 path, then there is no need for my suggestion.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like I forgot to merge @joeyaiello's feedback which had additional language to clarify this. Please review again.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, much clearer and acceptable as-is.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just wanted to throw this out there:
The RFC seems to sort Modules into 3 categories:
- Modules only compatible with WinPS
- Modules only compatible with PSCore
- Modules compatible with both WinPS and PSCore
...but I think there will be a fourth category for awhile...
- Modules that explicitly need both WinPS and PSCore (i.e. some operations occur in PSCore and some occur in WinPS via the WindowsCompatibility Module).
For this fourth category, I'm thinking...
- They should also go under the PSCore System32 $env:PSModulePath.
- CompatiblePSEditions should be set to 'Core' (since the Modules would be using the WindowsCompatibility from a pwsh shell)
- There should be another property that explicitly describes the need for both WinPS and PSCore in order for the Module to work properly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
WindowsCompatibility
module works with any Windows PowerShell module from PSCore6 irrespective of the CompatiblePSEditions value. This RFC is about "natively" supporting Windows PowerShell modules while WindowsCompatibility
achieves support via implicit remoting. I think we should keep those two things separate. Over time as more Windows PowerShell modules are ported, the need for WindowsCompatibility
module will be diminished and eventually unnecessary.
|
||
### PowerShell Core PSModulePath | ||
|
||
Modules in the PowerShell Core PSModulePaths are implicitly deemed compatible even if the manifest does not |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does "PowerShell Core PSModulePaths" here refer to:
- All paths in
$env:PSModulePath
(i.e. configured by the user)? - The default PowerShell Core module paths - being the ones that are part of
$env:PSModulePath
in a fresh PowerShell Core installation? - (2), but without the
System32
directory proposed to be added in this RFC?
For 2/3, the best documentation I can find for what these paths actually are is in the code in ModuleIntrinsics.cs, which lists the "PersonalModulePath", "SharedModulePath" and "PSHomeModulePath". Are those the module paths to declare implicitly compatible?
Would it be possible to enumerate the specific paths that are:
- to be module paths by default, and
- to be implicitly compatible module paths
in this RFC (in the same way as the Windows PowerShell module paths above)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PowerShell Core PSModulePaths
refers to all paths that are part of $env:PSModulePath
except System32
. If the user changed the system PSModulePath
env var, we should respect that. There is a separate PR that @BrucePay is authoring for PSModulePath6
that is outside the scope of this RFC.
The tl;dr; version is that we are special casing the System32
path in PSCore6. The existing PSModulePath
should behave as it behaves today.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So any path found in PowerShell Core's $env:PSModulePath
should be considered implicitly compatible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
The module manifest (since Windows PowerShell 5) may contain a `CompatiblePSEditions` property to indicate if it is compatible with | ||
Windows PowerShell (value of `Desktop` even on Windows Server) or PowerShell Core (value of `Core`). | ||
Currently, this property is only documentation and not observed by PowerShell. | ||
The proposal is to modify PowerShell Core 6.1 to respect this property. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the proposed behaviour for modules that don't have a manifest? I know the RFC is primarily to address published modules, but the handling of any PSModuleInfo
will be affected by this.
I'm thinking that the manifest-default behaviour of assuming CompatiblePSEditions = @("Desktop")
would be a serious break for simple .psm1
s. So some choices there are maybe:
- Set
CompatiblePSEditions = null
in thePSModuleInfo
and require code paths to handle that (and not treat it like the manifest default). - Set
CompatiblePSEditions = @("Core")
, on the basis that we assume only compatibility with the loading runtime. - Set
CompatiblePSEditions = @("Desktop", "Core")
, on the basis that.psm1
s without a manifest are informal enough that we take a "we won't get in your way; it should be easy to do simple things" policy.
|
||
### Windows PSModulePath | ||
|
||
Windows PowerShell, by default, has module paths in: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What paths do PowerShell Core use? Seems we need reword the line.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section is only about Windows PSModulePath
. PSCore6.1 change is the next section. This section is giving some contextual information.
2. Program files: $env:ProgramFiles\WindowsPowerShell\Modules | ||
3. System32: $env:Windir\System32\WindowsPowerShell\v1.0\Modules | ||
|
||
The proposed change is to add *only* the `System32` path to `PSModulePath` on PowerShell Core 6. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks like all modules in the folder is compatible with PowerShell Core 6. Seems the line should be moved in ### PowerShell Core PSModulePath paragraph.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can see how it may be confusing to cover PSCore6 in this section, so it may be better to move this line to the next section.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So I'd change the section header to "Proposed change in PSModulePath".
|
||
The proposed change is to add *only* the `System32` path to `PSModulePath` on PowerShell Core 6. | ||
|
||
Modules in the user profile should be re-installed under PowerShell Core 6. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why? Will it re-installed to another path?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can add more context here if needed, but the point is that if you run install-module
from Windows PowerShell, it installs to the Windows PowerShell location and won't be found by PSCore6 (unless Add-WindowsPSModulePath
is used)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a module was installed in $home\Documents\WindowsPowerShell\Modules
where it will be after re-install?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll replace the word under
with using
. The idea is that you would use install-module
from PSCore6 and thus it would be in the right location.
The proposed change is to add *only* the `System32` path to `PSModulePath` on PowerShell Core 6. | ||
|
||
Modules in the user profile should be re-installed under PowerShell Core 6. | ||
Duplicate modules are something that can be addressed in PowerShellGet and outside the scope of this RFC. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems we need define search path priority - set the order of viewing paths.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can add a section lower that clarifies the default paths in PSCore6 along with their order.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, maybe create a table to show paths and proposed change.
Modules in `Program Files` that may be compatible with PowerShell Core 6 is addressed below. | ||
|
||
Users who want to search the entirety of the Windows PowerShell `PSModulePath` should use `Add-WindowsPSModulePath` cmdlet | ||
from the `WindowsCompatibility` module. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is motivation of the difference?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The focus of this RFC is specifically the System32
folder and not all the Windows PSModulePaths (line 15 above). I can add more text to clarify this if needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add.
### PowerShell Core PSModulePath | ||
|
||
Modules in the PowerShell Core `PSModulePath` are implicitly deemed compatible even if the manifest does not | ||
declare compatibility. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All modules in RSAT will be PowerShell Core 6 compatible?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps eventually, but certainly not initially.
|
||
If the module manifest contains `CompatiblePSEditions` with value `Core`, then that module is treated as compatible. | ||
If the module manifest contains `CompatiblePSEditions` with only the value of `Desktop`, then that module is treated as incompatible. | ||
If the module manifest does not contain `CompatiblePSEditions`, then that module is treated the same as `Desktop` which is incompatible. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This conflict with line 51:
Modules in the PowerShell Core
PSModulePath
are implicitly deemed compatible even if the manifest does not declare compatibility.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section is specifically only about modules under System32
path
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand - in line 40 we say that we add system32
path to PSModulePath
.
|
||
## Alternate Proposals and Considerations | ||
|
||
Open issue: Should `CompatiblePSEditions` column only be added in `ModuleInfo` table format if used with `-SkipCompatibilityCheck`? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I believe we should show this always - we should inform users what modules is still not compatible to exclude hidden errors.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can see what the user feedback is once @rjmholt has some working code checked in. My only concern is taking up too much column space. Although in table formatting, we could call it PSEdition
and perhaps just D
or C
instead of Desktop
and Core
if we need to save space.
01d1f6b
to
a418431
Compare
|
||
`Get-Module -ListAvailable` will support `-SkipCompatibilityCheck` switch to list all modules in `PSModulePath`. | ||
|
||
If `Import-Module` is used with a module that is not declared in the manifest as compatible, it will throw a terminating error: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the prescribed behaviour for non-psd1
modules -- ones that have no manifest?
What should the PSModuleInfo.PSEdition
fields for those modules say?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since this only applies to modules in System32
, there shouldn't be any such modules. If there are, we should add a module manifest. However, if we missed any then I would expect it to be the same as having a module manifest without CompatiblePSEditions
property.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe I've missed something...
I'm thinking that Import-Module
and Get-Module
can be called on any module file, even ones not under System32
. They can both produce a PSModuleInfo
object and share code paths with manifest-described modules.
So with the new behaviour described in this RFC, Import-Module ./my/unpubslished/module.psm1
will have to make some decision on PSEdition
compatibility settings. It seems tempting to say that no CompatiblePSEditions
defaults to @("Desktop")
in general, but that will mean breaking all psm1
s in Core.
So we need to have a separate behaviour for standalone psm1
s that the module cmdlets should follow, like just assuming total compatibility.
So the questions are, for a psm1
:
- Should we always assume compatibility?
- What should
PSModuleInfo.CompatiblePSEditions
contain? - Does
-SkipCompatibilityCheck
have any function in that scenario?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, you found a case not covered explicitly in the RFC which is modules that in PSModulePath. The intent is that CompatiblePSEditions
is only enforced for modules under System32
in the section on line 63. So in all other cases, it is implicitly deemed compatible.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah!
I was reading the RFC (in the original version) as:
Modules in the PowerShell Core PSModulePaths are implicitly deemed compatible even if the manifest does not declare compatibility... If the module manifest contains CompatiblePSEditions with value Core, then that module is treated as compatible. If the module manifest contains CompatiblePSEditions with only the value of Desktop, then that module is treated as incompatible.
(meaning that modules not on the PowerShell Core PSModulePath are not implicitly compatible)
But are you saying that it's more specific to the System32
path:
All modules not found on the
System32
path are implicitly compatibility-whitelisted. The compatibility of modules found on theSystem32
path will depend on their respectiveCompatiblePSEditions
field.
Is there also intent for gallery module compatibility checking? Or only if they are installed to the System32
location?
My only issue is that until there is an update of the Modules housed in the System32 pushed out to users then this change is basically of no use to anyone because none of the modules contain this manifest property and personally don't think that modules should be getting installed here anymore. These should be left well alone and be Legacy modules. Also any updates to the manifest of these modules would end up BREAKING module loading on pre v5 systems as the So for those that decide to install Pwsh on Windows 8/2012 and below where they are by default have a default version of PowerShell that is lower than PowerShell v5.1 this will cause more headaches as shown below with a manually edited version of the ActiveDirectory Module Manifest to include the What would make more sense to me would be to get these modules that are included in the System 32 PSModulePath getting released to the PowerShell Gallery and control them being updated from there with the changes as expected otherwise you need to issue Windows updates All in all i don't think this is a well thought out RFC but this more stems from the poor implementation of the |
@kilasuit we are not making any changes to downlevel Windows. The changes to the modules and thus the module manifests are only going to be in the latest Win10/WinServer builds. Releasing Windows in-box modules not owned by the PowerShell team is up to the feature owners. Modules in PSGallery are perfectly fine not using |
9c62d28
to
2430094
Compare
…SCore6-and-Windows-Modules.md
@PowerShell/powershell-committee voted on this an accepted this RFC |
No description provided.