private/Get-OSDeployDisk.ps1
|
function Get-OSDeployDisk { <# .SYNOPSIS Gets online physical disks from the Windows Storage provider .DESCRIPTION Queries MSFT_Disk and MSFT_PhysicalDisk through a local CIM session, excludes offline disks and devices with no media, and enriches each disk with MediaType and SizeGB properties. Optional parameters filter the results. Provider failures write a nonterminating error and return no disk objects. .PARAMETER Number Filters by disk number. The aliases are Disk and DiskNumber. This filter is applied whenever the parameter is explicitly bound, including when its value is zero. .PARAMETER BootFromDisk Filters by the BootFromDisk Boolean property when explicitly bound. .PARAMETER IsBoot Filters by the IsBoot Boolean property when explicitly bound. .PARAMETER IsReadOnly Filters by the IsReadOnly Boolean property when explicitly bound. .PARAMETER IsSystem Filters by the IsSystem Boolean property when explicitly bound. .PARAMETER BusType Includes disks whose BusType is one of the supplied validated Windows Storage bus type names. .PARAMETER BusTypeNot Excludes disks whose BusType is one of the supplied validated Windows Storage bus type names. .PARAMETER MediaType Includes disks whose enriched MediaType is SSD, HDD, SCM, or Unspecified. .PARAMETER MediaTypeNot Excludes disks whose enriched MediaType is SSD, HDD, SCM, or Unspecified. .PARAMETER PartitionStyle Includes disks whose PartitionStyle is GPT, MBR, or RAW. .PARAMETER PartitionStyleNot Excludes disks whose PartitionStyle is GPT, MBR, or RAW. .EXAMPLE PS> Get-OSDeployDisk -BusType 'USB' -IsReadOnly $false Returns online USB disks that are not read-only. .INPUTS None. This function does not accept pipeline input. .OUTPUTS Microsoft.Management.Infrastructure.CimInstance. Returns zero or more MSFT_Disk instances enriched with MediaType and SizeGB note properties. .NOTES Author: David Segura Company: Recast Software Version: 1.0.0 Date: 2026-08-28 Dependencies: PowerShell Modules: Storage Windows Features: Windows Storage Management provider DotNet Classes: Microsoft.Management.Infrastructure.CimInstance, Microsoft.Management.Infrastructure.CimSession #> [CmdletBinding()] [OutputType([Microsoft.Management.Infrastructure.CimInstance])] param ( [Alias('Disk','DiskNumber')] [uint32]$Number, [bool]$BootFromDisk, [bool]$IsBoot, [bool]$IsReadOnly, [bool]$IsSystem, [ValidateSet('1394','ATA','ATAPI','Fibre Channel','File Backed Virtual','iSCSI','MMC','MAX','Microsoft Reserved','NVMe','RAID','SAS','SATA','SCSI','SD','SSA','Storage Spaces','USB','Virtual')] [string[]]$BusType, [ValidateSet('1394','ATA','ATAPI','Fibre Channel','File Backed Virtual','iSCSI','MMC','MAX','Microsoft Reserved','NVMe','RAID','SAS','SATA','SCSI','SD','SSA','Storage Spaces','USB','Virtual')] [string[]]$BusTypeNot, [ValidateSet('SSD','HDD','SCM','Unspecified')] [string[]]$MediaType, [ValidateSet('SSD','HDD','SCM','Unspecified')] [string[]]$MediaTypeNot, [ValidateSet('GPT','MBR','RAW')] [string[]]$PartitionStyle, [ValidateSet('GPT','MBR','RAW')] [string[]]$PartitionStyleNot ) $StorageNamespace = 'ROOT/Microsoft/Windows/Storage' $CimSession = $null try { # Storage supplies the MSFT_Disk type data used by downstream Storage cmdlets; enumeration below uses the .NET CIM API. Import-Module Storage -ErrorAction Stop $CimSession = [Microsoft.Management.Infrastructure.CimSession]::Create($env:COMPUTERNAME) $GetDisk = @($CimSession.QueryInstances($StorageNamespace, 'WQL', 'SELECT * FROM MSFT_Disk')) | Sort-Object Number $GetPhysicalDisk = @($CimSession.QueryInstances($StorageNamespace, 'WQL', 'SELECT * FROM MSFT_PhysicalDisk')) | Sort-Object DeviceId } catch { Write-Error -Message "[$(Get-Date -Format s)] [$($MyInvocation.MyCommand.Name)] Unable to enumerate disks by using the Storage CIM provider. $($_.Exception.Message)" -ErrorAction Continue return } finally { if ($null -ne $CimSession) { $CimSession.Dispose() } } $PhysicalDiskByDeviceId = @{} foreach ($PhysicalDisk in $GetPhysicalDisk) { $PhysicalDiskByDeviceId[[string]$PhysicalDisk.DeviceId] = $PhysicalDisk } foreach ($Disk in $GetDisk) { # MSFT_Disk does not expose reliable media type on every device, so preserve the existing DeviceId-to-Number enrichment. if ($PhysicalDiskByDeviceId.ContainsKey([string]$Disk.Number)) { $Disk | Add-Member -NotePropertyName 'MediaType' -NotePropertyValue $PhysicalDiskByDeviceId[[string]$Disk.Number].MediaType -Force } $Disk | Add-Member -NotePropertyName 'SizeGB' -NotePropertyValue ([int]($Disk.Size / 1GB)) -Force } $GetDisk = $GetDisk | Where-Object {$_.IsOffline -eq $false} $GetDisk = $GetDisk | Where-Object {$_.OperationalStatus -ne 'No Media'} if ($PSBoundParameters.ContainsKey('Number')) { $GetDisk = $GetDisk | Where-Object {$_.Number -eq $Number} } if ($PSBoundParameters.ContainsKey('BootFromDisk')) {$GetDisk = $GetDisk | Where-Object {$_.BootFromDisk -eq $BootFromDisk}} if ($PSBoundParameters.ContainsKey('IsBoot')) {$GetDisk = $GetDisk | Where-Object {$_.IsBoot -eq $IsBoot}} if ($PSBoundParameters.ContainsKey('IsReadOnly')) {$GetDisk = $GetDisk | Where-Object {$_.IsReadOnly -eq $IsReadOnly}} if ($PSBoundParameters.ContainsKey('IsSystem')) {$GetDisk = $GetDisk | Where-Object {$_.IsSystem -eq $IsSystem}} if ($BusType) {$GetDisk = $GetDisk | Where-Object {$_.BusType -in $BusType}} if ($BusTypeNot) {$GetDisk = $GetDisk | Where-Object {$_.BusType -notin $BusTypeNot}} if ($MediaType) {$GetDisk = $GetDisk | Where-Object {$_.MediaType -in $MediaType}} if ($MediaTypeNot) {$GetDisk = $GetDisk | Where-Object {$_.MediaType -notin $MediaTypeNot}} if ($PartitionStyle) {$GetDisk = $GetDisk | Where-Object {$_.PartitionStyle -in $PartitionStyle}} if ($PartitionStyleNot) {$GetDisk = $GetDisk | Where-Object {$_.PartitionStyle -notin $PartitionStyleNot}} return $GetDisk } |