What's the best way to determine the location

2019-01-01 08:03发布

Whenever I need to reference a common module or script, I like to use paths relative to the current script file, that way, my script can always find other scripts in the library.

So, what is the best, standard way of determining the directory of the current script? Currently, I'm doing:

$MyDir = [System.IO.Path]::GetDirectoryName($myInvocation.MyCommand.Definition)

I know in modules (.psm1) you can use $PSScriptRoot to get this information, but that doesn't get set in regular scripts (i.e. .ps1 files).

What's the canonical way to get the current PowerShell script file's location?

11条回答
零度萤火
2楼-- · 2019-01-01 08:26

Took me a while to develop something that took the accepted answer and turned it into a robust function.

Not sure about others but I work in an environment with machines on both PowerShell version 2 and 3 so I needed to handle both. The following function offers a graceful fallback:

Function Get-PSScriptRoot
{
    $ScriptRoot = ""

    Try
    {
        $ScriptRoot = Get-Variable -Name PSScriptRoot -ValueOnly -ErrorAction Stop
    }
    Catch
    {
        $ScriptRoot = Split-Path $script:MyInvocation.MyCommand.Path
    }

    Write-Output $ScriptRoot
}

It also means that the function refers to the Script scope rather than the parent's scope as outlined by Michael Sorens in his blog

查看更多
余欢
3楼-- · 2019-01-01 08:28
function func1() 
{
   $inv = (Get-Variable MyInvocation -Scope 1).Value
   #$inv.MyCommand | Format-List *   
   $Path1 = Split-Path $inv.scriptname
   Write-Host $Path1
}

function Main()
{
    func1
}

Main
查看更多
浪荡孟婆
4楼-- · 2019-01-01 08:33

For PowerShell 3.0

$PSCommandPath
    Contains the full path and file name of the script that is being run. 
    This variable is valid in all scripts.

The function is then:

function Get-ScriptDirectory {
    Split-Path -Parent $PSCommandPath
}
查看更多
不再属于我。
5楼-- · 2019-01-01 08:33

Very similar to already posted answers, but piping seems more PS-like.

$PSCommandPath | Split-Path -Parent
查看更多
泪湿衣
6楼-- · 2019-01-01 08:37

I use the automatic variable $ExecutionContext, it works from PowerShell 2 and later.

$ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath('.\')

$ExecutionContext Contains an EngineIntrinsics object that represents the execution context of the Windows PowerShell host. You can use this variable to find the execution objects that are available to cmdlets.

查看更多
有味是清欢
7楼-- · 2019-01-01 08:37

You might also consider split-path -parent $psISE.CurrentFile.Fullpath if any of the other methods fail. In particular, if you run a file to load a bunch of functions and then execute those functions with-in the ISE shell (or if you run-selected), it seems the Get-Script-Directory function as above doesn't work.

查看更多
登录 后发表回答