private/Get-OSDeployVolumeUSB.ps1
|
function Get-OSDeployVolumeUSB { <# .SYNOPSIS Gets volumes hosted on USB-connected disks .DESCRIPTION Uses Get-OSDeployDisk to find online USB disks, queries local MSFT_Partition and MSFT_Volume instances, and matches volumes to USB partition access paths. Returned rows contain selected identity, filesystem, capacity, and health properties. Provider failures write a nonterminating error and return no objects. .PARAMETER FileSystemLabel Filters results to volumes whose FileSystemLabel exactly equals the supplied value. When omitted, all matched USB volumes are returned. .EXAMPLE PS> Get-OSDeployVolumeUSB -FileSystemLabel 'OSDEPLOY' Returns USB volumes whose filesystem label is OSDEPLOY. .INPUTS None. This function does not accept pipeline input. .OUTPUTS System.Management.Automation.PSCustomObject. Returns zero or more selected volume rows with DriveLetter, FileSystemLabel, FileSystem, SizeGB, SizeRemainingGB, SizeRemainingMB, DriveType, OperationalStatus, HealthStatus, and UniqueId. .NOTES Author: David Segura Company: Recast Software Version: 1.0.0 Date: 2026-08-28 Dependencies: Module Functions: Get-OSDeployDisk PowerShell Modules: Storage Windows Features: Windows Storage Management provider DotNet Classes: Microsoft.Management.Infrastructure.CimSession, System.Management.Automation.PSCustomObject #> [CmdletBinding()] param ( [string]$FileSystemLabel ) # Get-OSDeployDisk filters out offline disks and card readers with no media $UsbDisks = Get-OSDeployDisk -BusType USB if (-not $UsbDisks) { return } $StorageNamespace = 'ROOT/Microsoft/Windows/Storage' $CimSession = $null try { # Storage supplies the MSFT_Partition and MSFT_Volume type data used by downstream Storage cmdlets. Import-Module Storage -ErrorAction Stop $CimSession = [Microsoft.Management.Infrastructure.CimSession]::Create($env:COMPUTERNAME) $Partitions = @($CimSession.QueryInstances($StorageNamespace, 'WQL', 'SELECT * FROM MSFT_Partition')) $VolumesRaw = @($CimSession.QueryInstances($StorageNamespace, 'WQL', 'SELECT * FROM MSFT_Volume')) # Collect all access paths from USB partitions; skip partitions with no mount point $UsbAccessPaths = $Partitions | Where-Object { $_.DiskNumber -in $UsbDisks.Number -and $null -ne $_.AccessPaths } | Select-Object -ExpandProperty AccessPaths if (-not $UsbAccessPaths) { return } # Match volumes by GUID path, which is present in both MSFT_Volume.Path and MSFT_Partition.AccessPaths $Volumes = $VolumesRaw | Sort-Object DriveLetter | Where-Object { $_.Path -in $UsbAccessPaths } | Select-Object DriveLetter, FileSystemLabel, FileSystem, @{Name = 'SizeGB'; Expression = { [int]($_.Size / 1GB) }}, @{Name = 'SizeRemainingGB'; Expression = { [int]($_.SizeRemaining / 1GB) }}, @{Name = 'SizeRemainingMB'; Expression = { [int]($_.SizeRemaining / 1MB) }}, DriveType, OperationalStatus, HealthStatus, UniqueId if ($PSBoundParameters.ContainsKey('FileSystemLabel')) { return ($Volumes | Where-Object { $_.FileSystemLabel -eq $FileSystemLabel }) } return $Volumes } catch { Write-Error -Message "[$(Get-Date -Format s)] [$($MyInvocation.MyCommand.Name)] Unable to enumerate USB volumes by using the Storage CIM provider. $($_.Exception.Message)" -ErrorAction Continue return } finally { if ($null -ne $CimSession) { $CimSession.Dispose() } } } |