Cut-paper collage illustration: an aged beige paper scroll bearing a faded key symbol on the left hands a relay baton through a gray server rack toward a modern deep-blue terminal window and a glowing blue shield with a key emblem on the right, representing the migration from slmgr.vbs to the PowerShell OSLicense module.

Earlier this month, Microsoft's Windows IT Pro blog told admins to stop treating slmgr.vbs as a permanent part of their automation and start moving to a new PowerShell module called OSLicense. Nobody is panicking, and that's the point. The deprecations that actually hurt you are never the ones with a countdown timer on the homepage. They're the quiet workhorse scripts sitting inside your task sequences, your GPO logon scripts, and your imaging runbooks — the ones that break two years from now on a Tuesday, in production, while you're on vacation.

The durable idea under this one is simple: when a platform component is retired, the rewrite is the easy part. The hard part is finding every copy of the old thing before the platform takes it away for you.

Why slmgr.vbs is living on borrowed time

slmgr.vbs has been the Windows licensing script since Vista and Server 2008. It does one thing — it shells out to the Windows script host (cscript/wscript) — and that one thing is exactly what's being retired. Microsoft formally deprecated VBScript back in 2023, and the removal is happening in three phases:

  1. Now: VBScript ships as a Feature on Demand (FOD) and is enabled by default.
  2. Later: the FOD stays available but is disabled by default — workflows that depend on it will need the feature re-enabled.
  3. Eventually: VBScript is removed from future Windows releases entirely. At that point slmgr.vbs stops working, full stop.

Microsoft's own wording is careful: they say to identify dependencies and prepare, not to panic-migrate overnight. There is no verified single kill date in the primary sources I've seen — anyone quoting one is quoting a third party. But the direction is unambiguous. If your activation automation still calls slmgr, cscript, or wscript, you are standing on a platform Microsoft has already told you is going away.

What the replacement actually covers

The OSLicense PowerShell module is the recommended replacement. It requires Windows PowerShell 5.1, and per Microsoft Learn it covers more than just the old /ato / /ipk / /dlv trio: operating system licensing, Active Directory-based activation, KMS, subscription licensing, and product key management. The cmdlets follow a consistent pattern:

  • Get-OSLicenseInfo, Invoke-OSLicense, Set-OSLicenseInfo — OS licensing
  • Get-ADLicenseInfo, Invoke-ADLicense — Active Directory-based activation
  • Get-KmsLicenseInfo, Invoke-KmsLicense, Set-KmsLicenseInfo — KMS
  • Get-SubscriptionLicenseInfo, Invoke-SubscriptionLicense, Set-SubscriptionLicenseInfo — subscription licensing

The genuine improvement isn't the syntax; it's the output. Get-OSLicenseInfo queries the software-licensing CIM classes and returns structured objects instead of formatted text. That means you can filter, log, and pipe license state into the rest of your automation without regex-parsing pop-up windows — which, if you've ever scripted around slmgr /dlv dialog boxes, you know is a real upgrade.

Task slmgr.vbs OSLicense equivalent
Activate Windows online slmgr.vbs /ato Invoke-OSLicense -ActivateOnline
Install a product key slmgr.vbs /ipk <key> Invoke-OSLicense -InstallProductKey <key>
View detailed license info slmgr.vbs /dlv Get-OSLicenseInfo
Point at a KMS host slmgr.vbs /skms <server>[:port] Set-KmsLicenseInfo -ServerName <server> -Port 1688
Clear KMS server override slmgr.vbs /ckms Invoke-KmsLicense -ClearServer

A note on that table: the first three mappings are Microsoft's own published examples. The KMS rows are the logical counterparts in the module — verify the exact parameter names against the published OSLicense reference before you put them in production. Microsoft gives the same advice.

The honest gotcha: it isn't available everywhere yet

This is the part that separates a careful migration from a weekend rewrite that breaks Monday. OSLicense availability differs by release:

  • Windows 11: requires the August 27, 2026 preview update (KB5120998) or later.
  • Windows Server: planned for the next major version. Early validation is possible on Server vNext preview build 29651 or later.
  • Microsoft Learn itself notes that the exact KB for module availability on some builds still needs confirmation.

So the migration is real, but so is the gap. You can inventory today and pilot on the client side; you cannot yet flip your Server 2019/2022 activation runbooks to a module that doesn't exist there. Any migration plan that ignores that gap is a plan to discover it in production.

The migration checklist: inventory first, rewrite second

Don't start with a rewrite. Start with finding out where the old thing lives. Work this list in order:

  1. Hunt the strings across your estate. Search for slmgr, cscript, wscript, and .vbs in: MDT/SCCM task sequences, Intune scripts and Proactive Remediations, GPO startup/logon scripts, Azure Automation runbooks, imaging and provisioning scripts, and — don't forget — your documentation wiki, where stale examples get copy-pasted into new work. A quick first pass over a script repo looks like the snippet at the end of this checklist.
  2. Classify each hit by blast radius. Critical: golden images, zero-touch provisioning, anything that runs before a user can log in. Convenience: one-off status checks you run by hand. Rewrite the critical ones first.
  3. Check module availability per fleet segment. Which devices already have KB5120998 or later? Which servers won't see the module until the next major release? Write this down as a matrix, not as vibes.
  4. Rewrite in the lab and diff the outputs. Run the old slmgr /dlv and the new Get-OSLicenseInfo side by side and confirm the license states agree. Pay attention to how you consume the output downstream — anything that parsed slmgr's text needs to change to property access on objects, which is the whole point but also the part that breaks quietly.
  5. Test the failure mode, not just the happy path. Disable the VBScript FOD in a lab VM and run your old scripts. See how they fail, so when a machine in the wild is missing the feature, you recognize the symptom instead of debugging activation.
  6. Run both during the transition, retire after a full cycle. Keep the slmgr path working where VBScript is still enabled while the replacement survives a complete deployment or provisioning cycle. Only then archive the old scripts.
  7. Write the mapping into your runbook. Future you — or the next person in the chair — shouldn't have to re-derive which parameter replaced /skms.

For step 1, a quick first pass over a script repo:

Get-ChildItem C:\Scripts -Recurse -Include *.ps1,*.cmd,*.bat,*.xml |
Select-String -Pattern 'slmgr|cscript|wscript|\.vbs' -CaseSensitive:$false

Sources

Nothing here is on fire today. That's precisely why this is the week to run the inventory: you get to do it calmly, with both tools still working, instead of doing it in a hurry after something in a task sequence stops resolving. Boring reliability is built on audits like this one — small, early, and complete.