Поделиться через


Запуск скриптов Windows PowerShell из файлов проекта MSBuild

Джейсон Ли

В этом разделе описывается запуск скрипта Windows PowerShell в процессе сборки и развертывания. Скрипт можно запускать локально (другими словами, на сервере сборки) или удаленно, например на целевом веб-сервере или сервере базы данных.

Существует множество причин, по которым может потребоваться запустить скрипт Windows PowerShell после развертывания. Например, можно сделать следующее:

  • Добавьте пользовательский источник событий в реестр.
  • Создайте каталог файловой системы для отправки.
  • Очистка каталогов сборки.
  • Запись записей в пользовательский файл журнала.
  • Отправка сообщений электронной почты с приглашением пользователей в недавно подготовленное веб-приложение.
  • Создание учетных записей пользователей с соответствующими разрешениями.
  • Настройте репликацию между экземплярами SQL Server.

В этом разделе показано, как выполнять скрипты Windows PowerShell локально и удаленно из пользовательского целевого объекта в файле проекта Microsoft Build Engine (MSBuild).

Этот раздел является частью серии учебников, основанных на требованиях к развертыванию на предприятии вымышленной компании Fabrikam, Inc. В этой серии учебников используется пример решения диспетчера контактов для представления веб-приложения с реалистичным уровнем сложности, включая приложение ASP.NET MVC 3, службу Windows Communication Foundation (WCF) и проект базы данных.

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

Обзор задачи

Чтобы запустить скрипт Windows PowerShell в рамках автоматизированного или одношагового процесса развертывания, необходимо выполнить следующие высокоуровневые задачи:

  • Добавьте скрипт Windows PowerShell в решение и в систему управления версиями.
  • Создайте команду, которая вызывает скрипт Windows PowerShell.
  • Экранирование всех зарезервированных XML-символов в команде.
  • Создайте целевой объект в пользовательском файле проекта MSBuild и выполните команду с помощью задачи Exec .

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

Создание и добавление скриптов Windows PowerShell

В задачах в этом разделе используется пример скрипта Windows PowerShell с именем LogDeploy.ps1, чтобы проиллюстрировать выполнение скриптов из MSBuild. Скрипт LogDeploy.ps1 содержит простую функцию, которая записывает однострочные записи в файл журнала:

function LogDeployment
{
  param([string]$filepath,[string]$deployDestination)
  $datetime = Get-Date
  $filetext = "Deployed package to " + $deployDestination + " on " + $datetime
  $filetext | Out-File -filepath $filepath -Append
}

LogDeployment $args[0] $args[1]

Скрипт LogDeploy.ps1 принимает два параметра. Первый параметр представляет полный путь к файлу журнала, в который требуется добавить запись, а второй — назначение развертывания, которое требуется записать в файл журнала. При запуске скрипт добавляет строку в файл журнала в следующем формате:

Deployed package to TESTWEB1 on 02/11/2012 09:28:18

Чтобы сделать скрипт LogDeploy.ps1 доступным для MSBuild, необходимо:

  • Добавьте скрипт в систему управления версиями.
  • Добавьте скрипт в решение в Visual Studio 2010.

Вам не нужно развертывать скрипт с содержимым решения, независимо от того, планируете ли вы запускать скрипт на сервере сборки или на удаленном компьютере. Один из вариантов — добавить скрипт в папку решения. В примере Диспетчера контактов, так как вы хотите использовать скрипт Windows PowerShell в процессе развертывания, имеет смысл добавить сценарий в папку решения Публикация.

В примере Диспетчера контактов, так как вы хотите использовать скрипт Windows PowerShell в процессе развертывания, имеет смысл добавить сценарий в папку решения Публикация.

Содержимое папок решений копируется для создания серверов в качестве исходного материала. Однако они не входят ни в какие выходные данные проекта.

Выполнение скрипта Windows PowerShell на сервере сборки

В некоторых сценариях может потребоваться выполнить Windows PowerShell скрипты на компьютере, который выполняет сборку проектов. Например, можно использовать скрипт Windows PowerShell для очистки папок сборки или записи в пользовательский файл журнала.

С точки зрения синтаксиса выполнение скрипта Windows PowerShell из файла проекта MSBuild аналогично запуску скрипта Windows PowerShell из обычной командной строки. Необходимо вызвать исполняемый файл powershell.exe и использовать параметр –command, чтобы предоставить команды, которые Windows PowerShell выполнять. (В Windows PowerShell версии 2 можно также использовать параметр –file. Команда должна иметь следующий формат:

powershell.exe –command "& { [Path to script] 'parameter1' 'parameter2' ... }"

Пример:

powershell.exe –command 
  "& { C:\LogDeploy.ps1 'C:\DeployLogs\log.txt' 'TESTWEB1' }"

Если путь к скрипту содержит пробелы, необходимо заключить путь к файлу в одинарные кавычки, предшествующие амперсанду. Вы не можете использовать двойные кавычки, так как вы уже использовали их для заключения команды:

powershell.exe –command 
  "& { &'C:\Path With Spaces\LogDeploy.ps1' 
        'C:\Path With Spaces\log.txt' 
        'TESTWEB1' }"

При вызове этой команды из MSBuild есть несколько дополнительных рекомендаций. Во-первых, необходимо включить флаг –NonInteractive , чтобы убедиться, что скрипт выполняется тихо. Затем следует включить флаг –ExecutionPolicy с соответствующим значением аргумента. Это указывает политику выполнения, которая Windows PowerShell будет применяться к скрипту, и позволяет переопределить политику выполнения по умолчанию, что может помешать выполнению скрипта. Вы можете выбрать один из следующих значений аргументов:

  • Значение Unrestricted позволит Windows PowerShell выполнять скрипт независимо от того, подписан ли скрипт.
  • Значение RemoteSigned позволит Windows PowerShell выполнять неподписанные скрипты, созданные на локальном компьютере. Однако скрипты, созданные в другом месте, должны быть подписаны. (На практике вы вряд ли создали скрипт Windows PowerShell локально на сервере сборки.
  • Значение AllSigned позволит Windows PowerShell выполнять только подписанные скрипты.

Политика выполнения по умолчанию ограничена, что не позволяет Windows PowerShell запускать какие-либо файлы скриптов.

Наконец, необходимо экранировать все зарезервированные XML-символы, которые встречаются в команде Windows PowerShell:

  • Замените одинарные кавычки '

  • Замените двойные кавычки &кавычками;

  • Замените амперсанды &

  • При внесении этих изменений команда будет выглядеть следующим образом:

powershell.exe –NonInteractive –ExecutionPolicy Unrestricted 
               –command "& { &'[Path to script]' 
                        '[parameter1]' 
                        '[parameter2]' } "

В пользовательском файле проекта MSBuild можно создать новый целевой объект и использовать задачу Exec для выполнения следующей команды:

<Target Name="WriteLogEntry" Condition=" '$(WriteLogEntry)'!='false' ">
  <PropertyGroup>
    <PowerShellExe Condition=" '$(PowerShellExe)'=='' "> 
      %WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe
    </PowerShellExe>
    <ScriptLocation Condition=" '$(ScriptLocation)'=='' ">
      C:\Path With Spaces\LogDeploy.ps1
    </ScriptLocation>
    <LogFileLocation Condition=" '$(LogFileLocation)'=='' ">
      C:\Path With Spaces\ContactManagerDeployLog.txt
    </LogFileLocation>
  </PropertyGroup>
  <Exec Command="$(PowerShellExe) -NonInteractive -executionpolicy Unrestricted 
                 -command &quot;&amp; { 
                          &amp;&apos;$(ScriptLocation)&apos; 
                          &apos;$(LogFileLocation)&apos; 
                          &apos;$(MSDeployComputerName)&apos;} &quot;" />
</Target>

В этом примере обратите внимание на следующее:

  • Все переменные, такие как значения параметров и расположение исполняемого файла Windows PowerShell, объявляются как свойства MSBuild.
  • Включены условия, позволяющие пользователям переопределять эти значения из командной строки.
  • Свойство MSDeployComputerName объявляется в другом месте файла проекта.

При выполнении этого целевого объекта в процессе сборки Windows PowerShell выполнит команду и запишет запись журнала в указанный файл.

Выполнение скрипта Windows PowerShell на удаленном компьютере

Windows PowerShell может выполнять скрипты на удаленных компьютерах с помощью удаленного управления Windows (WinRM). Для этого необходимо использовать командлет Invoke-Command . Это позволяет выполнять скрипт на одном или нескольких удаленных компьютерах без копирования скрипта на удаленные компьютеры. Все результаты возвращаются на локальный компьютер, с которого был запущен скрипт.

Примечание

Прежде чем использовать командлет Invoke-Command для выполнения Windows PowerShell скриптов на удаленном компьютере, необходимо настроить прослушиватель WinRM для приема удаленных сообщений. Это можно сделать, выполнив команду winrm quickconfig на удаленном компьютере. Дополнительные сведения см. в статье Установка и настройка удаленного управления Windows.

В окне Windows PowerShell можно использовать следующий синтаксис для запуска скрипта LogDeploy.ps1 на удаленном компьютере:

Invoke-Command –ComputerName 'REMOTESERVER1' 
               –ScriptBlock { &"C:\Path With Spaces\LogDeploy.ps1"
                               'C:\Path With Spaces\Log.txt'
                               'TESTWEB1' }

Примечание

Существует несколько других способов использования Invoke-Command для запуска файла скрипта, но этот подход является наиболее простым, когда необходимо указать значения параметров и управлять путями с пробелами.

При запуске из командной строки необходимо вызвать исполняемый файл Windows PowerShell и использовать параметр –command для предоставления инструкций:

powershell.exe –command 
  "& {Invoke-Command –ComputerName 'REMOTESERVER1' 
                     –ScriptBlock { &'C:\Path With Spaces\LogDeploy.ps1'
                                     'C:\Path With Spaces\Log.txt'
                                     'TESTWEB1' } "

Как и раньше, при выполнении команды из MSBuild необходимо предоставить дополнительные параметры и экранировать все зарезервированные XML-символы:

powershell.exe -NonInteractive -executionpolicy Unrestricted 
               -command &quot;&amp; Invoke-Command 
                 –ComputerName &apos;REMOTESERVER1&apos;
                 -ScriptBlock { &amp;&apos;C:\Path With Spaces\LogDeploy.ps1&apos; 
                                &apos; C:\Path With Spaces\Log.txt &apos;  
                                &apos;TESTWEB1&apos; } &quot;

Наконец, как и раньше, можно использовать задачу Exec в пользовательском целевом объекте MSBuild для выполнения команды:

<Target Name="WriteLogEntry" Condition=" '$(WriteLogEntry)'!='false' ">
  <PropertyGroup>
    <PowerShellExe Condition=" '$(PowerShellExe)'=='' "> 
      %WINDIR%\System32\WindowsPowerShell\v1.0\powershell.exe
    </PowerShellExe>
    <ScriptLocation Condition=" '$(ScriptLocation)'=='' ">
      C:\Path With Spaces\LogDeploy.ps1
    </ScriptLocation>
    <LogFileLocation Condition=" '$(LogFileLocation)'=='' ">
      C:\Path With Spaces\ContactManagerDeployLog.txt
    </LogFileLocation>
  </PropertyGroup>
  <Exec Command="$(PowerShellExe) -NonInteractive -executionpolicy Unrestricted 
                 -command &quot;&amp; invoke-command -scriptblock { 
                          &amp;&apos;$(ScriptLocation)&apos; 
                          &apos;$(LogFileLocation)&apos;  
                          &apos;$(MSDeployComputerName)&apos;}
                          &quot;"/>  
</Target>

При выполнении этого целевого объекта в процессе сборки Windows PowerShell будет выполнять скрипт на компьютере, указанном в аргументе –computername.

Заключение

В этом разделе описывается выполнение скрипта Windows PowerShell из файла проекта MSBuild. Этот подход можно использовать для запуска скрипта Windows PowerShell локально или на удаленном компьютере в рамках автоматизированного или одношагового процесса сборки и развертывания.

Дополнительные материалы

Рекомендации по подписи скриптов Windows PowerShell и управлению политиками выполнения см. в статье Выполнение скриптов Windows PowerShell. Инструкции по выполнению Windows PowerShell команд с удаленного компьютера см. в статье Выполнение удаленных команд.

Дополнительные сведения об использовании пользовательских файлов проекта MSBuild для управления процессом развертывания см. в разделах Общие сведения о файле проекта и Общие сведения о процессе сборки.