mirror of
https://github.com/fankes/beszel.git
synced 2025-10-19 09:49:28 +08:00
add winget support to windows install script
This commit is contained in:
@@ -2,7 +2,8 @@ param (
|
|||||||
[switch]$Elevated,
|
[switch]$Elevated,
|
||||||
[Parameter(Mandatory=$true)]
|
[Parameter(Mandatory=$true)]
|
||||||
[string]$Key,
|
[string]$Key,
|
||||||
[int]$Port = 45876
|
[int]$Port = 45876,
|
||||||
|
[string]$AgentPath = ""
|
||||||
)
|
)
|
||||||
|
|
||||||
# Check if key is provided or empty
|
# Check if key is provided or empty
|
||||||
@@ -15,60 +16,147 @@ if ([string]::IsNullOrWhiteSpace($Key)) {
|
|||||||
# Stop on first error
|
# Stop on first error
|
||||||
$ErrorActionPreference = "Stop"
|
$ErrorActionPreference = "Stop"
|
||||||
|
|
||||||
|
#region Utility Functions
|
||||||
|
|
||||||
# Function to check if running as admin
|
# Function to check if running as admin
|
||||||
function Test-Admin {
|
function Test-Admin {
|
||||||
return ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
return ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
|
||||||
}
|
}
|
||||||
|
|
||||||
# Non-admin tasks - install Scoop and Scoop apps - Only run if we're not in elevated mode
|
# Function to check if a command exists
|
||||||
if (-not $Elevated) {
|
function Test-CommandExists {
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]$Command
|
||||||
|
)
|
||||||
|
return (Get-Command $Command -ErrorAction SilentlyContinue)
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Installation Methods
|
||||||
|
|
||||||
|
# Function to install Scoop
|
||||||
|
function Install-Scoop {
|
||||||
|
Write-Host "Installing Scoop..."
|
||||||
try {
|
try {
|
||||||
# Check if Scoop is already installed
|
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
|
||||||
if (Get-Command scoop -ErrorAction SilentlyContinue) {
|
|
||||||
|
if (-not (Test-CommandExists "scoop")) {
|
||||||
|
throw "Failed to install Scoop"
|
||||||
|
}
|
||||||
|
Write-Host "Scoop installed successfully."
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
throw "Failed to install Scoop: $($_.Exception.Message)"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to install Git via Scoop
|
||||||
|
function Install-Git {
|
||||||
|
if (Test-CommandExists "git") {
|
||||||
|
Write-Host "Git is already installed."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Installing Git..."
|
||||||
|
scoop install git
|
||||||
|
|
||||||
|
if (-not (Test-CommandExists "git")) {
|
||||||
|
throw "Failed to install Git"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to install NSSM
|
||||||
|
function Install-NSSM {
|
||||||
|
param (
|
||||||
|
[string]$Method = "Scoop" # Default to Scoop method
|
||||||
|
)
|
||||||
|
|
||||||
|
if (Test-CommandExists "nssm") {
|
||||||
|
Write-Host "NSSM is already installed."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host "Installing NSSM..."
|
||||||
|
if ($Method -eq "Scoop") {
|
||||||
|
scoop install nssm
|
||||||
|
}
|
||||||
|
elseif ($Method -eq "WinGet") {
|
||||||
|
winget install -e --id NSSM.NSSM --accept-source-agreements --accept-package-agreements
|
||||||
|
|
||||||
|
# Refresh PATH environment variable to make NSSM available in current session
|
||||||
|
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw "Unsupported installation method: $Method"
|
||||||
|
}
|
||||||
|
|
||||||
|
if (-not (Test-CommandExists "nssm")) {
|
||||||
|
throw "Failed to install NSSM"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to install beszel-agent with Scoop
|
||||||
|
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
|
||||||
|
|
||||||
|
if (-not (Test-CommandExists "beszel-agent")) {
|
||||||
|
throw "Failed to install beszel-agent"
|
||||||
|
}
|
||||||
|
|
||||||
|
return $(Join-Path -Path $(scoop prefix beszel-agent) -ChildPath "beszel-agent.exe")
|
||||||
|
}
|
||||||
|
|
||||||
|
# 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
|
||||||
|
|
||||||
|
# Refresh PATH environment variable to make beszel-agent available in current session
|
||||||
|
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path", "User")
|
||||||
|
|
||||||
|
# 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"
|
||||||
|
}
|
||||||
|
|
||||||
|
return $agentPath
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to install using Scoop
|
||||||
|
function Install-WithScoop {
|
||||||
|
param (
|
||||||
|
[string]$Key,
|
||||||
|
[int]$Port
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
# Ensure Scoop is installed
|
||||||
|
if (-not (Test-CommandExists "scoop")) {
|
||||||
|
Install-Scoop | Out-Null
|
||||||
|
}
|
||||||
|
else {
|
||||||
Write-Host "Scoop is already installed."
|
Write-Host "Scoop is already installed."
|
||||||
} else {
|
|
||||||
Write-Host "Installing Scoop..."
|
|
||||||
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression
|
|
||||||
|
|
||||||
if (-not (Get-Command scoop -ErrorAction SilentlyContinue)) {
|
|
||||||
throw "Failed to install Scoop"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if git is already installed
|
|
||||||
if (Get-Command git -ErrorAction SilentlyContinue) {
|
|
||||||
Write-Host "Git is already installed."
|
|
||||||
} else {
|
|
||||||
Write-Host "Installing Git..."
|
|
||||||
scoop install git
|
|
||||||
|
|
||||||
if (-not (Get-Command git -ErrorAction SilentlyContinue)) {
|
|
||||||
throw "Failed to install Git"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Check if nssm is already installed
|
|
||||||
if (Get-Command nssm -ErrorAction SilentlyContinue) {
|
|
||||||
Write-Host "NSSM is already installed."
|
|
||||||
} else {
|
|
||||||
Write-Host "Installing NSSM..."
|
|
||||||
scoop install nssm
|
|
||||||
|
|
||||||
if (-not (Get-Command nssm -ErrorAction SilentlyContinue)) {
|
|
||||||
throw "Failed to install NSSM"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Add bucket and install agent
|
# Install Git (required for Scoop buckets)
|
||||||
Write-Host "Adding beszel bucket..."
|
Install-Git | Out-Null
|
||||||
scoop bucket add beszel https://github.com/henrygd/beszel-scoops
|
|
||||||
|
|
||||||
Write-Host "Installing beszel-agent..."
|
# Install NSSM
|
||||||
scoop install beszel-agent
|
Install-NSSM -Method "Scoop" | Out-Null
|
||||||
|
|
||||||
if (-not (Get-Command beszel-agent -ErrorAction SilentlyContinue)) {
|
# Install beszel-agent
|
||||||
throw "Failed to install beszel-agent"
|
$agentPath = Install-BeszelAgentWithScoop
|
||||||
}
|
|
||||||
|
return $agentPath
|
||||||
}
|
}
|
||||||
catch {
|
catch {
|
||||||
Write-Host "ERROR: $($_.Exception.Message)" -ForegroundColor Red
|
Write-Host "ERROR: $($_.Exception.Message)" -ForegroundColor Red
|
||||||
@@ -77,27 +165,48 @@ if (-not $Elevated) {
|
|||||||
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
||||||
exit 1
|
exit 1
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Check if we need admin privileges for the NSSM part
|
# Function to install using WinGet
|
||||||
if (-not (Test-Admin)) {
|
function Install-WithWinGet {
|
||||||
Write-Host "Admin privileges required for NSSM. Relaunching as admin..." -ForegroundColor Yellow
|
param (
|
||||||
Write-Host "Check service status with 'nssm status beszel-agent'"
|
[string]$Key,
|
||||||
Write-Host "Edit service configuration with 'nssm edit beszel-agent'"
|
[int]$Port
|
||||||
|
)
|
||||||
|
|
||||||
|
try {
|
||||||
|
# Install NSSM
|
||||||
|
Install-NSSM -Method "WinGet" | Out-Null
|
||||||
|
|
||||||
# Relaunch the script with the -Elevated switch and pass parameters
|
# Install beszel-agent
|
||||||
Start-Process powershell.exe -Verb RunAs -ArgumentList "-File `"$PSCommandPath`" -Elevated -Key `"$Key`" -Port $Port"
|
$agentPath = Install-BeszelAgentWithWinGet
|
||||||
exit
|
|
||||||
|
return $agentPath
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Host "ERROR: $($_.Exception.Message)" -ForegroundColor Red
|
||||||
|
Write-Host "Installation failed. Please check the error message above." -ForegroundColor Red
|
||||||
|
Write-Host "Press any key to exit..." -ForegroundColor Red
|
||||||
|
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
||||||
|
exit 1
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Admin tasks - service installation and firewall rules
|
#endregion
|
||||||
try {
|
|
||||||
$agentPath = Join-Path -Path $(scoop prefix beszel-agent) -ChildPath "beszel-agent.exe"
|
#region Service Configuration
|
||||||
if (-not $agentPath) {
|
|
||||||
throw "Could not find beszel-agent executable. Make sure it was properly installed."
|
# Function to install and configure the NSSM service
|
||||||
}
|
function Install-NSSMService {
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]$AgentPath,
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[string]$Key,
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[int]$Port
|
||||||
|
)
|
||||||
|
|
||||||
# Install and configure the service
|
|
||||||
Write-Host "Installing beszel-agent service..."
|
Write-Host "Installing beszel-agent service..."
|
||||||
|
|
||||||
# Check if service already exists
|
# Check if service already exists
|
||||||
@@ -112,7 +221,7 @@ try {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nssm install beszel-agent $agentPath
|
nssm install beszel-agent $AgentPath
|
||||||
if ($LASTEXITCODE -ne 0) {
|
if ($LASTEXITCODE -ne 0) {
|
||||||
throw "Failed to install beszel-agent service"
|
throw "Failed to install beszel-agent service"
|
||||||
}
|
}
|
||||||
@@ -129,6 +238,14 @@ try {
|
|||||||
$logFile = "$logDir\beszel-agent.log"
|
$logFile = "$logDir\beszel-agent.log"
|
||||||
nssm set beszel-agent AppStdout $logFile
|
nssm set beszel-agent AppStdout $logFile
|
||||||
nssm set beszel-agent AppStderr $logFile
|
nssm set beszel-agent AppStderr $logFile
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to configure firewall rules
|
||||||
|
function Configure-Firewall {
|
||||||
|
param (
|
||||||
|
[Parameter(Mandatory=$true)]
|
||||||
|
[int]$Port
|
||||||
|
)
|
||||||
|
|
||||||
# Create a firewall rule if it doesn't exist
|
# Create a firewall rule if it doesn't exist
|
||||||
$ruleName = "Allow beszel-agent"
|
$ruleName = "Allow beszel-agent"
|
||||||
@@ -154,7 +271,10 @@ try {
|
|||||||
Write-Host "Warning: Failed to create firewall rule: $($_.Exception.Message)" -ForegroundColor Yellow
|
Write-Host "Warning: Failed to create firewall rule: $($_.Exception.Message)" -ForegroundColor Yellow
|
||||||
Write-Host "You may need to manually create a firewall rule for port $Port." -ForegroundColor Yellow
|
Write-Host "You may need to manually create a firewall rule for port $Port." -ForegroundColor Yellow
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# Function to start and monitor the service
|
||||||
|
function Start-BeszelAgentService {
|
||||||
Write-Host "Starting beszel-agent service..."
|
Write-Host "Starting beszel-agent service..."
|
||||||
nssm start beszel-agent
|
nssm start beszel-agent
|
||||||
$startResult = $LASTEXITCODE
|
$startResult = $LASTEXITCODE
|
||||||
@@ -164,22 +284,23 @@ try {
|
|||||||
Write-Host "NSSM start command returned error code: $startResult" -ForegroundColor Yellow
|
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..."
|
Write-Host "This could be due to 'SERVICE_START_PENDING' state. Checking service status..."
|
||||||
|
|
||||||
# Allow up to 20 seconds for the service to start, checking every 2 seconds
|
# Allow up to 10 seconds for the service to start, checking every second
|
||||||
$maxWaitTime = 20 # seconds
|
$maxWaitTime = 10 # seconds
|
||||||
$elapsedTime = 0
|
$elapsedTime = 0
|
||||||
$serviceStarted = $false
|
$serviceStarted = $false
|
||||||
|
|
||||||
while (-not $serviceStarted -and $elapsedTime -lt $maxWaitTime) {
|
while (-not $serviceStarted -and $elapsedTime -lt $maxWaitTime) {
|
||||||
|
Start-Sleep -Seconds 1
|
||||||
|
$elapsedTime += 1
|
||||||
|
|
||||||
$serviceStatus = nssm status beszel-agent
|
$serviceStatus = nssm status beszel-agent
|
||||||
|
|
||||||
if ($serviceStatus -eq "SERVICE_RUNNING") {
|
if ($serviceStatus -eq "SERVICE_RUNNING") {
|
||||||
$serviceStarted = $true
|
$serviceStarted = $true
|
||||||
Write-Host "Success! The beszel-agent service is now running properly." -ForegroundColor Green
|
Write-Host "Success! The beszel-agent service is now running." -ForegroundColor Green
|
||||||
}
|
}
|
||||||
elseif ($serviceStatus -like "*PENDING*") {
|
elseif ($serviceStatus -like "*PENDING*") {
|
||||||
Write-Host "Service is still starting (status: $serviceStatus)... waiting" -ForegroundColor Yellow
|
Write-Host "Service is still starting (status: $serviceStatus)... waiting" -ForegroundColor Yellow
|
||||||
Start-Sleep -Seconds 2
|
|
||||||
$elapsedTime += 2
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
Write-Host "Warning: The service status is '$serviceStatus' instead of 'SERVICE_RUNNING'." -ForegroundColor Yellow
|
Write-Host "Warning: The service status is '$serviceStatus' instead of 'SERVICE_RUNNING'." -ForegroundColor Yellow
|
||||||
@@ -189,7 +310,7 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (-not $serviceStarted) {
|
if (-not $serviceStarted) {
|
||||||
Write-Host "Service did not reach running state within $maxWaitTime seconds." -ForegroundColor Yellow
|
Write-Host "Service did not reach running state." -ForegroundColor Yellow
|
||||||
Write-Host "You can check status manually with 'nssm status beszel-agent'" -ForegroundColor Yellow
|
Write-Host "You can check status manually with 'nssm status beszel-agent'" -ForegroundColor Yellow
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -197,13 +318,74 @@ try {
|
|||||||
Write-Host "Success! The beszel-agent service is running properly." -ForegroundColor Green
|
Write-Host "Success! The beszel-agent service is running properly." -ForegroundColor Green
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch {
|
|
||||||
Write-Host "ERROR: $($_.Exception.Message)" -ForegroundColor Red
|
#endregion
|
||||||
Write-Host "Installation failed. Please check the error message above." -ForegroundColor Red
|
|
||||||
|
#region Main Script Execution
|
||||||
|
|
||||||
|
# Non-admin tasks - Only run if we're not in elevated mode
|
||||||
|
if (-not $Elevated) {
|
||||||
|
try {
|
||||||
|
# Determine installation method
|
||||||
|
$AgentPath = ""
|
||||||
|
|
||||||
|
if (Test-CommandExists "scoop") {
|
||||||
|
Write-Host "Using Scoop for installation..."
|
||||||
|
$AgentPath = Install-WithScoop -Key $Key -Port $Port
|
||||||
|
}
|
||||||
|
elseif (Test-CommandExists "winget") {
|
||||||
|
Write-Host "Using WinGet for installation..."
|
||||||
|
$AgentPath = Install-WithWinGet -Key $Key -Port $Port
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
Write-Host "Neither Scoop nor WinGet is installed. Installing Scoop..."
|
||||||
|
$AgentPath = Install-WithScoop -Key $Key -Port $Port
|
||||||
|
}
|
||||||
|
|
||||||
|
# Check if we need admin privileges for the NSSM part
|
||||||
|
if (-not (Test-Admin)) {
|
||||||
|
Write-Host "Admin privileges required for NSSM. 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'"
|
||||||
|
|
||||||
|
# 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`""
|
||||||
|
exit
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Host "ERROR: $($_.Exception.Message)" -ForegroundColor Red
|
||||||
|
Write-Host "Installation failed. Please check the error message above." -ForegroundColor Red
|
||||||
|
Write-Host "Press any key to exit..." -ForegroundColor Red
|
||||||
|
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# Pause to see results before exit if this is an elevated window
|
# Admin tasks - service installation and firewall rules
|
||||||
if ($Elevated) {
|
if ($Elevated) {
|
||||||
|
try {
|
||||||
|
if (-not $AgentPath) {
|
||||||
|
throw "Could not find beszel-agent executable. Make sure it was properly installed."
|
||||||
|
}
|
||||||
|
|
||||||
|
# Install the service
|
||||||
|
Install-NSSMService -AgentPath $AgentPath -Key $Key -Port $Port
|
||||||
|
|
||||||
|
# Configure firewall
|
||||||
|
Configure-Firewall -Port $Port
|
||||||
|
|
||||||
|
# Start the service
|
||||||
|
Start-BeszelAgentService
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
Write-Host "ERROR: $($_.Exception.Message)" -ForegroundColor Red
|
||||||
|
Write-Host "Installation failed. Please check the error message above." -ForegroundColor Red
|
||||||
|
}
|
||||||
|
|
||||||
|
# Pause to see results before exit if this is an elevated window
|
||||||
Write-Host "Press any key to exit..." -ForegroundColor Cyan
|
Write-Host "Press any key to exit..." -ForegroundColor Cyan
|
||||||
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
Reference in New Issue
Block a user