如何从Powershell模块返回调用脚本的名称?

如何从Powershell模块返回调用脚本的名称?,powershell,powershell-2.0,Powershell,Powershell 2.0,我有两个Powershell文件,一个模块和一个调用该模块的脚本 模块:test.psm1 Function Get-Info { $MyInvocation.MyCommand.Name } Import-Module C:\Users\moomin\Documents\test.psm1 -force Get-Info Function Get-Info { $callstack = Get-PSCallStack $callstack[1].Location }

我有两个Powershell文件,一个模块和一个调用该模块的脚本

模块:test.psm1

Function Get-Info {
    $MyInvocation.MyCommand.Name
}
Import-Module C:\Users\moomin\Documents\test.psm1 -force
Get-Info
Function Get-Info {
    $callstack = Get-PSCallStack
    $callstack[1].Location
}
脚本:myTest.ps1

Function Get-Info {
    $MyInvocation.MyCommand.Name
}
Import-Module C:\Users\moomin\Documents\test.psm1 -force
Get-Info
Function Get-Info {
    $callstack = Get-PSCallStack
    $callstack[1].Location
}
当我运行
/myTest.ps1

获取信息


我想返回调用脚本的名称(test.ps1)。我如何才能做到这一点?

在您的模块中改用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
myTest.ps1: Line 2
如果只需要可以通过执行以下操作来管理的脚本的名称

GCI $MyInvocation.PSCommandPath | Select -Expand Name
这将产生:

myTest.ps1

我相信您可以使用cmdlet,它返回堆栈帧对象数组。您可以使用它来标识调用脚本,直至代码行

模块:test.psm1

Function Get-Info {
    $MyInvocation.MyCommand.Name
}
Import-Module C:\Users\moomin\Documents\test.psm1 -force
Get-Info
Function Get-Info {
    $callstack = Get-PSCallStack
    $callstack[1].Location
}
输出:

C:\Users\moomin\Documents\myTest.ps1
myTest.ps1: Line 2

使用$MyInvocation.MyCommand与它的作用域有关

(位于C:\Dev\Test script.ps1的脚本的)一个简单示例:

运行时的输出。\c:\Dev\Test-Script.ps1:

Command : C:\Dev\Test-Script.ps1 - Path : C:\Dev\Test-Script.ps1
Command : Get-Invocation - Path : 
如您所见,$MyInvocation是相对于作用域的。如果需要脚本的路径,请不要将其包含在函数中。如果希望调用该命令,则可以将其包装


您也可以按照建议使用callstack,但要注意范围规则。

我今天在尝试了几种技术后使用了它

$scriptPath = split-path -parent $MyInvocation.MyCommand.Definition
$ScriptName = $MyInvocation.MyCommand | select -ExpandProperty Name
Invoke-Expression ". $Script\$ScriptName"

这将为脚本路径提供尾随反斜杠作为一个变量,脚本名称作为另一个变量

该路径适用于Powershell 2.0、3.0和4.0,可能还有5.0 现在,Posershell$PSscriptroot在何处可用

$\u INST=$myinvocation.mycommand.path.substring(0,($myinvocation.mycommand.path.length-$myinvocation.mycommand.name.length))

$\u ScriptName=$myinvocation.mycommand.path.substring($myinvocation.mycommand.Definition.LastIndexOf('\'),($myinvocation.mycommand.name.length+1))


$\u ScriptName=$\u ScriptName.TrimStart('\')

要引用调用脚本的调用信息,请使用:

@(Get-PSCallStack)[1].InvocationInfo
e、 g:


如果您想要更可重用的方法,可以使用:

function Get-CallingFileName
{
    $cStack = @(Get-PSCallStack)
    $cStack[$cStack.Length-1].InvocationInfo.MyCommand.Name
}
我面临的挑战是要有一个可以在模块中重用的函数。其他一切都假设脚本直接调用模块函数,如果在一个步骤中删除了它,那么结果将是模块文件名。但是,如果源脚本正在调用模块中的一个函数,而该函数又在调用模块中的另一个函数,那么这是我看到的唯一能够确保您获得源脚本信息的答案


当然,这种方法是基于@iRon和@James发布的内容。

对于寻找快速复制粘贴解决方案的谷歌用户, 下面是Powershell 5.1中的工作原理

模块内部:

$Script = (Get-PSCallStack)[2].Command
这将只输出调用位于模块中的函数的脚本名(
ScriptName.ps1
)。

我在以下情况下使用它:


我意识到这可能只是一个学术练习,但为什么不直接从myTest.ps1脚本调用
$MyInvocation.MyCommand.Name
来获取这些信息呢?这不是一个学术练习。我已经发布了简单的示例代码来帮助回答者。我需要从模块中获取调用脚本的名称。@JohnC的可能副本:这个问题是关于调用脚本的,另一个问题是关于执行文件的。例如,如果main.ps1从module.psm1调用函数,则调用的脚本是main.ps1,执行sctipt的是module.psm1。不幸的是,这对PSv3+功能不起作用