2017-08-07 130 views
3

相当于此PowerShell命令的C#是什么?存储:C#相当于PowerShell命令

PS C:\WINDOWS\system32> gwmi win32_DiskDrive | %{gwmi -query "ASSOCIATORS OF {$($_.__RELPATH)} where resultclass = Win32_PnpEntity" | %{gwmi -query "ASSOCIATORS OF {$($_.__RELPATH)}"}} | fl __CLASS,__RELPATH 

上述命令的结果是:

... 
__CLASS : Win32_SystemDriver 
__RELPATH : Win32_SystemDriver.Name="disk" 

__CLASS : Win32_ComputerSystem 
__RELPATH : Win32_ComputerSystem.Name="JMR-ENG-SARAH" 

__CLASS : Win32_IDEController 
__RELPATH : Win32_IDEController.DeviceID="PCI\\VEN_8086&DEV_8C82&SUBSYS_79171462&REV_00\\3&11583659&0&FA" 

__CLASS : CIM_DataFile 
__RELPATH : CIM_DataFile.Name="c:\\windows\\system32\\drivers\\disk.sys" 

__CLASS : Win32_DiskDrive 
__RELPATH : Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE1" 


__CLASS : Win32_SCSIController 
__RELPATH : Win32_SCSIController.DeviceID="PCI\\VEN_144D&DEV_A804&SUBSYS_A801144D&REV_00\\6&381D8F6A&0&00080008" 

__CLASS : Win32_SystemDriver 
__RELPATH : Win32_SystemDriver.Name="disk" 

__CLASS : Win32_ComputerSystem 
__RELPATH : Win32_ComputerSystem.Name="JMR-ENG-SARAH" 

__CLASS : CIM_DataFile 
__RELPATH : CIM_DataFile.Name="c:\\windows\\system32\\drivers\\disk.sys" 

__CLASS : Win32_DiskDrive 
__RELPATH : Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE2" 
... 

我想我不明白的是如何PowerShell命令操作。我知道部分翻译。

  ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive"); 

foreach (ManagementObject wmi_HD in searcher.Get()) 
{ 
    String driveDeviceId = wmi_HD["DeviceID"].ToString(); 
} 

以上代码是gwmi win32_DiskDrive的一部分。我需要提取哪些属性以供讨论。我知道有一份归还物业的清单。

我有另一个代码片段,在那里我得到与物理磁盘相关的驱动器号,它使用ASSOCIATORS OF gwmi查询。这样,答案应类似于:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Management; 

String query2 = "ASSOCIATORS OF {Win32_DiskDrive.DeviceID='" + driveDeviceId + "'} WHERE AssocClass = Win32_DiskDriveToDiskPartition"; 
foreach (ManagementObject partition in new ManagementObjectSearcher(query2).Get()) 
{ 
    foreach (ManagementObject disk in new ManagementObjectSearcher(
       "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='" 
        + partition["DeviceID"] 
        + "'} WHERE AssocClass = Win32_LogicalDiskToPartition").Get()) 
    { 
     String diskMount = disk["Name"].ToString(); 
    } 
} 

|仅仅是一个嵌入式for循环,其中内WMI查询将使用其它环形元件的结果。我想要的查询更复杂一些,双套|,并使用双套{$($_.__RELPATH)}

如何在顶部为所需的PowerShell脚本编写C#代码?

+0

你的目标是什么? –

+0

@Bill_Stewart为了让C#程序设计等同于顶部给出的PowerScript命令。我试图解决方案的方向,因此其余的代码。 –

+1

如果我能改善问题,而不是反对票和近距离投票,我将不胜感激。投票加上近距离投票并没有说明问题。我想学习和改进,不仅仅是针对这个问题,而是针对未来的问题。有很多关于'ManagementObject'类的问题,但我没有发现,它讨论了这个PowerShell脚本中更复杂的元素。 –

回答

4

1:我奋斗了很长一段时间,做研究,终于明白了事情会好一点。我能够自己构建我的问题的答案。我将这个答案连同一个解释,希望教育其他人。至少对我而言,WMI很难理解,特别是错综复杂的情况。

  1. 重大更新结束,检查出来。

我的大突破是相信与否this Microsoft网页以及帮助从ScryptingGuythis SO文章在WMI查询过滤器逃逸美元符号。

我也意识到最后的过滤器适用于查询。源代码等同。将拉仅属性,如:

String propDiskRelpaths = wmiDisks["__RELPATH"].ToString(); 

我发现括号由WMI要求和指示的值。美元符号仅表示外部查询的结果。内涵($_.__RELPATH)是表达前一个查询的__RELPATH属性的奇特方式。

该查询首先枚举系统上的所有磁盘。然后第二个查询枚举磁盘的所有PNP实体(只有一个),而最后一个查询获取磁盘的所有路径关联(驱动程序层次结构)。每个查询将向下钻取一个级别。

如果任何人有兴趣,这里是PowerScript的细分,然后导致我到底部的代码。我在这里只列出一个磁盘驱动器,但我的系统上现在有6个驱动器:0到5.物理驱动器3显示如下。

PS C:\WINDOWS\system32> gwmi win32_DiskDrive | fl __CLASS,__RELPATH 

.... 
__CLASS : Win32_DiskDrive 
__RELPATH : Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE3" 

这里是第二个命令,这将产生磁盘的PNP实体。在这种情况下,我选择了我的C:驱动器,驱动器0,而不是我的M.2卡驱动器3,以此为例。真正的代码是在for循环,所以我会得到所有的驱动器。

PS C:\WINDOWS\system32> gwmi -query 'ASSOCIATORS OF {Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE0"} where resultclass = Win32_PnpEntity' | fl __CLASS,__RELPATH 

__CLASS : Win32_PnPEntity 
__RELPATH : Win32_PnPEntity.DeviceID="SCSI\\DISK&VEN_NVME&PROD_SAMSUNG_SSD_960\\7&335357E&0&000000" 

的最后一个命令,输出是:

PS C:\WINDOWS\system32> gwmi -query 'ASSOCIATORS OF {Win32_PnPEntity.DeviceID="SCSI\\DISK&VEN_NVME&PROD_SAMSUNG_SSD_960\\7&335357E&0&000000"}' | fl __CLASS,__RELPATH 


__CLASS : Win32_SCSIController 
__RELPATH : Win32_SCSIController.DeviceID="PCI\\VEN_144D&DEV_A804&SUBSYS_A801144D&REV_00\\6&381D8F6A&0&00080008" 

__CLASS : Win32_SystemDriver 
__RELPATH : Win32_SystemDriver.Name="disk" 

__CLASS : Win32_ComputerSystem 
__RELPATH : Win32_ComputerSystem.Name="JMR-ENG-SARAH" 

__CLASS : CIM_DataFile 
__RELPATH : CIM_DataFile.Name="c:\\windows\\system32\\drivers\\disk.sys" 

__CLASS : Win32_DiskDrive 
__RELPATH : Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE0" 

正如你看到的,我的M.2卡被列为SCSI设备,而不是作为一个NVMe PCIe卡,它确实是。我做了研究,这和预期的一样,因为Microsoft StorNVMe.sys驱动程序在设备驱动程序级别将NVMe作为IOCTL_SCSI_*转换为IOCTL_NVME_*命令。这在Windows Vista中是如此,显然在Windows 10中仍然如此。

PS C:\WINDOWS\system32> gwmi -query 'ASSOCIATORS OF {Win32_PnPEntity.DeviceID="SCSI\\DISK&VEN_NVME&PROD_SAMSUNG_SSD_960\\7&335357E&0&000000"}' | fl __CLASS,__RELPATH 


__CLASS : Win32_SCSIController 
__RELPATH : Win32_SCSIController.DeviceID="PCI\\VEN_144D&DEV_A804&SUBSYS_A801144D&REV_00\\6&381D8F6A&0&00080008" 

__CLASS : Win32_SystemDriver 
__RELPATH : Win32_SystemDriver.Name="disk" 

__CLASS : Win32_ComputerSystem 
__RELPATH : Win32_ComputerSystem.Name="JMR-ENG-SARAH" 

__CLASS : CIM_DataFile 
__RELPATH : CIM_DataFile.Name="c:\\windows\\system32\\drivers\\disk.sys" 

__CLASS : Win32_DiskDrive 
__RELPATH : Win32_DiskDrive.DeviceID="\\\\.\\PHYSICALDRIVE0" 

这是我想要的最终代码。我应该添加基于IDE的驱动器,然后我可以枚举IDE类并获得该磁盘支持的模式(IDE,AHCI,RAID等)。

希望这个解释很清楚。让我知道,如果它需要更多的解释。哦,下面的代码假设VS2017或以上。

using System; 
using System.Collections.Generic; 
using System.Management; 
using SiloStor.Tools; 

internal static void EnumerateClassPaths() 
{ 
    try 
    { 
     // Enumerate all disk drives. 
     ManagementObjectSearcher oSearcher = new ManagementObjectSearcher("SELECT * FROM Win32_DiskDrive"); 
     foreach (ManagementObject wmiDisks in oSearcher.Get()) 
     { 
      // Get the properties needed. 
      String propDiskRelpaths = wmiDisks["__RELPATH"].ToString(); 

      // 
      String wmiQuery1 = "ASSOCIATORS OF {" + propDiskRelpaths + "} WHERE ResultClass = Win32_PnpEntity"; 
      foreach (ManagementObject wmiPnp in new ManagementObjectSearcher(wmiQuery1).Get()) 
      { 
       // Get the properties needed. 
       String propPnpRelpaths = wmiPnp["__RELPATH"].ToString(); 

       // 
       String wmiQuery2 = "ASSOCIATORS OF {" + propPnpRelpaths + "}"; 
       foreach (ManagementObject wmiDrivers in new ManagementObjectSearcher(wmiQuery2).Get()) 
       { 
        String driverClass = wmiDrivers["__CLASS"].ToString(); 
        String driverRelpath = wmiDrivers["__RELPATH"].ToString(); 
        Console.WriteLine($"__CLASS : {driverClass}"); 
        Console.WriteLine($"__RELPATH : {driverRelpath}"); 
        Console.WriteLine(""); 
       } 
      } 
     } 
    } 

    catch (Exception ex) 
    { 
     // Log the error. 
     Errors.LogError(ex); 
    } 
} 

UPDATE:

昨天(2017年8月9日),我发现了一个link微软WMI Code Creator V1.0。我不是由微软支付的,也不是我认为这个工具是WMI工作的“必备”工具,但它实际上相当不错,而且根本没有广告。

WMI Code Creator为应用程序提供源代码,为WMI查询生成C#和VB.Net源代码。不幸的是,WMI查询仅限于基本命令,但仍然非常有用。另一个有用的是该工具显示用户可以查询的类,也非常有帮助。可悲的是,没有ASSOCIATORS OF或串联的查询,但确实有许多其他有用的功能。检查出来,并希望它有帮助。

+0

不错的工作,并感谢发布答案。 –