Public/System/Get-AllDriveInfo.ps1
function Get-AllDriveInfo { $signature = @' [DllImport("kernel32.dll", SetLastError=true)] [return: MarshalAs(UnmanagedType.Bool)] public static extern bool GetVolumePathNamesForVolumeNameW([MarshalAs(UnmanagedType.LPWStr)] string lpszVolumeName, [MarshalAs(UnmanagedType.LPWStr)] [Out] StringBuilder lpszVolumeNamePaths, uint cchBuferLength, ref UInt32 lpcchReturnLength); [DllImport("kernel32.dll", SetLastError = true)] public static extern IntPtr FindFirstVolume([Out] StringBuilder lpszVolumeName, uint cchBufferLength); [DllImport("kernel32.dll", SetLastError = true)] public static extern bool FindNextVolume(IntPtr hFindVolume, [Out] StringBuilder lpszVolumeName, uint cchBufferLength); [DllImport("kernel32.dll", SetLastError = true)] public static extern uint QueryDosDevice(string lpDeviceName, StringBuilder lpTargetPath, int ucchMax); '@; if (-not ([System.Management.Automation.PSTypeName]'PInvoke.Win32Utils').Type) { Add-Type -MemberDefinition $signature -Name Win32Utils -Namespace PInvoke -Using PInvoke, System.Text; } [UInt32] $lpcchReturnLength = 0; [UInt32] $Max = 65535 $sbVolumeName = New-Object System.Text.StringBuilder($Max, $Max) $sbPathName = New-Object System.Text.StringBuilder($Max, $Max) $sbMountPoint = New-Object System.Text.StringBuilder($Max, $Max) [IntPtr] $volumeHandle = [PInvoke.Win32Utils]::FindFirstVolume($sbVolumeName, $Max) do { $volume = $sbVolumeName.toString() $unused = [PInvoke.Win32Utils]::GetVolumePathNamesForVolumeNameW($volume, $sbMountPoint, $Max, [Ref] $lpcchReturnLength); $ReturnLength = [PInvoke.Win32Utils]::QueryDosDevice($volume.Substring(4, $volume.Length - 1 - 4), $sbPathName, [UInt32] $Max); if ($ReturnLength) { $DriveLetter = ($sbMountPoint.toString() -replace ':\\','') $VolumeData = Get-Volume -UniqueId $volume | Select-Object * $PartitionData = Get-Partition -DriveLetter $DriveLetter | Select-Object * try { $DiskData = Get-Disk -Number $PartitionData.DiskNumber | Select-Object * } catch { $DiskData = $null } [PSCustomObject]@{ DriveLetter = $DriveLetter DevicePath = $sbPathName.ToString() DiskNumber = $PartitionData.DiskNumber FriendlyName = $DiskData.FriendlyName Model = $DiskData.Model SerialNumber = $DiskData.SerialNumber NumberOfPartitions = $DiskData.NumberOfPartitions HealthStatus = $VolumeData.HealthStatus PartitionStyle = $DiskData.PartitionStyle BusType = $DiskData.BusType FirmwareVersion = $DiskData.FirmwareVersion DriveType = $VolumeData.DriveType FileSystem = $VolumeData.FileSystemType LogicalSectorSize = $DiskData.LogicalSectorSize AllocationUnitSize = $VolumeData.AllocationUnitSize FriendlyLabel = $VolumeData.FileSystemLabel Capacity = Format-Bytes -Bytes $VolumeData.Size RemainingSpace = Format-Bytes -Bytes $VolumeData.SizeRemaining VolumeName = $volume GptType = $PartitionData.GptType GUID = $PartitionData.Guid IsActive = $PartitionData.IsActive IsBoot = $PartitionData.IsBoot IsDAX = $PartitionData.IsDAX IsHidden = $PartitionData.IsHidden IsOffline = $PartitionData.IsOffline IsReadOnly = $PartitionData.IsReadOnly IsShadowCopy = $PartitionData.IsShadowCopy IsSystem = $PartitionData.IsSystem MbrType = $PartitionData.MbrType Offset = $PartitionData.Offset } } else { Write-Output "No mountpoint found for: " + $volume } } while ([PInvoke.Win32Utils]::FindNextVolume([IntPtr] $volumeHandle, $sbVolumeName, $Max)); } |