Public/Get-sqmDiskPartitionMap.ps1
|
<# .SYNOPSIS Zeigt die Zuordnung physischer Datentraeger zu logischen Laufwerksbuchstaben. .DESCRIPTION Ermittelt fuer jeden physischen Datentraeger (Win32_DiskDrive) alle zugeordneten logischen Laufwerksbuchstaben via CIM-Assoziationen: Win32_DiskDrive └─ Win32_DiskDriveToDiskPartition └─ Win32_DiskPartition └─ Win32_LogicalDiskToPartition └─ Win32_LogicalDisk (Laufwerksbuchstabe) Ob eine physische Disk "geteilt" ist (mehrere Laufwerksbuchstaben auf einer Disk), wird im Property IsShared angezeigt. Das ist besonders relevant, wenn eine Disk partitioniert wurde und unterschiedliche Laufwerksbuchstaben auf derselben physischen Disk liegen - in diesem Fall sind SerienNummern nicht eindeutig einem einzelnen Laufwerk zuzuordnen. Unterstuetzt lokale und Remote-Abfragen via CIM (DCOM/WMI, kein WinRM noetig). .PARAMETER ComputerName Zielrechner (ein oder mehrere). Standard: lokaler Computer. Aliase: SqlInstance, ServerName .PARAMETER NoClipboard Ergebnis NICHT in die Zwischenablage kopieren. .OUTPUTS PSCustomObject mit folgenden Properties je physischer Disk: - ComputerName : Zielrechner - DiskIndex : Disk-Nummer (0, 1, 2 ...) - Model : Disk-Modell - SerialNumber : Seriennummer der physischen Disk - SizeGB : Gesamtgroesse in GB - PartitionCount : Anzahl der Partitionen auf dieser Disk - DriveLetters : Kommagetrennte Liste der Laufwerksbuchstaben (z.B. "C:, D:") - IsShared : True wenn mehr als ein Laufwerksbuchstabe auf dieser Disk liegt - MediaType : Medientyp (HDD, SSD, ...) - InterfaceType : Schnittstellentyp (SCSI, USB, ...) .EXAMPLE Get-sqmDiskPartitionMap Zeigt die Partitions-Zuordnung des lokalen Rechners. .EXAMPLE Get-sqmDiskPartitionMap -ComputerName "SQL01" Remote-Abfrage gegen SQL01 via CIM/DCOM. .EXAMPLE Get-sqmDiskPartitionMap | Where-Object IsShared | Select-Object DiskIndex, DriveLetters Zeigt nur die geteilten Disks (mehrere Laufwerksbuchstaben). .EXAMPLE "SQL01","SQL02" | Get-sqmDiskPartitionMap Partitions-Map mehrerer Server per Pipeline. .NOTES Author: sqmSQLTool Prerequisites: CIM-Zugriff (DCOM/WMI), keine PowerShell Remoting erforderlich Clipboard: Ergebnis wird als Tabelle in die Zwischenablage kopiert (je Computer) #> function Get-sqmDiskPartitionMap { [CmdletBinding()] [OutputType([PSCustomObject])] param ( [Parameter(Mandatory = $false, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, Position = 0)] [Alias('SqlInstance', 'ServerName')] [string[]]$ComputerName = @($env:COMPUTERNAME), [Parameter(Mandatory = $false)] [switch]$NoClipboard ) begin { $functionName = $MyInvocation.MyCommand.Name $allResults = [System.Collections.Generic.List[PSCustomObject]]::new() } process { foreach ($computer in $ComputerName) { if ([string]::IsNullOrWhiteSpace($computer)) { $computer = $env:COMPUTERNAME } $isLocal = ($computer -eq $env:COMPUTERNAME -or $computer -eq '.' -or $computer -ieq 'localhost') $cimParams = if ($isLocal) { @{} } else { @{ ComputerName = $computer } } Invoke-sqmLogging -Message "[$computer] Ermittle Disk-Partitions-Map..." -FunctionName $functionName -Level 'INFO' try { $physDisks = @(Get-CimInstance -ClassName Win32_DiskDrive @cimParams -ErrorAction Stop) $disk2Part = @(Get-CimInstance -ClassName Win32_DiskDriveToDiskPartition @cimParams -ErrorAction Stop) $part2Log = @(Get-CimInstance -ClassName Win32_LogicalDiskToPartition @cimParams -ErrorAction Stop) # Lookup: Partition DeviceID → Laufwerksbuchstaben $partToLetters = @{} foreach ($assoc in $part2Log) { $partId = $assoc.Antecedent.DeviceID $letter = $assoc.Dependent.DeviceID if (-not $partToLetters.ContainsKey($partId)) { $partToLetters[$partId] = [System.Collections.Generic.List[string]]::new() } $partToLetters[$partId].Add($letter) } # Lookup: Disk DeviceID → Laufwerksbuchstaben (ueber Partition-Zwischenschicht) $diskToLetters = @{} foreach ($assoc in $disk2Part) { $diskId = $assoc.Antecedent.DeviceID $partId = $assoc.Dependent.DeviceID if (-not $diskToLetters.ContainsKey($diskId)) { $diskToLetters[$diskId] = [System.Collections.Generic.List[string]]::new() } if ($partToLetters.ContainsKey($partId)) { foreach ($letter in $partToLetters[$partId]) { $diskToLetters[$diskId].Add($letter) } } } $computerResults = [System.Collections.Generic.List[PSCustomObject]]::new() foreach ($disk in ($physDisks | Sort-Object Index)) { $diskId = $disk.DeviceID $letters = if ($diskToLetters.ContainsKey($diskId)) { @($diskToLetters[$diskId] | Sort-Object) } else { @() } $sizeGB = if ($disk.Size) { [math]::Round([double]$disk.Size / 1GB, 2) } else { 0 } $serial = if (-not [string]::IsNullOrWhiteSpace($disk.SerialNumber)) { $disk.SerialNumber.Trim() } else { 'N/A' } $model = if (-not [string]::IsNullOrWhiteSpace($disk.Model)) { $disk.Model.Trim() } else { 'N/A' } $partCount = if ($disk.Partitions) { [int]$disk.Partitions } else { 0 } $isShared = $letters.Count -gt 1 $letterStr = if ($letters.Count -gt 0) { $letters -join ', ' } else { '(keine)' } $diskIndex = if ($null -ne $disk.Index) { [int]$disk.Index } else { -1 } $obj = [PSCustomObject]@{ ComputerName = $computer DiskIndex = $diskIndex Model = $model SerialNumber = $serial SizeGB = $sizeGB PartitionCount = $partCount DriveLetters = $letterStr IsShared = $isShared MediaType = if ($disk.MediaType) { [string]$disk.MediaType } else { '' } InterfaceType = if ($disk.InterfaceType){ [string]$disk.InterfaceType } else { '' } } $tag = if ($isShared) { ' [GETEILT]' } else { '' } Invoke-sqmLogging -Message "[$computer] Disk $diskIndex : $model | $sizeGB GB | $partCount Partitionen | Laufwerke: $letterStr$tag" ` -FunctionName $functionName -Level 'INFO' $computerResults.Add($obj) $allResults.Add($obj) $obj } if (-not $NoClipboard -and $computerResults.Count -gt 0) { try { $clipText = $computerResults | Format-Table -AutoSize | Out-String Set-Clipboard -Value $clipText.Trim() Invoke-sqmLogging -Message "[$computer] Ergebnis in Zwischenablage kopiert." -FunctionName $functionName -Level 'INFO' } catch { Invoke-sqmLogging -Message "[$computer] Zwischenablage konnte nicht beschrieben werden: $($_.Exception.Message)" -FunctionName $functionName -Level 'WARNING' } } } catch { Invoke-sqmLogging -Message "[$computer] Fehler: $($_.Exception.Message)" -FunctionName $functionName -Level 'ERROR' Write-Error "Fehler beim Ermitteln der Partitions-Map fuer '$computer': $($_.Exception.Message)" } } } end { } } |