我如何获得当前的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
$PSCommandPath
variables受制于正常的范围规则(例如,如果将垫片放在一个函数中,该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的PSScriptRoot
和PSCommandPath
属性包含有关调用者或调用脚本的信息,而不是当前脚本。
例如
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