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 <noreply@anthropic.com>
This commit is contained in:
parent
b51dc9894c
commit
7cfcd73d83
4 changed files with 76 additions and 18 deletions
|
|
@ -3,9 +3,11 @@ ARG HUGO_VERSION=0.139.0
|
||||||
ARG NGINX_VERSION=1.27-alpine
|
ARG NGINX_VERSION=1.27-alpine
|
||||||
|
|
||||||
FROM hugomods/hugo:${HUGO_VERSION} AS build
|
FROM hugomods/hugo:${HUGO_VERSION} AS build
|
||||||
|
ARG SCRIPT_VERSION=dev
|
||||||
WORKDIR /src
|
WORKDIR /src
|
||||||
COPY . .
|
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}
|
FROM nginx:${NGINX_VERSION}
|
||||||
LABEL org.opencontainers.image.source="https://forgejo.viktorbarzin.me/viktor/kms-website" \
|
LABEL org.opencontainers.image.source="https://forgejo.viktorbarzin.me/viktor/kms-website" \
|
||||||
|
|
|
||||||
|
|
@ -314,10 +314,22 @@ cscript ospp.vbs /dstatus :: verify --LICENSED--</code></pre>
|
||||||
<summary>Will my activation be logged? What about privacy?</summary>
|
<summary>Will my activation be logged? What about privacy?</summary>
|
||||||
<p>The KMS protocol itself sends your machine's hostname, your client IP (from the TCP
|
<p>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
|
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
|
the operator can see overall traffic. The PowerShell scripts additionally send a small
|
||||||
itself transmits is collected; nothing is shared, sold, or retained beyond the operator's
|
<strong>anonymous</strong> diagnostics event (see next question) so the operator can spot
|
||||||
monitoring. If that bothers you, run your own vlmcsd — it's a single binary, the source
|
and fix script breakage. No personal data beyond what the KMS protocol itself transmits is
|
||||||
is on <a href="https://github.com/Wind4/vlmcsd" target="_blank" rel="noopener">GitHub</a>.</p>
|
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
|
||||||
|
<a href="https://github.com/Wind4/vlmcsd" target="_blank" rel="noopener">GitHub</a>.</p>
|
||||||
|
</details>
|
||||||
|
<details>
|
||||||
|
<summary>Does the script send anything back to the server?</summary>
|
||||||
|
<p>Yes — a single <strong>anonymous, fire-and-forget</strong> 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
|
||||||
|
<strong>not</strong> send your hostname, username, or product keys. It can never block or break
|
||||||
|
activation (3-second timeout, errors swallowed). Opt out entirely by setting
|
||||||
|
<code>$env:KMS_NO_TELEMETRY=1</code> before running the one-liner.</p>
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
<summary>Is this legal? Can I use it for anything?</summary>
|
<summary>Is this legal? Can I use it for anything?</summary>
|
||||||
|
|
|
||||||
|
|
@ -34,6 +34,29 @@ function OK($m) { Write-Host " OK: $m" -ForegroundColor Green }
|
||||||
function Warn($m) { Write-Host " !! $m" -ForegroundColor Yellow }
|
function Warn($m) { Write-Host " !! $m" -ForegroundColor Yellow }
|
||||||
function Bad($m) { Write-Host " !! $m" -ForegroundColor Red }
|
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 ----------------------------------------------------------
|
# --- Pre-flight ----------------------------------------------------------
|
||||||
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
|
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."
|
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
|
* 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)
|
* 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"
|
$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 ...)"
|
Step "Upgrading $cur -> $($t.edition) (changepk.exe /ProductKey ...)"
|
||||||
& $changepk /ProductKey $($t.gvlk)
|
& $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)."
|
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"
|
Step "Windows activation"
|
||||||
$slmgr = "$env:WINDIR\System32\slmgr.vbs"
|
$slmgr = "$env:WINDIR\System32\slmgr.vbs"
|
||||||
& cscript //Nologo $slmgr /skms "$KmsHost`:$KmsPort" | Out-Host
|
& 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
|
$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) {
|
if ($null -eq $lic) {
|
||||||
Step "No Volume License key - fetching the GVLK for this edition"
|
Step "No Volume License key - fetching the GVLK for this edition"
|
||||||
$gvlk = Resolve-WindowsGvlk
|
$gvlk = Resolve-WindowsGvlk
|
||||||
if (-not $gvlk) { Upgrade-WindowsEdition; return }
|
if (-not $gvlk) { Upgrade-WindowsEdition; return }
|
||||||
Write-Host " installing GVLK $gvlk"
|
Write-Host " installing GVLK $gvlk"
|
||||||
& cscript //Nologo $slmgr /ipk $gvlk | Out-Host
|
& 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
|
& cscript //Nologo $slmgr /ato | Out-Host
|
||||||
$lic = Get-WindowsLicense
|
$lic = Get-WindowsLicense
|
||||||
if ($lic -and $lic.Licensed) { OK "Windows licensed ($($lic.DaysLeft) days)" }
|
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" }
|
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 }
|
if ($doWin) { Activate-Windows }
|
||||||
|
|
||||||
|
|
@ -226,10 +250,10 @@ function Reinstall-OfficeVL([string]$product, [string]$channel) {
|
||||||
$odt = Join-Path $tmp 'odt.exe'
|
$odt = Join-Path $tmp 'odt.exe'
|
||||||
Step "Downloading the Office Deployment Tool"
|
Step "Downloading the Office Deployment Tool"
|
||||||
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
|
[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
|
Start-Process -FilePath $odt -ArgumentList "/extract:`"$tmp`"", '/quiet' -Wait
|
||||||
$setup = Join-Path $tmp 'setup.exe'
|
$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' } }
|
if (-not $channel) { $channel = if ($product -match '2021') { 'PerpetualVL2021' } elseif ($product -match '2019') { 'PerpetualVL2019' } else { 'PerpetualVL2024' } }
|
||||||
$cfg = Join-Path $tmp 'config.xml'
|
$cfg = Join-Path $tmp 'config.xml'
|
||||||
@"
|
@"
|
||||||
|
|
@ -266,7 +290,7 @@ Consequences:
|
||||||
* CLOSES all running Office apps (Word/Excel/Outlook/...)
|
* CLOSES all running Office apps (Word/Excel/Outlook/...)
|
||||||
* Several minutes
|
* 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 }
|
if (-not (Reinstall-OfficeVL $target $channel)) { return $null }
|
||||||
return $target
|
return $target
|
||||||
}
|
}
|
||||||
|
|
@ -299,7 +323,7 @@ function Activate-Ospp([string]$label) {
|
||||||
& cscript //Nologo $ospp /sethst:$KmsHost | Out-Host
|
& cscript //Nologo $ospp /sethst:$KmsHost | Out-Host
|
||||||
& cscript //Nologo $ospp /setprt:$KmsPort | Out-Host
|
& cscript //Nologo $ospp /setprt:$KmsPort | Out-Host
|
||||||
# Idempotent: skip /act when THIS family is already licensed.
|
# 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 -
|
# Installed VL products of this family. NB: avoid `switch ($label)` here -
|
||||||
# inside a switch, $_ is the switch input (the label), not the pipeline item.
|
# inside a switch, $_ is the switch input (the label), not the pipeline item.
|
||||||
$rels = Get-OfficeReleaseIds | Where-Object {
|
$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 }
|
if ($k) { Write-Host " $rel -> installing GVLK $k"; & cscript //Nologo $ospp /inpkey:$k | Out-Host }
|
||||||
}
|
}
|
||||||
& cscript //Nologo $ospp /act | 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 ($doOfficeAct) { Activate-Ospp 'Office' }
|
||||||
if ($doProjAct) { Activate-Ospp 'Project' }
|
if ($doProjAct) { Activate-Ospp 'Project' }
|
||||||
|
|
|
||||||
|
|
@ -29,6 +29,21 @@ function Step($m) { Write-Host "==> $m" -ForegroundColor Cyan }
|
||||||
function OK($m) { Write-Host " OK: $m" -ForegroundColor Green }
|
function OK($m) { Write-Host " OK: $m" -ForegroundColor Green }
|
||||||
function Bad($m) { Write-Host " !! $m" -ForegroundColor Red }
|
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)) {
|
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."
|
Bad "Must run as Administrator. Right-click PowerShell -> 'Run as administrator', then retry."
|
||||||
return
|
return
|
||||||
|
|
@ -83,6 +98,7 @@ if ($lic -and $lic.Licensed) {
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
Write-Host "==> Already licensed ($($lic.DaysLeft) days remaining). Nothing to do." -ForegroundColor Green
|
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."
|
Write-Host " Host is pinned to $KmsHost; Windows auto-renews every 7 days."
|
||||||
|
Send-Diag 'win' 'already-licensed'
|
||||||
return
|
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 " 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 " activate, run the interactive bootstrap (it shows the consequences first):"
|
||||||
Write-Host " iwr -UseBasicParsing https://kms.viktorbarzin.me/scripts/kms-bootstrap.ps1 | iex"
|
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
|
return
|
||||||
}
|
}
|
||||||
Step "Installing GVLK $gvlk"
|
Step "Installing GVLK $gvlk"
|
||||||
$out = & cscript //Nologo $slmgr /ipk $gvlk 2>&1
|
$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"
|
OK "GVLK installed"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -112,9 +129,11 @@ if ($lic.Licensed) {
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
Write-Host "==> SUCCESS: Windows is now licensed via KMS ($($lic.DaysLeft) days)." -ForegroundColor Green
|
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."
|
Write-Host " Renews automatically every 7 days; lasts 180 days per renewal."
|
||||||
|
Send-Diag 'win' 'ok' "$($lic.DaysLeft) days"
|
||||||
} else {
|
} else {
|
||||||
Write-Host ""
|
Write-Host ""
|
||||||
Write-Host "==> Activation did not stick." -ForegroundColor Yellow
|
Write-Host "==> Activation did not stick." -ForegroundColor Yellow
|
||||||
Write-Host " Most common cause: this Windows is not a Volume License edition"
|
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"
|
Write-Host " (Home / retail / OEM reject KMS). See https://kms.viktorbarzin.me/#faq"
|
||||||
|
Send-Diag 'win' 'fail' 'ato did not stick (non-VL edition?)'
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue