首页 文章

确定当前PowerShell脚本位置的最佳方法是什么?

提问于
浏览
404

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

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

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

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

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

11 回答

  • 671

    花了一些时间来开发一些能够接受所接受的答案并将其转化为强大功能的东西 .

    不确定其他人,但我在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
    }
    

    这也意味着该函数指的是脚本范围,而不是Michael Sorens在他的blog中概述的父范围 .

  • 49

    我使用automatic variable $ ExecutionContext,它适用于PowerShell 2及更高版本 .

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

    $ ExecutionContext包含一个EngineIntrinsics对象,该对象表示Windows PowerShell主机的执行上下文 . 您可以使用此变量来查找cmdlet可用的执行对象 .

  • 25
    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
    
  • 10

    适用于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.
    

    那么功能是:

    function Get-ScriptDirectory {
        Split-Path -Parent $PSCommandPath
    }
    
  • -3

    如果要创建V2模块,可以使用名为 $PSScriptRoot 的自动变量 .

    从PS>帮助automatic_variable

    $PSScriptRoot
           Contains the directory from which the script module is being executed.
           This variable allows scripts to use the module path to access other
           resources.
    
  • 6

    也许我在这里遗漏了一些东西......但是如果你想要现在的工作目录,你可以使用它: (Get-Location).Path 表示字符串,或 Get-Location 表示对象 .

    除非你指的是这样的东西,我在再次阅读这个问题后理解这一点 .

    function Get-Script-Directory
    {
        $scriptInvocation = (Get-Variable MyInvocation -Scope 1).Value
        return Split-Path $scriptInvocation.MyCommand.Path
    }
    
  • 8

    非常类似于已发布的答案,但管道似乎更像PS .

    $PSCommandPath | Split-Path -Parent
    
  • 13

    对于Powershell 3

    function Get-ScriptDirectory {
        if ($psise) {Split-Path $psise.CurrentFile.FullPath}
        else {$global:PSScriptRoot}
    }
    

    我把这个功能放在我的 Profiles 中 . 也可以使用F8 / Run Selection在ISE中运行 .

  • 1

    我需要知道脚本名称及其执行位置 .

    将“$ global:”前缀添加到MyInvocation结构时,将从主脚本和导入的.PSM1库文件的主行调用时返回完整路径和脚本名称 . 它也可以在导入库中的函数内部工作 .

    经过多次摆弄后,我决定使用$ global:MyInvocation.InvocationName . 它可靠地运行CMD,Run With Powershell和ISE . 本地和UNC启动都会返回正确的路径 .

  • 6

    PowerShell 3+

    # This is an automatic variable set to the current file's/module's directory
    $PSScriptRoot
    

    PowerShell 2

    在PowerShell 3之前,没有比查询通用脚本的 MyInvocation.MyCommand.Definition 属性更好的方法了 . 我在基本上每个PowerShell脚本的顶部都有以下行:

    $scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
    
  • 8

    如果任何其他方法失败,您也可以考虑 split-path -parent $psISE.CurrentFile.Fullpath . 特别是,如果你运行一个文件来加载一堆函数然后在ISE shell中执行这些函数(或者如果你运行选择),那么上面的 Get-Script-Directory 函数似乎不起作用 .

相关问题