Skip to main content
Glama
install.ps18.88 kB
#Requires -Version 5.1 <# .SYNOPSIS Installs the SI CLI binary for Windows. .DESCRIPTION Downloads and installs the SI CLI binary release for Windows x86_64. Automatically detects system architecture and handles installation. .PARAMETER Destination Destination directory for installation. Default: C:\Program Files\si (admin) or $env:LOCALAPPDATA\si (user) .PARAMETER Version Release version to install. Default: stable Examples: stable, 20250218.210911.0-sha.bda1ce6ea .PARAMETER AddToPath Add the installation directory to the system PATH. Default: $true .PARAMETER Help Show this help message. .EXAMPLE # Install to default location (user-specific) .\install.ps1 # Install system-wide (requires admin) .\install.ps1 # Install to custom location .\install.ps1 -Destination "C:\Tools\si" # Install specific version .\install.ps1 -Version "stable" .NOTES Requires PowerShell 5.1 or later #> [CmdletBinding()] param( [Parameter()] [string]$Destination, [Parameter()] [string]$Version = "stable", [Parameter()] [bool]$AddToPath = $true, [Parameter()] [switch]$Help ) $ErrorActionPreference = "Stop" # Script configuration $BinName = "si" $BinExe = "$BinName.exe" function Write-Header { param([string]$Message) Write-Host "--- $Message" -ForegroundColor Cyan } function Write-Info { param([string]$Message) Write-Host " - $Message" -ForegroundColor White } function Write-Success { param([string]$Message) Write-Host " + $Message" -ForegroundColor Green } function Write-Warn { param([string]$Message) Write-Host "!!! $Message" -ForegroundColor Yellow } function Write-Err { param([string]$Message) Write-Host "xxx $Message" -ForegroundColor Red } function Test-Administrator { $currentUser = [Security.Principal.WindowsIdentity]::GetCurrent() $principal = New-Object Security.Principal.WindowsPrincipal($currentUser) return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator) } function Get-DefaultDestination { $isAdmin = Test-Administrator if ($isAdmin) { return "C:\Program Files\$BinName" } else { return Join-Path $env:LOCALAPPDATA $BinName } } function Get-AssetUrl { param( [string]$Version, [string]$OsType, [string]$CpuType ) $type = "binary" $platform = "$OsType-$CpuType" $extension = "zip" $url = "https://artifacts.systeminit.com/$BinName/$Version/$type" $url = "$url/$OsType/$CpuType/$BinName-$Version-$type-$platform.$extension" return $url } function Download-File { param( [string]$Url, [string]$Destination ) Write-Info "Downloading $Url" try { # Use WebClient for download $webClient = New-Object System.Net.WebClient $webClient.DownloadFile($Url, $Destination) $webClient.Dispose() } catch { throw "Failed to download file: $_" } } function Extract-Archive { param( [string]$ArchivePath, [string]$DestinationPath ) Write-Info "Extracting archive..." try { # Use .NET for extraction (works on all PowerShell versions) Add-Type -AssemblyName System.IO.Compression.FileSystem [System.IO.Compression.ZipFile]::ExtractToDirectory($ArchivePath, $DestinationPath) # Verify binary was extracted $extractedBinary = Join-Path $DestinationPath $BinExe if (-not (Test-Path $extractedBinary)) { throw "Failed to extract binary '$BinExe' from archive" } } catch { throw "Failed to extract archive: $_" } } function Install-Binary { param( [string]$SourcePath, [string]$DestinationDir ) Write-Info "Installing '$BinExe' to '$DestinationDir'" try { # Create destination directory if it doesn't exist if (-not (Test-Path $DestinationDir)) { New-Item -ItemType Directory -Path $DestinationDir -Force | Out-Null } $destFile = Join-Path $DestinationDir $BinExe # Remove existing file if present if (Test-Path $destFile) { Remove-Item $destFile -Force } # Copy the binary Copy-Item -Path $SourcePath -Destination $destFile -Force Write-Success "Installed to $destFile" } catch { throw "Failed to install binary: $_" } } function Add-ToPath { param( [string]$Directory ) $isAdmin = Test-Administrator $target = if ($isAdmin) { "Machine" } else { "User" } # Get current PATH $currentPath = [Environment]::GetEnvironmentVariable("Path", $target) # Check if directory is already in PATH $pathEntries = $currentPath -split ";" | ForEach-Object { $_.Trim() } if ($pathEntries -contains $Directory) { Write-Info "Directory already in PATH" return } Write-Info "Adding directory to $target PATH" try { $newPath = "$currentPath;$Directory" [Environment]::SetEnvironmentVariable("Path", $newPath, $target) # Update current session PATH $env:Path = "$env:Path;$Directory" Write-Success "Added to $target PATH" Write-Warn "You may need to restart your terminal for PATH changes to take effect" } catch { Write-Warn "Failed to add to PATH: $_" Write-Info "You can manually add '$Directory' to your PATH" } } function Show-Help { Get-Help $PSCommandPath -Detailed } function Main { if ($Help) { Show-Help exit 0 } Write-Header "Installing '$BinName' for Windows" # Detect platform $osType = "windows" $cpuType = if ([Environment]::Is64BitOperatingSystem) { "x86_64" } else { "x86" } if ($cpuType -ne "x86_64") { Write-Err "Unsupported architecture: $cpuType. Only x86_64 is supported." exit 1 } $platform = "$osType-$cpuType" Write-Info "Detected platform: $platform" # Determine destination if (-not $Destination) { $Destination = Get-DefaultDestination } $isAdmin = Test-Administrator if ($isAdmin) { Write-Info "Running with administrator privileges" } else { Write-Info "Running without administrator privileges (user install)" } Write-Info "Installation directory: $Destination" Write-Info "Version: $Version" # Create temp directory $tempDir = Join-Path $env:TEMP "si-install-$(Get-Random)" New-Item -ItemType Directory -Path $tempDir -Force | Out-Null try { # Get download URL Write-Header "Downloading '$BinName' release '$Version'" $assetUrl = Get-AssetUrl -Version $Version -OsType $osType -CpuType $cpuType Write-Info "URL: $assetUrl" $zipFile = Join-Path $tempDir "si.zip" Download-File -Url $assetUrl -Destination $zipFile Write-Success "Downloaded successfully" # Extract archive Write-Header "Extracting archive" $extractDir = Join-Path $tempDir "extract" Extract-Archive -ArchivePath $zipFile -DestinationPath $extractDir Write-Success "Extracted successfully" # Install binary Write-Header "Installing binary" $binaryPath = Join-Path $extractDir $BinExe Install-Binary -SourcePath $binaryPath -DestinationDir $Destination # Add to PATH if ($AddToPath) { Write-Header "Configuring PATH" Add-ToPath -Directory $Destination } # Verify installation Write-Header "Verifying installation" $installedBinary = Join-Path $Destination $BinExe if (Test-Path $installedBinary) { Write-Success "Installation complete: $installedBinary" # Try to run --version try { $versionOutput = & $installedBinary --version 2>&1 Write-Info "Version: $versionOutput" } catch { Write-Info "Binary installed successfully" } } else { throw "Installation verification failed" } } catch { Write-Err "Installation failed: $_" Write-Info "" Write-Warn "If you need help, please join us on our Discord!" Write-Warn " https://discord.gg/system-init" exit 1 } finally { # Cleanup if (Test-Path $tempDir) { Remove-Item -Path $tempDir -Recurse -Force -ErrorAction SilentlyContinue } } Write-Header "Installation of '$BinName' release '$Version' complete" Write-Info "" Write-Success "Run 'si --help' to get started" if (-not $AddToPath) { $binaryLocation = Join-Path $Destination $BinExe Write-Info "Binary location: $binaryLocation" } } # Run main function Main

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/systeminit/si'

If you have feedback or need assistance with the MCP directory API, please join our Discord server