我有两个Powershell文件,一个模块和一个调用该模块的脚本。
模块:test.psm1
Function Get-Info {
$MyInvocation.MyCommand.Name
}
脚本:myTest.ps1
Import-Module C:\Users\moomin\Documents\test.psm1 -force
Get-Info
当我运行./myTest.ps1
时,我得到了
Get-Info
我想返回调用脚本的名称(test.ps1)。我怎么能这样做?
答案 0 :(得分:12)
在您的模块中使用PSCommandPath:
示例test.psm1
function Get-Info{
$MyInvocation.PSCommandPath
}
示例myTest.ps1
Import-Module C:\Users\moomin\Documents\test.psm1 -force
Get-Info
输出:
C:\Users\moomin\Documents\myTest.ps1
如果您只想要通过执行
管理的脚本名称GCI $MyInvocation.PSCommandPath | Select -Expand Name
那会输出:
myTest.ps1
答案 1 :(得分:7)
我相信你可以使用Get-PSCallStack cmdlet,它返回一个堆栈帧对象数组。您可以使用它来识别调用脚本到代码行。
模块:test.psm1
Function Get-Info {
$callstack = Get-PSCallStack
$callstack[1].Location
}
输出:
myTest.ps1: Line 2
答案 2 :(得分:2)
使用$ MyInvocation.MyCommand是相对于它的范围。
一个简单的例子(位于脚本中:C:\ Dev \ Test-Script.ps1):
$name = $MyInvocation.MyCommand.Name;
$path = $MyInvocation.MyCommand.Path;
function Get-Invocation(){
$path = $MyInvocation.MyCommand.Path;
$cmd = $MyInvocation.MyCommand.Name;
write-host "Command : $cmd - Path : $path";
}
write-host "Command : $cmd - Path : $path";
Get-Invocation;
运行时的输出。\ c:\ Dev \ Test-Script.ps1:
Command : C:\Dev\Test-Script.ps1 - Path : C:\Dev\Test-Script.ps1
Command : Get-Invocation - Path :
如您所见,$ MyInvocation与范围有关。如果您想要脚本的路径,请不要将其包含在函数中。如果要调用该命令,则将其包装起来。
您也可以按照建议使用callstack,但要注意范围规则。
答案 3 :(得分:1)
要引用调用脚本的调用信息,请使用:
@(Get-PSCallStack)[1].InvocationInfo
e.g:
@(Get-PSCallStack)[1].InvocationInfo.MyCommand.Name
答案 4 :(得分:0)
我在尝试了几种技术之后今天就用这个。
$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$ScriptName = $MyInvocation.MyCommand | select -ExpandProperty Name
Invoke-Expression ". $Script\$ScriptName"
答案 5 :(得分:0)
这为脚本路径提供了尾部反斜杠作为一个变量,脚本名称作为另一个变量。
该路径适用于Powershell 2.0和3.0和4.0,可能还有5.0 现在可以使用Posershell $ PSscriptroot。
$ _ INST = $ myinvocation.mycommand.path.substring(0,($ myinvocation.mycommand.path.length - $ MyInvocation.mycommand.name.length))
$ _ ScriptName = $ myinvocation.mycommand.path.substring($ MyInvocation.MyCommand.Definition.LastIndexOf(' \'),($ MyInvocation.mycommand.name.length +1))
$ _ ScriptName = $ _ScriptName.TrimStart(' \')
答案 6 :(得分:0)
如果您想要一种更可重用的方法,则可以使用:
function Get-CallingFileName
{
$cStack = @(Get-PSCallStack)
$cStack[$cStack.Length-1].InvocationInfo.MyCommand.Name
}
我面临的挑战是拥有一个可以在模块内重用的功能。其他所有条件都假定该脚本直接调用了模块函数,并且即使将其删除(即使仅执行了1步),结果也就是模块文件名。但是,如果源脚本正在调用模块中的一个函数,又在模块中调用另一个函数,那么这是我所见的唯一可以确保您获取源脚本信息的答案。 / p>
当然,这种方法基于@iRon和@James发布的内容。
答案 7 :(得分:0)
对于正在寻找快速复制粘贴解决方案的Google员工, 这是在Powershell 5.1中起作用的地方
在您的模块内部:
$Script = (Get-PSCallStack)[2].Command
这将仅输出调用位于模块中的功能的脚本名称(ScriptName.ps1
)。
答案 8 :(得分:0)
我在my module中使用它:
function Get-ScriptPath {
[CmdletBinding()]
param (
[string]
$Extension = '.ps1'
)
# Allow module to inherit '-Verbose' flag.
if (($PSCmdlet) -and (-not $PSBoundParameters.ContainsKey('Verbose'))) {
$VerbosePreference = $PSCmdlet.GetVariableValue('VerbosePreference')
}
# Allow module to inherit '-Debug' flag.
if (($PSCmdlet) -and (-not $PSBoundParameters.ContainsKey('Debug'))) {
$DebugPreference = $PSCmdlet.GetVariableValue('DebugPreference')
}
$callstack = Get-PSCallStack
$i = 0
$max = 100
while ($true) {
if (!$callstack[$i]) {
Write-Verbose "Cannot detect callstack frame '$i' in 'Get-ScriptPath'."
return $null
}
$path = $callstack[$i].ScriptName
if ($path) {
Write-Verbose "Callstack frame '$i': '$path'."
$ext = [IO.Path]::GetExtension($path)
if (($ext) -and $ext -eq $Extension) {
return $path
}
}
$i++
if ($i -gt $max) {
Write-Verbose "Exceeded the maximum of '$max' callstack frames in 'Get-ScriptPath'."
return $null
}
}
return $null
}