Call powershell script PS1 из другого PS1 script внутри Powershell ISE

Мне нужно выполнить вызов для myScript1.ps1 script внутри второго myScript2.ps1 script внутри Powershell ISE.

Следующий код внутри MyScript2.ps1 отлично работает с администрацией Powershell, но не работает внутри PowerShell ISE:

#Call myScript1 from myScript2
invoke-expression -Command .\myScript1.ps1

Я получаю следующую ошибку при выполнении MyScript2.ps1 из PowerShell ISE:

Термин ".\myScript1.ps1" не распознается как имя командлета, функции, файла script или исполняемой программы. Проверьте правильность написания имени или если путь был включен, проверьте правильность пути и повторите попытку.

Кто может мне помочь?

Ответ 1

Чтобы найти местоположение script, используйте Split-Path $MyInvocation.MyCommand.Path (убедитесь, что вы используете это в контексте script).

Причина, по которой вы должны использовать это, а не что-то еще, может быть проиллюстрирована в этом примере script.

## 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

Ответ 2

Текущий путь MyScript1.ps1 не совпадает с myScript2.ps1. Вы можете получить путь к папке MyScript2.ps1 и соединить его с MyScript1.ps1, а затем выполнить его. Оба сценария должны находиться в одном месте.

## MyScript2.ps1 ##
$ScriptPath = Split-Path $MyInvocation.InvocationName
& "$ScriptPath\MyScript1.ps1"

Ответ 3

Однострочное решение:

& ((Split-Path $MyInvocation.InvocationName) + "\MyScript1.ps1")

Ответ 4

У меня была проблема с этим. Я не использовал никаких умных вещей $MyInvocation, чтобы исправить это. Если вы откроете ISE, щелкнув правой кнопкой мыши файл script и выбрав edit, затем откройте второй script из ISE, который вы можете вызвать один из другого, просто используя обычный .\script. ps1. Я предполагаю, что ISE имеет представление о текущей папке и открывает ее так, как это устанавливает текущую папку в папку, содержащую скрипты. Когда я вызываю один script из другого в обычном использовании, я просто использую .\script.ps1, IMO неправильно изменять script, чтобы он работал в ISE правильно..

Ответ 5

Это дополнительная информация для ответов для передачи аргумента в другой файл

Где вы ожидаете аргумент

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 который, в свою очередь, распечатает строку "Joe"

Ответ 6

Возможно, вы уже нашли ответ, но вот что я делаю.

Я обычно размещаю эту строку в начале моих установочных скриптов:

if(!$PSScriptRoot){ $PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent } #In case if $PSScriptRoot is empty (version of powershell V.2).  

Затем я могу использовать переменную $PSScriptRoot в качестве местоположения текущего script (путь), как в следующем примере:

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)

В вашем случае вы можете заменить

Пуск-процесс... строка с

Вызов-выражение $PSScriptRoot\ScriptName.ps1

Вы можете узнать больше о автоматических переменных $MYINVOCATION и $PSScriptRoot на сайте Microsoft: https://msdn.microsoft.com/en-us/powershell/reference/5.1/microsoft.powershell.core/about/about_automatic_variables

Ответ 7

Я вызываю myScript1.ps1 из myScript2.ps1.

Предполагая, что оба script находятся в одном месте, сначала найдите местоположение script, используя следующую команду:

$PSScriptRoot

И затем добавьте имя script, которое вы хотите вызвать следующим образом:

& "$PSScriptRoot\myScript1.ps1".

Это должно работать.

Ответ 8

У меня была аналогичная проблема, и я решил ее таким образом.

Мой рабочий каталог представляет собой общую папку script и серверную конкретную папку script в том же корневом каталоге, мне нужно вызвать конкретную папку script (которая вызывает общий script с параметром конкретной проблемы). Итак, рабочий каталог похож на этот

\Nico\Scripts\Script1.ps1
             \Script2.ps1
      \Problem1\Solution1.ps1
               \ParameterForSolution1.config
      \Problem2\Solution2.ps1
               \ParameterForSolution2.config

Решения1 и Решения2 вызовите PS1 в папке 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"