From 133678feb5f686d2ea3fce15d5d362960b9963eb Mon Sep 17 00:00:00 2001 From: "manuel.maier" Date: Mon, 30 Mar 2026 10:04:37 +0200 Subject: [PATCH] install_newt-msp-site-win_v2.ps1 aktualisiert --- install_newt-msp-site-win_v2.ps1 | 181 +++++++++---------------------- 1 file changed, 51 insertions(+), 130 deletions(-) diff --git a/install_newt-msp-site-win_v2.ps1 b/install_newt-msp-site-win_v2.ps1 index a7837e6..544abf3 100644 --- a/install_newt-msp-site-win_v2.ps1 +++ b/install_newt-msp-site-win_v2.ps1 @@ -1,14 +1,11 @@ -<# -.SYNOPSIS - Windows-Installer für den Newt-Client. - Features: Winget.pro, NSSM-Service, Turbo-BITS, Log-Rotation, Safe-Update & Auto-Cleanup. -#> +# ========================================== +# Newt Installer - MAIEREDV +# ========================================== param([string]$mode = "install") [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12 [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 -# --- Konfiguration --- $Repo = "fosrl/newt" $InstallDir = "C:\Program Files\me-msp-newt" $ServiceName = "MAIEREDV-Managed-Site-Client" @@ -16,162 +13,86 @@ $Symlink = "$InstallDir\newt_latest.exe" $UpdaterTaskName = "MAIEREDV-Newt-Updater" $GiteaUrl = "https://me-gitea.maieredv.cloud/manuel.maier/update-install-newt/raw/branch/main/install_newt-msp-site-win_v2.ps1" -function Write-Log($msg, $color = "White") { - Write-Host "[$(Get-Date -Format 'HH:mm:ss')] $msg" -ForegroundColor $color -} +function Write-Log($msg, $color = "White") { Write-Host "[$(Get-Date -Format 'HH:mm:ss')] $msg" -ForegroundColor $color } -# --- Umgebung vorbereiten --- function Prepare-Environment { if (!(Get-Command winget -ErrorAction SilentlyContinue)) { - Write-Log "Winget fehlt. Installiere via winget.pro..." "Cyan" - try { - Invoke-RestMethod -Uri "https://winget.pro/install.ps1" | Invoke-Expression - $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") - } catch { - Write-Log "FEHLER: Winget Installation fehlgeschlagen." "Red"; exit 1 - } + try { irm winget.pro | iex } catch { Write-Log "Winget Error" "Red" } + $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") } - if (!(Get-Command nssm -ErrorAction SilentlyContinue)) { - Write-Log "NSSM wird via Winget bereitgestellt..." "Cyan" winget install nssm --silent --accept-package-agreements --accept-source-agreements | Out-Null $env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User") } } -function Get-LatestVersion { - try { - $url = "https://api.github.com/repos/${Repo}/releases/latest" - $json = Invoke-RestMethod -Uri $url -UseBasicParsing - return $json.tag_name - } catch { - Write-Log "FEHLER: GitHub API nicht erreichbar." "Red"; exit 1 - } -} - -# --- Download & Cleanup --- function Download-Newt { param($FullVersion) - $ArchSuffix = if ([Environment]::Is64BitOperatingSystem) { "windows_amd64.exe" } else { "windows_386.exe" } - $VersionOnly = $FullVersion.TrimStart('v') - $Url = "https://github.com/${Repo}/releases/download/${VersionOnly}/newt_${ArchSuffix}" - $Target = "${InstallDir}\newt_${VersionOnly}.exe" + $Arch = if ([Environment]::Is64BitOperatingSystem) { "windows_amd64.exe" } else { "windows_386.exe" } + $VOnly = $FullVersion.TrimStart('v') + $Url = "https://github.com/$Repo/releases/download/$VOnly/newt_$Arch" + $Target = "$InstallDir\newt_$VOnly.exe" - if (!(Test-Path $InstallDir)) { New-Item -ItemType Directory -Path $InstallDir -Force | Out-Null } + if (!(Test-Path $InstallDir)) { New-Item $InstallDir -ItemType Directory -Force | Out-Null } - # 1. Download if (!(Test-Path $Target)) { - Write-Log "Downloade Version $VersionOnly..." "Cyan" - try { - Start-BitsTransfer -Source $Url -Destination $Target -Priority Foreground -ErrorAction Stop - } catch { - Write-Log "BITS fehlgeschlagen. Versuche Web-Fallback..." "Yellow" - Invoke-WebRequest -Uri $Url -OutFile $Target -UseBasicParsing - } + Write-Log "Download $VOnly..." "Cyan" + try { Start-BitsTransfer -Source $Url -Destination $Target -Priority Foreground -ErrorAction Stop } + catch { Invoke-WebRequest -Uri $Url -OutFile $Target -UseBasicParsing } } - # 2. Safe-Swap (Dienst stoppen/starten) - $Service = Get-Service $ServiceName -ErrorAction SilentlyContinue - $WasRunning = $Service -and $Service.Status -eq 'Running' + $Svc = Get-Service $ServiceName -ErrorAction SilentlyContinue + $WasRunning = $Svc -and $Svc.Status -eq 'Running' + if ($WasRunning) { Stop-Service $ServiceName -Force } - if ($WasRunning) { - Write-Log "Stoppe Dienst für Datei-Update..." "Yellow" - Stop-Service $ServiceName -Force - } + try { Copy-Item -Path $Target -Destination $Symlink -Force } catch { Write-Log "Copy Error" "Red" } + + if ($WasRunning) { Start-Service $ServiceName } - try { - Copy-Item -Path $Target -Destination $Symlink -Force - Write-Log "newt_latest.exe auf Stand $VersionOnly aktualisiert." "Green" - } catch { - Write-Log "FEHLER: Datei blockiert." "Red" - } - - if ($WasRunning) { - Start-Service $ServiceName - Write-Log "Dienst wieder gestartet." "Green" - } - - # 3. AUFRÄUMEN (Cleanup) - # Wir behalten die newt_latest.exe und die letzten 2 Versions-Exen - Write-Log "Räume alte Versionen auf..." "Yellow" - $OldVersions = Get-ChildItem -Path $InstallDir -Filter "newt_*.exe" | - Where-Object { $_.Name -ne "newt_latest.exe" } | - Sort-Object LastWriteTime -Descending | - Select-Object -Skip 2 # Die neuesten 2 bleiben zur Sicherheit da - - foreach ($file in $OldVersions) { - Write-Log "Lösche alte Version: $($file.Name)" "Gray" - Remove-Item $file.FullName -Force - } + # Cleanup: Behalte die neuesten 2 exen + Get-ChildItem $InstallDir -Filter "newt_*.exe" | Where { $_.Name -ne "newt_latest.exe" } | Sort LastWriteTime -Desc | Select -Skip 2 | Remove-Item -Force } function Setup-Service { if (!(Get-Service $ServiceName -ErrorAction SilentlyContinue)) { - Write-Log "--- Dienst-Konfiguration ---" "Yellow" - $PangolinID = Read-Host "Bitte Pangolin ID eingeben" - $PangolinSecret = Read-Host "Bitte Secret eingeben" - $PangolinEndpoint = Read-Host "Bitte Endpoint eingeben" - - $ArgList = "--id ${PangolinID} --secret ${PangolinSecret} --endpoint ${PangolinEndpoint}" - - & nssm install $ServiceName "$Symlink" $ArgList - & nssm set $ServiceName Description "MAIEREDV Managed Site Client" - & nssm set $ServiceName AppExit Default Restart - & nssm set $ServiceName AppRestartDelay 5000 - - $LogFile = "${InstallDir}\newt_service.log" - & nssm set $ServiceName AppStdout "$LogFile" - & nssm set $ServiceName AppStderr "$LogFile" + $ID = Read-Host "ID"; $Sec = Read-Host "Secret"; $End = Read-Host "Endpoint" + $Args = "--id $ID --secret $Sec --endpoint $End" + & nssm install $ServiceName "$Symlink" $Args & nssm set $ServiceName AppRotateFiles 1 & nssm set $ServiceName AppRotateOnline 1 & nssm set $ServiceName AppRotateBytes 10485760 - Start-Service $ServiceName - Write-Log "Dienst gestartet." "Green" } } -function Setup-UpdaterTask { - $ActionCommand = "powershell.exe -NoProfile -ExecutionPolicy Bypass -Command `"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; & ([scriptblock]::Create((New-Object System.Net.WebClient).DownloadString('$GiteaUrl'))) -mode update`"" - $Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument $ActionCommand - $Trigger = New-ScheduledTaskTrigger -Daily -At 3am - Register-ScheduledTask -Action $Action -Trigger $Trigger -TaskName $UpdaterTaskName -User "SYSTEM" -Force | Out-Null - Write-Log "Update-Task registriert." "Green" +function Setup-Task { + $Cmd = "powershell.exe -NoProfile -ExecutionPolicy Bypass -Command `"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; & ([scriptblock]::Create((New-Object System.Net.WebClient).DownloadString('$GiteaUrl'))) -mode update`"" + $A = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -ExecutionPolicy Bypass -Command `"[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; `$s=(New-Object System.Net.WebClient).DownloadString('$GiteaUrl'); `$b=[scriptblock]::Create(`$s); & `$b -mode update`"" + $T = New-ScheduledTaskTrigger -Daily -At 3am + $P = New-ScheduledTaskPrincipal -UserId "SYSTEM" -LogonType ServiceAccount -RunLevel Highest + Register-ScheduledTask -Action $A -Trigger $T -Principal $P -TaskName $UpdaterTaskName -Force | Out-Null } -# --- Main --- +# --- Ausführung --- Prepare-Environment -switch ($mode) { - "install" { - $v = Get-LatestVersion - Download-Newt $v - Setup-Service - Setup-UpdaterTask - Write-Log "🚀 Installation abgeschlossen!" "Green" +if ($mode -eq "install") { + $v = (Invoke-RestMethod "https://api.github.com/repos/$Repo/releases/latest").tag_name + Download-Newt $v + Setup-Service + Setup-Task + Write-Log "Fertig." "Green" +} +elseif ($mode -eq "update") { + $v = (Invoke-RestMethod "https://api.github.com/repos/$Repo/releases/latest").tag_name + $vO = $v.TrimStart('v') + if (!(Test-Path "$InstallDir\newt_$vO.exe")) { Download-Newt $v } + else { Write-Log "Aktuell." "Cyan" } +} +elseif ($mode -eq "uninstall") { + if (Get-Service $ServiceName -ErrorAction SilentlyContinue) { + Stop-Service $ServiceName -Force + & nssm remove $ServiceName confirm } - "update" { - $v = Get-LatestVersion - $vOnly = $v.TrimStart('v') - $TargetVersionPath = "${InstallDir}\newt_${vOnly}.exe" - - $NeedsUpdate = $false - if (!(Test-Path $TargetVersionPath)) { - $NeedsUpdate = $true - } elseif (Test-Path $Symlink) { - $HashLatest = (Get-FileHash $Symlink).Hash - $HashTarget = (Get-FileHash $TargetVersionPath).Hash - if ($HashLatest -ne $HashTarget) { $NeedsUpdate = $true } - } else { - $NeedsUpdate = $true - } - - if ($NeedsUpdate) { - Download-Newt $v - Write-Log "🚀 Update auf $v durchgeführt." "Green" - } else { - Write-Log "System ist aktuell ($vOnly)." "Cyan" - if ((Get-Service $ServiceName).Status -ne 'Running') { Start-Service $ServiceName } - } - } - "uninstall \ No newline at end of file + Unregister-ScheduledTask $UpdaterTaskName -Confirm:$false -ErrorAction SilentlyContinue +} \ No newline at end of file