Make your -Path Parameter a System.IO.FileInfo object, and just pass in a relative path as the parameter. The file object will resolve with either a relative or full path, then you can use $path.FullName to reference the full path to the file.
Function Get-FilePathItemHC {
Param (
[Parameter(Mandatory)]
[ValidateScript({ $_.Exists })]
[System.IO.FileInfo]$Path
)
# The ValidateScript attribute makes sure the file you passed in exists
# so your validation code no longer is required
}
If you want to handle both directories and files, you would want to have two separate variables in this case as directory paths would become a System.IO.DirectoryInfo object, but you can make the arguments mutually exclusive:
Function Get-FilePathItemHC {
Param (
[Parameter(Mandatory=$true, ParameterSetName="FilePath")]
[ValidateScript({ $_.Exists })]
[System.IO.FileInfo]$FilePath,
[Parameter(Mandatory=$true, ParameterSetName="DirectoryPath")]
[ValidateScript({ $_.Exists })]
[System.IO.DirectoryInfo]$DirectoryPath
)
$Path = $FilePath
if( $DirectoryPath ) {
$Path = $DirectoryPath
}
# The ValidateScript attribute makes sure the file you passed in exists
# so your validation code no longer is required
}
Get-FilePathItemHC -Path .\path\to\file.txt
Get the relative path from $PSScriptRoot
I'm not sure why you need the path relative to $PSScriptRoot if you already have the full path to the file, but after getting the System.IO.FileInfo or System.IO.DirectoryInfo object, you can use Resolve-Path from $PSScriptRoot to get the relative path from that directory:
$file = Get-FilePathItemHC -Path .\path\to\file.txt
Push-Location $PSScriptRoot
$relativeFromScriptRootPath = Resolve-Path -Relative $file
Pop-Location
Push-Location and Pop-Location treat the location as a stack. The push operation sets a new location and adds it to the stack, and the pop operation removes the last added location from the stack and places you at the next most recent location. Works a bit like cd - on Linux if you're familiar.
Resolve-Path will return a file path, and the -Relative switch will return a path relative to your current directory. You cannot pass in an alternate directory to resolve from, which is why we change the location to run this.