C#9中使用PowerShell对象调用Get-PhysicalDisk cmdlet异常问题求助
问题核心原因
你当前使用的PowerShell SDK 7.x属于跨平台的PowerShell Core版本,默认不加载Windows专属的系统模块,Get-PhysicalDisk cmdlet存储在Windows原生的Storage模块中,仅在Windows PowerShell 5.x(对应你之前VB项目使用的.NET Framework环境)中原生支持,这是出现兼容问题的根本原因。另外你提到的Get-PhysicalDevice属于笔误,正确的cmdlet名称为Get-PhysicalDisk。
解决方案
方案1:PowerShell实例调用适配
在调用Get-PhysicalDisk前先导入Windows原生Storage模块,添加-UseWindowsPowerShell参数适配PowerShell Core环境,同时增加错误输出逻辑排查问题:
using (PowerShell PowerShellInstance = PowerShell.Create()) { // 导入Windows原生Storage模块,32位程序跑在64位系统下时需要把路径中的System32替换为SysNative PowerShellInstance.AddScript(@"Import-Module C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Storage\Storage.psd1 -UseWindowsPowerShell"); PowerShellInstance.AddStatement(); PowerShellInstance.AddScript("Get-PhysicalDisk"); Collection<PSObject> outlist = PowerShellInstance.Invoke(); // 错误排查逻辑 if (PowerShellInstance.HadErrors) { foreach (var error in PowerShellInstance.Streams.Error) { Console.WriteLine(error.ToString()); } } }
方案2:Runspace调用适配
Runspace执行前先执行导入模块的命令即可:
Runspace rs = RunspaceFactory.CreateRunspace(); rs.Open(); Pipeline p = rs.CreatePipeline(); // 先导入模块,注意32位程序的路径替换规则 p.Commands.Add(@"Import-Module C:\Windows\System32\WindowsPowerShell\v1.0\Modules\Storage\Storage.psd1 -UseWindowsPowerShell"); p.Commands.Add("Get-PhysicalDisk"); Collection<PSObject> results = p.Invoke(); rs.Close();
方案3:替换为WMI查询(更稳定)
如果不需要强依赖PowerShell,可以直接通过WMI查询物理磁盘信息,不需要处理模块兼容问题,调用更稳定:
using System.Management; var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive"); foreach (ManagementObject disk in searcher.Get()) { Console.WriteLine($"磁盘型号:{disk["Model"]}"); Console.WriteLine($"磁盘容量:{disk["Size"]} 字节"); Console.WriteLine($"接口类型:{disk["InterfaceType"]}"); // 可按需读取其他属性 }
注意事项
- 程序需要以管理员权限运行,否则部分磁盘属性无法正常读取。
- 32位程序运行在64位Windows系统上时,系统会自动将
System32路径重定向到SysWOW64,此时需要把模块路径中的System32替换为SysNative才能正确找到Storage模块。
内容的提问来源于stack exchange,提问作者Bluegrasser
相关产品推荐
相关产品推荐

