注意:PowerShell 1.0
我想获取当前正在执行的PowerShell文件名。也就是说,如果我像这样开始会话:
powershell.exe .\myfile.ps1
我想获取字符串“。\ myfile.ps1”(或类似名称)。编辑:“ myfile.ps1”是可取的。
有任何想法吗?
注意:PowerShell 1.0
我想获取当前正在执行的PowerShell文件名。也就是说,如果我像这样开始会话:
powershell.exe .\myfile.ps1
我想获取字符串“。\ myfile.ps1”(或类似名称)。编辑:“ myfile.ps1”是可取的。
有任何想法吗?
Answers:
我尝试在此处总结各种答案,这些答案针对PowerShell 5已更新:
如果您仅使用PowerShell 3或更高版本,请使用 $PSCommandPath
如果要与旧版本兼容,请插入垫片:
if ($PSCommandPath -eq $null) { function GetPSCommandPath() { return $MyInvocation.PSCommandPath; } $PSCommandPath = GetPSCommandPath; }
$PSCommandPath
如果尚不存在,则会添加。
填充代码可以在任何地方(顶级或在函数内部)执行,尽管$PSCommandPath
变量受常规作用域规则的约束(例如,如果将填充块放入函数中,则变量仅作用于该函数)。
在各种答案中使用了4种不同的方法,因此我编写了此脚本来演示每种方法(以及$PSCommandPath
):
function PSCommandPath() { return $PSCommandPath; }
function ScriptName() { return $MyInvocation.ScriptName; }
function MyCommandName() { return $MyInvocation.MyCommand.Name; }
function MyCommandDefinition() {
# Begin of MyCommandDefinition()
# Note: ouput of this script shows the contents of this function, not the execution result
return $MyInvocation.MyCommand.Definition;
# End of MyCommandDefinition()
}
function MyInvocationPSCommandPath() { 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: $(MyInvocationPSCommandPath)";
Write-Host "";
输出:
PS C:\> .\Test\test.ps1
PSVersion: 5.1.19035.1
$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:
# Begin of MyCommandDefinition()
# Note this is the contents of the MyCommandDefinition() function, not the execution results
return $MyInvocation.MyCommand.Definition;
# End of MyCommandDefinition()
$MyInvocation.PSCommandPath:
* Direct:
* Function: C:\Test\test.ps1
C:\
,但实际脚本是C:\Test\test.ps1
。.\Test\test.ps1
)$PSCommandPath
是唯一可靠的方法,但已在PowerShell 3中引入$PSCommandPath
如果不需要旧版(WindowsXP),则没有理由不使用。
function PSCommandPath
)和对错误函数的引用(Write-Host " * Direct: $PSCommandPath"; Write-Host " * Function: $(ScriptName)";
-还是我忽略了明显的东西?
尽管当前答案在大多数情况下是正确的,但在某些情况下它不会为您提供正确的答案。如果在脚本函数内部使用,则:
$MyInvocation.MyCommand.Name
返回函数名称,而不是脚本名称。
function test {
$MyInvocation.MyCommand.Name
}
无论您的脚本如何命名,都会给您“ 测试 ”。获取脚本名称的正确命令始终是
$MyInvocation.ScriptName
这将返回您正在执行的脚本的完整路径。如果您只需要脚本文件名,则此代码应该可以帮助您:
split-path $MyInvocation.PSCommandPath -Leaf
$MyInvocation.ScriptName
为我返回空字符串,PS v3.0。
$MyInvocation.ScriptName
仅在函数内部起作用。请参阅下面的答案。
尝试以下
$path = $MyInvocation.MyCommand.Definition
这可能不会为您提供实际键入的路径,但会为您提供文件的有效路径。
$path = Split-Path $MyInvocation.MyCommand.Definition -Parent
如果要查找执行脚本的当前目录,可以尝试以下操作:
$fullPathIncFileName = $MyInvocation.MyCommand.Definition
$currentScriptName = $MyInvocation.MyCommand.Name
$currentExecutingPath = $fullPathIncFileName.Replace($currentScriptName, "")
Write-Host $currentExecutingPath
C:\ilike.ps123\ke.ps1
吗?
Replace()
方法替换了每次出现的针头(不仅是最后一次出现的针头),并且我也对其进行了测试。但是,对字符串进行减法是一个好主意。
String.TrimEnd()
($currentExecutingPath = $fullPathIncFileName.TrimEnd($currentScriptName)
)呢?-运行正常:"Ich bin Hamster".TrimEnd("ster")
返回Ich bin Ham
并"Ich bin Hamsterchen".TrimEnd("ster")
返回Ich bin Hamsterchen
(而不是Ich bin Hamchen
)-很好!
$currentScriptPath = $MyInvocation.MyCommand.Definition; $currentScriptName = $MyInvocation.MyCommand.Name; $currentScriptDir = $currentScriptPath.Substring(0,$currentScriptPath.IndexOf($currentScriptName));
注意:与$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)
我认为通过设置变量$ MyInvocation.MyCommand.Path的范围,有更好的方法:
ex> $ script:MyInvocation.MyCommand.Name
此方法适用于所有调用环境:
例如: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
输出:
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
如先前的答复所述,使用“ $ MyInvocation”会遇到范围问题,并且不一定提供一致的数据(返回值与直接访问值)。我发现,无论范围(在主调用或后续/嵌套函数调用中)如何获取脚本信息(如脚本路径,名称,参数,命令行等)的“最干净”(最一致)方法是使用“ Get- “ 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/zh-cn/powershell/module/microsoft.powershell.utility/get-variable
在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