From 7cfcd73d8304d2b376ea77595e4d6a447c28bf6f Mon Sep 17 00:00:00 2001
From: Viktor Barzin
Date: Mon, 1 Jun 2026 19:46:49 +0000
Subject: [PATCH] kms-website: anonymous client diagnostics (Send-Diag ->
/diag) + FAQ disclosure
Fire-and-forget telemetry so script failures are captured server-side (Loki via
the kms-diag collector). kms-bootstrap.ps1 + setup-kms.ps1 POST a small anonymous
JSON event at each outcome (action, ok/fail, error text + exit codes, EditionID/
build/locale, detected Office products; no hostname/user/keys). 3s timeout,
errors swallowed -- never affects activation. $env:KMS_NO_TELEMETRY=1 opts out;
$env:KMS_DIAG_URL overrides. Version baked at build via Dockerfile sed
(__KMS_VERSION__ -> SCRIPT_VERSION build-arg). FAQ updated to disclose it.
Co-Authored-By: Claude Opus 4.7
---
Dockerfile | 4 ++-
layouts/index.html | 20 ++++++++++---
static/scripts/kms-bootstrap.ps1 | 49 ++++++++++++++++++++++++--------
static/scripts/setup-kms.ps1 | 21 +++++++++++++-
4 files changed, 76 insertions(+), 18 deletions(-)
diff --git a/Dockerfile b/Dockerfile
index 8491616..6611103 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -3,9 +3,11 @@ ARG HUGO_VERSION=0.139.0
ARG NGINX_VERSION=1.27-alpine
FROM hugomods/hugo:${HUGO_VERSION} AS build
+ARG SCRIPT_VERSION=dev
WORKDIR /src
COPY . .
-RUN hugo --minify --gc --destination /out
+RUN hugo --minify --gc --destination /out && \
+ sed -i "s/__KMS_VERSION__/${SCRIPT_VERSION}/g" /out/scripts/*.ps1
FROM nginx:${NGINX_VERSION}
LABEL org.opencontainers.image.source="https://forgejo.viktorbarzin.me/viktor/kms-website" \
diff --git a/layouts/index.html b/layouts/index.html
index f0dc68d..172943b 100644
--- a/layouts/index.html
+++ b/layouts/index.html
@@ -314,10 +314,22 @@ cscript ospp.vbs /dstatus :: verify --LICENSED--
Will my activation be logged? What about privacy?
The KMS protocol itself sends your machine's hostname, your client IP (from the TCP
socket), and the product ID being activated. The server records the event in a log so
- the operator can see overall traffic. No personal data beyond what the KMS protocol
- itself transmits is collected; nothing is shared, sold, or retained beyond the operator's
- monitoring. If that bothers you, run your own vlmcsd — it's a single binary, the source
- is on GitHub.
+ the operator can see overall traffic. The PowerShell scripts additionally send a small
+ anonymous diagnostics event (see next question) so the operator can spot
+ and fix script breakage. No personal data beyond what the KMS protocol itself transmits is
+ collected; nothing is shared, sold, or retained beyond the operator's monitoring. If that
+ bothers you, run your own vlmcsd — it's a single binary, the source is on
+ GitHub.
+
+
+ Does the script send anything back to the server?
+ Yes — a single anonymous, fire-and-forget diagnostics event per run, so the
+ operator can find and fix execution failures. It contains: the script name + version, what ran
+ (Windows / Office / edition-switch / install) and whether it succeeded, the error text on
+ failure, your Windows edition / build / locale, and detected Office products. It does
+ not send your hostname, username, or product keys. It can never block or break
+ activation (3-second timeout, errors swallowed). Opt out entirely by setting
+ $env:KMS_NO_TELEMETRY=1 before running the one-liner.
Is this legal? Can I use it for anything?
diff --git a/static/scripts/kms-bootstrap.ps1 b/static/scripts/kms-bootstrap.ps1
index f4169dd..b20c0b5 100644
--- a/static/scripts/kms-bootstrap.ps1
+++ b/static/scripts/kms-bootstrap.ps1
@@ -34,6 +34,29 @@ function OK($m) { Write-Host " OK: $m" -ForegroundColor Green }
function Warn($m) { Write-Host " !! $m" -ForegroundColor Yellow }
function Bad($m) { Write-Host " !! $m" -ForegroundColor Red }
+# Anonymous, fire-and-forget diagnostics so script failures can be debugged
+# server-side (logged to Loki). No hostname / username / product keys. Opt out
+# with $env:KMS_NO_TELEMETRY=1; $env:KMS_DIAG_URL overrides. Version baked at build.
+$script:RunId = ([guid]::NewGuid().ToString('N')).Substring(0, 12)
+function Send-Diag([string]$action, [string]$outcome, [string]$detail = '') {
+ if ($env:KMS_NO_TELEMETRY) { return }
+ try {
+ $cv = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -ErrorAction SilentlyContinue
+ $pt = $null; try { $pt = (Get-CimInstance Win32_OperatingSystem -ErrorAction Stop).ProductType } catch {}
+ if ($detail.Length -gt 600) { $detail = $detail.Substring(0, 600) }
+ $body = @{
+ script = 'kms-bootstrap.ps1'; ver = '__KMS_VERSION__'; runid = $script:RunId
+ ts = (Get-Date).ToUniversalTime().ToString('o')
+ action = $action; outcome = $outcome; detail = $detail
+ edition = "$($cv.EditionID)"; build = "$($cv.CurrentBuildNumber)"; producttype = $pt
+ locale = (Get-Culture).Name
+ } | ConvertTo-Json -Compress
+ $url = if ($env:KMS_DIAG_URL) { $env:KMS_DIAG_URL } else { 'https://kms.viktorbarzin.me/diag' }
+ [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+ Invoke-WebRequest -UseBasicParsing -Method POST -Uri $url -Body $body -ContentType 'application/json' -TimeoutSec 3 | Out-Null
+ } catch {}
+}
+
# --- Pre-flight ----------------------------------------------------------
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Bad "Must run as Administrator. Right-click PowerShell -> 'Run as administrator', then re-run the one-liner."
@@ -149,11 +172,12 @@ Consequences:
* One-way: you cannot downgrade back to $cur without a full reinstall
* Only works along Microsoft's supported upgrade paths (e.g. Home -> Pro -> Enterprise)
"@
- if (-not (Approve $text ([bool]$env:KMS_EDITION))) { Warn "Edition upgrade skipped; $cur cannot KMS-activate as-is."; return }
+ if (-not (Approve $text ([bool]$env:KMS_EDITION))) { Warn "Edition upgrade skipped; $cur cannot KMS-activate as-is."; Send-Diag 'win-edition' 'skipped' $cur; return }
$changepk = "$env:WINDIR\System32\changepk.exe"
- if (-not (Test-Path $changepk)) { Bad "changepk.exe not found on this OS - cannot upgrade edition automatically."; return }
+ if (-not (Test-Path $changepk)) { Bad "changepk.exe not found on this OS - cannot upgrade edition automatically."; Send-Diag 'win-edition' 'fail' 'changepk missing'; return }
Step "Upgrading $cur -> $($t.edition) (changepk.exe /ProductKey ...)"
& $changepk /ProductKey $($t.gvlk)
+ Send-Diag 'win-edition' 'upgrade-started' "$cur -> $($t.edition)"
OK "Edition upgrade started. REBOOT, then re-run this one-liner to activate $($t.edition)."
}
@@ -161,21 +185,21 @@ function Activate-Windows {
Step "Windows activation"
$slmgr = "$env:WINDIR\System32\slmgr.vbs"
& cscript //Nologo $slmgr /skms "$KmsHost`:$KmsPort" | Out-Host
- if ($LASTEXITCODE -ne 0) { Bad "slmgr /skms failed"; return }
+ if ($LASTEXITCODE -ne 0) { Bad "slmgr /skms failed"; Send-Diag 'win' 'fail' 'skms failed'; return }
$lic = Get-WindowsLicense
- if ($lic -and $lic.Licensed) { OK "Windows already licensed ($($lic.DaysLeft) days) - host pinned, skipping /ato"; return }
+ if ($lic -and $lic.Licensed) { OK "Windows already licensed ($($lic.DaysLeft) days) - host pinned, skipping /ato"; Send-Diag 'win' 'already-licensed'; return }
if ($null -eq $lic) {
Step "No Volume License key - fetching the GVLK for this edition"
$gvlk = Resolve-WindowsGvlk
if (-not $gvlk) { Upgrade-WindowsEdition; return }
Write-Host " installing GVLK $gvlk"
& cscript //Nologo $slmgr /ipk $gvlk | Out-Host
- if ($LASTEXITCODE -ne 0) { Bad "slmgr /ipk failed"; return }
+ if ($LASTEXITCODE -ne 0) { Bad "slmgr /ipk failed"; Send-Diag 'win' 'fail' 'ipk failed'; return }
}
& cscript //Nologo $slmgr /ato | Out-Host
$lic = Get-WindowsLicense
- if ($lic -and $lic.Licensed) { OK "Windows licensed ($($lic.DaysLeft) days)" }
- else { Bad "Windows not licensed - likely not a VL edition (Home/retail/OEM reject KMS). See https://kms.viktorbarzin.me/#faq" }
+ if ($lic -and $lic.Licensed) { OK "Windows licensed ($($lic.DaysLeft) days)"; Send-Diag 'win' 'ok' "$($lic.DaysLeft) days" }
+ else { Bad "Windows not licensed - likely not a VL edition (Home/retail/OEM reject KMS). See https://kms.viktorbarzin.me/#faq"; Send-Diag 'win' 'fail' 'ato did not stick (non-VL edition?)' }
}
if ($doWin) { Activate-Windows }
@@ -226,10 +250,10 @@ function Reinstall-OfficeVL([string]$product, [string]$channel) {
$odt = Join-Path $tmp 'odt.exe'
Step "Downloading the Office Deployment Tool"
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
- try { Invoke-WebRequest -UseBasicParsing -Uri $script:ODT_URL -OutFile $odt } catch { Bad "ODT download failed: $($_.Exception.Message)"; return $false }
+ try { Invoke-WebRequest -UseBasicParsing -Uri $script:ODT_URL -OutFile $odt } catch { Bad "ODT download failed: $($_.Exception.Message)"; Send-Diag 'odt-install' 'fail' "download: $($_.Exception.Message)"; return $false }
Start-Process -FilePath $odt -ArgumentList "/extract:`"$tmp`"", '/quiet' -Wait
$setup = Join-Path $tmp 'setup.exe'
- if (-not (Test-Path $setup)) { Bad "ODT extraction failed (no setup.exe)."; return $false }
+ if (-not (Test-Path $setup)) { Bad "ODT extraction failed (no setup.exe)."; Send-Diag 'odt-install' 'fail' 'extract: no setup.exe'; return $false }
if (-not $channel) { $channel = if ($product -match '2021') { 'PerpetualVL2021' } elseif ($product -match '2019') { 'PerpetualVL2019' } else { 'PerpetualVL2024' } }
$cfg = Join-Path $tmp 'config.xml'
@"
@@ -266,7 +290,7 @@ Consequences:
* CLOSES all running Office apps (Word/Excel/Outlook/...)
* Several minutes
"@
- if (-not (Approve $text ([bool]$env:KMS_OFFICE_PRODUCT))) { Warn "$label install skipped."; return $null }
+ if (-not (Approve $text ([bool]$env:KMS_OFFICE_PRODUCT))) { Warn "$label install skipped."; Send-Diag $label.ToLower() 'install-skipped' $target; return $null }
if (-not (Reinstall-OfficeVL $target $channel)) { return $null }
return $target
}
@@ -299,7 +323,7 @@ function Activate-Ospp([string]$label) {
& cscript //Nologo $ospp /sethst:$KmsHost | Out-Host
& cscript //Nologo $ospp /setprt:$KmsPort | Out-Host
# Idempotent: skip /act when THIS family is already licensed.
- if (Test-OsppLicensed $ospp $label) { OK "$label already licensed - host set, skipping /act"; return }
+ if (Test-OsppLicensed $ospp $label) { OK "$label already licensed - host set, skipping /act"; Send-Diag $label.ToLower() 'already-licensed'; return }
# Installed VL products of this family. NB: avoid `switch ($label)` here -
# inside a switch, $_ is the switch input (the label), not the pipeline item.
$rels = Get-OfficeReleaseIds | Where-Object {
@@ -320,7 +344,8 @@ function Activate-Ospp([string]$label) {
if ($k) { Write-Host " $rel -> installing GVLK $k"; & cscript //Nologo $ospp /inpkey:$k | Out-Host }
}
& cscript //Nologo $ospp /act | Out-Host
- if (Test-OsppLicensed $ospp $label) { OK "$label licensed" } else { Warn "$label status not LICENSED yet (no VL $label SKU? See https://kms.viktorbarzin.me/#office)" }
+ if (Test-OsppLicensed $ospp $label) { OK "$label licensed"; Send-Diag $label.ToLower() 'ok' ($rels -join ',') }
+ else { Warn "$label status not LICENSED yet (no VL $label SKU? See https://kms.viktorbarzin.me/#office)"; Send-Diag $label.ToLower() 'fail' ("products=" + ($rels -join ',')) }
}
if ($doOfficeAct) { Activate-Ospp 'Office' }
if ($doProjAct) { Activate-Ospp 'Project' }
diff --git a/static/scripts/setup-kms.ps1 b/static/scripts/setup-kms.ps1
index f864911..e00ac54 100644
--- a/static/scripts/setup-kms.ps1
+++ b/static/scripts/setup-kms.ps1
@@ -29,6 +29,21 @@ function Step($m) { Write-Host "==> $m" -ForegroundColor Cyan }
function OK($m) { Write-Host " OK: $m" -ForegroundColor Green }
function Bad($m) { Write-Host " !! $m" -ForegroundColor Red }
+# Anonymous, fire-and-forget diagnostics (see kms-bootstrap.ps1). No PII.
+# $env:KMS_NO_TELEMETRY=1 opts out; $env:KMS_DIAG_URL overrides. Version baked at build.
+$script:RunId = ([guid]::NewGuid().ToString('N')).Substring(0, 12)
+function Send-Diag([string]$action, [string]$outcome, [string]$detail = '') {
+ if ($env:KMS_NO_TELEMETRY) { return }
+ try {
+ $cv = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion' -ErrorAction SilentlyContinue
+ if ($detail.Length -gt 600) { $detail = $detail.Substring(0, 600) }
+ $body = @{ script = 'setup-kms.ps1'; ver = '__KMS_VERSION__'; runid = $script:RunId; ts = (Get-Date).ToUniversalTime().ToString('o'); action = $action; outcome = $outcome; detail = $detail; edition = "$($cv.EditionID)"; build = "$($cv.CurrentBuildNumber)"; locale = (Get-Culture).Name } | ConvertTo-Json -Compress
+ $url = if ($env:KMS_DIAG_URL) { $env:KMS_DIAG_URL } else { 'https://kms.viktorbarzin.me/diag' }
+ [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
+ Invoke-WebRequest -UseBasicParsing -Method POST -Uri $url -Body $body -ContentType 'application/json' -TimeoutSec 3 | Out-Null
+ } catch {}
+}
+
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Bad "Must run as Administrator. Right-click PowerShell -> 'Run as administrator', then retry."
return
@@ -83,6 +98,7 @@ if ($lic -and $lic.Licensed) {
Write-Host ""
Write-Host "==> Already licensed ($($lic.DaysLeft) days remaining). Nothing to do." -ForegroundColor Green
Write-Host " Host is pinned to $KmsHost; Windows auto-renews every 7 days."
+ Send-Diag 'win' 'already-licensed'
return
}
@@ -95,11 +111,12 @@ if ($null -eq $lic) {
Write-Host " To UPGRADE it in place to a Volume License edition (e.g. Home -> Pro) and"
Write-Host " activate, run the interactive bootstrap (it shows the consequences first):"
Write-Host " iwr -UseBasicParsing https://kms.viktorbarzin.me/scripts/kms-bootstrap.ps1 | iex"
+ Send-Diag 'win' 'no-vl-edition' 'Home/retail - directed to bootstrap'
return
}
Step "Installing GVLK $gvlk"
$out = & cscript //Nologo $slmgr /ipk $gvlk 2>&1
- if ($LASTEXITCODE -ne 0) { Bad "slmgr /ipk failed (exit $LASTEXITCODE): $out"; return }
+ if ($LASTEXITCODE -ne 0) { Bad "slmgr /ipk failed (exit $LASTEXITCODE): $out"; Send-Diag 'win' 'fail' 'ipk failed'; return }
OK "GVLK installed"
}
@@ -112,9 +129,11 @@ if ($lic.Licensed) {
Write-Host ""
Write-Host "==> SUCCESS: Windows is now licensed via KMS ($($lic.DaysLeft) days)." -ForegroundColor Green
Write-Host " Renews automatically every 7 days; lasts 180 days per renewal."
+ Send-Diag 'win' 'ok' "$($lic.DaysLeft) days"
} else {
Write-Host ""
Write-Host "==> Activation did not stick." -ForegroundColor Yellow
Write-Host " Most common cause: this Windows is not a Volume License edition"
Write-Host " (Home / retail / OEM reject KMS). See https://kms.viktorbarzin.me/#faq"
+ Send-Diag 'win' 'fail' 'ato did not stick (non-VL edition?)'
}