Как я могу получить текущий файл выполнения PowerShell?
Примечание: PowerShell 1.0
Я хотел бы получить имя текущего выполняемого файла PowerShell. То есть, если я начну свой сеанс так:
powershell.exe .myfile.ps1
Я хотел бы получить строку ".myfile.ps1" (или что-то в этом роде). EDIT: "myfile. ps1" предпочтительнее.
Есть идеи?
9 ответов:
в то время как текущий ответ является правильным в большинстве случаев, есть определенные ситуации, что он не даст вам правильный ответ. Если вы используете внутри вашего скрипта функции, то:
$MyInvocation.MyCommand.Nameвозвращает имя функции вместо имени скрипта.
function test { $MyInvocation.MyCommand.Name }даст вам "тест" независимо от того, как ваш скрипт называется. Правильная команда для получения имени скрипта всегда
$MyInvocation.ScriptNameэто возвращает полный путь скрипт выполняется. Если вам нужно только имя файла сценария, чем этот код должен помочь вам:
split-path $MyInvocation.PSCommandPath -Leaf
Если вы хотите только имя файла (не путь) используйте этот:
$ScriptName = $MyInvocation.MyCommand.Name
попробуйте следующее
$path = $MyInvocation.MyCommand.DefinitionЭто может не дать вам фактический путь, введенный, но это даст вам действительный путь к файлу.
Я попытался обобщить различные ответы здесь, обновленные для 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() { 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.- ни один метод не сообщает вам исходный вызов путь (
.\Test\test.ps1)$PSCommandPath- это единственный надежный способ, но был введен в PowerShell 3- для версий до 3, ни один метод не работает как внутри, так и снаружи функции
Если вы ищете текущий каталог, в котором выполняется скрипт, вы можете попробовать это:
$fullPathIncFileName = $MyInvocation.MyCommand.Definition $currentScriptName = $MyInvocation.MyCommand.Name $currentExecutingPath = $fullPathIncFileName.Replace($currentScriptName, "") Write-Host $currentExecutingPath
остерегайтесь: В отличие от
$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.Путь:
ex>$ script:MyInvocation.MyCommand.Name
этот метод работает при всех обстоятельствах вызова:
EX: Somescript.пс1
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
провел некоторое тестирование со следующим скриптом, как на 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
Как отмечалось в предыдущих ответах, использование "$MyInvocation " зависит от проблем с областью действия и не обязательно обеспечивает согласованность данных (возвращаемое значение и значение прямого доступа). Я обнаружил, что" самый чистый " (наиболее последовательный) метод получения информации о скрипте, такой как путь к скрипту, имя, parms, командная строка и т. д. независимо от области действия (в основном или последующих/вложенных вызовах функций) следует использовать "Get-Variable" на "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, поэтому не очень много помощи для действительно старых (не обновленных) систем.
есть также некоторые интересные аспекты при использовании "рамки" как вы можете возвратиться, чтобы получить имена и т. д. функции вызова(ов). 0=Текущий, 1=родитель, и т. д.
надеюсь, что это полезно.
Ref, https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/get-variable
Comments