ospp /dstatus lists every installed product, so the blanket '---LICENSED---'
match treated an Office-licensed machine as Project/Visio-licensed too, causing
KMS_AUTO=office,project to skip Project. Add Test-OsppLicensed that parses the
per-SKU LICENSE NAME/STATUS blocks and checks only the requested family.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Inside `switch ($label) {...}` the automatic $_ is the switch input (the label),
not the Where-Object pipeline item, so the per-product filter always matched and
KMS_AUTO=office would also install Project/Visio keys. Replace with explicit
label/$_ comparisons.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Scripts now detect the running edition and fetch the matching GVLK from a
published key list instead of requiring the user to copy one from the table.
- data/products.yaml: add editionid to every Windows/Server entry, plus build
numbers where an EditionID spans releases (LTSC, Server). Azure Edition left
unmapped on purpose (collides with Datacenter; KMS may fail there anyway).
- /keys.json: Hugo KEYS output format renders products.yaml as JSON
(single source of truth). layouts/index.keys.json.
- setup-kms.ps1: when no VL key is installed, read registry EditionID
(+build/ProductType for server) -> fetch /keys.json -> slmgr /ipk the match
-> activate. Only acts when not already licensed (never clobbers retail).
- kms-bootstrap.ps1: same for Windows; for Office/Project/Visio, read
Click-to-Run ProductReleaseIds -> ospp /inpkey the matching GVLK -> /act.
- $env:KMS_KEYS_URL overrides the key-list URL.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Em-dashes in the new idempotency status messages render as "?" garbage on
non-UTF-8 Windows consoles (cp437/850). Replace with ASCII hyphens.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Replace locale-dependent "License Status: Licensed" regex with a
locale-independent WMI probe (SoftwareLicensingProduct.LicenseStatus==1).
Fixes false "not licensed yet" reports on non-English Windows and on re-runs.
- Idempotent: always pin the KMS host, but skip /ato (Windows) and /act
(Office) when already licensed — report days remaining instead of
re-contacting the public KMS server.
- Find-Ospp now also checks Click-to-Run \root\Office16\ (+ \root\Office15\)
layouts, not just the MSI Office16 path.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
The page advertised kms.viktorbarzin.me:1688 as the KMS host, but that name
is the website (Traefik) — internally it resolves to 10.0.20.203 which has no
:1688 listener, so LAN clients failed with "KMS server cannot be reached".
Split the concern: siteHost (kms.viktorbarzin.me) serves the page + /scripts
downloads; kmsHost is now the dedicated A-only vlmcs.viktorbarzin.me endpoint
that resolves to the vlmcsd MetalLB IP (10.0.20.202) on the LAN (Technitium)
and to the public IP over the internet (Cloudflare -> pfSense WAN NAT :1688).
Moderate cleanup:
- remove the Office-install-via-ODT path from kms-bootstrap.ps1 (activation
only now; manual ODT install docs stay on the page)
- collapse Windows 8.1/8/7/Vista + Server 2012/2008 GVLK tables into a legacy
note (those keys still activate; just no longer tabled)
- drop the unused kmsHostLan param
Pairs with the infra /scripts Anubis carve-out that makes `iwr | iex` work.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
- Replace single interactive one-liner with three side-by-side cards
(Windows / Office+Project+Visio / Both) using $env:KMS_AUTO=...; the
contract is already supported by kms-bootstrap.ps1
- Make Downloads links use the 'download' attribute so browsers prompt
save-as instead of rendering .ps1 as text
- Strip operator-side framing: kms-bootstrap.ps1 no longer says
"this activation has been logged" and both scripts now point Source
at the public mirror instead of forgejo.viktorbarzin.me