private/core-device/Get-OSDCoreCacheContent.ps1
|
function Get-OSDCoreCacheContent { <# .SYNOPSIS Returns cached OSDCloud content found on local file system drives. .DESCRIPTION Enumerates mounted file system drives and discovers OSDCloud cache content. Returns objects with Type, Name, FullName, SizeMB, DriveRoot, VolumeLabel, VolumeUniqueId, and USB properties. Exports the returned object to $env:Temp\OSDCoreCacheContent.xml each time the function runs. If Type is omitted, retur ns all supported cache content types. Type values: - ESD: All .esd files under '<DriveLetter>:\OSDCloud\OS' recursively. - ISO: All .iso files under '<DriveLetter>:\OSDCloud\ISO' recursively. - DriverPacks: All .cab, .exe, .msi, and .zip files under '<DriveLetter>:\OSDCloud\DriverPacks' recursively. - Drivers: Immediate folders under '<DriveLetter>:\OSDCloud\Drivers' that contain at least one .inf file in any child folder. - Profiles: Immediate folders under '<DriveLetter>:\OSDCloud\Profiles'. - WIM: All .wim files under '<DriveLetter>:\OSDCloud\WIM' recursively. - *: Includes all supported Type values. .PARAMETER Type Optional cache content selector. Supports one or more values. Use '*' to return all supported cache content types. .PARAMETER Include Optional list of drive letters to include when searching for OSDCloud cache content. Accepts values such as 'C', 'D:', or 'E:\'. When omitted, all mounted file system drive letters are considered. .PARAMETER Exclude Optional list of drive letters to exclude when searching for OSDCloud cache content. Accepts values such as 'C', 'D:', or 'E:\'. Excluded drives are skipped even when they are also present in Include. .OUTPUTS System.Object[]. Objects with Type, Name, FullName, SizeMB, DriveRoot, VolumeLabel, VolumeUniqueId, and USB. .EXAMPLE Get-OSDCoreCacheContent Returns all supported cache content types. .EXAMPLE Get-OSDCoreCacheContent -Type ESD Returns all .esd files under each discovered cache OS folder. .EXAMPLE Get-OSDCoreCacheContent -Type ESD,DriverPacks Returns all .esd files and driver pack files from each discovered cache. .EXAMPLE Get-OSDCoreCacheContent -Type * Returns all supported cache content types. .EXAMPLE Get-OSDCoreCacheContent -Include C,D -Exclude D Searches only drive C for supported cache content types. #> [CmdletBinding()] [OutputType([System.Object[]])] param ( [Parameter()] [ValidateSet('ESD', 'ISO', 'DriverPacks', 'Drivers', 'Profiles', 'WIM', '*')] [string[]]$Type, [Parameter()] [ValidatePattern('^[a-zA-Z](:\\)?$|^[a-zA-Z]$')] [string[]]$Include, [Parameter()] [ValidatePattern('^[a-zA-Z](:\\)?$|^[a-zA-Z]$')] [string[]]$Exclude ) $Error.Clear() Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Start" # Write-Host -ForegroundColor DarkGray "[$(Get-Date -format s)] OSDCoreCacheContent is updating" function Get-FileOnlySizeMB { param( [Parameter(Mandatory)] [string]$Path ) if (-not (Test-Path -LiteralPath $Path)) { return 0 } $item = Get-Item -LiteralPath $Path -ErrorAction SilentlyContinue if (-not $item) { return 0 } if ($item.PSIsContainer) { $totalBytes = (Get-ChildItem -LiteralPath $Path -Recurse -File -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum if ($null -eq $totalBytes) { $totalBytes = 0 } return [math]::Round(($totalBytes / 1MB), 2) } return [math]::Round((([int64]$item.Length) / 1MB), 2) } function Get-DriveVolumeMetadata { param( [Parameter(Mandatory)] [string]$DriveRoot ) $volume = $null $usb = $false if ($DriveRoot -match '^[A-Z]:\\$') { try { $driveLetter = $DriveRoot.Substring(0, 1) $volume = Get-Volume -DriveLetter $driveLetter -ErrorAction Stop $usb = [bool](Get-Disk -ErrorAction SilentlyContinue | Where-Object { $_.BusType -eq 'USB' } | Get-Partition -ErrorAction SilentlyContinue | Where-Object { $_.DriveLetter -eq $driveLetter }) } catch { $volume = $null $usb = $false } } return [PSCustomObject]@{ DriveRoot = $DriveRoot VolumeLabel = if ($volume) { [string]$volume.FileSystemLabel } else { $null } VolumeUniqueId = if ($volume) { [string]$volume.UniqueId } else { $null } USB = [bool]$usb } } function New-CacheResultObject { param( [Parameter(Mandatory)] [string]$ResultType, [Parameter(Mandatory)] [string]$ResultFullName, [Parameter(Mandatory)] $VolumeMetadata ) [PSCustomObject]@{ Name = Split-Path -Path $ResultFullName -Leaf FullName = $ResultFullName SizeMB = Get-FileOnlySizeMB -Path $ResultFullName Type = $ResultType USB = [bool]$VolumeMetadata.USB DriveRoot = [string]$VolumeMetadata.DriveRoot VolumeLabel = [string]$VolumeMetadata.VolumeLabel VolumeUniqueId = [string]$VolumeMetadata.VolumeUniqueId } } function ConvertTo-DriveLetterList { param( [Parameter()] [string[]]$DriveLetters ) $normalized = foreach ($driveLetter in $DriveLetters) { if ([string]::IsNullOrWhiteSpace($driveLetter)) { continue } $value = $driveLetter.Trim().TrimEnd('\\') if ($value.Length -lt 1) { continue } $letter = $value.Substring(0, 1).ToUpperInvariant() if ($letter -match '^[A-Z]$') { $letter } } @($normalized | Sort-Object -Unique) } $includedDriveLetters = ConvertTo-DriveLetterList -DriveLetters $Include $excludedDriveLetters = ConvertTo-DriveLetterList -DriveLetters $Exclude $cachePaths = Get-PSDrive -PSProvider FileSystem | Where-Object { $_.Root -match '^[A-Z]:\\$' } | Where-Object { $driveLetter = ([string]$_.Root).Substring(0, 1).ToUpperInvariant() (($includedDriveLetters.Count -eq 0) -or ($driveLetter -in $includedDriveLetters)) -and ($driveLetter -notin $excludedDriveLetters) } | ForEach-Object { $driveRoot = [string]$_.Root $osdCloudPath = Join-Path -Path $driveRoot -ChildPath 'OSDCloud' if (Test-Path -LiteralPath $osdCloudPath) { $volumeMetadata = Get-DriveVolumeMetadata -DriveRoot $driveRoot [PSCustomObject]@{ CachePath = $osdCloudPath VolumeMetadata = $volumeMetadata } } } $cachePaths = @($cachePaths | Sort-Object -Property CachePath -Unique) $selectedTypes = if ($PSBoundParameters.ContainsKey('Type')) { @($Type | Sort-Object -Unique) } else { @('ESD', 'ISO', 'DriverPacks', 'Drivers', 'Profiles', 'WIM') } if ($selectedTypes -contains '*') { $selectedTypes = @('ESD', 'ISO', 'DriverPacks', 'Drivers', 'Profiles', 'WIM') } $result = foreach ($selectedType in $selectedTypes) { switch ($selectedType) { 'ESD' { foreach ($cacheEntry in $cachePaths) { $osPath = Join-Path -Path $cacheEntry.CachePath -ChildPath 'OS' if (Test-Path -LiteralPath $osPath) { Get-ChildItem -LiteralPath $osPath -Recurse -File -Filter '*.esd' -ErrorAction SilentlyContinue | ForEach-Object { New-CacheResultObject -ResultType 'ESD' -ResultFullName ([string]$_.FullName) -VolumeMetadata $cacheEntry.VolumeMetadata } } } break } 'ISO' { foreach ($cacheEntry in $cachePaths) { $isoPath = Join-Path -Path $cacheEntry.CachePath -ChildPath 'ISO' if (Test-Path -LiteralPath $isoPath) { Get-ChildItem -LiteralPath $isoPath -Recurse -File -Filter '*.iso' -ErrorAction SilentlyContinue | ForEach-Object { New-CacheResultObject -ResultType 'ISO' -ResultFullName ([string]$_.FullName) -VolumeMetadata $cacheEntry.VolumeMetadata } } } break } 'DriverPacks' { foreach ($cacheEntry in $cachePaths) { $driverPacksPath = Join-Path -Path $cacheEntry.CachePath -ChildPath 'DriverPacks' if (Test-Path -LiteralPath $driverPacksPath) { Get-ChildItem -LiteralPath $driverPacksPath -Recurse -File -ErrorAction SilentlyContinue | Where-Object { $_.Extension -in @('.cab', '.exe', '.msi', '.zip') } | ForEach-Object { New-CacheResultObject -ResultType 'DriverPacks' -ResultFullName ([string]$_.FullName) -VolumeMetadata $cacheEntry.VolumeMetadata } } } break } 'Drivers' { foreach ($cacheEntry in $cachePaths) { $driversPath = Join-Path -Path $cacheEntry.CachePath -ChildPath 'Drivers' if (Test-Path -LiteralPath $driversPath) { Get-ChildItem -LiteralPath $driversPath -Directory -ErrorAction SilentlyContinue | Where-Object { @(Get-ChildItem -LiteralPath $_.FullName -Recurse -File -Filter '*.inf' -ErrorAction SilentlyContinue).Count -gt 0 } | ForEach-Object { New-CacheResultObject -ResultType 'Drivers' -ResultFullName ([string]$_.FullName) -VolumeMetadata $cacheEntry.VolumeMetadata } } } break } 'Profiles' { foreach ($cacheEntry in $cachePaths) { $profilesPath = Join-Path -Path $cacheEntry.CachePath -ChildPath 'Profiles' if (Test-Path -LiteralPath $profilesPath) { Get-ChildItem -LiteralPath $profilesPath -Directory -ErrorAction SilentlyContinue | ForEach-Object { New-CacheResultObject -ResultType 'Profiles' -ResultFullName ([string]$_.FullName) -VolumeMetadata $cacheEntry.VolumeMetadata } } } break } 'WIM' { foreach ($cacheEntry in $cachePaths) { $wimPath = Join-Path -Path $cacheEntry.CachePath -ChildPath 'WIM' if (Test-Path -LiteralPath $wimPath) { Get-ChildItem -LiteralPath $wimPath -Recurse -File -Filter '*.wim' -ErrorAction SilentlyContinue | ForEach-Object { New-CacheResultObject -ResultType 'WIM' -ResultFullName ([string]$_.FullName) -VolumeMetadata $cacheEntry.VolumeMetadata } } } break } } } $result = @($result | Sort-Object -Property FullName, Type -Unique | Sort-Object -Property FullName) $result | Export-Clixml -Path (Join-Path -Path $env:Temp -ChildPath 'OSDCoreCacheContent.xml') -Force Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] Found $($result.Count) path(s)" Write-Verbose "[$(Get-Date -format s)] [$($MyInvocation.MyCommand.Name)] End" return $result } |