通过 API 从 C# 附加到 $PSModulePath

Ben*_*udo 5 .net powershell

当使用 C#/.Net 执行 PowerShell 脚本时,我想添加$PSModulePath 的路径,而不覆盖默认的 $PSModulePath。

我已经弄清楚如何使用 InitialSessionState.EnvironmentVariables 将 $PSModulePath 设置为我选择的值。但是,这种方法并不可取,因为它替换了默认的 $PSModulePath,而不是附加到它。

var state= InitialSessionState.CreateDefault();
state.EnvironmentVariables.Add(new SessionStateVariableEntry("PSModulePath", myModuleLoadPath, "PowerShell Module Search Locations"));
var runSpace = RunspaceFactory.CreateRunspace(initialState);

using (var powershell = PowerShell.Create())
{
    powershell
        .AddScript(script)
        .Invoke();
}
Run Code Online (Sandbox Code Playgroud)

有没有办法以编程方式使用 .Net API附加到 $PSModulePath?

Ben*_*udo 5

显然,环境变量在打开之前PSModulePath不会填充默认值。对传递给的an进行设置可抑制此自动填充。PSModulePathRunspacePSModulePathInitialSessionStateRunspaceFactory.CreateRunspace()

要操作默认值PSModulePath请等待相关Runspace打开SessionStateProxy.GetVariable(),然后根据需要使用/获取/设置变量SetVariable()

using (var runspace = RunspaceFactory.CreateRunspace())
{
    runspace.Open();

    var proxy = runspace.SessionStateProxy;
    var psModulePath = proxy.GetVariable("env:PSModulePath");
    proxy.SetVariable("env:PSModulePath", $"{psModulePath};{extraPathToAppend}");

    using (var powershell = PowerShell.Create())
    {
        powershell.Runspace = runspace;

        powershell
            .AddScript(script)
            .Invoke();
    }
}
Run Code Online (Sandbox Code Playgroud)

PowerShell通过访问当前实例的属性可以达到相同的效果Runspace。这种方法消除了显式创建和打开实例的需要Runspace

using (var powershell = PowerShell.Create())
{
    var proxy = powershell.Runspace.SessionStateProxy;
    var psModulePath = proxy.GetVariable("env:PSModulePath");
    proxy.SetVariable("env:PSModulePath", $"{psModulePath};{extraPathToAppend}");

    powershell
        .AddScript(script)
        .Invoke();

}
Run Code Online (Sandbox Code Playgroud)

感谢问题Adjust PSModulePath via Runspace in .Net code帮助我解决了这个问题!