| param (
|
| [switch]$Elevated
|
| )
|
|
|
|
|
| $ErrorActionPreference = "Stop"
|
|
|
|
|
|
|
|
|
| function Test-Admin {
|
| return ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
| }
|
|
|
|
|
| function Test-CommandExists {
|
| param (
|
| [Parameter(Mandatory=$true)]
|
| [string]$Command
|
| )
|
| return (Get-Command $Command -ErrorAction SilentlyContinue)
|
| }
|
|
|
|
|
| function Find-BeszelAgent {
|
|
|
| $agentCmd = Get-Command "beszel-agent" -ErrorAction SilentlyContinue
|
| if ($agentCmd) {
|
| return $agentCmd.Source
|
| }
|
|
|
|
|
| $commonPaths = @(
|
| "$env:USERPROFILE\scoop\apps\beszel-agent\current\beszel-agent.exe",
|
| "$env:ProgramData\scoop\apps\beszel-agent\current\beszel-agent.exe",
|
| "$env:LOCALAPPDATA\Microsoft\WinGet\Packages\henrygd.beszel-agent*\beszel-agent.exe",
|
| "$env:ProgramFiles\WinGet\Packages\henrygd.beszel-agent*\beszel-agent.exe",
|
| "${env:ProgramFiles(x86)}\WinGet\Packages\henrygd.beszel-agent*\beszel-agent.exe",
|
| "$env:ProgramFiles\beszel-agent\beszel-agent.exe",
|
| "$env:ProgramFiles(x86)\beszel-agent\beszel-agent.exe",
|
| "$env:SystemDrive\Users\*\scoop\apps\beszel-agent\current\beszel-agent.exe"
|
| )
|
|
|
| foreach ($path in $commonPaths) {
|
|
|
| if ($path.Contains("*")) {
|
| $foundPaths = Get-ChildItem -Path $path -ErrorAction SilentlyContinue
|
| if ($foundPaths) {
|
| return $foundPaths[0].FullName
|
| }
|
| } else {
|
| if (Test-Path $path) {
|
| return $path
|
| }
|
| }
|
| }
|
|
|
| return $null
|
| }
|
|
|
|
|
| function Find-NSSM {
|
|
|
| $nssmCmd = Get-Command "nssm" -ErrorAction SilentlyContinue
|
| if ($nssmCmd) {
|
| return $nssmCmd.Source
|
| }
|
|
|
|
|
| $commonPaths = @(
|
| "$env:USERPROFILE\scoop\apps\nssm\current\nssm.exe",
|
| "$env:ProgramData\scoop\apps\nssm\current\nssm.exe",
|
| "$env:LOCALAPPDATA\Microsoft\WinGet\Packages\NSSM.NSSM*\nssm.exe",
|
| "$env:ProgramFiles\WinGet\Packages\NSSM.NSSM*\nssm.exe",
|
| "${env:ProgramFiles(x86)}\WinGet\Packages\NSSM.NSSM*\nssm.exe",
|
| "$env:SystemDrive\Users\*\scoop\apps\nssm\current\nssm.exe"
|
| )
|
|
|
| foreach ($path in $commonPaths) {
|
|
|
| if ($path.Contains("*")) {
|
| $foundPaths = Get-ChildItem -Path $path -ErrorAction SilentlyContinue
|
| if ($foundPaths) {
|
| return $foundPaths[0].FullName
|
| }
|
| } else {
|
| if (Test-Path $path) {
|
| return $path
|
| }
|
| }
|
| }
|
|
|
| return $null
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
| function Upgrade-BeszelAgentWithScoop {
|
| Write-Host "Upgrading beszel-agent with Scoop..."
|
| scoop update beszel-agent
|
|
|
| if (-not (Test-CommandExists "beszel-agent")) {
|
| throw "Failed to upgrade beszel-agent with Scoop"
|
| }
|
|
|
| return $(Join-Path -Path $(scoop prefix beszel-agent) -ChildPath "beszel-agent.exe")
|
| }
|
|
|
|
|
| function Upgrade-BeszelAgentWithWinGet {
|
| Write-Host "Upgrading beszel-agent with WinGet..."
|
|
|
|
|
| $originalErrorActionPreference = $ErrorActionPreference
|
| $ErrorActionPreference = "Continue"
|
|
|
|
|
| & winget upgrade --exact --id henrygd.beszel-agent --accept-source-agreements --accept-package-agreements | Out-Null
|
| $wingetExitCode = $LASTEXITCODE
|
|
|
|
|
| $ErrorActionPreference = $originalErrorActionPreference
|
|
|
|
|
|
|
|
|
|
|
|
|
| if ($wingetExitCode -eq -1978335212 -or $wingetExitCode -eq -1978335189) {
|
| Write-Host "Package is already up to date." -ForegroundColor Green
|
| } elseif ($wingetExitCode -ne 0) {
|
| Write-Host "WinGet exit code: $wingetExitCode" -ForegroundColor Yellow
|
| }
|
|
|
|
|
| $env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
|
|
|
|
| $agentPath = (Get-Command beszel-agent -ErrorAction SilentlyContinue).Source
|
|
|
| if (-not $agentPath) {
|
|
|
| $agentPath = Find-BeszelAgent
|
| if (-not $agentPath) {
|
| throw "Could not find beszel-agent executable path after upgrade"
|
| }
|
| }
|
|
|
| return $agentPath
|
| }
|
|
|
|
|
| function Get-ServiceConfiguration {
|
| param (
|
| [string]$NSSMPath = ""
|
| )
|
|
|
|
|
| $nssmCommand = "nssm"
|
| if ($NSSMPath -and (Test-Path $NSSMPath)) {
|
| $nssmCommand = $NSSMPath
|
| } elseif (-not (Test-CommandExists "nssm")) {
|
| throw "NSSM is not available in PATH and no valid NSSMPath was provided"
|
| }
|
|
|
|
|
| $existingService = Get-Service -Name "beszel-agent" -ErrorAction SilentlyContinue
|
| if (-not $existingService) {
|
| throw "beszel-agent service does not exist. Please run the installation script first."
|
| }
|
|
|
|
|
| $config = @{}
|
|
|
| try {
|
|
|
| $currentPath = & $nssmCommand get beszel-agent Application
|
| if ($LASTEXITCODE -eq 0) {
|
| $config.CurrentPath = $currentPath.Trim()
|
| }
|
|
|
|
|
| $envVars = & $nssmCommand get beszel-agent AppEnvironmentExtra
|
| if ($LASTEXITCODE -eq 0 -and $envVars) {
|
| $config.EnvironmentVars = $envVars
|
| }
|
|
|
| Write-Host "Current service configuration retrieved successfully."
|
| Write-Host "Current agent path: $($config.CurrentPath)"
|
|
|
| return $config
|
| }
|
| catch {
|
| throw "Failed to retrieve current service configuration: $($_.Exception.Message)"
|
| }
|
| }
|
|
|
|
|
| function Update-ServicePath {
|
| param (
|
| [Parameter(Mandatory=$true)]
|
| [string]$NewAgentPath,
|
| [string]$NSSMPath = ""
|
| )
|
|
|
| Write-Host "Updating beszel-agent service path..."
|
|
|
|
|
| $nssmCommand = "nssm"
|
| if ($NSSMPath -and (Test-Path $NSSMPath)) {
|
| $nssmCommand = $NSSMPath
|
| Write-Host "Using NSSM from: $NSSMPath"
|
| } elseif (-not (Test-CommandExists "nssm")) {
|
| throw "NSSM is not available in PATH and no valid NSSMPath was provided"
|
| }
|
|
|
|
|
| & $nssmCommand set beszel-agent Application $NewAgentPath
|
| if ($LASTEXITCODE -ne 0) {
|
| throw "Failed to update beszel-agent service path"
|
| }
|
|
|
| Write-Host "Service path updated to: $NewAgentPath"
|
|
|
|
|
| Start-BeszelAgentService -NSSMPath $nssmCommand
|
| }
|
|
|
|
|
| function Start-BeszelAgentService {
|
| param (
|
| [string]$NSSMPath = ""
|
| )
|
|
|
| Write-Host "Starting beszel-agent service..."
|
|
|
|
|
| $nssmCommand = "nssm"
|
| if ($NSSMPath -and (Test-Path $NSSMPath)) {
|
| $nssmCommand = $NSSMPath
|
| } elseif (-not (Test-CommandExists "nssm")) {
|
| throw "NSSM is not available in PATH and no valid NSSMPath was provided"
|
| }
|
|
|
| & $nssmCommand start beszel-agent
|
| $startResult = $LASTEXITCODE
|
|
|
|
|
| if ($startResult -ne 0) {
|
| Write-Host "NSSM start command returned error code: $startResult" -ForegroundColor Yellow
|
| Write-Host "This could be due to 'SERVICE_START_PENDING' state. Checking service status..."
|
|
|
|
|
| $maxWaitTime = 10
|
| $elapsedTime = 0
|
| $serviceStarted = $false
|
|
|
| while (-not $serviceStarted -and $elapsedTime -lt $maxWaitTime) {
|
| Start-Sleep -Seconds 1
|
| $elapsedTime += 1
|
|
|
| $serviceStatus = & $nssmCommand status beszel-agent
|
|
|
| if ($serviceStatus -eq "SERVICE_RUNNING") {
|
| $serviceStarted = $true
|
| Write-Host "Success! The beszel-agent service is now running." -ForegroundColor Green
|
| }
|
| elseif ($serviceStatus -like "*PENDING*") {
|
| Write-Host "Service is still starting (status: $serviceStatus)... waiting" -ForegroundColor Yellow
|
| }
|
| else {
|
| Write-Host "Warning: The service status is '$serviceStatus' instead of 'SERVICE_RUNNING'." -ForegroundColor Yellow
|
| Write-Host "You may need to troubleshoot the service installation." -ForegroundColor Yellow
|
| break
|
| }
|
| }
|
|
|
| if (-not $serviceStarted) {
|
| Write-Host "Service did not reach running state." -ForegroundColor Yellow
|
| Write-Host "You can check status manually with 'nssm status beszel-agent'" -ForegroundColor Yellow
|
| }
|
| } else {
|
|
|
| Write-Host "Success! The beszel-agent service is running properly." -ForegroundColor Green
|
| }
|
| }
|
|
|
|
|
|
|
|
|
|
|
|
|
| $isAdmin = Test-Admin
|
|
|
| try {
|
| Write-Host "Beszel Agent Upgrade Script" -ForegroundColor Cyan
|
| Write-Host "===========================" -ForegroundColor Cyan
|
|
|
|
|
| $existingService = Get-Service -Name "beszel-agent" -ErrorAction SilentlyContinue
|
| if (-not $existingService) {
|
| Write-Host "ERROR: beszel-agent service does not exist." -ForegroundColor Red
|
| Write-Host "Please run the installation script first before attempting to upgrade." -ForegroundColor Red
|
| exit 1
|
| }
|
|
|
|
|
| $nssmPath = Find-NSSM
|
| if (-not $nssmPath -and (Test-CommandExists "nssm")) {
|
| $nssmPath = (Get-Command "nssm" -ErrorAction SilentlyContinue).Source
|
| }
|
|
|
| if (-not $nssmPath) {
|
| Write-Host "ERROR: NSSM not found. Cannot manage the service without NSSM." -ForegroundColor Red
|
| exit 1
|
| }
|
|
|
|
|
| Write-Host "Retrieving current service configuration..."
|
| $currentConfig = Get-ServiceConfiguration -NSSMPath $nssmPath
|
|
|
|
|
| Write-Host "Stopping beszel-agent service..."
|
| & $nssmPath stop beszel-agent
|
| if ($LASTEXITCODE -ne 0) {
|
| Write-Host "Warning: Failed to stop service, continuing anyway..." -ForegroundColor Yellow
|
| }
|
|
|
|
|
| Write-Host "Upgrading beszel-agent..."
|
| $newAgentPath = $null
|
|
|
| if (Test-CommandExists "scoop") {
|
| Write-Host "Using Scoop for upgrade..."
|
| $newAgentPath = Upgrade-BeszelAgentWithScoop
|
| }
|
| elseif (Test-CommandExists "winget") {
|
| Write-Host "Using WinGet for upgrade..."
|
| $newAgentPath = Upgrade-BeszelAgentWithWinGet
|
| }
|
| else {
|
| Write-Host "ERROR: Neither Scoop nor WinGet is available for upgrading." -ForegroundColor Red
|
| exit 1
|
| }
|
|
|
| if (-not $newAgentPath) {
|
| $newAgentPath = Find-BeszelAgent
|
| if (-not $newAgentPath) {
|
| throw "Could not find beszel-agent executable after upgrade."
|
| }
|
| }
|
|
|
| Write-Host "New agent path: $newAgentPath"
|
|
|
|
|
| if ($currentConfig.CurrentPath -eq $newAgentPath) {
|
| Write-Host "Agent path has not changed. Restarting service..." -ForegroundColor Green
|
| Start-BeszelAgentService -NSSMPath $nssmPath
|
| Write-Host "Upgrade completed successfully!" -ForegroundColor Green
|
| exit 0
|
| }
|
|
|
| Write-Host "Agent path has changed from:" -ForegroundColor Yellow
|
| Write-Host " Old: $($currentConfig.CurrentPath)" -ForegroundColor Yellow
|
| Write-Host " New: $newAgentPath" -ForegroundColor Yellow
|
| Write-Host ""
|
|
|
|
|
| if (-not $isAdmin -and -not $Elevated) {
|
| Write-Host "Admin privileges required for service path update. Relaunching as admin..." -ForegroundColor Yellow
|
|
|
|
|
| $argumentList = @(
|
| "-ExecutionPolicy", "Bypass",
|
| "-File", "`"$PSCommandPath`"",
|
| "-Elevated"
|
| )
|
|
|
|
|
| Start-Process powershell.exe -Verb RunAs -ArgumentList $argumentList
|
| exit
|
| }
|
|
|
|
|
| if ($isAdmin -or $Elevated) {
|
| Update-ServicePath -NewAgentPath $newAgentPath -NSSMPath $nssmPath
|
|
|
| Write-Host ""
|
| Write-Host "Upgrade completed successfully!" -ForegroundColor Green
|
| Write-Host "The beszel-agent service has been updated to use the new executable path." -ForegroundColor Green
|
|
|
|
|
| if ($Elevated) {
|
| Write-Host ""
|
| Write-Host "Press any key to exit..." -ForegroundColor Cyan
|
| $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
| }
|
| }
|
| }
|
| catch {
|
| Write-Host "ERROR: $($_.Exception.Message)" -ForegroundColor Red
|
| Write-Host "Upgrade failed. Please check the error message above." -ForegroundColor Red
|
|
|
|
|
| if ($Elevated -or (-not $isAdmin)) {
|
| Write-Host "Press any key to exit..." -ForegroundColor Red
|
| $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
| }
|
| exit 1
|
| }
|
|
|
| |