Team Service Erweiterung – Remote Deploy

Mit dem Remote Deploy Tool stellen Sie mithilfe von Windows Remote Management (WinRM) für PowerShell eine Verbindung zu den Host-Computern her, Deinstallieren und installieren Sie Ihr MSI Paket. Zusätzlich enthält das Skript noch die Ausführung von SQL Skripte für die Aktualisierung der Datenbank. Über den folgenden Link bekommen Sie das komplette Paket als ZIP bereitgestellt. Das Skript ist kostenfrei und kann nach Ihren wünschen angepasst werden. Donload Remote Deploy Team Service extensions f89cfef33b7c9dd537f5affcb4b4d296 ToDos: Als Vorraussetzung ist wie beschrieben Windows Remote Management für PowerShell. Eine Anleitung für die Konfiguration finden Sie hier: PowerShell Remotezugriff einrichten / prüfen. Entpacken Sie das Zip und Importieren den PowerShell Task. Eine Beschreibung für den Import finden Sie hier:  Eigene TFS Build / Release Aufgaben bereitstellen Erstellen Sie eine neue Release definition. Infos finden Sie hier: Define your CD release process Fügen Sie jetzt Ihre Aufgaben wie SPS Remote Deploy hinzu. Geben Sie nun alle notwendigen Werte ein und führen die Bereitstellung aus. Folgende Parameter können Sie mitgeben: Server: Full Qualified Name des Servers (MeinServer.Domaende.de) Admin Login: User der lokale Administrationsrechte besitzt (Domaende\Admin) Password: Passwort des Administrators Application URL / Name: Applikationsname für Protokollierung und SQL DB Name MSI Name: MSI Name (Setup.msi) Target Folder: MSI Ablageverzeichnis auf dem Zielsystem Action: Abhängig von der Tätigkeit haben Sie die Auswahl MSI Uninstall, MSI Install, SQL Run. MSI Arguments: MSI Parameter, z.B. INSTALLLOCATION=“$(WebIISRoot)\$(RELEASE.ENVIRONMENTNAME)“ MSINEWINSTANCE=$(MSINEWINSTANCE) TRANSFORMS=$(TRANSFORMS) INSTALLATIONMODE=$(INSTALLATIONMODE) INSTALLATIONURL=“$(RELEASE.ENVIRONMENTNAME)“ DATABASSERVERNAME=“$(SQLServer)“ DATABASSERVERPORT=“$(SQLServerPort)“ DATABASENAME=“$(RELEASE.ENVIRONMENTNAME)“ DATABASEUSER=“$(RELEASE.ENVIRONMENTNAME)“ DATABASEUSERPASSWORD=“$(AppSQLUserPassword)“ DATABSEENCRYPTION=“$(SQLDBEncryption)“ LOGDIR=“$(WebLogDir)\$(RELEASE.ENVIRONMENTNAME)“ ENABLEDLOGFILES=“$(ENABLEDLOGFILES)“ param ( [string]$Machine, [string]$AdminUserName, [string]$AdminPassword, [string]$DBName, [string]$Action, [string]$MSIFolderOrCode, [string]$AppName, [string]$MSIName [string]$TargetFolder, [string]$MSIArguments, [int]$Timeout ) if($Timeout -NOTmatch „[1-9]“){$Timeout = 300} Write-Output „Machine Name – $Machine“ Write-Output „Admin User Name – $AdminUserName“ Write-Output „Admin User Password – **********“ Write-Output „Application Name – $AppName“ Write-Output „Database Name – $DBName“ Write-Output „Action selected – $Action“ Write-Output „MSI Path or productcode – $MSIFolderOrCode“ Write-Output „MSI Path – $MSIPath“ Write-Output „Target Folder – $TargetFolder“ Write-Output „MSI Arguments – $MSIArguments“ Write-Output „Timeout in sec – $Timeout“ Write-Output „Start RemoteConnection“ $pass = ConvertTo-SecureString -AsPlainText $AdminPassword -Force $credential = new-object -typename System.Management.Automation.PSCredential -argumentlist $AdminUserName,$pass # Deploy Write-Output „Deploy“ Invoke-Command -ComputerName $Machine -credential $credential -ScriptBlock { param ( [string]$Machine, [string]$AdminUserName, [string]$AdminPassword, [string]$AppName, [string]$DBName, [string]$AppVersion, [string]$Action, [string]$MSIName, [string]$TargetFolder, [string]$MSIArguments, [int]$Timeout ) $DataStamp = get-date -Format yyyyMMddTHHmmss $MSIArguments = $MSIArguments -replace „`t|`n|`r“,“ “ $timeouted = $null if ($Action -eq „uninstall“) { Write-Output „Uninstall App – ($AppName)…….“ $uninstall = 0 # Check productcode and MSI exists if ($MSIFolderOrCode -like „{*}“){ $properties = „identifyingnumber“,“name“,“vendor“,“version“ Get-ChildItem HKLM:SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\*\Products | ForEach-Object { $root = $_.PsPath $_.GetSubKeyNames() | ForEach-Object { try { $RegKeyPath = (Join-Path -Path (Join-Path -Path $root -ChildPath $_) -ChildPath InstallProperties) $obj = Get-ItemProperty -Path $RegKeyPath -ErrorAction Stop if ($obj.UninstallString) { $guid = ($obj.UninstallString -replace „msiexec\.exe\s/[IX]{1}“,““) if($guid -eq $MSIFolderOrCode){ Write-Output „Uninstall guid: “ + $guid Write-Output „Uninstall version: “ + $obj.DisplayVersion Write-Output „Uninstall name: “ + $obj.DisplayName Write-Output „Uninstall vendor: “ + $obj.Publisher $obj = “ $uninstall = 1 } } } catch { } } } } elseif ($MSIFolderOrCode -like „*\*.msi“) { if (Test-Path $MSIFolderOrCode) { $uninstall = 1 } } # Uninstall if($uninstall -eq 1){ $logFile = ‚“‚+$AppName+‘-‚+$AppVersion+‘-Uninstall-‚ + $DataStamp+‘.log“‚ $arguments = ‚/q /x ‚ + $MSIFolderOrCode + ‚ /passive ‚ + $MSIArguments + ‚ /l*v ‚ + $logFile $output = ‚Start-Process „msiexec.exe“ -ArgumentList ‚ + $arguments + ‚ -PassThru‘ Write-Output $output $Request = Start-Process „msiexec.exe“ -ArgumentList $arguments -PassThru $Request | Wait-Process -Timeout $Timeout If ($($Request.ExitCode) -eq ‚0‘) { Write-Output „$AppName uninstalled successfully!“ } else{ Write-Error -Message „$AppName failed to uninstall with exit error: $($Request.ExitCode)“ } Write-Output „Request: $Request“ } } else{ Write-Error ‚MSI or productcode not found: $MSIFolderOrCode‘ } } if ($Action -eq „install“) { Write-Output „Install App – ($AppName)…….“ $msi = $TargetFolder + ‚\‘ + $MSIName # Check MSI exists if (Test-Path $msi) { $logFile = ‚“‚+$TargetFolder+’\’+$AppName+‘-‚+$AppVersion+‘-Install-‚ + $DataStamp+‘.log“‚ $arguments = ‚/q /i „‚ + $msi + ‚“ ALLUSERS=“ALLUSERS“ /passive ‚ + $MSIArguments + ‚ /l*v ‚ + $logFile $output = ‚Start-Process „msiexec.exe“ -ArgumentList ‚ + $arguments + ‚ -PassThru‘ Write-Output $output $Request = Start-Process „msiexec.exe“ -ArgumentList $arguments -PassThru $Request | Wait-Process -Timeout $Timeout If($($Request.ExitCode) -eq ‚0‘) { Write-Output „$AppName installed successfully!“ } else{ Write-Error -Message „$AppName failed to install with exit error: $($Request.ExitCode)“ } } else{ Write-Error ‚MSI not found: $msi‘ } } if ($Action -eq „sql“) { Write-Output „Run SQL Script – ($AppName)…….“ Write-Output „Provide modul sqlps in powershell“ import-module „sqlps“ -DisableNameChecking # Check SQL files and run if (Test-Path $TargetFolder) { # Dateien suchen und ausfuehren Write-Output „SQL file search: $TargetFolder\*.slq“ $files = Get-ChildItem „$TargetFolder\*.sql“ -Recurse | Select-Object Name, Fullname | Sort-Object Name foreach ($file in $files){ try{ Write-Output „Script run: invoke-sqlcmd -ServerInstance $Machine -Database $DBName -InputFile $file.FullName -QueryTimeout $Timeout -ConnectionTimeout $Timeout -ErrorAction ‚Stop'“ invoke-sqlcmd -ServerInstance $Machine -Database $DBName -InputFile $file.FullName -QueryTimeout $Timeout -ConnectionTimeout $Timeout -ErrorAction ‚Stop‘ } catch{ Write-Error „Error in script: “ + $file.FullName Write-Error $error -foregroundcolor red } } } else{ Write-Error ‚SQL path not found: $TargetFolder‘ } } } -ArgumentList ($Machine, $AdminUserName, $AdminPassword, $AppName, $DBName, $AppVersion, $Action, $MSIName, $TargetFolder, $MSIArguments, $Timeout) Weitere Infos: Release Management Team Service Erweiterung – Application Pool Start / Stop Team Service Erweiterung – Download Artifacts Team Service Erweiterung – Deploy