You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Get-Item for files outputs PSObject instead of FileSystemInfo after Get-WmiObject #12014
Get-Item normally outputs System.IO.FileInfo or System.IO.DirectoryInfo objects for the FileSystem provider. After invoking Get-WmiObject, however, Get-Item outputs PSObject objects instead. This causes binding to any command expecting one of the specific FileSystemInfo types to fail.
Steps to reproduce
(Get-Item .).GetType().Name
Get-WmiObject bogus -ea si
(Get-Item .).GetType().Name
Expected behavior
DirectoryInfo
DirectoryInfo
Actual behavior
DirectoryInfo
PSObject
Environment data
Name Value
---- -----
PSVersion 7.0.0-rc.2
PSEdition Core
GitCommitId 7.0.0-rc.2
OS Microsoft Windows 6.3.9600
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Get-WmiObject is a Windows PowerShell cmdlet; by invoking that, you're importing a Windows PowerShell module, which (by the looks of it) also include Get-Item. Because the built-in remoting logic mirrors these cmdlets as functions they take precedence over PowerShell Core cmdlets.
/cc Paul Higinbotham (@PaulHigin) -- looks like we need to add some explicit exclusions to cmdlets we're importing from a Windows PowerShell module.
alx9r in the meantime, I would recommend simply using Get-CimInstance instead, so that you don't need to invoke a Windows PowerShell session to run the command. Get-WmiObject has been deprecated since PowerShell v3.
Reacted by Paul Higinbotham
Reacted by Patrick Meinecke, alx9r and Paul Higinbotham
Get-WmiObject is a Windows PowerShell cmdlet; by invoking that, you're importing a Windows PowerShell module, which (by the looks of it) also include Get-Item
Nice diagnosis.
Yeah we need to solve the module encapsulation of the Windows PowerShell modules, and possibly exclude some WinPS modules from imports.
I've been thinking we need to write a simple proxy module that only exposes the different commands from the WinPS modules.
Rob Holt (@rjmholt)Andrew (@anmenaga) I'd also suggest that any cmdlets that have the same name as ones already present in the pwsh builtin modules are not automatically given proxy functions, regardless of which module is imported.
Yeah we need to solve the module encapsulation of the Windows PowerShell modules, and possibly exclude some WinPS modules from imports.
It doesn't help in the issue. We discussed this earlier. The example shows that we need "import" only one cmdlet from the module. And my suggestion was that we need to have a white list. Otherwise we import whole WinPS Microsoft.PowerShell.Management and overload PS Core Microsoft.PowerShell.Management. Alternative proposal was to make second one more high priority in discovering process,
Otherwise we import whole WinPS Microsoft.PowerShell.Management and overload PS Core Microsoft.PowerShell.Management
My thinking was to use a wrapper module that imports the WinPS module as a nested module and only exposes the commands that we want to add to the PS 7 session.
However, playing with that now I'm not sure how possible that is.
But we support that! The 5.1 Microsoft.PowerShell.Management.dll is importable into PowerShell. The problem is the way commands exported from it currently override things
I guess you mean "the binary can be loaded" but we can not support the 5.1 module on 7.0. A similar module importing happened when we had a mess with the module paths. My suggestion was explicitly disable this for modules in the repo.
MPM.dll depends on MPS.dll and SMA.dll.
Now PS Core SMA.dll has 7.0.0.0 version, Windows PS SMA.dll - 3.0.0.0. Will Windows MPM.dll load Windows PS SMA.dll?
If we cleaned up something in SMA this can cause type discover issues.
Rob Holt (@rjmholt)Ilya (@iSazonov)Rain Sallow (/u/ta11ow) (@vexx32) I've been experimenting with this behavior. My findings suggest that the impact of how PowerShell 7 resolves names is broader than just what occurs when a Windows PowerShell module is imported. There seems to have been a change to how names are resolved between 5.1 and 7. That change introduces name resolution side-effects, in general, between modules. I haven't to be able to reproduce that in 5.1. I have opened #12036 which is a repro of a similar issue to this but not involving WIndows PowerShell at all. If you have a chance please take a look at that issue too.
My findings suggest that the impact of how PowerShell 7 resolves names is broader than just what occurs when a Windows PowerShell module is imported. There seems to have been a change to how names are resolved between 5.1 and 7. That change introduces name resolution side-effects, in general, between modules
Can you give an example where this new behaviour is causing an issue? It would help us pin down the change and the issue
Rob Holt (@rjmholt) The new behavior of auto-importing of Windows PowerShell proxy commands caused a problem during the same PowerShell 5.1 to 7 transition I described here and it occurred in a similar manner to that story: I had a module that invoked Get-WmiObject that inadvertently loaded the wrong Get-Item. Most modules that called Get-Item (which is a lot) then resolved to the wrong Get-Item which resulted in errors when the output type didn't match the input type of the downstream command. None of those modules contained a call to Import-Module Microsoft.PowerShell.Management so they were all resolving Get-Item in the global scope. That is a mistake, it seems, albeit not one that is obvious even now. The solution seems to be to include explicit imports for each module within the module that uses it.
Another idea is to replace Get-WmiObject with Get-CimInstance that is in PS-Core-compatible module CimCmdlets. CIM cmdlets were done as a replacement for WMI.
Activity
vexx32 commentedon Mar 4, 2020
Get-WmiObjectis a Windows PowerShell cmdlet; by invoking that, you're importing a Windows PowerShell module, which (by the looks of it) also include Get-Item. Because the built-in remoting logic mirrors these cmdlets as functions they take precedence over PowerShell Core cmdlets./cc Paul Higinbotham (@PaulHigin) -- looks like we need to add some explicit exclusions to cmdlets we're importing from a Windows PowerShell module.
alx9r in the meantime, I would recommend simply using
Get-CimInstanceinstead, so that you don't need to invoke a Windows PowerShell session to run the command.Get-WmiObjecthas been deprecated since PowerShell v3.rjmholt commentedon Mar 5, 2020
Nice diagnosis.
Yeah we need to solve the module encapsulation of the Windows PowerShell modules, and possibly exclude some WinPS modules from imports.
I've been thinking we need to write a simple proxy module that only exposes the different commands from the WinPS modules.
rjmholt commentedon Mar 5, 2020
Andrew (@anmenaga)
alx9r commentedon Mar 5, 2020
Rain Sallow (/u/ta11ow) (@vexx32) Thank you very much for explaining how that's happening. I confirmed your explanation with this example:
.{ Get-Command Get-Item Get-WmiObject bogus -ea si Get-Command Get-Item } | % {[pscustomobject]@{ CommandType = $_.CommandType ModulePath = $_.Module.Path }}which outputs
vexx32 commentedon Mar 5, 2020
Rob Holt (@rjmholt) Andrew (@anmenaga) I'd also suggest that any cmdlets that have the same name as ones already present in the pwsh builtin modules are not automatically given proxy functions, regardless of which module is imported.
iSazonov commentedon Mar 5, 2020
It doesn't help in the issue. We discussed this earlier. The example shows that we need "import" only one cmdlet from the module. And my suggestion was that we need to have a white list. Otherwise we import whole WinPS Microsoft.PowerShell.Management and overload PS Core Microsoft.PowerShell.Management. Alternative proposal was to make second one more high priority in discovering process,
rjmholt commentedon Mar 5, 2020
My thinking was to use a wrapper module that imports the WinPS module as a nested module and only exposes the commands that we want to add to the PS 7 session.
However, playing with that now I'm not sure how possible that is.
rjmholt commentedon Mar 5, 2020
Looks like I've found a new bug in PowerShell!
Try this:
iSazonov commentedon Mar 5, 2020
I'd expect that
Import-Module ./wincompat.psd1fail on loading .Net Framework dll and write the error.rjmholt commentedon Mar 5, 2020
But we support that! The 5.1 Microsoft.PowerShell.Management.dll is importable into PowerShell. The problem is the way commands exported from it currently override things
iSazonov commentedon Mar 5, 2020
I guess you mean "the binary can be loaded" but we can not support the 5.1 module on 7.0. A similar module importing happened when we had a mess with the module paths. My suggestion was explicitly disable this for modules in the repo.
MPM.dll depends on MPS.dll and SMA.dll.
alx9r commentedon Mar 5, 2020
Rob Holt (@rjmholt) Ilya (@iSazonov) Rain Sallow (/u/ta11ow) (@vexx32) I've been experimenting with this behavior. My findings suggest that the impact of how PowerShell 7 resolves names is broader than just what occurs when a Windows PowerShell module is imported. There seems to have been a change to how names are resolved between 5.1 and 7. That change introduces name resolution side-effects, in general, between modules. I haven't to be able to reproduce that in 5.1. I have opened #12036 which is a repro of a similar issue to this but not involving WIndows PowerShell at all. If you have a chance please take a look at that issue too.
rjmholt commentedon Mar 5, 2020
Can you give an example where this new behaviour is causing an issue? It would help us pin down the change and the issue
anmenaga commentedon Mar 5, 2020
Good ideas on this thread. The original issue with
Get-WmiObjectis covered by #11419alx9r commentedon Mar 5, 2020
(I wasn't sure which "new behavior" you were asking about. I answered for the new module resolution behavior over on #12036.)
Rob Holt (@rjmholt) The new behavior of auto-importing of Windows PowerShell proxy commands caused a problem during the same PowerShell 5.1 to 7 transition I described here and it occurred in a similar manner to that story: I had a module that invoked
Get-WmiObjectthat inadvertently loaded the wrongGet-Item. Most modules that calledGet-Item(which is a lot) then resolved to the wrongGet-Itemwhich resulted in errors when the output type didn't match the input type of the downstream command. None of those modules contained a call toImport-Module Microsoft.PowerShell.Managementso they were all resolvingGet-Itemin the global scope. That is a mistake, it seems, albeit not one that is obvious even now. The solution seems to be to include explicit imports for each module within the module that uses it.rjmholt commentedon Mar 5, 2020
Thanks for looking into this so deeply alx9r
anmenaga commentedon Mar 5, 2020
Another idea is to replace
Get-WmiObjectwithGet-CimInstancethat is in PS-Core-compatible moduleCimCmdlets. CIM cmdlets were done as a replacement for WMI.