Как вернуть имя вызывающего script из модуля Powershell?

У меня есть два файла Powershell, модуль и script, который вызывает модуль.

Модуль: test.psm1

Function Get-Info {
    $MyInvocation.MyCommand.Name
}

Script: myTest.ps1

Import-Module C:\Users\moomin\Documents\test.psm1 -force
Get-Info

Когда я запускаю ./myTest.ps1, я получаю

Get-Info

Я хочу вернуть имя вызывающего script (test.ps1). Как я могу это сделать?

Ответ 1

Используйте 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

Если вы хотите, чтобы с помощью

можно было управлять только именем script
GCI $MyInvocation.PSCommandPath | Select -Expand Name

Это приведет к выводу:

myTest.ps1

Ответ 2

Я считаю, что вы можете использовать командлет Get-PSCallStack, который возвращает массив объектов фрейма стека. Вы можете использовать это, чтобы идентифицировать вызывающий script до строки кода.

Модуль: test.psm1

Function Get-Info {
    $callstack = Get-PSCallStack
    $callstack[1].Location
}

Вывод:

myTest.ps1: Line 2

Ответ 3

Использование $MyInvocation.MyCommand относится к нему.

Простой пример (из script расположен: 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 относится к области охвата. Если вам нужен путь к вашему script, не вставляйте его в функцию. Если вы хотите вызвать команду, то вы ее обернете.

Вы также можете использовать столбец, как было предложено, но имейте в виду правила определения области видимости.

Ответ 4

Я использовал это сегодня, пробовав несколько методов.

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

Ответ 5

Чтобы ссылаться на информацию о вызове вызывающего script, используйте:

@(Get-PSCallStack)[1].InvocationInfo

например:.

@(Get-PSCallStack)[1].InvocationInfo.MyCommand.Name

Ответ 6

Это обеспечивает путь script с завершающей обратной косой чертой как одну переменную и имя script как другое.

Путь работает с 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('\')

Ответ 7

Если вы хотите использовать более повторно используемый подход, вы можете использовать:

function Get-CallingFileName
{
    $cStack = @(Get-PSCallStack)
    $cStack[$cStack.Length-1].InvocationInfo.MyCommand.Name
}

У меня была проблема с функцией, которую можно было повторно использовать в модуле. Все остальное предполагало, что скрипт вызывал функцию модуля напрямую, и если он был удален хотя бы на 1 шаг, результатом будет имя файла модуля. Однако, если исходный скрипт вызывает функцию в модуле, которая, в свою очередь, вызывает другую функцию в модуле, то это единственный ответ, который я видел, который может гарантировать, что вы получаете информацию об исходном скрипте.

Конечно, этот подход основан на сообщениях @iRon и @James.