Eerste commit
This commit is contained in:
@@ -0,0 +1,225 @@
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Rolt een gepubliceerde versie van MijnBesluit uit op deze server.
|
||||
|
||||
.DESCRIPTION
|
||||
Draai dit OP DE SERVER, in een PowerShell-venster dat je als administrator hebt geopend.
|
||||
|
||||
Het script haalt het pad en de toepassingsgroep uit IIS, zet de site stil, bewaart de huidige
|
||||
versie als terugvaloptie, pakt de nieuwe versie uit, start de site en controleert of hij
|
||||
antwoordt. Gaat er iets mis, dan wordt de vorige versie teruggezet.
|
||||
|
||||
De map met gegevens (sleutelbestand, kluisbestanden, appsettings.secrets.json) wordt niet
|
||||
aangeraakt: die staat daar bewust buiten.
|
||||
|
||||
.EXAMPLE
|
||||
# De zip rechtstreeks van je eigen pc halen via de externe-bureaubladverbinding:
|
||||
.\Uitrollen.ps1 -Zip \\tsclient\D\publish\mijnbesluit.zip
|
||||
|
||||
.EXAMPLE
|
||||
# Of vanaf een bestand dat al op de server staat:
|
||||
.\Uitrollen.ps1 -Zip D:\mijnbesluit.zip
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
# Het zip-bestand dat Publiceren.ps1 heeft gemaakt.
|
||||
[Parameter(Mandatory = $true)]
|
||||
[string] $Zip,
|
||||
|
||||
# De naam van de site zoals die in IIS staat. Pad en toepassingsgroep worden daaruit
|
||||
# opgehaald, zodat je die niet hoeft te onthouden.
|
||||
[string] $Site = 'mijnbesluit',
|
||||
|
||||
# Alleen invullen als je wilt afwijken van wat er in IIS staat.
|
||||
[string] $Doel,
|
||||
[string] $Pool,
|
||||
|
||||
# Adres om na afloop te controleren. Niet meegeven laat het script het afleiden uit de
|
||||
# bindingen van de site; een lege tekst slaat de controle over.
|
||||
[string] $Controleer,
|
||||
|
||||
# Zoveel vorige versies blijven bewaard om op terug te kunnen vallen.
|
||||
[int] $BewaarVersies = 5
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
# ---------------------------------------------------------------- vooraf controleren
|
||||
|
||||
$beheerder = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()
|
||||
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||
if (-not $beheerder) {
|
||||
throw 'Dit script heeft beheerdersrechten nodig. Open PowerShell met "Als administrator uitvoeren".'
|
||||
}
|
||||
|
||||
if (-not (Test-Path $Zip)) {
|
||||
throw "Het zip-bestand is niet gevonden: $Zip"
|
||||
}
|
||||
|
||||
Import-Module WebAdministration -ErrorAction Stop
|
||||
|
||||
# ---------------------------------------------------------------- gegevens uit IIS halen
|
||||
|
||||
$website = Get-Website -Name $Site -ErrorAction SilentlyContinue
|
||||
if (-not $website) {
|
||||
$bestaande = (Get-Website | Select-Object -ExpandProperty Name) -join ', '
|
||||
throw "Site '$Site' bestaat niet in IIS. Aanwezige sites: $bestaande"
|
||||
}
|
||||
|
||||
if (-not $Doel) { $Doel = [Environment]::ExpandEnvironmentVariables($website.physicalPath) }
|
||||
if (-not $Pool) { $Pool = $website.applicationPool }
|
||||
|
||||
if (-not (Test-Path "IIS:\AppPools\$Pool")) {
|
||||
throw "De toepassingsgroep '$Pool' bestaat niet in IIS."
|
||||
}
|
||||
|
||||
# Een ASP.NET Core-applicatie hoort in een toepassingsgroep zonder beheerde code te draaien.
|
||||
# Staat dat verkeerd, dan krijg je een 500.19 of 500.21 die lastig te herleiden is.
|
||||
$runtime = (Get-ItemProperty "IIS:\AppPools\$Pool" -Name managedRuntimeVersion).Value
|
||||
if ($runtime -ne '') {
|
||||
Write-Host ''
|
||||
Write-Host "Let op: toepassingsgroep '$Pool' staat op .NET CLR-versie '$runtime'." -ForegroundColor Yellow
|
||||
Write-Host 'Voor ASP.NET Core hoort dat "Geen beheerde code" te zijn. Aanpassen met:' -ForegroundColor Yellow
|
||||
Write-Host " Set-ItemProperty 'IIS:\AppPools\$Pool' -Name managedRuntimeVersion -Value ''"
|
||||
Write-Host ''
|
||||
}
|
||||
|
||||
# Controleadres afleiden uit de bindingen als het niet is meegegeven.
|
||||
if (-not $PSBoundParameters.ContainsKey('Controleer')) {
|
||||
$binding = $website.bindings.Collection | Where-Object { $_.protocol -eq 'https' } | Select-Object -First 1
|
||||
if (-not $binding) { $binding = $website.bindings.Collection | Select-Object -First 1 }
|
||||
|
||||
if ($binding) {
|
||||
# bindingInformation ziet eruit als "*:443:mijnbesluit.nl"
|
||||
$delen = $binding.bindingInformation -split ':'
|
||||
$hostnaam = if ($delen.Count -ge 3 -and $delen[2]) { $delen[2] } else { 'localhost' }
|
||||
$Controleer = "$($binding.protocol)://$hostnaam/inloggen"
|
||||
}
|
||||
}
|
||||
|
||||
$BackupWortel = Join-Path (Split-Path $Doel -Parent) '_vorige-versies'
|
||||
$Stempel = Get-Date -Format 'yyyyMMdd-HHmmss'
|
||||
$BackupMap = Join-Path $BackupWortel "$(Split-Path $Doel -Leaf)-$Stempel"
|
||||
|
||||
Write-Host ''
|
||||
Write-Host 'MijnBesluit uitrollen' -ForegroundColor Cyan
|
||||
Write-Host " Zip : $Zip"
|
||||
Write-Host " Site : $Site"
|
||||
Write-Host " Doel : $Doel"
|
||||
Write-Host " App-pool : $Pool"
|
||||
Write-Host " Controleer : $(if ($Controleer) { $Controleer } else { '(overslaan)' })"
|
||||
Write-Host ''
|
||||
|
||||
# ---------------------------------------------------------------- uitpakken naar een tijdelijke map
|
||||
|
||||
# Eerst helemaal uitpakken en controleren, en pas daarna de site stilzetten. Zo staat de site
|
||||
# maar een paar seconden uit, en niet de hele tijd dat het uitpakken duurt.
|
||||
$Tijdelijk = Join-Path $env:TEMP "mijnbesluit-$Stempel"
|
||||
Write-Host 'Uitpakken...' -ForegroundColor Cyan
|
||||
Expand-Archive -Path $Zip -DestinationPath $Tijdelijk -Force
|
||||
|
||||
foreach ($nodig in @('MijnBesluit.Web.dll', 'web.config')) {
|
||||
if (-not (Test-Path (Join-Path $Tijdelijk $nodig))) {
|
||||
Remove-Item $Tijdelijk -Recurse -Force
|
||||
throw "Dit lijkt geen geldige publicatie: $nodig ontbreekt in het zip-bestand."
|
||||
}
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------- site stilzetten
|
||||
|
||||
$draaide = (Get-WebAppPoolState -Name $Pool).Value -eq 'Started'
|
||||
if ($draaide) {
|
||||
Write-Host 'Toepassingsgroep stoppen...' -ForegroundColor Cyan
|
||||
Stop-WebAppPool -Name $Pool
|
||||
|
||||
# Wachten tot IIS de bestanden echt heeft losgelaten; anders mislukt het kopieren.
|
||||
$wachtTot = (Get-Date).AddSeconds(30)
|
||||
while ((Get-WebAppPoolState -Name $Pool).Value -ne 'Stopped' -and (Get-Date) -lt $wachtTot) {
|
||||
Start-Sleep -Milliseconds 500
|
||||
}
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
|
||||
try {
|
||||
# ------------------------------------------------------------ vorige versie bewaren
|
||||
|
||||
if (Test-Path $Doel) {
|
||||
Write-Host 'Vorige versie bewaren...' -ForegroundColor Cyan
|
||||
New-Item -ItemType Directory -Path $BackupWortel -Force | Out-Null
|
||||
Move-Item -Path $Doel -Destination $BackupMap -Force
|
||||
}
|
||||
|
||||
# ------------------------------------------------------------ nieuwe versie neerzetten
|
||||
|
||||
Write-Host 'Nieuwe versie plaatsen...' -ForegroundColor Cyan
|
||||
New-Item -ItemType Directory -Path $Doel -Force | Out-Null
|
||||
Copy-Item -Path (Join-Path $Tijdelijk '*') -Destination $Doel -Recurse -Force
|
||||
}
|
||||
catch {
|
||||
Write-Host 'Er ging iets mis; vorige versie terugzetten...' -ForegroundColor Red
|
||||
if ((Test-Path $BackupMap) -and -not (Test-Path (Join-Path $Doel 'MijnBesluit.Web.dll'))) {
|
||||
if (Test-Path $Doel) { Remove-Item $Doel -Recurse -Force }
|
||||
Move-Item -Path $BackupMap -Destination $Doel -Force
|
||||
}
|
||||
if ($draaide) { Start-WebAppPool -Name $Pool }
|
||||
throw
|
||||
}
|
||||
finally {
|
||||
if (Test-Path $Tijdelijk) { Remove-Item $Tijdelijk -Recurse -Force }
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------- weer starten
|
||||
|
||||
Write-Host 'Toepassingsgroep starten...' -ForegroundColor Cyan
|
||||
Start-WebAppPool -Name $Pool
|
||||
|
||||
# ---------------------------------------------------------------- controleren
|
||||
|
||||
if ($Controleer) {
|
||||
Write-Host "Controleren: $Controleer" -ForegroundColor Cyan
|
||||
$gelukt = $false
|
||||
|
||||
# De eerste aanroep duurt langer: dan start de applicatie op.
|
||||
for ($poging = 1; $poging -le 10; $poging++) {
|
||||
try {
|
||||
$antwoord = Invoke-WebRequest -Uri $Controleer -UseBasicParsing -TimeoutSec 30
|
||||
if ($antwoord.StatusCode -eq 200) { $gelukt = $true; break }
|
||||
}
|
||||
catch {
|
||||
Start-Sleep -Seconds 3
|
||||
}
|
||||
}
|
||||
|
||||
if ($gelukt) {
|
||||
Write-Host 'De site antwoordt.' -ForegroundColor Green
|
||||
}
|
||||
else {
|
||||
Write-Host ''
|
||||
Write-Host 'De site antwoordt niet.' -ForegroundColor Red
|
||||
Write-Host 'Kijk in Logboeken > Windows-logboeken > Toepassing, of zet in web.config'
|
||||
Write-Host 'stdoutLogEnabled op true en kijk daarna in de map logs.'
|
||||
Write-Host ''
|
||||
Write-Host 'Terugvallen op de vorige versie:' -ForegroundColor Yellow
|
||||
Write-Host " Stop-WebAppPool '$Pool'"
|
||||
Write-Host " Remove-Item '$Doel' -Recurse -Force"
|
||||
Write-Host " Move-Item '$BackupMap' '$Doel'"
|
||||
Write-Host " Start-WebAppPool '$Pool'"
|
||||
}
|
||||
}
|
||||
|
||||
# ---------------------------------------------------------------- oude versies opruimen
|
||||
|
||||
if (Test-Path $BackupWortel) {
|
||||
Get-ChildItem $BackupWortel -Directory |
|
||||
Sort-Object Name -Descending |
|
||||
Select-Object -Skip $BewaarVersies |
|
||||
ForEach-Object {
|
||||
Write-Host "Oude versie opruimen: $($_.Name)"
|
||||
Remove-Item $_.FullName -Recurse -Force
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ''
|
||||
Write-Host 'Klaar.' -ForegroundColor Green
|
||||
Write-Host " Vorige versie staat in: $BackupMap"
|
||||
Write-Host ''
|
||||
Reference in New Issue
Block a user