简体   繁体   English

存储:C#相当于PowerShell命令

[英]Storage: C# equivalent of PowerShell command

What is the C# equivalent to this PowerShell command? 什么是与此PowerShell命令等效的C#?

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

The result of the above command is: 上述命令的结果是:

...
__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"
...

I guess what I do not understand is how the PowerShell command operates. 我想我不明白的是PowerShell命令是如何运作的。 I do know part of the translation. 我知道部分翻译。

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

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

The above code is the gwmi win32_DiskDrive part. 上面的代码是gwmi win32_DiskDrive部分。 What property I need to extract is open to discussion. 我需要提取的属性可供讨论。 I know that there is a laundry list of returned properties. 我知道有一份归还房产的清单。

I have another code fragment, where I get the drive letters associated with physical disks, which uses the ASSOCIATORS OF gwmi query. 我有另一个代码片段,我得到与物理磁盘相关的驱动器号,它使用ASSOCIATORS OF gwmi查询。 As such, the answer should be similar to: 因此,答案应该类似于:

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();
    }
}

The | | is simply an embedded for-loop, where the inner wmi query would use the result of the other loop element. 它只是一个嵌入式for循环,其中内部wmi查询将使用另一个循环元素的结果。 The query that I would like is a bit more complex with a double set of | 我想要的查询有点复杂,有一组双| and uses a double set of {$($_.__RELPATH)} . 并使用一组{$($_.__RELPATH)}

How would I write the C# code for the desired PowerShell script at the top? 如何在顶部编写所需PowerShell脚本的C#代码?

Note 1: I struggled for quite some time and did research and finally understood things a bit better. 1:我挣扎了很长时间并进行了研究,最后对事情有所了解。 I was able to construct the answer to my question on my own. 我能够自己构建问题的答案。 I am placing the answer here along with an explanation in hopes to educate others. 我在这里给出答案以及希望教育他人的解释。 At least for me, WMI is quite difficult to understand, especially with the intricacies. 至少对我来说,WMI很难理解,尤其是错综复杂的情况。

  1. Great update at end, check it out. 最后更新,检查出来。

My big breakthrough came with believe it or not this Microsoft web page along with help from ScryptingGuy and this SO article on escaping dollar signs in a WMI query filter. 我的重大突破来自于相信这个微软网页以及ScryptingGuy的帮助以及关于在WMI查询过滤器中逃避美元符号的这篇 SO文章。

I also realized that the filter at the end applies to queries. 我还意识到最后的过滤器适用于查询。 The source code equivalent would be to pull only that property, such as: 等效的源代码是仅提取该属性,例如:

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

I found out that braces are required by WMI and indicate a value. 我发现WMI需要大括号并指示一个值。 The dollar sign merely indicates the result from the outer query. 美元符号仅表示外部查询的结果。 The connotation ($_.__RELPATH) is a fancy way of saying the __RELPATH property of the previous query. 内涵($_.__RELPATH)是一种说出前一个查询的__RELPATH属性的奇特方式。

The query first enumerates all disks on the system. 查询首先枚举系统上的所有磁盘。 The second query then enumerates all PNP Entities for the disk (there is only one), while the last query gets all path associations (driver hierarchy) for the disk. 然后,第二个查询枚举磁盘的所有PNP实体(只有一个),而最后一个查询获取磁盘的所有路径关联(驱动程序层次结构)。 Each query drills down one level. 每个查询向下钻取一个级别。

In case anyone is interested, here is the breakdown in PowerScript, which then led me to the code at the bottom. 如果有人感兴趣,这里是PowerScript的细分,然后引导我到底部的代码。 I only list one disk drive here, but I have 6 drives on my system at the moment: 0 through 5. Physical drive 3 shows below. 我这里只列出一个磁盘驱动器,但我的系统上有6个驱动器:0到5.物理驱动器3显示如下。

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

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

Here is the second command, which yields the PNP Entities for the disk. 这是第二个命令,它产生磁盘的PNP实体。 In this case, I chose my C: drive, drive 0, rather than my M.2 card, drive 3, to list here as an example. 在这种情况下,我选择了我的C:驱动器,驱动器0,而不是我的M.2卡,驱动器3,在此列出作为示例。 The real code is in a for-loop, so I would get all drives. 真正的代码是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"

The last command and the output is: 最后一个命令和输出是:

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"

As you can see, my M.2 card gets listed as a SCSI device rather than as an NVMe PCIe card that it really is. 如您所见,我的M.2卡被列为SCSI设备而不是NVMe PCIe卡。 I did research and that is as expected, because the Microsoft StorNVMe.sys driver implements NVMe as IOCTL_SCSI_* translated to IOCTL_NVME_* commands at the device driver level. 我做了研究,这是预期的,因为Microsoft StorNVMe.sys驱动程序实现NVMe,因为IOCTL_SCSI_*在设备驱动程序级别转换为IOCTL_NVME_*命令。 That was true in Windows Vista and evidently true still with Windows 10. 在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"

Here is the final code that I wanted. 这是我想要的最终代码。 I should add that had for IDE based drives, I can then enumerate the IDE class and get supported modes for that disk (IDE, AHCI, RAID, etc.). 我应该添加基于IDE的驱动器,然后我可以枚举IDE类并获得该磁盘支持的模式(IDE,AHCI,RAID等)。

Hopefully, this explanation is clear. 希望这个解释很清楚。 Let me know, if it needs anymore explanation. 如果它需要解释,请告诉我。 Oh, the code below assumes VS2017 or above. 哦,下面的代码假定为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: 更新:

Yesterday (August 9, 2017), I found a link to Microsoft WMI Code Creator v1.0. 昨天(2017年8月9日),我找到了Microsoft WMI Code Creator v1.0的链接 I am not being paid by Microsoft nor do I think this tool a "Must Have" for WMI work, but it is actually quite nice and not advertised at all. 我没有被微软支付,也不认为这个工具对于WMI工作来说是“必须拥有的”,但它实际上相当不错而且根本没有做广告。

The WMI Code Creator , for which gives source code to the App, generates C# and VB.Net source code for WMI queries. WMI Code Creator为应用程序提供源代码,为WMI查询生成C#和VB.Net源代码。 Sadly, the WMI queries are limited to basic commands, but still, very helpful. 遗憾的是,WMI查询仅限于基本命令,但仍然非常有用。 The other useful thing is that the tool shows classes that a user can query, also very helpful. 另一个有用的东西是该工具显示用户可以查询的类,也非常有用。 Sadly, there are no ASSOCIATORS OF or concatenated queries, but does have many other useful features. 遗憾的是,没有ASSOCIATORS OF或连接查询,但确实有许多其他有用的功能。 Check it out and hope that it helps. 检查出来,希望它有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM