每当需要引用公共模块或脚本时,我喜欢使用相对于当前脚本文件的路径。这样,我的脚本总能在库中找到其他脚本。

那么,确定当前脚本目录的最佳标准方法是什么?目前,我正在做:

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

我知道在模块(.psm1)中,您可以使用$PSScriptRoot来获取此信息,但在常规脚本(即.ps1文件)中不会设置此信息。

获取当前PowerShell脚本文件位置的规范方法是什么?


当前回答

我需要知道脚本名称以及它在哪里执行。

给MyInvocation结构加上前缀“$global:”,当从主脚本和导入的. psm1库文件的主线调用时,将返回完整的路径和脚本名称。它也可以在导入库中的函数中工作。

在反复折腾之后,我决定使用$global: myinvoke . invocationname。 它可靠地工作与CMD启动,运行与Powershell,和ISE。 本地和UNC发射都返回正确的路径。

其他回答

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

我花了一段时间来开发一些东西,把接受的答案变成一个健壮的函数。

我不确定其他人的情况,但我在一个同时使用PowerShell版本2和3的机器的环境中工作,所以我需要同时处理这两个版本。下面的函数提供了一个优雅的回退:

Function Get-PSScriptRoot
{
    $ScriptRoot = ""

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

    Write-Output $ScriptRoot
}

这也意味着函数引用Script作用域,而不是Michael Sorens在他的一篇博客文章中概述的父作用域。

从所有这些回答和评论中,我把这些问题整理在一起,供将来看到这个问题的人参考。它涵盖了其他答案中列出的所有情况,我添加了另一个我发现的故障保险。

function Get-ScriptPath()
{
    # If using PowerShell ISE
    if ($psISE)
    {
        $ScriptPath = Split-Path -Parent -Path $psISE.CurrentFile.FullPath
    }
    # If using PowerShell 3.0 or greater
    elseif($PSVersionTable.PSVersion.Major -gt 3)
    {
        $ScriptPath = $PSScriptRoot
    }
    # If using PowerShell 2.0 or lower
    else
    {
        $ScriptPath = split-path -parent $MyInvocation.MyCommand.Path
    }

    # If still not found
    # I found this can happen if running an exe created using PS2EXE module
    if(-not $ScriptPath) {
        $ScriptPath = [System.AppDomain]::CurrentDomain.BaseDirectory.TrimEnd('\')
    }

    # Return result
    return $ScriptPath
}

非常类似于已经发布的答案,但管道似乎更像powershell:

$PSCommandPath | Split-Path -Parent

我使用自动变量$ExecutionContext。 它将在PowerShell 2及更高版本中工作。

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

美元的ExecutionContext 对象的engineintrinsic对象 Windows PowerShell主机的执行上下文。你可以 使用此变量查找执行对象 可用于cmdlet。