Powershell: .Net core 2.1 Powershell SDK 6.1.1 can not get correct PSModulePath

Created on 11 Jan 2019  路  7Comments  路  Source: PowerShell/PowerShell

Hi,

I have installed PowerShell Core 6.1.1 from MSI file on my machine and its module locates by default at
C:Program FilesPowerShell6Modules.

I open CMD with Powershell 6 and type "$env:PSModulePath". It returns
"C:Program FilesPowerShell6Modules" => Matched with my location this is correct.
"C:Program FilesPowerShellModules"
"C:windowssystem32WindowsPowerShellv1.0Modules"

I write a .Net core 2.1 Console App with Powershell SDK 6.1.1 with simple testing "$env:PSModulePath"

using (var ps = PowerShell.Create())
{
    ps.AddScript("$env:PSModulePath;");
    var results = ps.Invoke();
    foreach (var result in results)
    {
        var itemPath = result.ToString();
    }
}

And only get these. It seems the console app can not find my PS Core 6 path correctly.
"C:Program FilesPowerShellModules"
"C:windowssystem32WindowsPowerShellv1.0Modules"

Is this a bug? Thanks

Issue-Discussion WG-DevEx-SDK

Most helpful comment

Thanks, @SteveL-MSFT and @adityapatwardhan.


Re documentation:

Can I suggest:

  • first, amending the descriptions of the NuGet packages to contain this information? E.g., package PowerShellStandard.Library just states Contains the reference assemblies for PowerShell Standard 5 and System.Management.Automation does not indicate that it shouldn't be used directly.

  • second, compiling this information in documentation that covers all editions and platforms? All I could find was - outdated - WinPS information (Installing the Windows PowerShell SDK) and nothing re Core; though https://github.com/PowerShell/PowerShell-Docs suggests that may already be underway.


Re behavior:

  • As for $env:PSModulePath: it almost sounds like the SDK should disregard this variable altogether, given that it only has meaning for a _regular_ PS installation (which is related to the discussions in https://github.com/PowerShell/PowerShell/issues/6850 and https://github.com/PowerShell/PowerShell/issues/8635, where it is cross-_edition_ use of $env:PSModulePath that causes problems, and a distinct variable for Core is being considered in a yet-to-be-written-RFC).

  • If the SDK is to be self-contained (no dependency on a regular installation), things like the package management modules, the compression (archive) module, and the thread-job module:

    • appear to be missing from the Microsoft.PowerShell.SDK package['s dependencies]
    • even if present, the SDK doesn't find them.

      • It seems that Start-PSBootstrap when you build the PS Core repo from source installs these packages (packagemanagement, powershellget, microsoft.powershell.archive, threadjob), which, incidentally, aren't directly available as NuGet packages themselves; what these packages have in common is that they're PowerShell _modules_.

As a result, calling commands such as Install-Module from the SDK doesn't work.

All 7 comments

That is indeed an interesting omission (which I personally cannot explain): $PSHOME\Modules isn't there when using the Core SDK.

6850 may be distantly related; the code that sets $env:PSModulePath in PS Core is in ModuleIntrinsics.cs

@mklement0 There are some weird responses on some PS commands if you run PS in CMD and run PS in .net core app.

Another example with this code

using (var ps = PowerShell.Create())
{
    ps.AddScript("Get-PSRepository");
    var results = ps.Invoke();
    foreach (var result in results)
    {
        var itemPath = result.ToString();
    }
}

It returns nothing in C# but if I run "Get-PSRepository" in CMD, I get 1 record with PSGallery row. That makes my scripts work fine in CMD but failed when running with c#.

And I am not sure because of ModulePath issues?

Taking a step back, it seems that the SDK is designed to be _self-contained_ and independent of a regular PowerShell installation, if any.

Yet, that is at odds with SDK-invoked commands still seeing and respecting $env:PSModulePath with directory entries from a regular PowerShell installation.

Conversely, the SDK packages appear to lack modules such as PowerShellGet (which contains Get-PSRepository) and microsoft.powershell.archive.

The Core SDK _does_ dynamically add $PSHome/Modules to $env:PSModulePath, yet it does so based on what _it_ considers $PSHOME, which is the (virtually useless) location of the platform-specific System.Management.Automation.dll file inside the locally cached relevant NuGet package.

The official docs (the ones I could find) offer little to clear up the confusion, and there appear to be multiple SDK-related NuGet packages, whose relationship is unclear:

  • Windows PowerShell: Microsoft.PowerShell.5.ReferenceAssemblies vs. PowerShellStandard.Library

  • PowerShell Core: Microsoft.PowerShell.SDK vs. System.Management.Automation

@SteveL-MSFT, can you shed some light on what the _expected_ behavior is?

I know this has come up before and directly related to SMA.dll being in a different folder being a nupkg. I believe expectation is that the app needs to set appropriate $env:PSModulePath for itself since SMA.dll cannot determine which other modules are there in what paths (if being brought into the project as nupkgs themselves). cc @adityapatwardhan

Yes, that is correct. Since we are using the SDK, the SMA.dll is being placed in nuget cache or in the publish folder, we cannot guess where $PSHome will be on the system even as a relative path. As @SteveL-MSFT recommended, the module path must be updated by the application to resolve this.

@mklement0 - Short description about the various packages.

Microsoft.PowerShell.5.ReferenceAssemblies - Used for building Windows PowerShell application.
PowerShellStandard.Library - Used for building PowerShell Core application compatible with Windows PowerShell.
Microsoft.PowerShell.SDK - Used for building PowerShell Core application.
System.Management.Automation - Not recommended to use directly.

Thanks, @SteveL-MSFT and @adityapatwardhan.


Re documentation:

Can I suggest:

  • first, amending the descriptions of the NuGet packages to contain this information? E.g., package PowerShellStandard.Library just states Contains the reference assemblies for PowerShell Standard 5 and System.Management.Automation does not indicate that it shouldn't be used directly.

  • second, compiling this information in documentation that covers all editions and platforms? All I could find was - outdated - WinPS information (Installing the Windows PowerShell SDK) and nothing re Core; though https://github.com/PowerShell/PowerShell-Docs suggests that may already be underway.


Re behavior:

  • As for $env:PSModulePath: it almost sounds like the SDK should disregard this variable altogether, given that it only has meaning for a _regular_ PS installation (which is related to the discussions in https://github.com/PowerShell/PowerShell/issues/6850 and https://github.com/PowerShell/PowerShell/issues/8635, where it is cross-_edition_ use of $env:PSModulePath that causes problems, and a distinct variable for Core is being considered in a yet-to-be-written-RFC).

  • If the SDK is to be self-contained (no dependency on a regular installation), things like the package management modules, the compression (archive) module, and the thread-job module:

    • appear to be missing from the Microsoft.PowerShell.SDK package['s dependencies]
    • even if present, the SDK doesn't find them.

      • It seems that Start-PSBootstrap when you build the PS Core repo from source installs these packages (packagemanagement, powershellget, microsoft.powershell.archive, threadjob), which, incidentally, aren't directly available as NuGet packages themselves; what these packages have in common is that they're PowerShell _modules_.

As a result, calling commands such as Install-Module from the SDK doesn't work.

@mklement0 submitted PR to fix PowerShell Standard description

Was this page helpful?
0 / 5 - 0 ratings