2026-05-09 17:54:38 +00:00
# kms-bootstrap.ps1
#
2026-06-01 08:05:31 +00:00
# Interactive KMS activator. Asks what you want to activate (Windows /
# already-installed Office / Project / Visio) and runs only what you confirm.
# Points each product at the public KMS host (default: vlmcs.viktorbarzin.me:1688).
2026-05-09 17:54:38 +00:00
#
# Usage:
# iwr -UseBasicParsing https://kms.viktorbarzin.me/scripts/kms-bootstrap.ps1 | iex
#
# Non-interactive (CI / automation):
# $env:KMS_AUTO = 'win,office'; iwr ... | iex
2026-06-01 08:05:31 +00:00
# (comma list of: win, office, project, visio)
2026-05-09 17:54:38 +00:00
#
# Custom KMS host:
# $env:KMS_HOST = 'kms.example.com'; iwr ... | iex
#
2026-05-09 22:12:21 +00:00
# Source: https://kms.viktorbarzin.me/scripts/kms-bootstrap.ps1
2026-05-09 17:54:38 +00:00
# Licence: MIT, no warranty, KMS activates Volume License SKUs only.
[ CmdletBinding ( ) ]
param (
2026-06-01 08:05:31 +00:00
[ string ] $KmsHost = $ ( if ( $env:KMS_HOST ) { $env:KMS_HOST } else { 'vlmcs.viktorbarzin.me' } ) ,
2026-05-09 17:54:38 +00:00
[ 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
2026-06-01 08:05:31 +00:00
if ( -not ( $doWin -or $doOfficeAct -or $doProjAct -or $doVisioAct ) ) {
2026-05-09 17:54:38 +00:00
Warn " Nothing selected. Exiting. "
return
}
# --- Windows -------------------------------------------------------------
2026-06-01 08:53:20 +00:00
# Locale-independent license probe (slmgr /dlv text is localized; the WMI
# LicenseStatus integer is not). 1 = Licensed. $null = no KMS-client SKU.
function Get-WindowsLicense {
$q = " SELECT LicenseStatus, GracePeriodRemaining FROM SoftwareLicensingProduct WHERE Name LIKE 'Windows%' AND PartialProductKey IS NOT NULL "
$p = $null
try { $p = Get-CimInstance -Query $q -ErrorAction Stop | Select-Object -First 1 }
catch { try { $p = Get-WmiObject -Query $q -ErrorAction Stop | Select-Object -First 1 } catch { } }
if ( -not $p ) { return $null }
[ pscustomobject ] @ { Licensed = ( $p . LicenseStatus -eq 1 ) ; DaysLeft = [ int ] ( [ math ] :: Round ( $p . GracePeriodRemaining / 1440 ) ) }
}
2026-05-09 17:54:38 +00:00
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 }
2026-06-01 08:53:20 +00:00
$lic = Get-WindowsLicense
if ( $null -eq $lic ) { Bad " No Volume License Windows SKU — install a GVLK first (slmgr /ipk <GVLK>). " ; return }
if ( $lic . Licensed ) { OK " Windows already licensed ( $( $lic . DaysLeft ) days) — host pinned, skipping /ato " ; return }
2026-05-09 17:54:38 +00:00
& cscript / / Nologo $slmgr / ato | Out-Host
2026-06-01 08:53:20 +00:00
$lic = Get-WindowsLicense
if ( $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 " }
2026-05-09 17:54:38 +00:00
}
if ( $doWin ) { Activate-Windows }
# --- Office / Project / Visio: activate already-installed ----------------
function Find-Ospp {
2026-06-01 08:53:20 +00:00
# Covers MSI (Office16/15) and Click-to-Run (\root\Office16) layouts, 64- and 32-bit.
2026-05-09 17:54:38 +00:00
$candidates = @ (
" ${env:ProgramFiles} \Microsoft Office\Office16\ospp.vbs " ,
" $ {env:ProgramFiles(x86)}\Microsoft Office\Office16\ospp.vbs " ,
2026-06-01 08:53:20 +00:00
" ${env:ProgramFiles} \Microsoft Office\root\Office16\ospp.vbs " ,
" $ {env:ProgramFiles(x86)}\Microsoft Office\root\Office16\ospp.vbs " ,
2026-05-09 17:54:38 +00:00
" ${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
2026-06-01 08:53:20 +00:00
# Idempotent: skip /act when already licensed (the '---LICENSED---' marker
# in ospp output is a fixed literal, not localized).
$st = & cscript / / Nologo $ospp / dstatus 2 > & 1 | Out-String
if ( $st -match '---LICENSED---' ) { OK " $label already licensed — host set, skipping /act " ; return }
& cscript / / Nologo $ospp / act | Out-Host
2026-05-09 17:54:38 +00:00
$st = & cscript / / Nologo $ospp / dstatus 2 > & 1 | Out-String
2026-06-01 08:53:20 +00:00
if ( $st -match '---LICENSED---' ) { OK " $label licensed " } else { Warn " $label status not LICENSED yet (no VL Office SKU? See https://kms.viktorbarzin.me/#office) " }
2026-05-09 17:54:38 +00:00
}
if ( $doOfficeAct ) { Activate-Ospp 'Office' }
if ( $doProjAct ) { Activate-Ospp 'Project' }
if ( $doVisioAct ) { Activate-Ospp 'Visio' }
Write-Host " "
Step " Done. "
Write-Host " Re-run any time to re-check status. KMS licences renew automatically every 7 days. "
2026-05-09 22:12:21 +00:00
Write-Host " Privacy: see https://kms.viktorbarzin.me/#faq "