產出物抵達 Windows 伺服器後,需要一套嚴謹且具備容錯能力的指令碼來完成最後的「落地」工作。本篇將解析 DeploySite.ps1 的核心邏輯,這套腳本負責處理解壓縮、IIS 配置與版本標記。
在自動化部署中,我們希望腳本具備兩個特性:
# 設定失敗即停止,這是自動化腳本的標配
$ErrorActionPreference = "Stop"
# 1. 載入並解析 Jenkins 傳來的元數據
$paramsPath = "D:\AP\Incoming\deploy_params.json"
if (!(Test-Path $paramsPath)) { throw "Metadata file not found!" }
$params = Get-Content $paramsPath | ConvertFrom-Json
$appName = $params.AppName
$zipFile = $params.ZipFileName
$targetPath = "D:\AP\Sites\$appName"
Write-Host "Starting deployment for $appName..."
# 2. IIS 站台與管理 (使用 WebAdministration 模組)
Import-Module WebAdministration
# 確保站台停止,避免檔案鎖定 (File Lock)
if (Get-Website -Name $appName) { Stop-Website -Name $appName }
if (Get-WebAppPool -Name $appName) { Stop-WebAppPool -Name $appName }
# 3. 檔案清理與解壓縮
if (Test-Path $targetPath) {
# 這裡可以加入備份邏輯,若部署失敗可回滾
Remove-Item "$targetPath\*" -Recurse -Force
} else {
New-Item -ItemType Directory -Path $targetPath
}
Expand-Archive -Path "D:\AP\Incoming\$zipFile" -DestinationPath $targetPath -Force
# 4. 配置 Web Application (冪等性處理)
if (!(Get-WebApplication -Name $appName -Site "Default Web Site")) {
New-WebApplication -Name $appName -Site "Default Web Site" -PhysicalPath $targetPath -ApplicationPool $appName
}
# 5. 啟動站台
Start-WebAppPool -Name $appName
Start-Website -Name $appName
# 6. 寫入版本標記
$params.CommitHash | Out-File -FilePath "$targetPath\version.txt"
Write-Host "Deployment completed successfully!"
在 .NET 應用程式運行時,許多 .dll 檔案會被 IIS 的工作進程 (w3wp.exe) 鎖定。腳本中先執行 Stop-WebAppPool 是確保後續 Remove-Item 成功的關鍵。
WebAdministration 模組將 IIS 配置映射為一個虛擬磁碟機 IIS:\。這讓我們能像操作檔案系統一樣操作 IIS:Set-ItemProperty "IIS:\AppPools\$appName" -Name "managedRuntimeVersion" -Value "v4.0"
將 CommitHash 寫入 version.txt 並存放在站台根目錄。當維運人員發現環境有問題時,只需查看此檔案,就能立即得知目前站台對應的是哪一次 Git 提交。
DeploySite.ps1 是 CD 流程在目標主機上的執行代理。它將複雜的 IIS 管理動作封裝成標準化的程序。然而,我們該如何從 Jenkins 安全地「觸發」這個腳本呢?明天,我們將介紹透過 Windows 工作排程器來解決權限限制的絕招。