Private/Test-ExportPathWritable.ps1
|
function Test-ExportPathWritable { <# .SYNOPSIS Pre-flight check: validates an export file path is writable before expensive operations begin. .DESCRIPTION Checks that the target export file is not locked by another process (e.g., Excel), and that the parent directory exists or can be created. Call this early in functions that accept -ExportPath/-ExportResultsPath to fail fast before API calls. .PARAMETER Path The file path to validate. .OUTPUTS Returns $true if the path is writable. Throws on failure. #> [CmdletBinding()] [OutputType([bool])] param( [Parameter(Mandatory = $true)] [string]$Path ) # Ensure parent directory exists or can be created $parentDir = Split-Path -Path $Path -Parent if ($parentDir -and -not (Test-Path -Path $parentDir)) { try { New-Item -ItemType Directory -Path $parentDir -Force | Out-Null } catch { throw "Cannot create export directory '$parentDir': $($_.Exception.Message)" } } # If file doesn't exist yet, path is writable if (-not (Test-Path -Path $Path)) { return $true } # File exists - test if it's locked by trying to open it for write try { $fileStream = [System.IO.File]::Open($Path, [System.IO.FileMode]::Open, [System.IO.FileAccess]::Write, [System.IO.FileShare]::None) $fileStream.Close() $fileStream.Dispose() return $true } catch [System.IO.IOException] { throw "Export file '$Path' is locked by another process (e.g., Excel). Close the file and try again." } catch { throw "Cannot write to export file '$Path': $($_.Exception.Message)" } } |