Uruchamianie skryptów programu Windows PowerShell z plików projektu MSBuild

Autor: Jason Lee

W tym temacie opisano sposób uruchamiania skryptu programu Windows PowerShell w ramach procesu kompilacji i wdrażania. Skrypt można uruchomić lokalnie (innymi słowy na serwerze kompilacji) lub zdalnie, na przykład na docelowym serwerze internetowym lub serwerze bazy danych.

Istnieje wiele powodów, dla których warto uruchomić skrypt programu Windows PowerShell po wdrożeniu. Na przykład możesz chcieć:

  • Dodaj niestandardowe źródło zdarzeń do rejestru.
  • Wygeneruj katalog systemu plików dla przesyłania.
  • Wyczyść katalogi kompilacji.
  • Zapisz wpisy w niestandardowym pliku dziennika.
  • Wysyłaj wiadomości e-mail z zaproszeniem użytkowników do nowo aprowizowanej aplikacji internetowej.
  • Utwórz konta użytkowników z odpowiednimi uprawnieniami.
  • Konfigurowanie replikacji między wystąpieniami programu SQL Server.

W tym temacie pokazano, jak uruchamiać skrypty programu Windows PowerShell zarówno lokalnie, jak i zdalnie z niestandardowego obiektu docelowego w pliku projektu microsoft Build Engine (MSBuild).

Ten temat stanowi część serii samouczków opartych na wymaganiach dotyczących wdrażania w przedsiębiorstwie fikcyjnej firmy o nazwie Fabrikam, Inc. W tej serii samouczków użyto przykładowego rozwiązania — rozwiązania Contact Manager — do reprezentowania aplikacji internetowej o realistycznym poziomie złożoności, w tym aplikacji ASP.NET MVC 3, usługi Windows Communication Foundation (WCF) i projektu bazy danych.

Metoda wdrażania w centrum tych samouczków jest oparta na metodzie podzielonego pliku projektu opisanego w opisie pliku projektu, w którym proces kompilacji jest kontrolowany przez dwa pliki projektu — jeden zawierający instrukcje kompilacji, które mają zastosowanie do każdego środowiska docelowego, oraz jeden zawierający ustawienia kompilacji i wdrażania specyficzne dla środowiska. W czasie kompilacji plik projektu specyficzny dla środowiska jest scalony z plikiem projektu niezależnego od środowiska w celu utworzenia pełnego zestawu instrukcji kompilacji.

Omówienie zadania

Aby uruchomić skrypt programu Windows PowerShell w ramach zautomatyzowanego lub jednoetapowego procesu wdrażania, należy wykonać następujące zadania wysokiego poziomu:

  • Dodaj skrypt programu Windows PowerShell do rozwiązania i do kontroli źródła.
  • Utwórz polecenie, które wywołuje skrypt programu Windows PowerShell.
  • Unikaj jakichkolwiek zastrzeżonych znaków XML w swoim poleceniu.
  • Utwórz element docelowy w niestandardowym pliku projektu MSBuild i uruchom polecenie za pomocą zadania Exec .

W tym temacie przedstawiono sposób wykonywania tych procedur. W zadaniach i przewodnikach w tym temacie założono, że znasz już obiekty docelowe i właściwości programu MSBuild oraz wiesz, jak używać niestandardowego pliku projektu MSBuild do napędzania procesu kompilacji i wdrażania. Aby uzyskać więcej informacji, zobacz Opis pliku projektu i Opis procesu kompilacji.

Tworzenie i dodawanie skryptów programu Windows PowerShell

Zadania w tym temacie używają przykładowego skryptu programu Windows PowerShell o nazwie LogDeploy.ps1 , aby zilustrować sposób uruchamiania skryptów z programu MSBuild. Skrypt LogDeploy.ps1 zawiera prostą funkcję, która zapisuje wpis jednowierszowy do pliku dziennika:

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]

Skrypt LogDeploy.ps1 akceptuje dwa parametry. Pierwszy parametr reprezentuje pełną ścieżkę do pliku dziennika, do którego chcesz dodać wpis, a drugi parametr reprezentuje miejsce docelowe wdrożenia, które chcesz zarejestrować w pliku dziennika. Po uruchomieniu skryptu dodaje wiersz do pliku dziennika w następującym formacie:

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

Aby udostępnić skrypt LogDeploy.ps1 programowi MSBuild, należy wykonać następujące działania:

  • Dodaj skrypt do kontroli źródła.
  • Dodaj skrypt do rozwiązania w programie Visual Studio 2010.

Nie musisz wdrażać skryptu z zawartością rozwiązania, niezależnie od tego, czy planujesz uruchomić skrypt na serwerze kompilacji, czy na komputerze zdalnym. Jedną z opcji jest dodanie skryptu do folderu rozwiązania. W przykładzie Menedżera kontaktów, ponieważ chcesz użyć skryptu programu Windows PowerShell w ramach procesu wdrażania, warto dodać skrypt do folderu Publikuj rozwiązanie.

W przykładzie Menedżera kontaktów, ponieważ chcesz użyć skryptu programu Windows PowerShell w ramach procesu wdrażania, warto dodać skrypt do folderu Publikuj rozwiązanie.

Zawartość folderów rozwiązań jest kopiowana do serwerów kompilacji jako materiał źródłowy. Nie stanowią one jednak żadnej części żadnych danych wyjściowych projektu.

Wykonywanie skryptu programu Windows PowerShell na serwerze kompilacji

W niektórych scenariuszach możesz chcieć uruchomić skrypty programu Windows PowerShell na komputerze, który kompiluje projekty. Na przykład możesz użyć skryptu programu Windows PowerShell, aby wyczyścić foldery kompilacji lub zapisać wpisy w niestandardowym pliku dziennika.

Jeśli chodzi o składnię, uruchomienie skryptu programu Windows PowerShell z pliku projektu MSBuild jest takie samo jak uruchamianie skryptu programu Windows PowerShell z zwykłego wiersza polecenia. Musisz wywołać plik wykonywalny powershell.exe i użyć przełącznika –command , aby podać polecenia, które mają być uruchamiane przez program Windows PowerShell. (W programie Windows PowerShell w wersji 2 można również użyć przełącznika –file ). Polecenie powinno mieć następujący format:

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

Przykład:

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

Jeśli ścieżka do skryptu zawiera spacje, należy ująć ścieżkę pliku w pojedynczy cudzysłów poprzedzony znakiem ampersand. Nie można użyć cudzysłowów podwójnych, ponieważ użyto ich już do zawierania polecenia.

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

Podczas wywoływania tego polecenia z programu MSBuild należy wziąć pod uwagę kilka dodatkowych zagadnień. Najpierw należy dołączyć flagę –NonInteractive , aby upewnić się, że skrypt jest wykonywany cicho. Następnie należy uwzględnić flagę –ExecutionPolicy z odpowiednią wartością argumentu. Określa zasady wykonywania, które program Windows PowerShell będzie stosować do skryptu i umożliwia zastąpienie domyślnych zasad wykonywania, które mogą uniemożliwić wykonywanie skryptu. Możesz wybrać spośród następujących wartości argumentów:

  • Wartość Unrestricted umożliwi programowi Windows PowerShell wykonanie skryptu niezależnie od tego, czy skrypt jest podpisany.
  • Wartość RemoteSigned umożliwi programowi Windows PowerShell wykonywanie niepodpisanych skryptów utworzonych na komputerze lokalnym. Jednak skrypty, które zostały utworzone gdzie indziej, muszą być podpisane. (W praktyce jest bardzo mało prawdopodobne, aby skrypt programu Windows PowerShell został utworzony lokalnie na serwerze kompilacji).
  • Wartość AllSigned umożliwi programowi Windows PowerShell wykonywanie tylko podpisanych skryptów.

Domyślne zasady wykonywania są ograniczone, co uniemożliwia programowi Windows PowerShell uruchamianie plików skryptów.

Na koniec należy uniknąć wszelkich zarezerwowanych znaków XML występujących w poleceniu programu Windows PowerShell:

  • Zamień pojedyncze cudzysłowy na '

  • Zastąp cudzysłowy kodem "

  • Zamień ampersand na &

  • Po wprowadzeniu tych zmian polecenie będzie wyglądać podobnie do następującego:

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

W niestandardowym pliku projektu MSBuild możesz utworzyć nowy element docelowy i użyć zadania Exec , aby uruchomić to polecenie:

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

W tym przykładzie należy pamiętać, że:

  • Wszystkie zmienne, takie jak wartości parametrów i lokalizacja pliku wykonywalnego programu Windows PowerShell, są deklarowane jako właściwości programu MSBuild.
  • Warunki są uwzględniane w celu umożliwienia użytkownikom zastąpienia tych wartości z wiersza polecenia.
  • Właściwość MSDeployComputerName jest zadeklarowana w innym miejscu w pliku projektu.

Po wykonaniu tego obiektu docelowego w ramach procesu kompilacji program Windows PowerShell uruchomi polecenie i napisze wpis dziennika do określonego pliku.

Wykonywanie skryptu programu Windows PowerShell na komputerze zdalnym

Program Windows PowerShell może uruchamiać skrypty na komputerach zdalnych za pośrednictwem zdalnego zarządzania systemem Windows (WinRM). W tym celu należy użyć polecenia cmdlet Invoke-Command . Umożliwia to wykonanie skryptu na co najmniej jednym komputerze zdalnym bez kopiowania skryptu na komputery zdalne. Wszystkie wyniki są zwracane na komputer lokalny, z którego uruchomiono skrypt.

Uwaga / Notatka

Przed użyciem polecenia cmdlet Invoke-Command do wykonywania skryptów programu Windows PowerShell na komputerze zdalnym należy skonfigurować odbiornik WinRM do akceptowania komunikatów zdalnych. Można to zrobić, uruchamiając polecenie winrm quickconfig na komputerze zdalnym. Aby uzyskać więcej informacji, zobacz Instalacja i konfiguracja usługi zdalnego zarządzania systemem Windows.

W oknie programu Windows PowerShell użyjesz tej składni do uruchomienia skryptu LogDeploy.ps1 na komputerze zdalnym:

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

Uwaga / Notatka

Istnieją różne inne sposoby używania polecenia Invoke-Command do uruchamiania pliku skryptu, ale takie podejście jest najprostsze, gdy trzeba podać wartości parametrów i zarządzać ścieżkami ze spacjami.

Po uruchomieniu tego polecenia z poziomu wiersza polecenia należy wywołać plik wykonywalny programu Windows PowerShell i użyć parametru –command , aby podać instrukcje:

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

Tak jak wcześniej, należy podać kilka dodatkowych przełączników i uniknąć wszelkich zastrzeżonych znaków XML podczas uruchamiania polecenia z msBuild:

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;

Na koniec, tak jak wcześniej, można użyć zadania Exec w niestandardowym obiekcie docelowym MSBuild do wykonania polecenia:

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

Po wykonaniu tego obiektu docelowego w ramach procesu kompilacji program Windows PowerShell uruchomi skrypt na komputerze określonym w argumencie –computername .

Podsumowanie

W tym temacie opisano sposób uruchamiania skryptu programu Windows PowerShell z pliku projektu MSBuild. Za pomocą tego podejścia można uruchomić skrypt programu Windows PowerShell lokalnie lub na komputerze zdalnym w ramach zautomatyzowanego lub jednoetapowego procesu kompilowania i wdrażania.

Dalsza lektura

Aby uzyskać wskazówki dotyczące podpisywania skryptów programu Windows PowerShell i zarządzania zasadami wykonywania, zobacz Uruchamianie skryptów programu Windows PowerShell. Aby uzyskać wskazówki dotyczące uruchamiania poleceń programu Windows PowerShell z komputera zdalnego, zobacz Uruchamianie poleceń zdalnych.

Aby uzyskać więcej informacji na temat używania niestandardowych plików projektu MSBuild do kontrolowania procesu wdrażania, zobacz Opis pliku projektu i Opis procesu kompilacji.