Запуск скриптов 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 из файла проекта 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 "& {
&'$(ScriptLocation)'
'$(LogFileLocation)'
'$(MSDeployComputerName)'} "" />
</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 "& Invoke-Command
–ComputerName 'REMOTESERVER1'
-ScriptBlock { &'C:\Path With Spaces\LogDeploy.ps1'
' C:\Path With Spaces\Log.txt '
'TESTWEB1' } "
Наконец, как и раньше, можно использовать задачу 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 "& invoke-command -scriptblock {
&'$(ScriptLocation)'
'$(LogFileLocation)'
'$(MSDeployComputerName)'}
""/>
</Target>
При выполнении этого целевого объекта в процессе сборки Windows PowerShell будет выполнять скрипт на компьютере, указанном в аргументе –computername.
Заключение
В этом разделе описывается выполнение скрипта Windows PowerShell из файла проекта MSBuild. Этот подход можно использовать для запуска скрипта Windows PowerShell локально или на удаленном компьютере в рамках автоматизированного или одношагового процесса сборки и развертывания.
Дополнительные материалы
Рекомендации по подписи скриптов Windows PowerShell и управлению политиками выполнения см. в статье Выполнение скриптов Windows PowerShell. Инструкции по выполнению Windows PowerShell команд с удаленного компьютера см. в статье Выполнение удаленных команд.
Дополнительные сведения об использовании пользовательских файлов проекта MSBuild для управления процессом развертывания см. в разделах Общие сведения о файле проекта и Общие сведения о процессе сборки.