Получить метку тома из номера диска (не буквы диска)

#c# #powershell #wmi

#c# #powershell #wmi

Вопрос:

Я могу получить метку тома (какую я хочу) из букв диска следующим образом..

  try
        {
            DriveInfo[] myDrives = DriveInfo.GetDrives();

        foreach (DriveInfo drive in myDrives)
        {
            Console.WriteLine("Drive:"   drive.Name);
            Console.WriteLine("Drive Type:"   drive.DriveType);

            if (drive.IsReady == true)
            {
                Console.WriteLine("Vol Label:"   drive.VolumeLabel);

            }
        }
    }
    catch (Exception)
    {

        throw;
    }
  

но я хочу, чтобы метка тома была из номера диска. Я могу получить номера дисков с помощью этого…

  foreach (var drive in new ManagementObjectSearcher("Select * from Win32_LogicalDiskToPartition").Get().Cast<ManagementObject>().ToList())
            {

                var driveNumber = Regex.Match((string)drive["Antecedent"], @"Disk #(d*),").Groups[1].Value;

                Console.WriteLine("Drive Number: "   driveNumber);
                Console.WriteLine(Environment.NewLine);
            }
  

Как я могу собрать что-то вместе, чтобы получить метку тома из всех заданных номеров дисков (из показанного 2-го блока кода)?

Дополнительная информация: Я не могу использовать «LogicalDisk …» для запроса, потому что я нахожу смонтированные виртуальные диски, которые, похоже, не считаются «logicalDisks

введите описание изображения здесь

Комментарии:

1. ИМХО, вы ищете Label свойство Win32_Volume класса. К сожалению, я не вижу никакой связи с Win32_DiskPartition классом.

Ответ №1:

Завершите поиск по Win32_LogicalDiskToPartition с помощью поиска по Win32_LogicalDisk фильтрации по установленному DriveLetter, возвращающему VolumeName свойство.

             var drives = new ManagementObjectSearcher("Select * from Win32_LogicalDiskToPartition").Get().Cast<ManagementObject>();
            var disks = new ManagementObjectSearcher("Select * from Win32_LogicalDisk").Get().Cast<ManagementObject>();
            foreach (var drive in drives)
            {
                var driveLetter = Regex.Match((string)drive["Dependent"], @"DeviceID=""(.*)""").Groups[1].Value;
                var driveNumber = Regex.Match((string)drive["Antecedent"], @"Disk #(d*),").Groups[1].Value;

                Console.WriteLine("Drive Letter: "   driveLetter);
                Console.WriteLine("Drive Number: "   driveNumber);

                // TODO: Enhance this to properly handle when the LINQ returns nothing.
                //       Likely only an edge case, but BSTS.
                var foundDisk = disks.Where((d) => d["Name"].ToString() == driveLetter).FirstOrDefault();

                // In the event that Drive Letter is not available, try the disk path
                if (foundDisk == null) {
                  foundDisk = disks.Where((d) => d.Path.ToString() == drive["Dependent"].ToString()).FirstOrDefault();
                }

                if (foundDisk == null) {
                  Console.WriteLine("Drive Label: <Unknown>");
                } else {
                  Console.WriteLine("Drive Label: "   foundDisk["VolumeName"]);
                }

                Console.WriteLine(Environment.NewLine);
            }

  

Комментарии:

1. Диски, которые я запрашиваю, не имеют буквы диска, только номер диска

2. @nlstack01 — хорошо — в приведенном выше примере используется то, Path что хранится в Dependent свойстве LogicalDiskToPartition. Это работает?

3. не сработало. Я не думаю, что смогу использовать LogicalDiskwhatever, потому что я смонтировал виртуальные диски, и они не считаются логическими дисками

4. Есть ли у вашего смонтированного VHD-диска имя тома?

5. itprotoday.com/server-virtualization/… — содержит несколько ссылок на команды Powershell для получения соответствующего логического диска. Может помочь направить вас.

Ответ №2:

То, что вы называете «номером диска», на языке WMI называется «Индексом диска». Вам не нужно ничего анализировать, чтобы установить отношения между классами WMI.

Вы можете получить метку тома только из свойства VolumeName Win32_LogicalDisk. Это должно работать и для смонтированного VHD (X). Следующий код просматривает все разделы (обратите внимание, что на диске может быть несколько разделов) и сбрасывает связанные логические диски (обратите внимание, что в разделе может быть несколько логических дисков), имена томов, если таковые имеются:

 foreach (var partition in new ManagementObjectSearcher("SELECT * FROM Win32_DiskPartition").Get())
{
    Console.WriteLine("Caption : "   partition["Caption"]);
    Console.WriteLine("Disk Index : "   partition["DiskIndex"]);

    // associate the partition with logical disk(s)
    foreach (var logicalDisk in new ManagementObjectSearcher(
        "ASSOCIATORS OF {Win32_DiskPartition.DeviceID='"  
        partition["DeviceID"]  
        "'} WHERE AssocClass=Win32_LogicalDiskToPartition").Get())
    {
        Console.WriteLine(" "   logicalDisk["VolumeName"]);
    }
}
  

Если вам нужны названия разделов и томов для данного диска, просто ограничьте начальный запрос, вот так: SELECT * FROM Win32_DiskPartition WHERE DiskIndex=1 например.

Комментарии:

1. Я добавил скриншот к вопросу. Что я ожидаю получить, так это метку «Система зарезервирована»

2. Вы можете попробовать запустить SELECT * FROM Win32_Volume и посмотреть, получите ли вы что-нибудь в Label свойстве, но я предполагаю, что вы смотрите на зарезервированный системой раздел , в котором нет логического диска (и тома, поскольку это одно и то же). Пользовательский интерфейс отображает текст «Зарезервировано системой», это не метка и не имя.