.NET Core控制台执行Get-WindowsCapability报错原因及配置咨询
我是.NET Core中PowerShell的新手,脚本Get-WindowsCapability -Online -Name Microsoft.Windows.Notepad*在PowerShell ISE中运行正常,但在.NET Core控制台应用中执行时报错。已以管理员身份运行控制台应用,相关信息如下:
脚本:
Get-WindowsCapability -Online -Name Microsoft.Windows.Notepad*
PowerShell ISE输出:
Name : Microsoft.Windows.Notepad~~~~0.0.1.0
State : Installed
DisplayName : Notepad
Description : View, edit, and search through plain text documents and source code files instantly.
DownloadSize : 301710
InstallSize : 647868
.NET Core控制台代码片段:
var psInstance = PowerShell.Create(); psInstance.AddScript("Get-WindowsCapability -Online -Name Microsoft.Windows.Notepad*"); var output = psInstance.Invoke(); psInstance?.Runspace?.Close(); if (psInstance.HadErrors) { var error = psInstance.Streams.Error.Select(e => e.ToString()); }
报错信息:
Count = 5
[0]: "The 'Get-WindowsCapability' command was found in the module 'Dism', but the module could not be loaded due to the following error: [File C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Dism\Dism.psm1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https://go.microsoft.com/fwlink/?LinkID=135170.]\r\nFor more information, run 'Import-Module Dism'."
[1]: "The 'Get-WindowsCapability' command was found in the module 'Dism', but the module could not be loaded due to the following error: [File C:\WINDOWS\system32\WindowsPowerShell\v1.0\Modules\Dism\Dism.psm1 cannot be loaded because running scripts is disabled on this system. For more information, see about_Execution_Policies at https://go.microsoft.com/fwlink/?LinkID=135170.]\r\nFor more information, run 'Import-Module Dism'."
[2]: "[localhost] Connecting to remote server localhost failed with the following error message : WinRM cannot process the request. The following error with errorcode 0x8009030e occurred while using Negotiate authentication: A specified logon session does not exist. It may already have been terminated. \r\n Possible causes are:\r\n -The user name or password specified are invalid.\r\n -Kerberos is used when no authentication method and no user name are specified.\r\n -Kerberos accepts domain user names, but not local user names.\r\n -The Service Principal Name (SPN) for the remote computer name and port does not exist.\r\n -The client and remote computers are in different domains and there is no trust between the two domains.\r\n After checking for the above issues, try the following:\r\n -Check the Event Viewer for events related to authentication.\r\n -Change the authentication method; add the destination computer to the WinRM TrustedHosts configuration setting or use HTTPS transport.\r\n Note that computers in the TrustedHosts list might not be authenticated.\r\n -For more information about WinRM configuration, run the following command: winrm help config. For more information, see the about_Remote_Troubleshooting Help topic.\r\n Other Possible Cause:\r\n -The domain or computer name was not included with the specified credential, for example: DOMAIN\UserName or COMPUTER\UserName."
[3]: "Cannot validate argument on parameter 'Session'. The argument is null or empty. Provide an argument that is not null or empty, and then try the command again."
[4]: "Cannot validate argument on parameter 'Id'. The argument is null. Provide a valid value for the argument, and then try running the command again."
请问为何脚本在PowerShell ISE中正常运行,却在控制台应用中报错?是否需要对PowerShell实例对象进行额外配置?
核心原因
- 执行策略差异:PowerShell ISE基于传统Windows PowerShell环境,默认执行策略允许加载系统模块脚本;而.NET Core调用的PowerShell实例默认采用更严格的执行策略,导致Dism模块的.psm1脚本无法加载。
- 本地会话配置缺失:
-Online参数依赖本地WinRM会话支持,.NET Core创建的PowerShell实例未默认配置该会话,引发连接失败。
具体配置步骤
1. 设置进程级执行策略
在执行目标命令前,为当前PowerShell实例设置临时执行策略,允许加载系统脚本:
var psInstance = PowerShell.Create(); // 仅对当前进程生效,避免修改全局策略 psInstance.AddCommand("Set-ExecutionPolicy") .AddParameter("ExecutionPolicy", "RemoteSigned") .AddParameter("Scope", "Process") .AddParameter("Force"); psInstance.Invoke(); psInstance.Commands.Clear();
2. 手动导入Dism模块
显式导入Dism模块,绕过自动加载时的权限限制:
psInstance.AddCommand("Import-Module").AddParameter("Name", "Dism"); psInstance.Invoke(); psInstance.Commands.Clear();
3. 绑定本地Runspace(可选)
若仍存在WinRM相关错误,可显式创建并绑定本地Runspace,确保会话正常:
var runspace = RunspaceFactory.CreateRunspace(); runspace.Open(); var psInstance = PowerShell.Create(); psInstance.Runspace = runspace;
完整修正代码示例
using System.Management.Automation; using System.Linq; var runspace = RunspaceFactory.CreateRunspace(); runspace.Open(); var psInstance = PowerShell.Create(); psInstance.Runspace = runspace; // 设置临时执行策略 psInstance.AddCommand("Set-ExecutionPolicy") .AddParameter("ExecutionPolicy", "RemoteSigned") .AddParameter("Scope", "Process") .AddParameter("Force"); psInstance.Invoke(); psInstance.Commands.Clear(); // 导入Dism模块 psInstance.AddCommand("Import-Module").AddParameter("Name", "Dism"); psInstance.Invoke(); psInstance.Commands.Clear(); // 执行目标命令 psInstance.AddScript("Get-WindowsCapability -Online -Name Microsoft.Windows.Notepad*"); var output = psInstance.Invoke(); // 错误处理 if (psInstance.HadErrors) { var errors = psInstance.Streams.Error.Select(e => e.ToString()).ToList(); // 自定义错误处理逻辑 } // 资源清理 psInstance?.Dispose(); runspace?.Close(); runspace?.Dispose();
内容的提问来源于stack exchange,提问作者JohnB

