Skip to content

Instantly share code, notes, and snippets.

@AssassinUKG
Last active July 16, 2025 11:44
Show Gist options
  • Save AssassinUKG/a3f15ae98a8e2e51fdd9b72027b16335 to your computer and use it in GitHub Desktop.
Save AssassinUKG/a3f15ae98a8e2e51fdd9b72027b16335 to your computer and use it in GitHub Desktop.
NetBird auto updater Script
# NetBird Auto-Updater Script - Improved Version
# Only updates if current version differs from latest version
[cmdletbinding()]
param ()
#########################################################################
# Settings
#########################################################################
$ForcedMinimumVersion = [version]"0.48.0"
$NetbirdUrlScheme = "https"
$NetbirdUiStartup = $true
$WorkingFolderName = "_Intune"
$packageName = 'Netbird-Check'
$workingDir = Join-Path $env:ProgramData $WorkingFolderName
$logFolder = Join-Path $workingDir 'Logs'
$monthTimestamp = (Get-Date -UFormat '%Y%m')
$workingTimeStamp = (Get-Date -UFormat '%Y%m%d-%H%M%S')
$logFileName = "${packageName}_${monthTimestamp}_${workingTimeStamp}.txt"
$logFilePath = Join-Path $logFolder $logFileName
$downloadFolder = Join-Path $workingDir 'Downloads'
$downloadFileName = "Netbird.Client_${workingTimeStamp}.msi"
$downloadPath = Join-Path $downloadFolder $downloadFileName
$releasesUrl = 'https://api.github.com/repos/netbirdio/netbird/releases'
$assetMatch = 'netbird*_windows_amd64.msi'
$msiLogFileTemplate = "${logFolder}\${packageName}_${workingTimeStamp}_msi.txt"
$netbirdExePath = "C:\Program Files\Netbird\netbird.exe"
$netbirdUiExePath = "C:\Program Files\Netbird\Netbird-ui.exe"
$netbirdConfigPath = "$env:ProgramData\Netbird\config.json"
#########################################################################
# Functions
#########################################################################
function Write-Log {
param([string]$msg)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logMessage = "[$timestamp] $msg"
Write-Host $logMessage
# Try to write to log file with retry logic for file locking issues
$maxRetries = 3
$retryDelay = 100
for ($i = 0; $i -lt $maxRetries; $i++) {
try {
Add-Content -Path $logFilePath -Value $logMessage -Force -ErrorAction Stop
break
} catch {
if ($i -eq ($maxRetries - 1)) {
Write-Host "Warning: Could not write to log file after $maxRetries attempts: $($_.Exception.Message)"
} else {
Start-Sleep -Milliseconds $retryDelay
$retryDelay *= 2 # Exponential backoff
}
}
}
}
function Get-Netbird-Urls {
if (Test-Path $netbirdConfigPath) {
try {
$configData = Get-Content -Raw -Path $netbirdConfigPath | ConvertFrom-Json
$script:NetbirdManagementUrl = $configData.ManagementURL.Host
$script:NetbirdAdminUrl = $configData.AdminURL.Host
$script:NetbirdUrlScheme = $configData.ManagementURL.Scheme
} catch {
Write-Log "Failed to parse config.json, using defaults."
}
}
if (-not $script:NetbirdManagementUrl) { $script:NetbirdManagementUrl = "localhost:443" }
if (-not $script:NetbirdAdminUrl) { $script:NetbirdAdminUrl = "localhost:443" }
}
function Get-Current-Version {
if (Test-Path $netbirdExePath) {
try {
$versionInfo = & $netbirdExePath version 2>$null
if ($versionInfo -match "version\s+(\d+\.\d+\.\d+)") {
$currentVersion = [version]$matches[1]
Write-Log "Current NetBird version: $currentVersion"
return $currentVersion
}
} catch {
Write-Log "Failed to get current version via CLI, trying file properties..."
}
# Fallback to file version
try {
$fileVersion = (Get-ItemProperty $netbirdExePath).VersionInfo.FileVersion
if ($fileVersion -match "(\d+\.\d+\.\d+)") {
$currentVersion = [version]$matches[1]
Write-Log "Current NetBird version (from file): $currentVersion"
return $currentVersion
}
} catch {
Write-Log "Failed to get version from file properties"
}
}
Write-Log "NetBird not found or version could not be determined"
return $null
}
function Get-Latest-Version {
Write-Log "Fetching latest release info from GitHub..."
try {
$json = Invoke-RestMethod -Uri $releasesUrl -UseBasicParsing
$latest = $json | Where-Object { $_.tag_name -match "^v\d" } | Select-Object -First 1
if ($latest) {
$latestVersion = [version]($latest.tag_name -replace '[^0-9\.]')
Write-Log "Latest NetBird version: $latestVersion"
return @{
Version = $latestVersion
Release = $latest
}
}
} catch {
Write-Log "Failed to fetch latest version: $($_.Exception.Message)"
}
return $null
}
function Download-Latest-Netbird {
param($releaseInfo)
$asset = $releaseInfo.Release.assets | Where-Object { $_.name -like $assetMatch } | Select-Object -First 1
if (-not $asset) {
Write-Log "No matching asset found for download."
return $false
}
Write-Log "Downloading NetBird version $($releaseInfo.Version)..."
New-Item -ItemType Directory -Path $downloadFolder -Force | Out-Null
try {
Invoke-WebRequest -Uri $asset.browser_download_url -OutFile $downloadPath -UseBasicParsing
Write-Log "Download completed: $downloadPath"
return $true
} catch {
Write-Log "Download failed: $($_.Exception.Message)"
return $false
}
}
function Install-Netbird {
Write-Log "Installing NetBird MSI..."
try {
$process = Start-Process msiexec.exe -ArgumentList @("/i", $downloadPath, "/qn", "/norestart", "/l*v", $msiLogFileTemplate) -Wait -PassThru
if ($process.ExitCode -eq 0) {
Write-Log "NetBird installation completed successfully"
} else {
Write-Log "NetBird installation failed with exit code: $($process.ExitCode)"
}
} catch {
Write-Log "Installation error: $($_.Exception.Message)"
}
# Cleanup download file
if (Test-Path $downloadPath) {
Remove-Item -Path $downloadPath -Force -ErrorAction SilentlyContinue
Write-Log "Cleaned up download file"
}
}
function Ensure-Service {
Write-Log "Ensuring NetBird service is configured..."
try {
$service = Get-Service Netbird -ErrorAction SilentlyContinue
if ($service) {
Write-Log "NetBird service found, configuring..."
Set-Service Netbird -StartupType Automatic
if ($service.Status -ne 'Running') {
Start-Service Netbird
Write-Log "NetBird service started"
} else {
Write-Log "NetBird service already running"
}
} elseif (Test-Path $netbirdExePath) {
Write-Log "Installing NetBird service..."
& $netbirdExePath service install
Start-Service Netbird
Write-Log "NetBird service installed and started"
} else {
Write-Log "NetBird executable not found, cannot configure service"
}
} catch {
Write-Log "Service configuration error: $($_.Exception.Message)"
}
}
function Fix-Config {
if (Test-Path $netbirdConfigPath) {
try {
$json = Get-Content -Raw -Path $netbirdConfigPath | ConvertFrom-Json
$json.ManagementURL.Host = $NetbirdManagementUrl
$json.ManagementURL.Scheme = $NetbirdUrlScheme
$json.AdminURL.Host = $NetbirdAdminUrl
$json.AdminURL.Scheme = $NetbirdUrlScheme
$json | ConvertTo-Json -Depth 10 | Set-Content $netbirdConfigPath -Encoding UTF8
Write-Log "NetBird config updated successfully"
} catch {
Write-Log "Failed to update config: $($_.Exception.Message)"
}
} else {
Write-Log "NetBird config file not found, skipping config update"
}
}
function Setup-UI-Startup {
if ($NetbirdUiStartup -and (Test-Path $netbirdUiExePath)) {
try {
$runKey = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Run'
Set-ItemProperty -Path $runKey -Name 'netbird-ui' -Value $netbirdUiExePath
Write-Log "NetBird UI startup configured"
} catch {
Write-Log "Failed to configure UI startup: $($_.Exception.Message)"
}
}
}
#########################################################################
# Main Execution
#########################################################################
New-Item -ItemType Directory -Path $logFolder -Force | Out-Null
Write-Log "=== NetBird Auto-Updater Started ==="
Write-Log "Script version: Improved with version checking"
Get-Netbird-Urls
# Get current version
$currentVersion = Get-Current-Version
# Get latest version
$latestInfo = Get-Latest-Version
if (-not $latestInfo) {
Write-Log "Could not fetch latest version information. Exiting."
exit 1
}
$latestVersion = $latestInfo.Version
# Check if minimum version requirement is met
if ($latestVersion -lt $ForcedMinimumVersion) {
Write-Log "Latest version $latestVersion is below required minimum $ForcedMinimumVersion"
Write-Log "No update will be performed"
exit 1
}
# Determine if update is needed
$needsUpdate = $false
if (-not $currentVersion) {
Write-Log "NetBird not installed or version not detectable - will install"
$needsUpdate = $true
} elseif ($currentVersion -lt $latestVersion) {
Write-Log "Update needed: Current=$currentVersion, Latest=$latestVersion"
$needsUpdate = $true
} else {
Write-Log "NetBird is up to date: Current=$currentVersion, Latest=$latestVersion"
Write-Log "No update required"
}
# Perform update if needed
if ($needsUpdate) {
Write-Log "Proceeding with NetBird update/installation..."
if (Download-Latest-Netbird -releaseInfo $latestInfo) {
Install-Netbird
Write-Log "Update/installation completed"
} else {
Write-Log "Failed to download NetBird, skipping installation"
}
} else {
Write-Log "Skipping download and installation - already up to date"
}
# Always ensure service and config are properly configured
Ensure-Service
Fix-Config
Setup-UI-Startup
Write-Log "=== NetBird Auto-Updater Completed ==="
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment