Como identifico um volume no WMI de um nome de volume informado no log de eventos?

4

Eu tenho um servidor Windows 2008R2 que está relatando o seguinte erro:

The file system structure on the disk is corrupt and unusable. Please run the chkdsk utility on the volume \Device\HarddiskVolume2.

Usando o Powershell e o WMI, como identifico o volume que é quando se consulta Win32_Volume .

Por exemplo, se eu fizer isso:

Get-WmiObject Win32_Volume

Eu obtenho uma lista de todos os volumes no servidor, no entanto, nenhuma das propriedades da classe Win32_Volume usa (o que parece ser) esse nome "amigável" - \Device\HarddiskVolume2 . Eu posso ver que há uma propriedade DeviceID que retorna um valor como este:

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

Há também uma propriedade Name , mas é apenas a letra da unidade atribuída ao volume. Nenhuma das outras propriedades tem um valor remotamente parecido com o que é relatado no log de eventos.

Sei que posso analisar a saída de fltmc volumes ou DISKPART para obter essas informações, mas deve haver uma maneira de obter isso usando o WMI em um script do PowerShell.

Também observei as classes Win32_DiskDrive , Win32_DiskPartition e Win32_LogicalDisk , mas não há menção aos valores de propriedade que se assemelham a \Device\HarddiskVolume2 .

    
por Kev 31.01.2014 / 18:57

2 respostas

3

Dê uma olhada neste código: link parece fazer as conversões que você precisa para ver o que você quer, você pode ser capaz de ajustá-lo para atender às suas necessidades, deixe-me saber se você precisar de ajuda com isso, mas eu acho que você pode descobrir por conta própria.

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
        }
    }
}
    
por 02.02.2014 / 18:55
0

Não tenho certeza se esse é o tipo de resposta que você está procurando, mas não parece que esses dados estão listados muito bem no Windows, pelo que consigo ver na linha de comando. Tentei extrair os dados do diskpart para mostrar as informações, mas não listei o nome do dispositivo. Em uma nota lateral, parece que mais comandos de disco foram adicionados a 2012 como get-volume, get-disk e get-physicaldisk, mas isso não ajuda em 2008.

Alguns utilitários de terceiros farão isso

  1. O link só precisa executar "dd -list"
  2. link

Ambos os utilitários têm opções de linha de comando, portanto devem ser capazes de usá-los com scripts do powershell.

    
por 31.01.2014 / 22:05