MSBuild 프로젝트 파일에서 Windows PowerShell 스크립트 실행
작성자: Jason Lee
이 항목에서는 빌드 및 배포 프로세스의 일부로 Windows PowerShell 스크립트를 실행하는 방법을 설명합니다. 스크립트를 로컬로(즉, 빌드 서버에서) 실행하거나 대상 웹 서버 또는 데이터베이스 서버와 같이 원격으로 실행할 수 있습니다.
배포 후 Windows PowerShell 스크립트를 실행하려는 데는 여러 가지 이유가 있습니다. 예를 들어, 다음을 수행합니다.
- 레지스트리에 사용자 지정 이벤트 원본을 추가합니다.
- 업로드할 파일 시스템 디렉터리를 생성합니다.
- 빌드 디렉터리를 정리합니다.
- 사용자 지정 로그 파일에 항목을 씁니다.
- 사용자를 새로 프로비전된 웹 애플리케이션에 초대하는 이메일을 보냅니다.
- 적절한 권한으로 사용자 계정을 만듭니다.
- SQL Server 인스턴스 간에 복제를 구성합니다.
이 항목에서는 MSBuild(Microsoft Build Engine) 프로젝트 파일의 사용자 지정 대상에서 로컬 및 원격으로 Windows PowerShell 스크립트를 실행하는 방법을 보여 줍니다.
이 항목은 Fabrikam, Inc.라는 가상 회사의 엔터프라이즈 배포 요구 사항을 기반으로 하는 일련의 자습서의 일부를 구성합니다. 이 자습서 시리즈에서는 샘플 솔루션인 Contact Manager 솔루션을 사용하여 ASP.NET MVC 3 애플리케이션, WCF(Windows Communication Foundation) 서비스 및 데이터베이스 프로젝트를 포함하여 현실적인 수준의 복잡성이 있는 웹 애플리케이션을 나타냅니다.
이 자습서의 핵심인 배포 방법은 프로젝트 파일 이해에 설명된 분할 프로젝트 파일 접근 방식을 기반으로 하며, 빌드 프로세스는 모든 대상 환경에 적용되는 빌드 지침과 환경별 빌드 및 배포 설정을 포함하는 두 개의 프로젝트 파일에 의해 제어됩니다. 빌드 시 환경별 프로젝트 파일은 환경에 구애받지 않은 프로젝트 파일로 병합되어 전체 빌드 지침 집합을 형성합니다.
작업 개요
자동화 또는 단일 단계 배포 프로세스의 일부로 Windows PowerShell 스크립트를 실행하려면 다음 상위 수준 작업을 완료해야 합니다.
- 솔루션 및 소스 제어에 Windows PowerShell 스크립트를 추가합니다.
- Windows PowerShell 스크립트를 호출하는 명령을 만듭니다.
- 명령에서 예약된 XML 문자를 이스케이프합니다.
- 사용자 지정 MSBuild 프로젝트 파일에 대상을 만들고 Exec 작업을 사용하여 명령을 실행합니다.
이 항목에서는 이러한 절차를 수행하는 방법을 보여 줍니다. 이 항목의 작업 및 연습에서는 MSBuild 대상 및 속성에 이미 익숙하고 사용자 지정 MSBuild 프로젝트 파일을 사용하여 빌드 및 배포 프로세스를 구동하는 방법을 이해하고 있다고 가정합니다. 자세한 내용은 프로젝트 파일 이해 및 빌드 프로세스 이해를 참조하세요.
Windows PowerShell 스크립트 만들기 및 추가
이 항목의 태스크는LogDeploy.ps1라는 샘플 Windows PowerShell 스크립트를 사용하여 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
MSBuild에서LogDeploy.ps1 스크립트를 사용할 수 있도록 하려면 다음을 수행해야 합니다.
- 소스 제어에 스크립트를 추가합니다.
- Visual Studio 2010에서 솔루션에 스크립트를 추가합니다.
빌드 서버 또는 원격 컴퓨터에서 스크립트를 실행할 계획인지 여부에 관계없이 솔루션 콘텐츠로 스크립트를 배포할 필요가 없습니다. 한 가지 옵션은 솔루션 폴더에 스크립트를 추가하는 것입니다. Contact Manager 예제에서는 배포 프로세스의 일부로 Windows PowerShell 스크립트를 사용하려고 하므로 스크립트를 솔루션 게시 폴더에 추가하는 것이 좋습니다.
솔루션 폴더의 내용은 원본 자료로 서버를 빌드하기 위해 복사됩니다. 그러나 프로젝트 출력의 일부를 구성하지 않습니다.
빌드 서버에서 Windows PowerShell 스크립트 실행
일부 시나리오에서는 프로젝트를 빌드하는 컴퓨터에서 Windows PowerShell 스크립트를 실행할 수 있습니다. 예를 들어 Windows PowerShell 스크립트를 사용하여 빌드 폴더를 클린 사용자 지정 로그 파일에 항목을 쓸 수 있습니다.
구문 측면에서 MSBuild 프로젝트 파일에서 Windows PowerShell 스크립트를 실행하는 것은 일반 명령 프롬프트에서 Windows PowerShell 스크립트를 실행하는 것과 동일합니다. powershell.exe 실행 파일을 호출하고 –command 스위치를 사용하여 Windows PowerShell 실행할 명령을 제공해야 합니다. (Windows PowerShell v2에서는 –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 스크립트 파일을 실행하지 못하게 합니다.
마지막으로 Windows PowerShell 명령에서 발생하는 예약된 XML 문자를 이스케이프해야 합니다.
작은따옴표를 &apos로 바꿉니다.
큰따옴표를 &따옴표로 바꾸면 됩니다.
앰퍼샌드를 &
이러한 변경을 수행하면 명령이 다음과 유사합니다.
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 WinRM(Windows 원격 관리)을 통해 원격 컴퓨터에서 스크립트를 실행할 수 있습니다. 이렇게 하려면 Invoke-Command cmdlet을 사용해야 합니다. 이렇게 하면 스크립트를 원격 컴퓨터에 복사하지 않고 하나 이상의 원격 컴퓨터에 대해 스크립트를 실행할 수 있습니다. 모든 결과는 스크립트를 실행한 로컬 컴퓨터로 반환됩니다.
참고
Invoke-Command cmdlet을 사용하여 원격 컴퓨터에서 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' } "
마지막으로 이전과 마찬가지로 사용자 지정 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 "& invoke-command -scriptblock {
&'$(ScriptLocation)'
'$(LogFileLocation)'
'$(MSDeployComputerName)'}
""/>
</Target>
빌드 프로세스의 일부로 이 대상을 실행하면 Windows PowerShell –computername 인수에 지정한 컴퓨터에서 스크립트를 실행합니다.
결론
이 항목에서는 MSBuild 프로젝트 파일에서 Windows PowerShell 스크립트를 실행하는 방법을 설명했습니다. 이 방법을 사용하여 자동화 또는 단일 단계 빌드 및 배포 프로세스의 일부로 로컬 또는 원격 컴퓨터에서 Windows PowerShell 스크립트를 실행할 수 있습니다.
추가 정보
Windows PowerShell 스크립트 서명 및 실행 정책 관리에 대한 지침은 Windows PowerShell 스크립트 실행을 참조하세요. 원격 컴퓨터에서 Windows PowerShell 명령을 실행하는 방법에 대한 지침은 원격 명령 실행을 참조하세요.
사용자 지정 MSBuild 프로젝트 파일을 사용하여 배포 프로세스를 제어하는 방법에 대한 자세한 내용은 프로젝트 파일 이해 및 빌드 프로세스 이해를 참조하세요.