代码之家  ›  专栏  ›  技术社区  ›  Ron Klein Noa Kuperberg

如何获取当前PowerShell执行文件?

  •  74
  • Ron Klein Noa Kuperberg  · 技术社区  · 17 年前

    注:PowerShell 1.0
    我想获取当前正在执行的PowerShell文件名。也就是说,如果我像这样开始我的课程:

    powershell.exe .\myfile.ps1
    

    我想拿绳子 “.MyFr.PS1” (或者类似的东西)。 编辑 : “MyFr.PS1” 优先考虑。
    有什么想法吗?

    9 回复  |  直到 8 年前
        1
  •  66
  •   rory.ap    9 年前

    虽然目前的答案在大多数情况下是正确的,但在某些情况下,它不会给出正确的答案。如果在脚本函数中使用,则:

    $MyInvocation.MyCommand.Name 
    

    返回函数名,而不是脚本名。

    function test {
        $MyInvocation.MyCommand.Name
    }
    

    会给你“ 测试 “不管你的脚本是如何命名的。 获取脚本名的正确命令始终是

    $MyInvocation.ScriptName
    

    这将返回正在执行的脚本的完整路径。如果您只需要脚本文件名,那么此代码应该对您有所帮助:

    split-path $MyInvocation.PSCommandPath -Leaf
    
        2
  •  66
  •   Keith Hill    17 年前

    如果只需要文件名(而不是完整路径),请使用:

    $ScriptName = $MyInvocation.MyCommand.Name
    
        3
  •  32
  •   JaredPar    17 年前

    尝试以下操作

    $path =  $MyInvocation.MyCommand.Definition 
    

    这可能无法为您提供键入的实际路径,但会为您提供文件的有效路径。

        4
  •  29
  •   gregmac    8 年前

    我尝试在这里总结各种答案,为PowerShell5更新:

    • 如果只使用PowerShell 3或更高版本,请使用 $PSCommandPath
    • 如果要与旧版本兼容,请插入垫片:

      if ($PSCommandPath -eq $null) { function GetPSCommandPath() { return $MyInvocation.PSCommandPath; } $PSCommandPath = GetPSCommandPath; }

      这增加了 $PSReaveDePATH 如果它还不存在。

      尽管如此,填充代码可以在任何地方执行(顶级或函数内部) $PSReaveDePATH 变量受正常范围规则的约束(例如,如果将填充程序放入函数中,则变量的范围仅限于该函数)。

    细节

    在不同的答案中有4种不同的方法,所以我编写了这个脚本来演示每种方法(加上 $PSReaveDePATH ):

    function PSCommandPath() { return $PSCommandPath; }
    function ScriptName() { return $MyInvocation.ScriptName; }
    function MyCommandName() { return $MyInvocation.MyCommand.Name; }
    function MyCommandDefinition() { return $MyInvocation.MyCommand.Definition; # Note this is the contents of the MyCommandDefinition function  
    }
    function PSCommandPath() { return $MyInvocation.PSCommandPath; }
    
    Write-Host "";
    Write-Host "PSVersion: $($PSVersionTable.PSVersion)";
    Write-Host "";
    Write-Host "`$PSCommandPath:";
    Write-Host " *   Direct: $PSCommandPath";
    Write-Host " * Function: $(ScriptName)";
    Write-Host "";
    Write-Host "`$MyInvocation.ScriptName:";
    Write-Host " *   Direct: $($MyInvocation.ScriptName)";
    Write-Host " * Function: $(ScriptName)";
    Write-Host "";
    Write-Host "`$MyInvocation.MyCommand.Name:";
    Write-Host " *   Direct: $($MyInvocation.MyCommand.Name)";
    Write-Host " * Function: $(MyCommandName)";
    Write-Host "";
    Write-Host "`$MyInvocation.MyCommand.Definition:";
    Write-Host " *   Direct: $($MyInvocation.MyCommand.Definition)";
    Write-Host " * Function: $(MyCommandDefinition)";
    Write-Host "";
    Write-Host "`$MyInvocation.PSCommandPath:";
    Write-Host " *   Direct: $($MyInvocation.PSCommandPath)";
    Write-Host " * Function: $(PSCommandPath)";
    Write-Host "";
    

    输出:

    PS C:\> .\Test\test.ps1
    
    PSVersion: 5.1.14393.1066
    
    $PSCommandPath:
     *   Direct: C:\Test\test.ps1
     * Function: C:\Test\test.ps1
    
    $MyInvocation.ScriptName:
     *   Direct:
     * Function: C:\Test\test.ps1
    
    $MyInvocation.MyCommand.Name:
     *   Direct: test.ps1
     * Function: MyCommandName
    
    $MyInvocation.MyCommand.Definition:
     *   Direct: C:\Test\test.ps1
     * Function:  return $MyInvocation.MyCommand.Definition; # Note this is the contents of the MyCommandDefinition function
    
    
    $MyInvocation.PSCommandPath:
     *   Direct:
     * Function: C:\Test\test.ps1
    

    笔记:

    • 执行自 C:\ ,但实际脚本是 C:\Test\test.ps1 .
    • 没有方法告诉您原始调用路径( .\Test\test.ps1 )
    • $PSReaveDePATH 是唯一可靠的方法,但在PowerShell3中引入了
    • 对于3之前的版本,函数内部和外部都不能使用单个方法
        5
  •  7
  •   Ryk    15 年前

    如果要查找当前执行脚本的目录,可以尝试以下操作:

    $fullPathIncFileName = $MyInvocation.MyCommand.Definition
    $currentScriptName = $MyInvocation.MyCommand.Name
    $currentExecutingPath = $fullPathIncFileName.Replace($currentScriptName, "")
    
    Write-Host $currentExecutingPath
    
        6
  •  6
  •   chiwangc Alexander    11 年前

    当心: 不像 $PSScriptRoot $PSCommandPath 自动变量, PSScriptRoot PSCommandPath 的属性 $MyInvocation 自动的 变量包含有关调用程序或调用脚本的信息,而不是 当前脚本。

    例如

    PS C:\Users\S_ms\OneDrive\Documents> C:\Users\SP_ms\OneDrive\Documents\DPM ...
    =!C:\Users\S_ms\OneDrive\Documents\DPM.ps1
    

    …在哪里 DPM.ps1 包含

    Write-Host ("="+($MyInvocation.PSCommandPath)+"!"+$PSCommandPath)
    
        7
  •  4
  •   Daddio    8 年前

    我认为,通过设置变量$myinvocation.mycommand.path的作用域,有一个更好的方法:

    EX & GT;$ 脚本 :myinvocation.mycommand.name

    此方法在调用的所有情况下都有效:

    前任: PS1

    function printme () {
        "In function:"
        ( "MyInvocation.ScriptName: " + [string]($MyInvocation.ScriptName) )
        ( "script:MyInvocation.MyCommand.Name: " + [string]($script:MyInvocation.MyCommand.Name) )
        ( "MyInvocation.MyCommand.Name: " + [string]($MyInvocation.MyCommand.Name) )
    }
    "Main:"
    ( "MyInvocation.ScriptName: " + [string]($MyInvocation.ScriptName) )
    ( "script:MyInvocation.MyCommand.Name: " + [string]($script:MyInvocation.MyCommand.Name) )
    ( "MyInvocation.MyCommand.Name: " + [string]($MyInvocation.MyCommand.Name) )
    " "
    printme
    exit
    

    输出:

    PS> powershell C:\temp\test.ps1
    Main:
    MyInvocation.ScriptName:
    script:MyInvocation.MyCommand.Name: test.ps1
    MyInvocation.MyCommand.Name: test.ps1
    
    In function:
    MyInvocation.ScriptName: C:\temp\test.ps1
    script:MyInvocation.MyCommand.Name: test.ps1
    MyInvocation.MyCommand.Name: printme
    

    请注意,当从main调用时,上面接受的回答不会返回值。另外,请注意,当问题只请求脚本名时,上面接受的答案返回完整路径。作用域变量在所有地方都有效。

    另外,如果您想要完整的路径,那么您只需调用:

    $script:MyInvocation.MyCommand.Path
    
        8
  •  1
  •   Mark Crashley    9 年前

    在ps 2和ps 4上使用以下脚本进行了一些测试,结果相同。我希望这能帮助人们。

    $PSVersionTable.PSVersion
    function PSscript {
      $PSscript = Get-Item $MyInvocation.ScriptName
      Return $PSscript
    }
    ""
    $PSscript = PSscript
    $PSscript.FullName
    $PSscript.Name
    $PSscript.BaseName
    $PSscript.Extension
    $PSscript.DirectoryName
    
    ""
    $PSscript = Get-Item $MyInvocation.InvocationName
    $PSscript.FullName
    $PSscript.Name
    $PSscript.BaseName
    $PSscript.Extension
    $PSscript.DirectoryName
    

    结果-

    Major  Minor  Build  Revision
    -----  -----  -----  --------
    4      0      -1     -1      
    
    C:\PSscripts\Untitled1.ps1
    Untitled1.ps1
    Untitled1
    .ps1
    C:\PSscripts
    
    C:\PSscripts\Untitled1.ps1
    Untitled1.ps1
    Untitled1
    .ps1
    C:\PSscripts
    
        9
  •  1
  •   AntGut    8 年前

    如前所述,使用“$myinvocation”会受到范围问题的影响,不一定提供一致的数据(返回值与直接访问值)。我发现,获取脚本信息的“最干净”(最一致)方法,如脚本路径、名称、参数、命令行等,不管作用域(在主函数调用或后续/嵌套函数调用中)是在“myinvocation”上使用“get variable”…

    # Get the MyInvocation variable at script level
    # Can be done anywhere within a script
    $ScriptInvocation = (Get-Variable MyInvocation -Scope Script).Value
    
    # Get the full path to the script
    $ScriptPath = $ScriptInvocation.MyCommand.Path
    
    # Get the directory of the script
    $ScriptDirectory = Split-Path $ScriptPath
    
    # Get the script name
    # Yes, could get via Split-Path, but this is "simpler" since this is the default return value
    $ScriptName = $ScriptInvocation.MyCommand.Name
    
    # Get the invocation path (relative to $PWD)
    # @GregMac, this addresses your second point
    $InvocationPath = ScriptInvocation.InvocationName
    

    因此,您可以获得与$pscommandpath相同的信息,但在交易中可以获得更多信息。不确定,但看起来“get variable”直到PS3才可用,所以对于真正的旧(未更新)系统没有太多帮助。

    使用“-scope”时还有一些有趣的方面,因为您可以回溯以获取调用函数的名称等。0=当前,1=父级等。

    希望这能有所帮助。

    裁判, https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-variable

    推荐文章