如何根据事件日志报告的卷名识别 WMI 中的卷?

如何根据事件日志报告的卷名识别 WMI 中的卷?

我有一台 Windows 2008R2 服务器,它报告以下错误:

磁盘上的文件系统结构已损坏且无法使用。请在卷上运行 chkdsk 实用程序\设备\硬盘卷2

使用 Powershell 和 WMI,查询时如何识别这是哪个卷Win32_Volume

例如如果我这样做:

Get-WmiObject Win32_Volume

我获得了服务器上所有卷的列表,但是没有任何Win32_Volume类属性使用(看起来是)这个“友好”名称 - \Device\HarddiskVolume2。我可以看到有一个DeviceID属性返回这样的值:

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

还有一个Name属性,但那只是分配给卷的驱动器号。其他属性的值都与事件日志中报告的值不太相似。

我知道我可以解析输出fltmc volumesDISKPART获取此信息,但必须有一种方法可以使用 PowerShell 脚本中的 WMI 获取此信息。

我也查看了Win32_DiskDriveWin32_DiskPartitionWin32_LogicalDisk类,但没有提及类似的属性值\Device\HarddiskVolume2

答案1

看一下这段代码: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
        }
    }
}

答案2

不确定这是否是您要找的答案,但从我在命令行中看到的情况来看,这些数据似乎在 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 脚本一起使用。

相关内容