kms-website: public scripts + sanitized copy + slack notifier
- static/scripts/{setup-kms.ps1,kms-bootstrap.ps1}: public, internet-friendly
- Drop \\nas.viktorbarzin.lan\\Emo shared\\ refs (internal SMB share, leaks personal name)
- Reframe LAN section as optional auto-discovery for self-hosters
- Add privacy + legality FAQs
- Quick Start uses one-liner: iwr | iex against /scripts/kms-bootstrap.ps1
- bootstrapURL now points at site-relative /scripts/
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
parent
129410793a
commit
5da130be93
4 changed files with 327 additions and 41 deletions
|
|
@ -4,11 +4,12 @@ title = "kms.viktorbarzin.me"
|
||||||
disableKinds = ["taxonomy", "term", "RSS", "sitemap", "404"]
|
disableKinds = ["taxonomy", "term", "RSS", "sitemap", "404"]
|
||||||
|
|
||||||
[params]
|
[params]
|
||||||
description = "Self-hosted KMS activation reference for Windows, Office, Project, Visio."
|
description = "Public KMS host for activating Microsoft Volume License Windows, Office, Project, and Visio. Free, no signup, no tracking."
|
||||||
kmsHost = "kms.viktorbarzin.lan"
|
kmsHost = "kms.viktorbarzin.me"
|
||||||
kmsHostExt = "kms.viktorbarzin.me"
|
kmsHostLan = "kms.viktorbarzin.lan"
|
||||||
kmsPort = 1688
|
kmsPort = 1688
|
||||||
bootstrapURL = "https://nas.viktorbarzin.lan/Emo%20shared/kms-bootstrap.ps1"
|
bootstrapURL = "/scripts/kms-bootstrap.ps1"
|
||||||
|
setupURL = "/scripts/setup-kms.ps1"
|
||||||
|
|
||||||
[markup]
|
[markup]
|
||||||
[markup.goldmark.renderer]
|
[markup.goldmark.renderer]
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
<span class="logo">⊞</span>
|
<span class="logo">⊞</span>
|
||||||
<div>
|
<div>
|
||||||
<h1>kms.viktorbarzin.me</h1>
|
<h1>kms.viktorbarzin.me</h1>
|
||||||
<p class="tag">Self-hosted KMS for Windows · Office · Project · Visio</p>
|
<p class="tag">Free public KMS · Windows · Office · Project · Visio · No signup, no tracking</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<nav>
|
<nav>
|
||||||
|
|
@ -36,22 +36,22 @@
|
||||||
<div class="wrap">
|
<div class="wrap">
|
||||||
<h2>Activate Microsoft Volume License products in seconds.</h2>
|
<h2>Activate Microsoft Volume License products in seconds.</h2>
|
||||||
<p class="lede">
|
<p class="lede">
|
||||||
One private KMS host, every supported edition. Auto-discovery via DNS SRV from inside the network,
|
Public KMS host. Point any VL Windows / Office / Project / Visio at it and it activates —
|
||||||
manual <code>/skms</code> from outside. No keys to remember — just install a Volume License edition
|
no keys to remember, no account, no logs of personal data beyond the activation event itself.
|
||||||
and it activates itself.
|
Run the one-liner below, or use the GVLK tables further down.
|
||||||
</p>
|
</p>
|
||||||
<div class="kms-target">
|
<div class="kms-target">
|
||||||
<div class="kms-target-item">
|
<div class="kms-target-item">
|
||||||
<span class="muted">Internal LAN host</span>
|
<span class="muted">Public KMS host</span>
|
||||||
<code class="copy" data-copy="{{ .Site.Params.kmsHost }}:{{ .Site.Params.kmsPort }}">{{ .Site.Params.kmsHost }}:{{ .Site.Params.kmsPort }}</code>
|
<code class="copy" data-copy="{{ .Site.Params.kmsHost }}:{{ .Site.Params.kmsPort }}">{{ .Site.Params.kmsHost }}:{{ .Site.Params.kmsPort }}</code>
|
||||||
</div>
|
</div>
|
||||||
<div class="kms-target-item">
|
<div class="kms-target-item">
|
||||||
<span class="muted">External / off-LAN host</span>
|
<span class="muted">Reachable from</span>
|
||||||
<code class="copy" data-copy="{{ .Site.Params.kmsHostExt }}:{{ .Site.Params.kmsPort }}">{{ .Site.Params.kmsHostExt }}:{{ .Site.Params.kmsPort }}</code>
|
<code>any IPv4 internet</code>
|
||||||
</div>
|
</div>
|
||||||
<div class="kms-target-item">
|
<div class="kms-target-item">
|
||||||
<span class="muted">Auto-discovery SRV</span>
|
<span class="muted">Cost</span>
|
||||||
<code class="copy" data-copy="_vlmcs._tcp.viktorbarzin.lan">_vlmcs._tcp.viktorbarzin.lan</code>
|
<code>free, forever</code>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
@ -60,24 +60,29 @@
|
||||||
<main class="wrap">
|
<main class="wrap">
|
||||||
|
|
||||||
<section id="quickstart">
|
<section id="quickstart">
|
||||||
<h2>Quick start — fully automatic on a new machine</h2>
|
<h2>Quick start</h2>
|
||||||
<p>
|
<p>
|
||||||
On the home / lab network, a freshly-installed Volume License edition will activate itself
|
Open <strong>PowerShell as Administrator</strong> on a Volume License Windows install
|
||||||
once Windows can find the SRV record. The bootstrap script below sets the Primary DNS Suffix,
|
and paste the one-liner. The script asks what you want to activate (Windows, Office,
|
||||||
optionally installs Office + Project (LTSC 2024 VL), triggers <code>slmgr /ato</code> + <code>ospp.vbs /act</code>,
|
Project, Visio), points each at <code>{{ .Site.Params.kmsHost }}:{{ .Site.Params.kmsPort }}</code>,
|
||||||
and prompts for a single reboot.
|
runs the activation, and prints the result.
|
||||||
</p>
|
</p>
|
||||||
<div class="card terminal">
|
<div class="card terminal">
|
||||||
<div class="card-head"><span>PowerShell (run as Administrator)</span><button class="btn-copy" data-copy-target="quickstart-cmd">Copy</button></div>
|
<div class="card-head"><span>One-liner — interactive</span><button class="btn-copy" data-copy-target="quickstart-cmd">Copy</button></div>
|
||||||
<pre id="quickstart-cmd"><code>powershell -ExecutionPolicy Bypass -File "\\nas.viktorbarzin.lan\Emo shared\kms-bootstrap.ps1"</code></pre>
|
<pre id="quickstart-cmd"><code>iwr -UseBasicParsing https://{{ .Site.Params.kmsHost }}{{ .Site.Params.bootstrapURL }} | iex</code></pre>
|
||||||
</div>
|
</div>
|
||||||
<p class="hint">Off-LAN? Skip auto-discovery and pin the host explicitly:</p>
|
<p class="hint">
|
||||||
|
Prefer to read the script first? <a href="{{ .Site.Params.bootstrapURL }}">View kms-bootstrap.ps1</a>
|
||||||
|
or <a href="{{ .Site.Params.setupURL }}">setup-kms.ps1</a> (a smaller, non-interactive variant
|
||||||
|
that just points Windows at the KMS host and runs <code>slmgr /ato</code>).
|
||||||
|
</p>
|
||||||
|
<p class="hint">Want to skip the script entirely? Two cmd.exe lines do the same job:</p>
|
||||||
<div class="card terminal">
|
<div class="card terminal">
|
||||||
<div class="card-head"><span>cmd.exe — explicit KMS host</span><button class="btn-copy" data-copy-target="explicit-cmd">Copy</button></div>
|
<div class="card-head"><span>cmd.exe — manual</span><button class="btn-copy" data-copy-target="explicit-cmd">Copy</button></div>
|
||||||
<pre id="explicit-cmd"><code>slmgr /skms kms.viktorbarzin.me
|
<pre id="explicit-cmd"><code>slmgr /skms {{ .Site.Params.kmsHost }}:{{ .Site.Params.kmsPort }}
|
||||||
slmgr /ato
|
slmgr /ato
|
||||||
|
|
||||||
cscript "C:\Program Files\Microsoft Office\Office16\ospp.vbs" /sethst:kms.viktorbarzin.me
|
cscript "C:\Program Files\Microsoft Office\Office16\ospp.vbs" /sethst:{{ .Site.Params.kmsHost }}
|
||||||
cscript "C:\Program Files\Microsoft Office\Office16\ospp.vbs" /act</code></pre>
|
cscript "C:\Program Files\Microsoft Office\Office16\ospp.vbs" /act</code></pre>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
@ -117,11 +122,11 @@ cscript "C:\Program Files\Microsoft Office\Office16\ospp.vbs" /act</code></pre>
|
||||||
<details class="card">
|
<details class="card">
|
||||||
<summary>How to use a GVLK on Windows</summary>
|
<summary>How to use a GVLK on Windows</summary>
|
||||||
<pre><code>:: open cmd.exe as Administrator
|
<pre><code>:: open cmd.exe as Administrator
|
||||||
slmgr /upk :: remove existing key
|
slmgr /upk :: remove existing key
|
||||||
slmgr /ipk <PASTE-GVLK-HERE> :: install GVLK
|
slmgr /ipk <PASTE-GVLK-HERE> :: install GVLK
|
||||||
slmgr /skms kms.viktorbarzin.me :: optional: skip auto-discovery
|
slmgr /skms {{ .Site.Params.kmsHost }}:{{ .Site.Params.kmsPort }} :: point at this server
|
||||||
slmgr /ato :: activate
|
slmgr /ato :: activate
|
||||||
slmgr /dlv :: verify (look for "LICENSED")</code></pre>
|
slmgr /dlv :: verify (look for "LICENSED")</code></pre>
|
||||||
</details>
|
</details>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
|
|
@ -201,7 +206,8 @@ slmgr /dlv :: verify (look for "LICENSED")<
|
||||||
<details class="card">
|
<details class="card">
|
||||||
<summary>Activation — bare commands</summary>
|
<summary>Activation — bare commands</summary>
|
||||||
<pre><code>cd "C:\Program Files\Microsoft Office\Office16"
|
<pre><code>cd "C:\Program Files\Microsoft Office\Office16"
|
||||||
cscript ospp.vbs /sethst:kms.viktorbarzin.me
|
cscript ospp.vbs /sethst:{{ .Site.Params.kmsHost }}
|
||||||
|
cscript ospp.vbs /setprt:{{ .Site.Params.kmsPort }}
|
||||||
cscript ospp.vbs /inpkey:<PASTE-GVLK>
|
cscript ospp.vbs /inpkey:<PASTE-GVLK>
|
||||||
cscript ospp.vbs /act
|
cscript ospp.vbs /act
|
||||||
cscript ospp.vbs /dstatus :: verify --LICENSED--</code></pre>
|
cscript ospp.vbs /dstatus :: verify --LICENSED--</code></pre>
|
||||||
|
|
@ -231,11 +237,18 @@ cscript ospp.vbs /dstatus :: verify --LICENSED--</code></pre>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h3 class="family-head">Bootstrap script</h3>
|
<h3 class="family-head">PowerShell scripts</h3>
|
||||||
<p>One-shot PowerShell that wires DNS suffix, Office install, and activation:</p>
|
<p>Both scripts are open-source, single-file, no dependencies. Read before running.</p>
|
||||||
<a class="dl" href="{{ .Site.Params.bootstrapURL }}" target="_blank" rel="noopener">
|
<ul class="dl-list">
|
||||||
kms-bootstrap.ps1 ↗
|
<li>
|
||||||
</a>
|
<a href="{{ .Site.Params.bootstrapURL }}" target="_blank" rel="noopener">kms-bootstrap.ps1 ↗</a>
|
||||||
|
<span class="muted"> — interactive: prompts for Windows / Office / Project / Visio and activates each.</span>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a href="{{ .Site.Params.setupURL }}" target="_blank" rel="noopener">setup-kms.ps1 ↗</a>
|
||||||
|
<span class="muted"> — minimal: <code>slmgr /skms</code> + <code>/ato</code>. No Office install.</span>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section id="faq">
|
<section id="faq">
|
||||||
|
|
@ -267,12 +280,31 @@ cscript ospp.vbs /dstatus :: verify --LICENSED--</code></pre>
|
||||||
first, then install the VL edition.</p>
|
first, then install the VL edition.</p>
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
<summary>How does auto-discovery work?</summary>
|
<summary>How does auto-discovery work? Do I need it?</summary>
|
||||||
<p>The Software Protection Service queries DNS for
|
<p>No — the Quick Start one-liner pins the host explicitly so auto-discovery is irrelevant
|
||||||
<code>_vlmcs._tcp.<primary-dns-suffix></code>. If the SRV resolves it connects to that
|
for internet visitors. It exists for managed corporate networks: the Software Protection
|
||||||
host on the returned port (1688 by default). On this network the suffix is
|
Service queries DNS for <code>_vlmcs._tcp.<primary-dns-suffix></code>, and if the SRV
|
||||||
<code>viktorbarzin.lan</code> and the SRV resolves to <code>kms.viktorbarzin.lan:1688</code>.
|
resolves, Windows connects there on the returned port. If you want it on your own LAN,
|
||||||
Set the suffix once via System Properties → Computer Name → More → Primary DNS suffix.</p>
|
publish a SRV record pointing at <code>{{ .Site.Params.kmsHost }}:{{ .Site.Params.kmsPort }}</code>
|
||||||
|
(or any vlmcsd you self-host) and set the matching DNS suffix on each client.</p>
|
||||||
|
</details>
|
||||||
|
<details>
|
||||||
|
<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
|
||||||
|
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 <a href="https://github.com/Wind4/vlmcsd" target="_blank" rel="noopener">GitHub</a>.</p>
|
||||||
|
</details>
|
||||||
|
<details>
|
||||||
|
<summary>Is this legal? Can I use it for anything?</summary>
|
||||||
|
<p>KMS activates only <strong>Volume License (VL)</strong> editions of Microsoft software.
|
||||||
|
VL keys are licensed per-organization by Microsoft; using a VL edition without a real VL
|
||||||
|
agreement violates Microsoft's licensing terms. This server exists for personal lab /
|
||||||
|
learning / unsupported-OS-revival use. If you don't have a VL agreement, evaluate
|
||||||
|
Windows + Office through Microsoft's free trial channels instead. The site operator is
|
||||||
|
not responsible for how visitors use the host.</p>
|
||||||
</details>
|
</details>
|
||||||
<details>
|
<details>
|
||||||
<summary>How long does a KMS license last?</summary>
|
<summary>How long does a KMS license last?</summary>
|
||||||
|
|
|
||||||
186
static/scripts/kms-bootstrap.ps1
Normal file
186
static/scripts/kms-bootstrap.ps1
Normal file
|
|
@ -0,0 +1,186 @@
|
||||||
|
# kms-bootstrap.ps1
|
||||||
|
#
|
||||||
|
# Interactive activator for a public KMS host (default: kms.viktorbarzin.me:1688).
|
||||||
|
# Asks what you want to activate (Windows / already-installed Office / Project /
|
||||||
|
# Visio), and optionally what you want to *install* (Office LTSC 2024 ProPlus,
|
||||||
|
# Project Pro 2024, Visio Pro 2024 — all VL editions installed via the official
|
||||||
|
# Microsoft Office Deployment Tool). Runs only what you confirm.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# iwr -UseBasicParsing https://kms.viktorbarzin.me/scripts/kms-bootstrap.ps1 | iex
|
||||||
|
#
|
||||||
|
# Non-interactive (CI / automation):
|
||||||
|
# $env:KMS_AUTO = 'win,office'; iwr ... | iex
|
||||||
|
# (comma list of: win, office, project, visio, install-office,
|
||||||
|
# install-project, install-visio)
|
||||||
|
#
|
||||||
|
# Custom KMS host:
|
||||||
|
# $env:KMS_HOST = 'kms.example.com'; iwr ... | iex
|
||||||
|
#
|
||||||
|
# Source: https://forgejo.viktorbarzin.me/viktor/kms-website
|
||||||
|
# Licence: MIT, no warranty, KMS activates Volume License SKUs only.
|
||||||
|
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[string]$KmsHost = $(if ($env:KMS_HOST) { $env:KMS_HOST } else { 'kms.viktorbarzin.me' }),
|
||||||
|
[int] $KmsPort = $(if ($env:KMS_PORT) { [int]$env:KMS_PORT } else { 1688 })
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
$ProgressPreference = 'SilentlyContinue'
|
||||||
|
|
||||||
|
function Step($m) { Write-Host "==> $m" -ForegroundColor Cyan }
|
||||||
|
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 }
|
||||||
|
|
||||||
|
# --- 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."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host " kms.viktorbarzin.me bootstrap" -ForegroundColor White
|
||||||
|
Write-Host " KMS host: $KmsHost`:$KmsPort"
|
||||||
|
Write-Host " Read the script: https://kms.viktorbarzin.me/scripts/kms-bootstrap.ps1"
|
||||||
|
Write-Host ""
|
||||||
|
|
||||||
|
# --- Decide what to do ---------------------------------------------------
|
||||||
|
function Ask([string]$question, [bool]$default) {
|
||||||
|
$hint = if ($default) { '[Y/n]' } else { '[y/N]' }
|
||||||
|
Write-Host -NoNewline " $question $hint " -ForegroundColor Yellow
|
||||||
|
$a = Read-Host
|
||||||
|
if ([string]::IsNullOrWhiteSpace($a)) { return $default }
|
||||||
|
return $a -match '^[yY]'
|
||||||
|
}
|
||||||
|
|
||||||
|
$auto = @{}
|
||||||
|
if ($env:KMS_AUTO) { $env:KMS_AUTO.Split(',') | ForEach-Object { $auto[$_.Trim().ToLower()] = $true } }
|
||||||
|
|
||||||
|
function Choice([string]$key, [string]$prompt, [bool]$default) {
|
||||||
|
if ($auto.Count -gt 0) { return [bool]$auto[$key] }
|
||||||
|
return Ask $prompt $default
|
||||||
|
}
|
||||||
|
|
||||||
|
Step "What would you like to do?"
|
||||||
|
$doWin = Choice 'win' "Activate this Windows installation against KMS?" $true
|
||||||
|
$doOfficeAct = Choice 'office' "Activate an already-installed Office (Pro Plus 2024 / 2021 / 2019 / 2016)?" $false
|
||||||
|
$doProjAct = Choice 'project' "Activate an already-installed Project (Pro 2024 / 2021 / 2019 / 2016)?" $false
|
||||||
|
$doVisioAct = Choice 'visio' "Activate an already-installed Visio (Pro 2024 / 2021 / 2019 / 2016)?" $false
|
||||||
|
|
||||||
|
$doInstOff = Choice 'install-office' "Install Office LTSC 2024 ProPlus (VL, ~3 GB) and activate?" $false
|
||||||
|
$doInstProj = Choice 'install-project' "Install Project Pro 2024 (VL) and activate?" $false
|
||||||
|
$doInstVis = Choice 'install-visio' "Install Visio Pro 2024 (VL) and activate?" $false
|
||||||
|
|
||||||
|
if (-not ($doWin -or $doOfficeAct -or $doProjAct -or $doVisioAct -or $doInstOff -or $doInstProj -or $doInstVis)) {
|
||||||
|
Warn "Nothing selected. Exiting."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
# --- Windows -------------------------------------------------------------
|
||||||
|
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 }
|
||||||
|
& cscript //Nologo $slmgr /ato | Out-Host
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Bad "slmgr /ato failed. Most likely cause: not a Volume License edition (Home/retail/OEM cannot KMS-activate)."
|
||||||
|
Write-Host " See https://kms.viktorbarzin.me/#faq"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
$dlv = & cscript //Nologo $slmgr /dlv 2>&1 | Out-String
|
||||||
|
if ($dlv -match 'License Status:\s*Licensed') { OK "Windows licensed" } else { Warn "Status not 'Licensed' yet — try 'slmgr /dlv' in a minute" }
|
||||||
|
}
|
||||||
|
if ($doWin) { Activate-Windows }
|
||||||
|
|
||||||
|
# --- Office / Project / Visio: activate already-installed ----------------
|
||||||
|
function Find-Ospp {
|
||||||
|
$candidates = @(
|
||||||
|
"${env:ProgramFiles}\Microsoft Office\Office16\ospp.vbs",
|
||||||
|
"${env:ProgramFiles(x86)}\Microsoft Office\Office16\ospp.vbs",
|
||||||
|
"${env:ProgramFiles}\Microsoft Office\Office15\ospp.vbs",
|
||||||
|
"${env:ProgramFiles(x86)}\Microsoft Office\Office15\ospp.vbs"
|
||||||
|
)
|
||||||
|
foreach ($c in $candidates) { if (Test-Path $c) { return $c } }
|
||||||
|
return $null
|
||||||
|
}
|
||||||
|
|
||||||
|
function Activate-Ospp([string]$label) {
|
||||||
|
$ospp = Find-Ospp
|
||||||
|
if (-not $ospp) {
|
||||||
|
Warn "$label`: ospp.vbs not found (Office not installed?). Skipping."
|
||||||
|
return
|
||||||
|
}
|
||||||
|
Step "$label activation via $ospp"
|
||||||
|
& cscript //Nologo $ospp /sethst:$KmsHost | Out-Host
|
||||||
|
& cscript //Nologo $ospp /setprt:$KmsPort | Out-Host
|
||||||
|
& cscript //Nologo $ospp /act | Out-Host
|
||||||
|
$st = & cscript //Nologo $ospp /dstatus 2>&1 | Out-String
|
||||||
|
if ($st -match '---LICENSED---') { OK "$label licensed" } else { Warn "$label status not LICENSED yet" }
|
||||||
|
}
|
||||||
|
if ($doOfficeAct) { Activate-Ospp 'Office' }
|
||||||
|
if ($doProjAct) { Activate-Ospp 'Project' }
|
||||||
|
if ($doVisioAct) { Activate-Ospp 'Visio' }
|
||||||
|
|
||||||
|
# --- Install via ODT -----------------------------------------------------
|
||||||
|
$ODT_URL = 'https://download.microsoft.com/download/2/7/A/27AF1BE6-DD20-4CB4-B154-EBAB8A7D4A7E/officedeploymenttool_19127-20198.exe'
|
||||||
|
|
||||||
|
function Install-Odt-Bundle([string[]]$products) {
|
||||||
|
$tmp = Join-Path $env:TEMP "kms-odt-$(Get-Random)"
|
||||||
|
New-Item -ItemType Directory -Force -Path $tmp | Out-Null
|
||||||
|
$odtExe = Join-Path $tmp 'odt.exe'
|
||||||
|
Step "Downloading Office Deployment Tool to $tmp"
|
||||||
|
Invoke-WebRequest -UseBasicParsing -Uri $ODT_URL -OutFile $odtExe
|
||||||
|
Step "Extracting ODT"
|
||||||
|
Start-Process -FilePath $odtExe -ArgumentList "/extract:`"$tmp`"", '/quiet' -Wait
|
||||||
|
$setup = Join-Path $tmp 'setup.exe'
|
||||||
|
if (-not (Test-Path $setup)) { Bad "ODT extraction failed (no setup.exe in $tmp)"; return }
|
||||||
|
|
||||||
|
# Build Configuration.xml — only the requested VL Products.
|
||||||
|
$productXml = ($products | ForEach-Object { "<Product ID=`"$_`"><Language ID=`"en-us`" /></Product>" }) -join ''
|
||||||
|
$cfgXml = @"
|
||||||
|
<Configuration>
|
||||||
|
<Add OfficeClientEdition="64" Channel="PerpetualVL2024">
|
||||||
|
$productXml
|
||||||
|
</Add>
|
||||||
|
<Updates Enabled="TRUE" Channel="PerpetualVL2024" />
|
||||||
|
<Display Level="None" AcceptEULA="TRUE" />
|
||||||
|
<Property Name="AUTOACTIVATE" Value="1" />
|
||||||
|
<Property Name="FORCEAPPSHUTDOWN" Value="TRUE" />
|
||||||
|
</Configuration>
|
||||||
|
"@
|
||||||
|
$cfg = Join-Path $tmp 'Configuration.xml'
|
||||||
|
Set-Content -Path $cfg -Value $cfgXml -Encoding UTF8
|
||||||
|
|
||||||
|
Step "Running setup.exe /configure (this can take 5-15 min depending on bandwidth)"
|
||||||
|
Start-Process -FilePath $setup -ArgumentList '/configure', "`"$cfg`"" -Wait
|
||||||
|
if ($LASTEXITCODE -ne 0 -and $LASTEXITCODE -ne $null) { Warn "ODT exit code $LASTEXITCODE" }
|
||||||
|
|
||||||
|
# Pin KMS host + activate
|
||||||
|
$ospp = Find-Ospp
|
||||||
|
if ($ospp) {
|
||||||
|
Step "Pinning Office at $KmsHost`:$KmsPort and activating"
|
||||||
|
& cscript //Nologo $ospp /sethst:$KmsHost | Out-Host
|
||||||
|
& cscript //Nologo $ospp /setprt:$KmsPort | Out-Host
|
||||||
|
& cscript //Nologo $ospp /act | Out-Host
|
||||||
|
$st = & cscript //Nologo $ospp /dstatus 2>&1 | Out-String
|
||||||
|
if ($st -match '---LICENSED---') { OK "Office bundle licensed" } else { Warn "Status not LICENSED yet" }
|
||||||
|
} else {
|
||||||
|
Warn "ospp.vbs still not found post-install — manual /act needed."
|
||||||
|
}
|
||||||
|
|
||||||
|
Remove-Item -Recurse -Force $tmp -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
|
||||||
|
$installList = @()
|
||||||
|
if ($doInstOff) { $installList += 'ProPlus2024Volume' }
|
||||||
|
if ($doInstProj) { $installList += 'ProjectPro2024Volume' }
|
||||||
|
if ($doInstVis) { $installList += 'VisioPro2024Volume' }
|
||||||
|
if ($installList.Count -gt 0) { Install-Odt-Bundle $installList }
|
||||||
|
|
||||||
|
Write-Host ""
|
||||||
|
Step "Done."
|
||||||
|
Write-Host " Re-run any time to re-check status. KMS licences renew automatically every 7 days."
|
||||||
|
Write-Host " Operator-side: this activation has been logged. Privacy notes: https://kms.viktorbarzin.me/#faq"
|
||||||
67
static/scripts/setup-kms.ps1
Normal file
67
static/scripts/setup-kms.ps1
Normal file
|
|
@ -0,0 +1,67 @@
|
||||||
|
# setup-kms.ps1
|
||||||
|
#
|
||||||
|
# Minimal KMS-host wiring for an already-installed Volume License Windows.
|
||||||
|
# Runs `slmgr /skms <host>:<port>` + `slmgr /ato` and prints the licence status.
|
||||||
|
# Does NOT install Office. Does NOT change DNS suffix. Pin only.
|
||||||
|
#
|
||||||
|
# Usage:
|
||||||
|
# iwr -UseBasicParsing https://kms.viktorbarzin.me/scripts/setup-kms.ps1 | iex
|
||||||
|
#
|
||||||
|
# Or with a custom KMS host (e.g. self-hosted):
|
||||||
|
# $env:KMS_HOST = 'kms.example.com'; iwr ... | iex
|
||||||
|
#
|
||||||
|
# Source: https://forgejo.viktorbarzin.me/viktor/kms-website
|
||||||
|
# Licence: MIT, no warranty, KMS activates Volume License SKUs only.
|
||||||
|
|
||||||
|
[CmdletBinding()]
|
||||||
|
param(
|
||||||
|
[string]$KmsHost = $(if ($env:KMS_HOST) { $env:KMS_HOST } else { 'kms.viktorbarzin.me' }),
|
||||||
|
[int] $KmsPort = $(if ($env:KMS_PORT) { [int]$env:KMS_PORT } else { 1688 })
|
||||||
|
)
|
||||||
|
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
|
||||||
|
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 }
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
|
|
||||||
|
Step "KMS host = $KmsHost`:$KmsPort"
|
||||||
|
$slmgr = "$env:WINDIR\System32\slmgr.vbs"
|
||||||
|
|
||||||
|
Step "slmgr /skms $KmsHost`:$KmsPort"
|
||||||
|
$out = & cscript //Nologo $slmgr /skms "$KmsHost`:$KmsPort" 2>&1
|
||||||
|
Write-Host $out
|
||||||
|
if ($LASTEXITCODE -ne 0) { Bad "slmgr /skms failed (exit $LASTEXITCODE)"; return }
|
||||||
|
OK "KMS host pinned"
|
||||||
|
|
||||||
|
Step "slmgr /ato (activate)"
|
||||||
|
$out = & cscript //Nologo $slmgr /ato 2>&1
|
||||||
|
Write-Host $out
|
||||||
|
if ($LASTEXITCODE -ne 0) {
|
||||||
|
Bad "slmgr /ato failed (exit $LASTEXITCODE)"
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "Most common cause: this Windows is not a Volume License edition."
|
||||||
|
Write-Host "KMS activates only VL SKUs (Pro, Enterprise, Education, LTSC, Server)."
|
||||||
|
Write-Host "Home / retail / OEM keys reject KMS responses. See https://kms.viktorbarzin.me/#faq"
|
||||||
|
return
|
||||||
|
}
|
||||||
|
OK "Activation request sent"
|
||||||
|
|
||||||
|
Step "slmgr /dlv (status)"
|
||||||
|
$out = & cscript //Nologo $slmgr /dlv 2>&1
|
||||||
|
Write-Host $out
|
||||||
|
|
||||||
|
if ($out -match 'License Status:\s*Licensed') {
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "==> SUCCESS: Windows is now licensed via KMS." -ForegroundColor Green
|
||||||
|
Write-Host " Licence renews automatically every 7 days; lasts 180 days per renewal."
|
||||||
|
} else {
|
||||||
|
Write-Host ""
|
||||||
|
Write-Host "==> Activation request sent but status is not 'Licensed' yet." -ForegroundColor Yellow
|
||||||
|
Write-Host " Re-run 'slmgr /dlv' in a minute, or check https://kms.viktorbarzin.me/#faq"
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue