Installation automatisieren
Geschrieben von Daniel von PhySonix
Zuletzt aktualisiert Vor etwa 1 Jahr
Einleitung
Mit Patchmanagement-Software können Sie die Installation und Aktualisierung von PhySonix Easy Connect ganz einfach automatisieren. Damit sind Sie immer Up-To-Date, und können manuellen Aufwand reduzieren.
Die Installer sind Standard MSI-Installer, und können mittels
/quietohne Oberfläche ausgeführt werden (Details)Die aktuellen Versionen der MSI-Installer sind über eine fixe URL erreichbar (Details)
Diese Infos sollten Ihnen einen guten Start bieten, um die Installation und Aktualisierung zu automatisieren.
Falls Sie den Easy Connect Server auf Linux installieren oder in einem Docker Container laufen lassen möchten, stimmen Sie für Easy Connect Server auf Linux oder als Docker Image ab oder hinterlassen Sie dort einen Kommentar.
PowerShell Script
Als weitere Hilfe haben wir ein PowerShell Script vorbereitet, welches folgende Funktionen unterstützt:
Unterstützt PhySonix Easy Connect Server und Client
Einstellungen vordefinieren mittels Parameter, oder Auswahl über GUI oder Konsole
Auswahl des Software-Kanals (Release oder Beta) (Details)
Herunterladen und entpacken der MSI-Installer
Ausführen der MSI-Installer ohne Oberfläche (mit
/quiet)
############################################################################
# 1) Param-Block: Direkte Parameterverwendung
############################################################################
Param(
[string]$InstallPath = "C:\PhySonix\Install",
[ValidateSet("ServerAndClient","ServerOnly","ClientOnly")]
[string]$Components = "ServerAndClient",
[ValidateSet("Release","Beta")]
[string]$InstallerType = "Release"
)
############################################################################
# 2) Prüfung, ob Parameter übergeben wurden
# => Wenn $PSBoundParameters.Count > 0, direkt mit Parametern weiter.
############################################################################
$paramModeActive = $PSBoundParameters.Count -gt 0
############################################################################
# 3) Prüfen auf GUI-Verfügbarkeit (nur relevant, wenn KEIN Param-Mode aktiv)
############################################################################
$useGui = $true
if (-not $paramModeActive) {
try {
if (-not [System.Environment]::UserInteractive) {
Write-Host "System ist nicht interaktiv (UserInteractive=$false). Wechsle zu Konsolen-Modus."
$useGui = $false
} else {
Add-Type -AssemblyName System.Windows.Forms -ErrorAction Stop
Add-Type -AssemblyName System.Drawing -ErrorAction Stop
}
}
catch {
Write-Host "Fehler beim Laden der WinForms-Assembly. Wechsle zu Konsolen-Modus."
$useGui = $false
}
}
############################################################################
# 4) GUI-Funktion
############################################################################
function Show-InstallUI {
# Hauptformular erzeugen
$form = New-Object System.Windows.Forms.Form
$form.Text = "PhySonix Easy Connect Installer"
$form.Size = New-Object System.Drawing.Size(520, 300)
$form.StartPosition = "CenterScreen"
# --- Label & TextBox: Installationspfad ---
$lblInstallPath = New-Object System.Windows.Forms.Label
$lblInstallPath.Text = "Download- und Arbeitsverzeichnis:"
$lblInstallPath.AutoSize = $true
$lblInstallPath.Location = New-Object System.Drawing.Point(10, 10)
$form.Controls.Add($lblInstallPath)
$txtInstallPath = New-Object System.Windows.Forms.TextBox
$txtInstallPath.Text = "C:\PhySonix\Install"
$txtInstallPath.Width = 400
$txtInstallPath.Location = New-Object System.Drawing.Point(10, 30)
$form.Controls.Add($txtInstallPath)
# --- Label & ComboBox: Komponenten (Server/Client) ---
$lblComponents = New-Object System.Windows.Forms.Label
$lblComponents.Text = "Zu installierende Komponenten:"
$lblComponents.AutoSize = $true
$lblComponents.Location = New-Object System.Drawing.Point(10, 70)
$form.Controls.Add($lblComponents)
$cboComponents = New-Object System.Windows.Forms.ComboBox
$cboComponents.DropDownStyle = "DropDownList"
$cboComponents.Width = 200
$cboComponents.Location = New-Object System.Drawing.Point(10, 90)
$cboComponents.Items.Add("ServerAndClient")
$cboComponents.Items.Add("ServerOnly")
$cboComponents.Items.Add("ClientOnly")
# Standard-Auswahl = "ServerAndClient"
$cboComponents.SelectedIndex = 0
$form.Controls.Add($cboComponents)
# --- Label & ComboBox: Release / Beta ---
$lblInstallerType = New-Object System.Windows.Forms.Label
$lblInstallerType.Text = "Release- oder Beta-Version?"
$lblInstallerType.AutoSize = $true
$lblInstallerType.Location = New-Object System.Drawing.Point(10, 130)
$form.Controls.Add($lblInstallerType)
$cboInstallerType = New-Object System.Windows.Forms.ComboBox
$cboInstallerType.DropDownStyle = "DropDownList"
$cboInstallerType.Width = 120
$cboInstallerType.Location = New-Object System.Drawing.Point(10, 150)
$cboInstallerType.Items.Add("Release")
$cboInstallerType.Items.Add("Beta")
$cboInstallerType.SelectedIndex = 0
$form.Controls.Add($cboInstallerType)
# --- Buttons: OK / Abbrechen ---
$okButton = New-Object System.Windows.Forms.Button
$okButton.Text = "OK"
$okButton.Width = 80
$okButton.Location = New-Object System.Drawing.Point(10, 200)
$form.Controls.Add($okButton)
$cancelButton = New-Object System.Windows.Forms.Button
$cancelButton.Text = "Abbrechen"
$cancelButton.Width = 80
$cancelButton.Location = New-Object System.Drawing.Point(100, 200)
$form.Controls.Add($cancelButton)
$script:FormResult = $null
# --- Event: OK-Button ---
$okButton.Add_Click({
$result = [PSCustomObject]@{
InstallPath = $txtInstallPath.Text
Components = $cboComponents.SelectedItem
InstallerType = $cboInstallerType.SelectedItem
}
$script:FormResult = $result
$form.Close()
})
# --- Event: Abbrechen-Button ---
$cancelButton.Add_Click({
# Wir geben $null zurück und schließen die Form
$script:FormResult = $null
$form.Close()
})
[void]$form.ShowDialog()
return $script:FormResult
}
############################################################################
# 5) Konsolen-Fallback-Funktion (Read-Host)
############################################################################
function Show-InstallConsole {
param(
[string]$DefaultInstallPath = "C:\PhySonix\Install"
)
Write-Host "=== Konsolenmodus ==="
$obj = [PSCustomObject]@{
InstallPath = $DefaultInstallPath
Components = "ServerAndClient"
InstallerType = "Release"
}
# InstallPath
$installPathInput = Read-Host "Bitte geben Sie das Download- und Arbeitsverzeichnis an (Standard: $($DefaultInstallPath))"
if (-not [string]::IsNullOrWhiteSpace($installPathInput)) {
$obj.InstallPath = $installPathInput
}
# Components
Write-Host "1) ServerAndClient (Standard)"
Write-Host "2) ServerOnly"
Write-Host "3) ClientOnly"
$compInput = Read-Host "Bitte Auswahl eingeben (1/2/3)"
switch ($compInput) {
{$_ -eq "" -or $_ -eq "1"} { $obj.Components = "ServerAndClient" }
"2" { $obj.Components = "ServerOnly" }
"3" { $obj.Components = "ClientOnly" }
default {
Write-Error "Ungültige Auswahl."
exit 1
}
}
# InstallerType
Write-Host "1) Release (Standard)"
Write-Host "2) Beta"
$typeInput = Read-Host "Bitte Auswahl eingeben (1/2)"
switch ($typeInput) {
{$_ -eq "" -or $_ -eq "1"} { $obj.InstallerType = "Release" }
"2" { $obj.InstallerType = "Beta" }
default {
Write-Error "Ungültige Auswahl."
exit 1
}
}
return $obj
}
############################################################################
# 6) Ermittlung der finalen Parameter (GUI / Konsole / Direkt)
############################################################################
if ($paramModeActive) {
# --- Direkte Parameter-Übergabe ---
Write-Host "Parameter-Modus erkannt. Verwende übergebene Werte:"
Write-Host "InstallPath = $InstallPath"
Write-Host "Components = $Components"
Write-Host "InstallerType = $InstallerType"
}
else {
# --- Keine Parameter => GUI oder Konsole ---
if ($useGui) {
Write-Host "GUI-Modus wird verwendet..."
$uiResult = Show-InstallUI
# 1) Prüfung: Hat der/die Benutzer*in auf Abbrechen geklickt?
if (-not $uiResult) {
Write-Host "Installation abgebrochen (GUI)."
[System.Windows.Forms.Application]::Exit()
exit 0
}
# 2) Prüfung: Sind irgendwelche Felder leer?
elseif (
[string]::IsNullOrWhiteSpace($uiResult.InstallPath) -or
[string]::IsNullOrWhiteSpace($uiResult.Components) -or
[string]::IsNullOrWhiteSpace($uiResult.InstallerType)
) {
Write-Host "Installation abgebrochen: Mindestens ein Feld wurde leer gelassen."
[System.Windows.Forms.Application]::Exit()
exit 0
}
# Werte übernehmen
$InstallPath = $uiResult.InstallPath
$Components = $uiResult.Components
$InstallerType = $uiResult.InstallerType
}
else {
Write-Host "Konsolen-Modus wird verwendet..."
$consoleResult = Show-InstallConsole
if (-not $consoleResult) {
Write-Host "Installation abgebrochen (Konsole)."
exit 0
}
elseif (
[string]::IsNullOrWhiteSpace($consoleResult.InstallPath) -or
[string]::IsNullOrWhiteSpace($consoleResult.Components) -or
[string]::IsNullOrWhiteSpace($consoleResult.InstallerType)
) {
Write-Host "Installation abgebrochen: Mindestens ein Feld wurde leer gelassen."
exit 0
}
$InstallPath = $consoleResult.InstallPath
$Components = $consoleResult.Components
$InstallerType = $consoleResult.InstallerType
}
}
############################################################################
# 7) Haupt-Logik: Download, Entpacken, Installieren
############################################################################
Write-Host "`n=== INSTALLATION START ==="
Write-Host "InstallPath = $InstallPath"
Write-Host "Components = $Components"
Write-Host "InstallerType = $InstallerType"
Write-Host "================================`n"
# Pfad anlegen (falls nicht vorhanden)
if (-not (Test-Path $InstallPath)) {
New-Item -ItemType Directory -Path $InstallPath -Force | Out-Null
}
# URLs definieren
$releaseUrls = @{
Server = "https://physonix.blob.core.windows.net/downloads/updates/easy-connect-server/PhySonix%20Easy%20Connect%20Server%20Installer.zip"
Client = "https://physonix.blob.core.windows.net/downloads/updates/easy-connect/PhySonix%20Easy%20Connect%20Installer.zip"
}
$betaUrls = @{
Server = "https://physonix.blob.core.windows.net/downloads/updates/easy-connect-server/PhySonix%20Easy%20Connect%20Server%20Installer%20(Beta).zip"
Client = "https://physonix.blob.core.windows.net/downloads/updates/easy-connect/PhySonix%20Easy%20Connect%20Installer%20(Beta).zip"
}
switch ($InstallerType) {
"Release" { $urls = $releaseUrls; Write-Host "Release-Version ausgewählt." }
"Beta" { $urls = $betaUrls; Write-Host "Beta-Version ausgewählt." }
}
# Welche Komponenten sollen installiert werden?
switch ($Components) {
"ServerAndClient" {
$installServer = $true
$installClient = $true
}
"ServerOnly" {
$installServer = $true
$installClient = $false
}
"ClientOnly" {
$installServer = $false
$installClient = $true
}
}
# Entpackpfad
$extractPath = Join-Path -Path $InstallPath -ChildPath "PhySonix Easy Connect Extracted"
if (Test-Path $extractPath) {
Remove-Item -Path "$extractPath\*" -Recurse -Force -ErrorAction SilentlyContinue
} else {
New-Item -ItemType Directory -Path $extractPath -Force | Out-Null
}
# Download-Funktion
function Download-File {
param (
[string]$url,
[string]$outputPath
)
try {
Write-Host "Lade Datei herunter von: $url"
Invoke-WebRequest -Uri $url -OutFile $outputPath -ErrorAction Stop
Write-Host "Datei erfolgreich heruntergeladen: $outputPath"
}
catch {
Write-Error "Fehler beim Herunterladen: $url - $_"
exit 1
}
}
# Entpack-Funktion
function Extract-Zip {
param (
[string]$zipFilePath,
[string]$destinationPath
)
try {
Write-Host "Entpacke Datei: $zipFilePath nach $destinationPath"
Add-Type -AssemblyName System.IO.Compression.FileSystem -ErrorAction Stop
[System.IO.Compression.ZipFile]::ExtractToDirectory($zipFilePath, $destinationPath)
Write-Host "Datei erfolgreich entpackt: $zipFilePath"
Remove-Item -Path $zipFilePath -Force
Write-Host "ZIP-Datei gelöscht: $zipFilePath"
}
catch {
Write-Error "Fehler beim Entpacken: $zipFilePath - $_"
exit 1
}
}
# MSI-Installation
function Install-MSI {
param (
[string]$msiFilePath
)
try {
Write-Host "Starte Installation der MSI: $msiFilePath"
$process = Start-Process -FilePath $msiFilePath -ArgumentList "/quiet" -PassThru -ErrorAction Stop
$process.WaitForExit()
if ($process.ExitCode -eq 0) {
Write-Host "Installation erfolgreich: $msiFilePath"
}
else {
Write-Warning "Fehler bei der Installation: $msiFilePath (Exit-Code: $($process.ExitCode))"
}
}
catch {
Write-Error "Fehler beim Installieren der MSI-Datei: $msiFilePath - $_"
}
}
# == Server-Installation ==
if ($installServer) {
$zipFile = Join-Path -Path $InstallPath -ChildPath "PhySonix Easy Connect Server.zip"
Download-File -url $urls["Server"] -outputPath $zipFile
Extract-Zip -zipFilePath $zipFile -destinationPath $extractPath
$serverMsi = Get-ChildItem -Path $extractPath -Filter "*.msi" `
| Where-Object { $_.Name -match "Server" } `
| Select-Object -First 1
if ($serverMsi) {
Write-Host "Stoppe ggf. vorhandenen Dienst 'PhySonixEasyConnectServer'..."
Stop-Service -Name "PhySonixEasyConnectServer" -ErrorAction SilentlyContinue
Install-MSI -msiFilePath $serverMsi.FullName
}
else {
Write-Warning "Server-MSI-Datei nicht gefunden."
}
}
# == Client-Installation ==
if ($installClient) {
$zipFile = Join-Path -Path $InstallPath -ChildPath "PhySonix Easy Connect Client.zip"
Download-File -url $urls["Client"] -outputPath $zipFile
Extract-Zip -zipFilePath $zipFile -destinationPath $extractPath
$clientMsi = Get-ChildItem -Path $extractPath -Filter "*.msi" `
| Where-Object { $_.Name -match "Client|Easy Connect" } `
| Select-Object -First 1
if ($clientMsi) {
Install-MSI -msiFilePath $clientMsi.FullName
}
else {
Write-Warning "Client-MSI-Datei nicht gefunden."
}
}
Write-Host "`nSkript abgeschlossen."