Skip to content
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

Cert:\ PSDrive is unavailable on PowerShell 5.1 launched by cmd when cmd is launched on PowerShell 7.3 #18530

Closed
5 tasks done
masaru-iritani opened this issue Nov 11, 2022 · 8 comments
Labels
Resolution-Answered The question is answered.

Comments

@masaru-iritani
Copy link

Prerequisites

Steps to reproduce

Cert:\ PSDrive provided by Certificate provider is unavailable on PowerShell 5.1 launched by cmd.exe if and only if the cmd.exe was launched on PowerShell 7.3. This issue causes an error on running a batch script which launches PowerShell 5.1.

Although this issue happens on PowerShell 5.1, I file it for PowerShell 7.3 because it is reproduced only when cmd.exe is launched on PowerShell 7.3.

Environment Issue
PS 5.1 Not repro
PS 5.1 on PS 7.3 Not repro
PS 5.1 on cmd on PS 5.1 Not repro
PS 5.1 on cmd on PS 7.2.7 Not repro
PS 5.1 on cmd on PS 7.3 Repro

Expected behavior

PS> cmd /c C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command Get-PSDrive

Name           Used (GB)     Free (GB) Provider      Root               CurrentLocation
----           ---------     --------- --------      ----               ---------------
Alias                                  Alias
C                 445.17         30.10 FileSystem    C:\                ..._7.3.0.0_x64__8wekyb3d8bbwe
Cert                                   Certificate   \
D                 906.38         25.13 FileSystem    D:\
E                   0.06          0.42 FileSystem    E:\
Env                                    Environment
Function                               Function
HKCU                                   Registry      HKEY_CURRENT_USER
HKLM                                   Registry      HKEY_LOCAL_MACHINE
Variable                               Variable
WSMan                                  WSMan

Actual behavior

PS> cmd /c C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command Get-PSDrive

Name           Used (GB)     Free (GB) Provider      Root               CurrentLocation
----           ---------     --------- --------      ----               ---------------
Alias                                  Alias
C                 445.17         30.10 FileSystem    C:\                ..._7.3.0.0_x64__8wekyb3d8bbwe
Cert                                   Certificate   \
D                 906.38         25.13 FileSystem    D:\
E                   0.06          0.42 FileSystem    E:\
Env                                    Environment
Function                               Function
HKCU                                   Registry      HKEY_CURRENT_USER
HKLM                                   Registry      HKEY_LOCAL_MACHINE
Variable                               Variable
WSMan                                  WSMan

Error details

No error is returned.

Environment data

PS> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.3.0
PSEdition                      Core
GitCommitId                    7.3.0
OS                             Microsoft Windows 10.0.22623
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Visuals

CertPSDriveUnavailable.zip is a step recording capturing following steps.

  1. Launch PowerShell 7.3 with no profile.
  2. Run "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command Get-PSDrive" and get Cert PSDrive as expected.
  3. Run "cmd /c C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -Command Get-PSDrive" and get no Cert PSDrive.
@masaru-iritani masaru-iritani added the Needs-Triage The issue is new and needs to be triaged by a work group. label Nov 11, 2022
@dwtaber
Copy link
Contributor

dwtaber commented Nov 12, 2022

It looks like this bug was introduced in 7.3.0-preview.7. More specifically, I believe it was introduced by #16355. Check this out:

PS7.3> cmd /c powershell -noprofile
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.

PS5.1> Get-PSDrive cert
Get-PSDrive : Cannot find drive. A drive with the name 'cert' does not exist.
At line:1 char:1
+ Get-PSDrive cert
+ ~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (cert:String) [Get-PSDrive], DriveNotFoundException
    + FullyQualifiedErrorId : GetLocationNoMatchingDrive,Microsoft.PowerShell.Commands.GetPSDriveCommand

PS5.1> Import-Module Microsoft.PowerShell.Security
Import-Module : The following error occurred while loading the extended type data file: Error in TypeData "System.Security.AccessControl.ObjectSecurity":
The member AuditToString is already present.
Error in TypeData "System.Security.AccessControl.ObjectSecurity": The member AccessToString is already present.
Error in TypeData "System.Security.AccessControl.ObjectSecurity": The member Sddl is already present.
Error in TypeData "System.Security.AccessControl.ObjectSecurity": The member Access is already present.
Error in TypeData "System.Security.AccessControl.ObjectSecurity": The member Group is already present.
Error in TypeData "System.Security.AccessControl.ObjectSecurity": The member Owner is already present.
Error in TypeData "System.Security.AccessControl.ObjectSecurity": The member Path is already present.
At line:1 char:1
+ Import-Module Microsoft.PowerShell.Security
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (:) [Import-Module], RuntimeException
    + FullyQualifiedErrorId : FormatXmlUpdateException,Microsoft.PowerShell.Commands.ImportModuleCommand

PS5.1> Import-Module Microsoft.PowerShell.Security -RequiredVersion 3.0.0.0
PS5.1> Get-PSDrive cert

Name           Used (GB)     Free (GB) Provider      Root                                                                                   CurrentLocation
----           ---------     --------- --------      ----                                                                                   ---------------
Cert                                   Certificate   \

Here's what I think is happening: PowerShell 7 modifies the value of PSModulePath for the special case of launching Windows PowerShell from PowerShell 7. In this scenario, however, PowerShell 7 is launching cmd, not PowerShell.exe, so the special handling of PSModulePath doesn't happen, and Windows PowerShell launches with PowerShell 7 modules in its PSModulePath. (What initially tipped me off was the surprise of seeing history-based prediction in Windows PowerShell.)

Since the PowerShell 7 version of Microsoft.PowerShell.Security is the latest version available to it in this scenario, that's what Windows PowerShell tries to load. Until 7.3.0-preview.7, Windows PowerShell was able to load this PowerShell 7 module. Now, when it tries to import the PowerShell 7 version, it throws errors for the types that were moved into the module in #16355.

In the meantime, as a workaround, if you're able to modify the scripts that started failing on you, have them explicitly import version 3.0.0.0 of Microsoft.PowerShell.Security before attempting to access cert:\

@masaru-iritani
Copy link
Author

Thank you for the information, dwtaber. Importing Microsoft.PowerShell.Security 3.0.0.0 explicitly mitigated the error.

@SteveL-MSFT SteveL-MSFT added the Review - Committee The PR/Issue needs a review from the PowerShell Committee label Nov 23, 2022
@SteveL-MSFT
Copy link
Member

When we approved the change to move the types out of SMA, we didn't anticipate the impact on the cert: drive that multiple users have reported. Committee will discuss this after the long weekend.

@daxian-dbw
Copy link
Member

daxian-dbw commented Nov 23, 2022

The root problem is that when doing pwsh -> cmd -> powershell, the $env:PSModulePath in the powershell process will be incorrectly using the module path from pwsh. This is because the cmd derives that environment value from pwsh, and then powershell derives that from cmd. Below is a screenshot of the value of that env variable from within powershell.

image

With the incorrect module path value, when doing Import-Module Microsoft.PowerShell.Security in powershell, it’s actually attempting to import the pwsh version of the Microsoft.PowerShell.Security module, not the Windows PowerShell version that comes in-box with powershell.exe.


Doing the pwsh -> cmd -> powershell is doomed to run into problems because the module paths are just wrong for powershell.exe -- even if we reverted this change, there will be another change in future that just make the pwsh version of a built-in module no longer work in powershell.exe.

That’s why we special-cased the pwsh -> powershell.exe scenario to fix the PSModulePath environment variable before starting powershell.exe.

@masaru-iritani In your workflow, I suggest you unset the environment variable PSModulePath in cmd by set PSModulePath= before starting powershell.exe, so that the powershell.exe process will be guaranteed to use the correct module path.

@SteveL-MSFT SteveL-MSFT removed the Review - Committee The PR/Issue needs a review from the PowerShell Committee label Nov 28, 2022
@SteveL-MSFT
Copy link
Member

Ok, what @daxian-dbw says makes sense to me based on how this works and "supposed" to work. cmd being in the middle will not hit the code paths that explicitly fixes up PSModulePath but unsetting it will cause either pwsh or powershell to create it.

@SteveL-MSFT SteveL-MSFT added Resolution-Answered The question is answered. and removed Needs-Triage The issue is new and needs to be triaged by a work group. labels Nov 28, 2022
@ghost
Copy link

ghost commented Nov 30, 2022

This issue has been marked as answered and has not had any activity for 1 day. It has been closed for housekeeping purposes.

@zurcher
Copy link

zurcher commented Dec 14, 2022

Copying my comment over from a duplicate bug:

I'm hitting this bug in a long-term product support codebase and probably can't check in the workaround. I also suspect we'll see more reports of this issue as more people move to 7.3, and the error message gives no easy indication of what the problem is.

If pwsh and powershell already know how to rebuild PSModulePath, could the pwsh -> powershell.exe special-case be applied to all executable calls?

@eliassal
Copy link

eliassal commented Dec 26, 2022

I had azure pipeline that uses powershell inline script which runs on an self-hosted build agent where I have powershell standard and Ps7, Pipeline used to work like a charm until I upgraded 2 weeks back PS7 to 7.3
Script started to fail with the following error
image

I opened a ticket with VS community at
https://developercommunity.visualstudio.com/t/dotnet-coverage-not-showing-analysis-onl/10177746#T-ND10238787

They pointed me to this ticket
As you will notice in PS command line it calls the right 3.0.0.0 version and in PS7 as well it calls its correct version and script on both works fine
I issued set "PSModulePath=" in PS command line even I added

import-module -Name 'Microsoft.PowerShell.Security' -RequiredVersion 3.0.0.0
in the inline script in the pipeline but nothing helped

So not sure what is needed to be doen in order to make the script in the pipeline work correctly

PSandPS7

Visual Studio Feedback

shcheklein added a commit to iterative/dvc-exe that referenced this issue Feb 9, 2024
shcheklein added a commit to iterative/dvc-exe that referenced this issue Feb 9, 2024
* debug sign build

* Update sign.py: set PSModulePath

PowerShell/PowerShell#18530 (comment)
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Resolution-Answered The question is answered.
Projects
None yet
Development

No branches or pull requests

6 participants