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

ToDos:

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)“
Team Service Erweiterung Deploy
Team Service Erweiterung Deploy MSI Install
Team Service Erweiterung Deploy
Team Service Erweiterung Deploy MSI Uninstall
Team Service Erweiterung Deploy
Team Service Erweiterung Deploy SQL

Datei RemoteDeployDeploy.ps1

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