PowerShell 2.0 - запуск сценариев для вызова командной строки по сравнению с ISE - PullRequest
4 голосов
/ 24 мая 2010

После написания сценариев развертывания изнутри ISE нам нужен наш сервер непрерывной интеграции (CI), чтобы иметь возможность запускать их автоматически, то есть из командной строки или через пакетный файл.

Я заметил некоторые существенные различия между следующими вызовами:

powershell.exe -File Script.ps1
powershell.exe -Command "& '.\Script.ps1'"
powershell.exe .\Script.ps1

Несколько простых примеров:

  • При использовании -File ошибки обрабатываются точно так же, как и ISE .
  • Два других вызова, похоже, игнорируют переменную $ErrorActionPreference и не перехватывают Write-Error в блоках try / catch.

При использовании pSake :

  • Последние два вызова работают отлично
  • При использовании параметра ISE или -File произойдет сбой со следующей ошибкой:

The variable '$script:context' cannot be retrieved because it has not been set


Каковы последствия каждого синтаксиса и почему они ведут себя по-разному? В идеале я хотел бы найти синтаксис, который работает все время и ведет себя как ISE.

Ответы [ 2 ]

2 голосов
/ 24 мая 2010

Не ответ, просто примечание.

Я искал объяснение параметра -file. Большинство источников говорят только «Выполнить файл сценария». На http://technet.microsoft.com/en-us/library/dd315276.aspx я читаю

Runs the specified script in the local scope ("dot-sourced"), so that the functions
and variables that the script creates are available in the current session. Enter
the script file path and any parameters.

После этого я попытался назвать это:

powershell -command ". c:\temp\aa\script.ps1"
powershell -file c:\temp\aa\script.ps1
powershell -command "& c:\temp\aa\script.ps1"

Обратите внимание, что первые два останавливаются после Get-Foo, а последний - нет.

Проблема, которую я описал выше, связана с модулями - если вы определите Get-Foo внутри script.ps1, все 3 описанных мною вызова останавливаются после вызова Get-Foo.

Просто попробуйте определить его внутри script.ps1 или поставьте файл с Get-Foo и проверьте его. Есть шанс, что это сработает:)

0 голосов
/ 24 мая 2010

Вот конкретный пример поведения, которое я описал.

MyModule.psm1

function Get-Foo
{
    Write-Error 'Failed'
}

Script.ps1

$ErrorActionPreference = 'Stop'

$currentFolder = (Split-Path $MyInvocation.MyCommand.Path)
Import-Module $currentFolder\MyModule.psm1

try
{
    Get-Foo 
    Write-Host "Success"
}
catch
{
    "Error occurred"
} 

Запуск Script.ps1:

  • Из ISE или с параметром -File

    выведет «Ошибкапроизошла "и остановка

  • Из командной строки без параметра -File

    будет выводиться" Failed "с последующим"Успехом" (т.е. не пойман)

...