Skip to content

Instantly share code, notes, and snippets.

@robertsinfosec
Last active October 29, 2025 06:19
Show Gist options
  • Select an option

  • Save robertsinfosec/36227f5b4c1a7ec45a2526070358f47b to your computer and use it in GitHub Desktop.

Select an option

Save robertsinfosec/36227f5b4c1a7ec45a2526070358f47b to your computer and use it in GitHub Desktop.
Add LLM CLI's via PowerShell. This first installs the Node Version Manager (NVM), then installs the latest NodeJS. Then, this installs: Google Gemini CLI, Anthropic Claude CLI, GitHub Copilot CLI, OpenCode (for running against Ollama), and OpenAI's Codex CLI.
# Install-LlmClis.ps1
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
# --- 0) Require Administrator ---
$IsAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()
).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
if (-not $IsAdmin) { throw "This script must be run from an Administrator PowerShell." }
# --- 1) Ensure winget ---
if (-not (Get-Command winget -ErrorAction SilentlyContinue)) {
throw "winget is required. Install 'App Installer' from Microsoft Store, then re-run."
}
function Install-WinGetPackage {
param([Parameter(Mandatory=$true)][string]$Id)
$null = winget list --exact --id $Id --accept-source-agreements --accept-package-agreements 2>$null
if ($LASTEXITCODE -eq 0) {
Write-Host "✓ $Id already installed."
return
}
winget install --exact --id $Id --source winget `
--accept-source-agreements --accept-package-agreements --silent
}
# --- 2) Prereqs ---
Install-WinGetPackage -Id "Git.Git"
Install-WinGetPackage -Id "CoreyButler.NVMforWindows"
# --- 3) Locate nvm.exe robustly (FIXED) ---
function Get-NvmExe {
# Prefer what's on PATH
$cmd = Get-Command nvm.exe -ErrorAction SilentlyContinue
if ($cmd) { return $cmd.Source }
# Common install locations
$candidates = @(
(Join-Path $env:ProgramFiles "nvm\nvm.exe"),
(Join-Path ${env:ProgramFiles(x86)} "nvm\nvm.exe"),
(Join-Path $env:LOCALAPPDATA "nvm\nvm.exe"),
(Join-Path $env:LOCALAPPDATA "Programs\nvm\nvm.exe")
) | Where-Object { $_ -and (Test-Path $_) }
if ($candidates -and $candidates.Count -gt 0) { return $candidates[0] }
# Last resort: bounded search
$roots = @($env:ProgramFiles, ${env:ProgramFiles(x86)}, $env:LOCALAPPDATA) | Where-Object { $_ }
foreach ($r in $roots) {
$found = Get-ChildItem -Path $r -Filter 'nvm.exe' -File -Recurse -ErrorAction SilentlyContinue |
Select-Object -First 1
if ($found) { return $found.FullName }
}
return $null
}
$NvmExe = Get-NvmExe
if (-not $NvmExe) {
throw "nvm.exe not found after install. Close and reopen an **Administrator** PowerShell and re-run. If it persists, verify the nvm-windows install."
}
Write-Host "nvm.exe: $NvmExe"
# --- 4) Discover latest Node LTS and activate it ---
try {
$index = Invoke-RestMethod -UseBasicParsing -Uri "https://nodejs.org/dist/index.json"
$latestLts = ($index | Where-Object { $_.lts -ne $false } | Select-Object -First 1).version.TrimStart('v')
} catch {
throw "Failed to query Node releases. Check network and try again."
}
& $NvmExe install $latestLts | Out-Null
& $NvmExe use $latestLts | Out-Null
# --- 5) Resolve node/npm from the active toolchain (no hardcoded paths) ---
function Resolve-Cmd([string]$name) {
$cmd = Get-Command $name -ErrorAction SilentlyContinue
if ($cmd) { return $cmd.Source }
$path = (& where.exe $name) 2>$null | Select-Object -First 1
if ($path) { return $path }
return $null
}
$NodeExe = Resolve-Cmd "node.exe"
$NpmCmd = Resolve-Cmd "npm.cmd"
if (-not $NodeExe) { throw "Node not found in PATH after 'nvm use'. Open a NEW Admin PowerShell and re-run." }
if (-not $NpmCmd) { throw "npm not found in PATH after 'nvm use'. Open a NEW Admin PowerShell and re-run." }
Write-Host ("node: {0} | npm: {1}" -f (& $NodeExe -v), (& $NpmCmd -v))
# --- 6) Global CLI installs (safe to re-run) ---
$packages = @(
"@google/gemini-cli@latest",
"@anthropic-ai/claude-code@latest",
"@github/copilot@latest",
"opencode-ai@latest",
"@openai/codex@latest"
)
foreach ($pkg in $packages) {
Write-Host "Installing $pkg ..."
& $NpmCmd install -g $pkg
}
# --- 7) Quick sanity (non-fatal) ---
$cmds = @("gemini", "claude", "copilot", "opencode", "codex")
foreach ($c in $cmds) {
try { & $c --version 2>$null | Out-Host } catch { }
}
Write-Host "✅ Done. If commands aren't found, open a NEW Admin PowerShell and try again."
Write-Host " Note: Codex CLI on Windows is experimental; WSL (Ubuntu) is recommended if you hit issues."
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment