2

Plenty of people have asked, and gotten several variations of answers to, the question "How do I get the path of the script itself in Powershell?". However, in my situation I have a few utility functions stored in a common module alongside the script but I don't actually run the script from that particular directory, instead I have symlink'd the script to $HOME\bin, which I have in PATH. And I do not want to symlink all the utility libraries into the $HOME\bin directory.

How can I get the path of the "real" script path in Powershell, given that the script the user actually runs (i.e. is found in PATH) can be a symlink?

1 Answer 1

2

It's a little clunky, but use the common $PSCommandPath to get the script pathname, then try to look up what it links to. If there's no result then $PSCommandPath is the answer. Otherwise check if it's an absolute link target path; if it is then that is the answer. Otherwise join the path of the symlink with its target. Finally Resolve-Path is used to "remove" the relative part of the merged pathname.

Function Get-RealScriptPath() {
  # Get script path and name
  $ScriptPath = $PSCommandPath

  # Attempt to extract link target from script pathname
  $link_target = Get-Item $ScriptPath | Select-Object -ExpandProperty Target

  # If it's not a link ..
  If(-Not($link_target)) {
    # .. then the script path is the answer.
    return $ScriptPath
  }

  # If the link target is absolute ..
  $is_absolute = [System.IO.Path]::IsPathRooted($link_target)
  if($is_absolute) {
    # .. then it is the answer.
    return $link_target
  }

  # At this point:
  # - we know that script was launched from a link
  # - the link target is probably relative (depending on how accurate
  #   IsPathRooted() is).
  # Try to make an absolute path by merging the script directory and the link
  # target and then normalize it through Resolve-Path.
  $joined = Join-Path $PSScriptRoot $link_target
  $resolved = Resolve-Path -Path $joined
  return $resolved
}

Function Get-ScriptDirectory() {
  $ScriptPath = Get-RealScriptPath
  $ScriptDir = Split-Path -Parent $ScriptPath
  return $ScriptDir
}

$ScriptDir = Get-ScriptDirectory
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.