mirror of
https://github.com/fankes/beszel.git
synced 2025-10-18 17:29:28 +08:00
fix: windows paths when regular and admin install users differ (#739)
This commit is contained in:
@@ -3,7 +3,8 @@ param (
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$Key,
|
||||
[int]$Port = 45876,
|
||||
[string]$AgentPath = ""
|
||||
[string]$AgentPath = "",
|
||||
[string]$NSSMPath = ""
|
||||
)
|
||||
|
||||
# Check if key is provided or empty
|
||||
@@ -32,6 +33,78 @@ function Test-CommandExists {
|
||||
return (Get-Command $Command -ErrorAction SilentlyContinue)
|
||||
}
|
||||
|
||||
# Function to find beszel-agent in common installation locations
|
||||
function Find-BeszelAgent {
|
||||
# First check if it's in PATH
|
||||
$agentCmd = Get-Command "beszel-agent" -ErrorAction SilentlyContinue
|
||||
if ($agentCmd) {
|
||||
return $agentCmd.Source
|
||||
}
|
||||
|
||||
# Common installation paths to check
|
||||
$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) {
|
||||
# Handle wildcard paths
|
||||
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 to find NSSM in common installation locations
|
||||
function Find-NSSM {
|
||||
# First check if it's in PATH
|
||||
$nssmCmd = Get-Command "nssm" -ErrorAction SilentlyContinue
|
||||
if ($nssmCmd) {
|
||||
return $nssmCmd.Source
|
||||
}
|
||||
|
||||
# Common installation paths to check
|
||||
$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) {
|
||||
# Handle wildcard paths
|
||||
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
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Installation Methods
|
||||
@@ -39,11 +112,17 @@ function Test-CommandExists {
|
||||
# Function to install Scoop
|
||||
function Install-Scoop {
|
||||
Write-Host "Installing Scoop..."
|
||||
|
||||
# Check if running as admin - Scoop should not be installed as admin
|
||||
if (Test-Admin) {
|
||||
throw "Scoop cannot be installed with administrator privileges. Please run this script as a regular user first to install Scoop and beszel-agent, then run as admin to configure the service."
|
||||
}
|
||||
|
||||
try {
|
||||
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
|
||||
|
||||
if (-not (Test-CommandExists "scoop")) {
|
||||
throw "Failed to install Scoop"
|
||||
throw "Failed to install Scoop - command not available after installation"
|
||||
}
|
||||
Write-Host "Scoop installed successfully."
|
||||
}
|
||||
@@ -102,8 +181,8 @@ function Install-BeszelAgentWithScoop {
|
||||
Write-Host "Adding beszel bucket..."
|
||||
scoop bucket add beszel https://github.com/henrygd/beszel-scoops | Out-Null
|
||||
|
||||
Write-Host "Installing beszel-agent..."
|
||||
scoop install beszel-agent | Out-Null
|
||||
Write-Host "Installing / updating beszel-agent..."
|
||||
scoop install beszel-agent
|
||||
|
||||
if (-not (Test-CommandExists "beszel-agent")) {
|
||||
throw "Failed to install beszel-agent"
|
||||
@@ -114,8 +193,29 @@ function Install-BeszelAgentWithScoop {
|
||||
|
||||
# Function to install beszel-agent with WinGet
|
||||
function Install-BeszelAgentWithWinGet {
|
||||
Write-Host "Installing beszel-agent..."
|
||||
winget install --exact --id henrygd.beszel-agent --accept-source-agreements --accept-package-agreements | Out-Null
|
||||
Write-Host "Installing / updating beszel-agent..."
|
||||
|
||||
# Temporarily change ErrorActionPreference to allow WinGet to complete and show output
|
||||
$originalErrorActionPreference = $ErrorActionPreference
|
||||
$ErrorActionPreference = "Continue"
|
||||
|
||||
# Use call operator (&) and capture exit code properly
|
||||
& winget install --exact --id henrygd.beszel-agent --accept-source-agreements --accept-package-agreements | Out-Null
|
||||
$wingetExitCode = $LASTEXITCODE
|
||||
|
||||
# Restore original ErrorActionPreference
|
||||
$ErrorActionPreference = $originalErrorActionPreference
|
||||
|
||||
# WinGet exit codes:
|
||||
# 0 = Success
|
||||
# -1978335212 (0x8A150014) = No applicable upgrade found (package is up to date)
|
||||
# -1978335189 (0x8A15002B) = Another "no upgrade needed" variant
|
||||
# Other codes indicate actual errors
|
||||
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
|
||||
}
|
||||
|
||||
# Refresh PATH environment variable to make beszel-agent available in current session
|
||||
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
||||
@@ -123,7 +223,6 @@ function Install-BeszelAgentWithWinGet {
|
||||
# Find the path to the beszel-agent executable
|
||||
$agentPath = (Get-Command beszel-agent -ErrorAction SilentlyContinue).Source
|
||||
|
||||
|
||||
if (-not $agentPath) {
|
||||
throw "Could not find beszel-agent executable path after installation"
|
||||
}
|
||||
@@ -204,31 +303,41 @@ function Install-NSSMService {
|
||||
[Parameter(Mandatory=$true)]
|
||||
[string]$Key,
|
||||
[Parameter(Mandatory=$true)]
|
||||
[int]$Port
|
||||
[int]$Port,
|
||||
[string]$NSSMPath = ""
|
||||
)
|
||||
|
||||
Write-Host "Installing beszel-agent service..."
|
||||
|
||||
# Determine the NSSM executable to use
|
||||
$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"
|
||||
}
|
||||
|
||||
# Check if service already exists
|
||||
$existingService = Get-Service -Name "beszel-agent" -ErrorAction SilentlyContinue
|
||||
if ($existingService) {
|
||||
Write-Host "Service already exists. Stopping and removing existing service..."
|
||||
try {
|
||||
nssm stop beszel-agent
|
||||
nssm remove beszel-agent confirm
|
||||
& $nssmCommand stop beszel-agent
|
||||
& $nssmCommand remove beszel-agent confirm
|
||||
} catch {
|
||||
Write-Host "Warning: Failed to remove existing service: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
|
||||
nssm install beszel-agent $AgentPath
|
||||
& $nssmCommand install beszel-agent $AgentPath
|
||||
if ($LASTEXITCODE -ne 0) {
|
||||
throw "Failed to install beszel-agent service"
|
||||
}
|
||||
|
||||
Write-Host "Configuring service environment variables..."
|
||||
nssm set beszel-agent AppEnvironmentExtra "+KEY=$Key"
|
||||
nssm set beszel-agent AppEnvironmentExtra "+PORT=$Port"
|
||||
& $nssmCommand set beszel-agent AppEnvironmentExtra "+KEY=$Key"
|
||||
& $nssmCommand set beszel-agent AppEnvironmentExtra "+PORT=$Port"
|
||||
|
||||
# Configure log files
|
||||
$logDir = "$env:ProgramData\beszel-agent\logs"
|
||||
@@ -236,8 +345,8 @@ function Install-NSSMService {
|
||||
New-Item -ItemType Directory -Path $logDir -Force | Out-Null
|
||||
}
|
||||
$logFile = "$logDir\beszel-agent.log"
|
||||
nssm set beszel-agent AppStdout $logFile
|
||||
nssm set beszel-agent AppStderr $logFile
|
||||
& $nssmCommand set beszel-agent AppStdout $logFile
|
||||
& $nssmCommand set beszel-agent AppStderr $logFile
|
||||
}
|
||||
|
||||
# Function to configure firewall rules
|
||||
@@ -275,8 +384,21 @@ function Configure-Firewall {
|
||||
|
||||
# Function to start and monitor the service
|
||||
function Start-BeszelAgentService {
|
||||
param (
|
||||
[string]$NSSMPath = ""
|
||||
)
|
||||
|
||||
Write-Host "Starting beszel-agent service..."
|
||||
nssm start beszel-agent
|
||||
|
||||
# Determine the NSSM executable to use
|
||||
$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
|
||||
|
||||
# Only enter the status check loop if the NSSM start command failed
|
||||
@@ -293,7 +415,7 @@ function Start-BeszelAgentService {
|
||||
Start-Sleep -Seconds 1
|
||||
$elapsedTime += 1
|
||||
|
||||
$serviceStatus = nssm status beszel-agent
|
||||
$serviceStatus = & $nssmCommand status beszel-agent
|
||||
|
||||
if ($serviceStatus -eq "SERVICE_RUNNING") {
|
||||
$serviceStarted = $true
|
||||
@@ -331,13 +453,15 @@ try {
|
||||
if (-not $AgentPath) {
|
||||
# Check for problematic case: running as admin and need Scoop
|
||||
if ($isAdmin -and -not (Test-CommandExists "scoop") -and -not (Test-CommandExists "winget")) {
|
||||
Write-Host "ERROR: You're running as administrator but need to install Scoop." -ForegroundColor Red
|
||||
Write-Host "ERROR: You're running as administrator but neither Scoop nor WinGet is available." -ForegroundColor Red
|
||||
Write-Host "Scoop should be installed without admin privileges." -ForegroundColor Red
|
||||
Write-Host "Please run this script again without administrator privileges." -ForegroundColor Red
|
||||
Write-Host ""
|
||||
Write-Host "Please either:" -ForegroundColor Yellow
|
||||
Write-Host "1. Run this script again without administrator privileges" -ForegroundColor Yellow
|
||||
Write-Host "2. Install WinGet and run this script again" -ForegroundColor Yellow
|
||||
exit 1
|
||||
}
|
||||
|
||||
Write-Host "Installing beszel-agent..."
|
||||
if (Test-CommandExists "scoop") {
|
||||
Write-Host "Using Scoop for installation..."
|
||||
$AgentPath = Install-WithScoop -Key $Key -Port $Port
|
||||
@@ -356,27 +480,84 @@ try {
|
||||
throw "Could not find beszel-agent executable. Make sure it was properly installed."
|
||||
}
|
||||
|
||||
# Find NSSM path if not already provided
|
||||
if (-not $NSSMPath) {
|
||||
$NSSMPath = Find-NSSM
|
||||
|
||||
if (-not $NSSMPath -and (Test-CommandExists "nssm")) {
|
||||
$NSSMPath = (Get-Command "nssm" -ErrorAction SilentlyContinue).Source
|
||||
}
|
||||
|
||||
# If we still don't have NSSM, try to install it if we have package managers
|
||||
if (-not $NSSMPath) {
|
||||
if (Test-CommandExists "winget") {
|
||||
Write-Host "NSSM not found. Attempting to install via WinGet..."
|
||||
try {
|
||||
Install-NSSM -Method "WinGet"
|
||||
$NSSMPath = Find-NSSM
|
||||
if (-not $NSSMPath -and (Test-CommandExists "nssm")) {
|
||||
$NSSMPath = (Get-Command "nssm" -ErrorAction SilentlyContinue).Source
|
||||
}
|
||||
} catch {
|
||||
Write-Host "Failed to install NSSM via WinGet: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||
}
|
||||
} elseif (Test-CommandExists "scoop") {
|
||||
Write-Host "NSSM not found. Attempting to install via Scoop..."
|
||||
try {
|
||||
Install-NSSM -Method "Scoop"
|
||||
$NSSMPath = Find-NSSM
|
||||
if (-not $NSSMPath -and (Test-CommandExists "nssm")) {
|
||||
$NSSMPath = (Get-Command "nssm" -ErrorAction SilentlyContinue).Source
|
||||
}
|
||||
} catch {
|
||||
Write-Host "Failed to install NSSM via Scoop: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
|
||||
# Final check - if we still don't have NSSM and we're admin, we have a problem
|
||||
if (-not $NSSMPath -and ($isAdmin -or $Elevated)) {
|
||||
throw "NSSM is required for service installation but was not found and could not be installed. Please install NSSM manually or run as a regular user to install it."
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Second: If we need admin rights for service installation and we don't have them, relaunch
|
||||
if (-not $isAdmin -and -not $Elevated) {
|
||||
Write-Host "Admin privileges required for service installation. Relaunching as admin..." -ForegroundColor Yellow
|
||||
Write-Host "Check service status with 'nssm status beszel-agent'"
|
||||
Write-Host "Edit service configuration with 'nssm edit beszel-agent'"
|
||||
|
||||
# Prepare arguments for the elevated script
|
||||
$argumentList = @(
|
||||
"-ExecutionPolicy", "Bypass",
|
||||
"-File", "`"$PSCommandPath`"",
|
||||
"-Elevated",
|
||||
"-Key", "`"$Key`"",
|
||||
"-Port", $Port,
|
||||
"-AgentPath", "`"$AgentPath`""
|
||||
)
|
||||
|
||||
# Add NSSMPath if we found it
|
||||
if ($NSSMPath) {
|
||||
$argumentList += "-NSSMPath"
|
||||
$argumentList += "`"$NSSMPath`""
|
||||
}
|
||||
|
||||
# Relaunch the script with the -Elevated switch and pass parameters
|
||||
Start-Process powershell.exe -Verb RunAs -ArgumentList "-File `"$PSCommandPath`" -Elevated -Key `"$Key`" -Port $Port -AgentPath `"$AgentPath`""
|
||||
Start-Process powershell.exe -Verb RunAs -ArgumentList $argumentList
|
||||
exit
|
||||
}
|
||||
|
||||
# Third: If we have admin rights, install service and configure firewall
|
||||
if ($isAdmin -or $Elevated) {
|
||||
# Install the service
|
||||
Install-NSSMService -AgentPath $AgentPath -Key $Key -Port $Port
|
||||
Install-NSSMService -AgentPath $AgentPath -Key $Key -Port $Port -NSSMPath $NSSMPath
|
||||
|
||||
# Configure firewall
|
||||
Configure-Firewall -Port $Port
|
||||
|
||||
# Start the service
|
||||
Start-BeszelAgentService
|
||||
Start-BeszelAgentService -NSSMPath $NSSMPath
|
||||
|
||||
# Pause to see results if this is an elevated window
|
||||
if ($Elevated) {
|
||||
|
Reference in New Issue
Block a user