我如何获得当前的PowerShell执行文件?

注意:PowerShell 1.0
我想获得当前执行的PowerShell文件名。 也就是说,如果我这样开始我的会话:

powershell.exe .\myfile.ps1 

我想获得string“。\ myfile.ps1” (或类似的东西)。 编辑“myfile.ps1”是可取的。
有任何想法吗?

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

 $MyInvocation.MyCommand.Name 

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

 function test { $MyInvocation.MyCommand.Name } 

无论您的脚本如何命名,都会给您“ testing ”。 获取脚本名称的正确命令始终是

 $MyInvocation.ScriptName 

这将返回正在执行的脚本的完整path。 如果你只需要脚本文件名而不是这个代码应该可以帮助你:

 split-path $MyInvocation.PSCommandPath -Leaf 

如果你只想要文件名(不是完整的path),使用这个:

 $ScriptName = $MyInvocation.MyCommand.Name 

尝试以下

 $path = $MyInvocation.MyCommand.Definition 

这可能不会给你input的实际path,但它会给你一个有效的文件path。

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

 $fullPathIncFileName = $MyInvocation.MyCommand.Definition $currentScriptName = $MyInvocation.MyCommand.Name $currentExecutingPath = $fullPathIncFileName.Replace($currentScriptName, "") Write-Host $currentExecutingPath 

我试图总结这里的各种答案,更新了PowerShell 5:

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

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

    如果它尚不存在,则添加$PSCommandPath

    尽pipe$PSCommandPathvariables受制于正常的范围规则(例如,如果将垫片放在一个函数中,该variables仅限于该函数的范围),那么垫片代码可以在任何位置(顶层或函数内部)执行。

细节

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

 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
  • 没有方法告诉你原来的调用path( .\Test\test.ps1
  • $PSCommandPath是唯一可靠的方法,但在PowerShell 3中引入
  • 对于3之前的版本,function内部和外部都不能使用单一的方法

注意:与$PSScriptRoot$PSCommandPath自动variables不同, $MyInvocation自动variables的PSScriptRootPSCommandPath属性包含有关调用者或调用脚本的信息,而不是当前脚本。

例如

 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) 

在PS 2和PS 4上用下面的脚本进行了一些testing,结果相同。 我希望这有助于人们。

 $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 

我认为有一个更好的方法,通过设置variables$ MyInvocation.MyCommand.Path的作用域:

ex> $ script :MyInvocation.MyCommand.Name

此方法适用于所有调用情况:

EX:Somescript.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 

OUTPUT:

 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调用时不返回一个值。 另外请注意,当问题仅请求脚本名称时,以上接受的答案将返回完整path。 范围variables适用于所有地方。

另外,如果你确实需要完整的path,那么你只需要调用:

 $script:MyInvocation.MyCommand.Path 

正如前面的回应所指出的那样,使用“$ MyInvocation”受限于范围问题,并不一定提供一致的数据(返回值与直接访问值)。 我发现,无论范围(主函数或后继/嵌套函数调用),获取脚本path,名称,参数,命令行等脚本信息的“最干净”(最一致的)方法是使用“Get-variables“on”MyInvocation“…

 # 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