Bram
Bram

Reputation: 825

How to write a Powershell file parameter that accepts a relative path

The following sample code correctly reads both the PSD1 and the regular file when the path to the PSD1 is a fully qualified path (or when the current location is the same as the current directory). It fails when supplied a relative path.

param (
    [Parameter(Mandatory=$true)][System.IO.FileInfo]$PsdFile,
    [Parameter(Mandatory=$false)][System.IO.FileInfo]$RegularFile = 'testfile'
)

$RegularFileContent = Get-Content $RegularFile
$PsdData = Import-LocalizedData -BaseDirectory $PsdFile.DirectoryName -FileName $PsdFile.Name

echo "regular file contents: $RegularFileContent"

echo "Psd data:"
echo $PsdData.Name

How can I fix this so the user can enter a relative path?

I believe the underlying problem is similar to the problem described in this post about FileInfo but I don't know how to incorporate Resolve-Path or similar into the parameter handling.

Upvotes: 2

Views: 4563

Answers (2)

Iuri Carraro
Iuri Carraro

Reputation: 11

param (
    [Parameter(Mandatory = $true)]
    [ValidateScript( {
            if (-Not (Test-Path -Path $_ ) ) { throw "File not found." }
            elseif (-Not (Test-Path -Path $_ -PathType Leaf) ) { throw "PsdFile should be a file." }
            return $true
        })]
    [System.IO.FileInfo] $PsdFile,

    [Parameter(Mandatory = $false)]
    [ValidateScript( {
            if (-Not (Test-Path -Path $_ ) ) { throw "File not found." }
            elseif (-Not (Test-Path -Path $_ -PathType Leaf) ) { throw "PsdFile should be a file." }
            return $true
        })]
    [System.IO.FileInfo] $RegularFile = 'testfile'
)

$PsdFile = (Resolve-Path -Path $PsdFile).Path;
$RegularFile = (Resolve-Path -Path $RegularFile).Path;

$RegularFileContent = Get-Content $RegularFile.FullName
$PsdData = Import-LocalizedData -BaseDirectory $PsdFile.DirectoryName -FileName $PsdFile.Name

Upvotes: 1

Maximilian Burszley
Maximilian Burszley

Reputation: 19654

A lot of your question hinges on which relative you're referring to as that itself is relative. If you want the path to be relative to a user's working directory versus the script's root, you can accomplish that like so:

param(
    [Parameter(Mandatory)]
    [string]
    $PsdFile,

    [Parameter()] # Mandatory is $false by default
    [string]
    $RegularFile = 'testfile'
)

[System.IO.FileInfo]$psd = Join-Path -Path $PWD.Path -ChildPath $PsdFile

$data = Import-LocalizedData -BaseDirectory $psd.DirectoryName -FileName $PsdFile.Name
$content = Get-Content -Path $RegularFile

"regular file contents: $content"
"Psd data:" + $data.Name

Upvotes: 2

Related Questions