Назад | Перейти на главную страницу

Как определить том в WMI по имени тома, указанному в журнале событий?

У меня есть сервер Windows 2008R2, который сообщает о следующей ошибке:

Структура файловой системы на диске повреждена и непригодна для использования. Запустите утилиту chkdsk на томе \ Устройство \ HarddiskVolume2.

Используя Powershell и WMI, как определить, какой это том, при запросе Win32_Volume.

Например, если я делаю:

Get-WmiObject Win32_Volume

Я получаю список всех томов на сервере, но ни один из Win32_Volume свойства класса используют (как представляется) это "понятное" имя - \Device\HarddiskVolume2. Я вижу есть DeviceID свойство, которое возвращает такое значение:

DeviceID    : \\?\Volume{4bc3df2a-65c7-11e0-9c33-806e6f6e6963}\

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

Я знаю, что могу разобрать вывод fltmc volumes или DISKPART чтобы получить эту информацию, но должен быть способ получить ее с помощью WMI в сценарии PowerShell.

Я также посмотрел на Win32_DiskDrive, Win32_DiskPartition и Win32_LogicalDisk классов, но нет упоминания о значениях свойств, напоминающих \Device\HarddiskVolume2.

Взгляните на этот код: http://poshcode.org/4768 кажется, он выполняет преобразования, которые вам нужны, чтобы увидеть, что вы хотите, вы можете настроить его в соответствии со своими потребностями, дайте мне знать, если вам понадобится помощь с этим, но я думаю, вы можете выяснить это самостоятельно.

function Get-DevicePath
{
<#
.SYNOPSIS

    Returns the device paths for each volume.

    Author: Matthew Graeber (@mattifestation)
    License: BSD 3-Clause

.DESCRIPTION

    Get-DevicePath returns the corresponding device path for each drive letter. This is useful for converting device paths to drive letters.

.EXAMPLE

    Get-DevicePath

    DevicePath              DriveLetter
    ----------              -----------
    \Device\HarddiskVolume2 D:
    \Device\HarddiskVolume4 C:

.OUTPUTS

    PSObject[]

    For each mount point, a PSObject is returned representing the drive letter and device path.
#>

    # Utilize P/Invoke in order to call QueryDosDevice. I prefer using 
    # reflection over Add-Type since it doesn't require compiling C# code.
    $DynAssembly = New-Object System.Reflection.AssemblyName('SysUtils')
    $AssemblyBuilder = [AppDomain]::CurrentDomain.DefineDynamicAssembly($DynAssembly, [Reflection.Emit.AssemblyBuilderAccess]::Run)
    $ModuleBuilder = $AssemblyBuilder.DefineDynamicModule('SysUtils', $False)

    # Define [Kernel32]::QueryDosDevice method
    $TypeBuilder = $ModuleBuilder.DefineType('Kernel32', 'Public, Class')
    $PInvokeMethod = $TypeBuilder.DefinePInvokeMethod('QueryDosDevice', 'kernel32.dll', ([Reflection.MethodAttributes]::Public -bor [Reflection.MethodAttributes]::Static), [Reflection.CallingConventions]::Standard, [UInt32], [Type[]]@([String], [Text.StringBuilder], [UInt32]), [Runtime.InteropServices.CallingConvention]::Winapi, [Runtime.InteropServices.CharSet]::Auto)
    $DllImportConstructor = [Runtime.InteropServices.DllImportAttribute].GetConstructor(@([String]))
    $SetLastError = [Runtime.InteropServices.DllImportAttribute].GetField('SetLastError')
    $SetLastErrorCustomAttribute = New-Object Reflection.Emit.CustomAttributeBuilder($DllImportConstructor, @('kernel32.dll'), [Reflection.FieldInfo[]]@($SetLastError), @($true))
    $PInvokeMethod.SetCustomAttribute($SetLastErrorCustomAttribute)
    $Kernel32 = $TypeBuilder.CreateType()

    $Max = 65536
    $StringBuilder = New-Object System.Text.StringBuilder($Max)

    Get-WmiObject Win32_Volume | ? { $_.DriveLetter } | % {
        $ReturnLength = $Kernel32::QueryDosDevice($_.DriveLetter, $StringBuilder, $Max)

        if ($ReturnLength)
        {
            $DriveMapping = @{
                DriveLetter = $_.DriveLetter
                DevicePath = $StringBuilder.ToString()
            }

            New-Object PSObject -Property $DriveMapping
        }
    }
}

Не уверен, что это именно тот ответ, который вы ищете, но не похоже, что эти данные вообще очень хорошо перечислены в Windows из того, что я вижу из командной строки. Я попытался вытащить данные из diskpart, чтобы показать информацию, но не указал имя устройства. Кстати, похоже, что в 2012 году было добавлено больше дисковых команд, таких как get-volume, get-disk и get-physicaldisk, но это не поможет вам с 2008 годом.

Несколько сторонних утилит сделают это

  1. http://www.chrysocome.net/dd просто нужно запустить "dd --list"
  2. http://nirsoft.net/utils/drive_letter_view.html

Обе утилиты имеют параметры командной строки, поэтому у них должна быть возможность использовать их со сценариями PowerShell.