Artem Yukhimenko
Artem Yukhimenko

Reputation: 417

How to convert relative path to absolute path in PowerShell?

How to convert relative path to absolute path in PowerShell?

$path1 = C:/1/2/3/
$parth2 = ../../base/
=====
$result = C:/1/base/

Upvotes: 14

Views: 15132

Answers (5)

Stefan Lippeck
Stefan Lippeck

Reputation: 455

I had to write a script where i wanted to provide default parameters for folder and file locations but since the user could overwrite them AND launch the script form any directory, i needed to properly handle this in a way it was as userfriendly as possible (e.g. using autocomplete of the ps-console provides for file paths)

I thought i'd share this here as I also struggled to properly handle relative paths (and wasted way too much time with .NET-Objects, trying to solve this)

as @Artem Yukhimenko provided the curcual cmdlet resolve-path. I want to give the credits to him.

param (
    [string] $SubFolderOne = "./SubfolderOne/",
    [string] $ConfigFile = "./config.json",
    [string] $SiblingFolder = "../SiblingFolder/"
)

function ResolveDefaultParameters {
    # If the script has been run from a different directory and the path variables have been omitted, the default values would point to the wrong location.
    # This function resolves the path to the script's directory if the path has been omitted.
    param (
        [string] $Path,
        [string] $VarName
    )

    try {
        # this will succeed if the path is already correct
        $Path = $Path | Resolve-Path -ErrorAction Stop
    }
    catch {
        try {
            # This will fix the path so the default parameter value will join with the script's directory. 
            # If the parameter has been provided with a wrong path, the error will stop the script.
            $Path = Join-Path $PSScriptRoot $Path | Resolve-Path -ErrorAction Stop
        }
        catch {
            # had to manually throw the error, because the error from the `Resolve-Path` cmdlet would be missleading.
            throw "Can't resolve path for `$$VarName`: '$Path'"
        }
    }
    return $Path
}

$SubFolderOne = ResolveDefaultParameters -Path $SubFolderOne -VarName "SubFolderOne"
$ConfigFile = ResolveDefaultParameters -Path $ConfigFile -VarName "ConfigFile"
$SiblingFolder = ResolveDefaultParameters -Path $SiblingFolder -VarName "SiblingFolder"

# after handling the passed path parameters, we can set the script's location as the current location so we can access other files with known location more easily
$origLocation = Get-Location
Set-Location $PSScriptRoot

try {
    # do the work here
    Write-Host "SubFolderOne: $SubFolderOne"
    Write-Host "ConfigFile: $ConfigFile"
    Write-Host "SiblingFolder: $SiblingFolder"

    #exeecute an a related script
    .\Subroutines\RelatedScript.ps1
}
catch {
    throw $_.Exception.Message
}
finally {
    # return to original location
    Set-Location $origLocation
}

Upvotes: 0

SynCap
SynCap

Reputation: 6294

Using the built-in .NET API - System.IO.Path.GetRelativePath:

[System.IO.Path]::GetFullPath($BasePath, $RelativePath)
# OR relative to current dir when ($BasePath -eq $PWD):
[System.IO.Path]::GetFullPath($RelativePath)

Upvotes: 1

Doug
Doug

Reputation: 7057

If your path is not existent yet, most of the above will blow up on you.

Either of the following will work even if the path doesn't exist yet:

[IO.Path]::GetFullPath(".\abc")
$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath(".\abc.txt")

Upvotes: 7

Artem Yukhimenko
Artem Yukhimenko

Reputation: 417

(Join-Path $path1 $path2) | Resolve-Path

Upvotes: 16

TheIdesOfMark
TheIdesOfMark

Reputation: 176

I think I get what you're looking for. But feel free to give a little more information if this isn't what you wanted.

$result = Get-Item $path2 | Select-Object PSPath -ExpandProperty PSPath
$result.Substring(38)

This should give you what you an absolute path. It strips out "Microsoft.Powershell.Core\Filesystem::" Which will be different if you're using Powershell 5 or earlier. But play with the Get-Item cmdlet to see how that displays if you want more detail.

Upvotes: 0

Related Questions