Public/Export-WindowsDeviceLinkCsv.ps1
|
function Export-WindowsDeviceLinkCsv { [CmdletBinding()] param( [Parameter(Mandatory, ValueFromPipeline)] [PSTypeName('Windows.DeviceLink.Information')] [psobject]$InputObject, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$DestinationPath, [ValidateRange(5, 600)] [int]$TimeoutSeconds = 120 ) process { try { $resolvedDestination = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($DestinationPath) } catch { throw "Invalid destination path '$DestinationPath': $($_.Exception.Message)" } if (Test-Path -LiteralPath $resolvedDestination) { $destinationItem = Get-Item -LiteralPath $resolvedDestination -ErrorAction Stop if (-not $destinationItem.PSIsContainer) { throw "Destination path '$DestinationPath' exists but is not a directory." } $destinationFolder = $destinationItem.FullName } else { New-Item -Path $resolvedDestination -ItemType Directory -Force -ErrorAction Stop | Out-Null $destinationFolder = (Get-Item -LiteralPath $resolvedDestination -ErrorAction Stop).FullName } function ConvertTo-SafeFileNamePart { param([string]$Value) if ([string]::IsNullOrWhiteSpace($Value)) { return 'Unknown' } $safe = $Value.Trim() foreach ($character in [IO.Path]::GetInvalidFileNameChars()) { $safe = $safe.Replace([string]$character, '-') } $safe = $safe -replace '\s+', '-' $safe = $safe -replace '-{2,}', '-' $safe.Trim('-', '.', ' ') } $nativeExportFolder = Join-Path -Path $destinationFolder -ChildPath ('.WindowsDeviceLinkExport-' + [Guid]::NewGuid().ToString('N')) New-Item -Path $nativeExportFolder -ItemType Directory -Force -ErrorAction Stop | Out-Null try { try { if ($InputObject.ActivationMode -eq 'RegisteredWinRT') { $nativePath = [WinPEDeviceLink.Native.DeviceLinkClient]::ExportCsvRegistered($nativeExportFolder, $TimeoutSeconds) } else { $nativePath = [WinPEDeviceLink.Native.DeviceLinkClient]::ExportCsv($InputObject.DllPath, $nativeExportFolder, $TimeoutSeconds) } } catch { $message = $_.Exception.Message if ($_.Exception.InnerException -and $_.Exception.InnerException.Message) { $message = $_.Exception.InnerException.Message } throw "Native DeviceLink CSV export failed: $message" } if ([string]::IsNullOrWhiteSpace($nativePath)) { throw 'Native DeviceLink CSV export completed without identifying the created CSV file.' } $nativePath = [Environment]::ExpandEnvironmentVariables($nativePath) if (-not [IO.Path]::IsPathRooted($nativePath)) { $nativePath = Join-Path -Path $nativeExportFolder -ChildPath $nativePath } if (-not (Test-Path -LiteralPath $nativePath -PathType Leaf)) { throw "Windows returned DeviceLink CSV path '$nativePath', but the file was not found." } $serial = ConvertTo-SafeFileNamePart $InputObject.SerialNumber $manufacturer = ConvertTo-SafeFileNamePart $InputObject.Manufacturer $model = ConvertTo-SafeFileNamePart $InputObject.Model $date = [DateTime]::UtcNow.ToString('yyyy-MM-dd') $baseName = '{0}_{1}_{2}_{3}' -f $serial, $manufacturer, $model, $date $targetPath = Join-Path -Path $destinationFolder -ChildPath ($baseName + '.devicelink.csv') $suffix = 2 while (Test-Path -LiteralPath $targetPath) { $targetPath = Join-Path -Path $destinationFolder -ChildPath ('{0}_{1}.devicelink.csv' -f $baseName, $suffix) $suffix++ } Move-Item -LiteralPath $nativePath -Destination $targetPath -ErrorAction Stop Get-Item -LiteralPath $targetPath } finally { if (Test-Path -LiteralPath $nativeExportFolder) { Remove-Item -LiteralPath $nativeExportFolder -Recurse -Force -ErrorAction SilentlyContinue } } } } |