Вызов сценария PowerShell PS1 из другого сценария PS1 внутри Powershell ISE
Я хочу выполнить вызов для сценария myScript1.ps1 внутри второго сценария myScript2.ps1 внутри Powershell ISE.
следующий код внутри MyScript2. ps1, отлично работает от администрирования Powershell, но не работает внутри PowerShell ISE:
#Call myScript1 from myScript2
invoke-expression -Command .myScript1.ps1
Я получаю следующую ошибку при выполнении MyScript2. ps1 из PowerShell ISE:
термин'. myScript1. ps1 ' не распознается как имя командлета, функции, файла сценария или действующая программа. Проверьте правильность написания имени, или если путь был включен, убедитесь, что путь указан правильно и повторите попытку.
9 ответов:
чтобы найти расположение скрипта, используйте
Split-Path $MyInvocation.MyCommand.Path
(убедитесь, что вы используете это в контексте сценария).причина, по которой вы должны использовать это, а не что-либо еще, может быть проиллюстрирована этим примером сценария.
## ScriptTest.ps1 Write-Host "InvocationName:" $MyInvocation.InvocationName Write-Host "Path:" $MyInvocation.MyCommand.Path
вот некоторые результаты.
PS C:\Users\JasonAr> .\ScriptTest.ps1 InvocationName: .\ScriptTest.ps1 Path: C:\Users\JasonAr\ScriptTest.ps1 PS C:\Users\JasonAr> . .\ScriptTest.ps1 InvocationName: . Path: C:\Users\JasonAr\ScriptTest.ps1 PS C:\Users\JasonAr> & ".\ScriptTest.ps1" InvocationName: & Path: C:\Users\JasonAr\ScriptTest.ps1на PowerShell 3.0 и позже вы можете использовать автоматическую переменную
$PSScriptRoot
:## ScriptTest.ps1 Write-Host "Script:" $PSCommandPath Write-Host "Path:" $PSScriptRoot
PS C:\Users\jarcher> .\ScriptTest.ps1 Script: C:\Users\jarcher\ScriptTest.ps1 Path: C:\Users\jarcher
текущий путь MyScript1.ps1 не совпадает с myScript2. ps1.вы можете получить путь к папке MyScript2.ps1 и объединить его с MyScript1.ps1, а затем выполнить его. Оба сценария должны находиться в одном и том же месте.
## MyScript2.ps1 ## $ScriptPath = Split-Path $MyInvocation.InvocationName & "$ScriptPath\MyScript1.ps1"
у меня была проблема с этим. Я не использовал никаких умных
$MyInvocation
вещи, чтобы исправить это, хотя. Если вы открываете ISE, щелкнув правой кнопкой мыши файл сценария и выбравedit
затем откройте второй скрипт из ISE вы можете вызвать один из другого, просто используя обычный.\script.ps1 синтаксис. Я предполагаю, что ISE имеет понятие текущей папки и открывает ее, как это устанавливает текущую папку в папку, содержащую сценарии. Когда я вызываю один скрипт из еще при нормальном использовании, я просто использовать .\сценарий.пс1 ИМО это неправильно модифицировать скрипт, чтобы он работал в ИНО правильно...
Это просто дополнительная информация к ответам чтобы передать аргумент в другой файл
там, где вы ожидаете аргумент
PrintName. ps1
Param( [Parameter( Mandatory = $true)] $printName = "Joe" ) Write-Host $printName
как вызвать файл
Param( [Parameter( Mandatory = $false)] $name = "Joe" ) & ((Split-Path $MyInvocation.InvocationName) + "\PrintName.ps1") -printName $name
Если вы не предоставите никаких входных данных, он будет по умолчанию "Joe" , и это будет передано в качестве аргумента в аргумент printName вPrintName.ps1 file который, в свою очередь, распечатает "Джо" строка
возможно, вы уже нашли ответ на него, но вот что я делаю.
обычно я помещаю эту строку в начале моих сценариев установки:
if(!$PSScriptRoot){ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent } #In case if $PSScriptRoot is empty (version of powershell V.2).
тогда я могу использовать переменную $PSScriptRoot в качестве местоположения текущего скрипта( пути), как в примере ниже:
if(!$PSScriptRoot){ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent } #In case if $PSScriptRoot is empty (version of powershell V.2). Try { If (Test-Path 'C:\Program Files (x86)') { $ChromeInstallArgs= "/i", "$PSScriptRoot\googlechromestandaloneenterprise64_v.57.0.2987.110.msi", "/q", "/norestart", "/L*v `"C:\Windows\Logs\Google_Chrome_57.0.2987.110_Install_x64.log`"" Start-Process -FilePath msiexec -ArgumentList $ChromeInstallArgs -Wait -ErrorAction Stop $Result= [System.Environment]::ExitCode } Else { $ChromeInstallArgs= "/i", "$PSScriptRoot\googlechromestandaloneenterprise_v.57.0.2987.110.msi", "/q", "/norestart", "/L*v `"C:\Windows\Logs\Google_Chrome_57.0.2987.110_Install_x86.log`"" Start-Process -FilePath msiexec -ArgumentList $ChromeInstallArgs -Wait -ErrorAction Stop $Result= [System.Environment]::ExitCode } } ### End Try block Catch { $Result = [System.Environment]::Exitcode [System.Environment]::Exit($Result) } [System.Environment]::Exit($Result)
в вашем случае, вы можете заменить
Start-process... строку с
Invoke-Expression $PSScriptRoot\ScriptName. ps1
вы можете прочитать больше о $MYINVOCATION и $PSScriptRoot автоматические переменные на сайте Microsoft: https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_automatic_variables
Я вызываю myScript1.ps1 из myScript2 .ps1.
предполагая, что оба сценария находятся в одном и том же месте, сначала получите местоположение сценария с помощью этой команды :
$PSScriptRoot
и затем добавьте имя скрипта, которое вы хотите вызвать следующим образом:
& "$PSScriptRoot\myScript1.ps1".
Это должно работать.
чтобы легко выполнить файл сценария в той же папке( или подпапке), что и вызывающий, вы можете использовать это:
# Get full path to the script: $ScriptRoute = [System.IO.Path]::GetFullPath([System.IO.Path]::Combine($PSScriptRoot, "Scriptname.ps1")) # Execute script at location: &"$ScriptRoute"
у меня была аналогичная проблема, и я решил ее таким образом.
мой рабочий каталог - это общая папка скрипта и серверная конкретная папка скрипта в том же корне, мне нужно вызвать конкретную папку скрипта (которая вызывает общий скрипт с параметром конкретной проблемы). Так что рабочий каталог выглядит так
\Nico\Scripts\Script1.ps1 \Script2.ps1 \Problem1\Solution1.ps1 \ParameterForSolution1.config \Problem2\Solution2.ps1 \ParameterForSolution2.config
решения 1 и решения 2 вызывают папку PS1 in Scripts, загружая параметр, сохраненный в ParameterForSolution. Поэтому в powershell ISE я запускаю это команда
.\Nico\Problem1\Solution1.PS1
и код внутри Solution1. PS1:
# This is the path where my script is running $path = split-path -parent $MyInvocation.MyCommand.Definition # Change to root dir cd "$path\..\.." $script = ".\Script\Script1.PS1" $parametro = "Problem1\ParameterForSolution1.config" # Another set of parameter Script1.PS1 can receive for debuggin porpuose $parametro +=' -verbose' Invoke-Expression "$script $parametro"