Every Windows admin has typed cscript slmgr.vbs /ato at least once. It is one of those commands that has been around for so long it feels permanent. It is not. VBScript is being removed from Windows, and slmgr.vbs goes with it. Microsoft now has a direct PowerShell replacement - the OSLicense module - available on devices running the September 2026 servicing update. The window to migrate before things start breaking is open. This post gives you the full playbook.
Microsoft is removing VBScript from Windows in stages - currently off by default, eventually gone entirely. slmgr.vbs is the most common casualty: it drives activation, key checks, and KMS queries across thousands of runbooks, task sequences, and Intune scripts. The replacement is the OSLicense PowerShell module, available on Windows 11 builds 26100.9278 / 26200.9278 and later (September 2026 update). The migration is a clean swap - three commands cover 90% of use cases. The risk is the dependencies you have not found yet.
The problem: slmgr.vbs will stop working
The symptom you will eventually see looks like this: a Windows activation script that has run reliably for years returns a blank result, an error, or silently does nothing. If your script calls cscript.exe slmgr.vbs /ato or reads output from wscript //E:vbscript, it depends on the Windows Script Host VBScript engine. Once that engine is removed from the OS, those commands produce no output at all - no error, no activation, no log entry. They just stop.
This is not theoretical. VBScript is currently available as a Feature on Demand (FoD) but is no longer installed by default in recent Windows 11 builds. Microsoft has published the full deprecation timeline and is steadily moving toward complete removal. Any workflow that calls slmgr.vbs is on borrowed time.
The most exposed workflows are:
- Intune device remediation scripts that call slmgr.vbs /ato on activation failures
- ConfigMgr / SCCM / MDT task sequences with activation steps (these are the highest-volume source)
- Helpdesk runbooks and service desk automation for KMS troubleshooting
- Post-provisioning PowerShell that calls cscript inline to parse slmgr output
- Group Policy logon scripts (.vbs) that activate or check license status
- Scheduled tasks that fire slmgr.vbs on a timer
Why it happens: VBScript's staged removal from Windows
To understand why slmgr.vbs breaks, you need to understand what it actually is. The file lives at C:\Windows\System32\slmgr.vbs and it is a VBScript file - a plain text script that the Windows Script Host (cscript.exe or wscript.exe) interprets at runtime. The script calls the Software Licensing (SLM) WMI API - specifically the SoftwareLicensingProduct and SoftwareLicensingService WMI classes in the root\CIMV2 namespace.
The underlying WMI classes are not going anywhere. It is the VBScript interpreter itself - the engine that reads and executes .vbs files - that Microsoft is removing. When the VBScript engine is absent, cscript.exe cannot execute any .vbs file, regardless of what it does.
The removal is happening in three phases:
- Phase 1 (current): VBScript is disabled by default in Windows 11 24H2 and later. Administrators can re-enable it by installing the VBScript Feature on Demand (FoD). This is the state most organisations are in right now.
- Phase 2 (near-term): The FoD remains available but VBScript is removed from the default image entirely. Enabling it requires an explicit action by an administrator.
- Phase 3 (final): The FoD is removed. VBScript cannot be installed at all. Any remaining .vbs scripts fail permanently.
Why did Microsoft not just rewrite slmgr.vbs as a PowerShell script? Because the activation management surface has been rebuilt around a new PowerShell module - the OSLicense module - which calls the same underlying SLM WMI API directly from PowerShell, with proper error handling and object output instead of the plain-text parsing that made slmgr.vbs output so difficult to work with.
How to verify: find every VBScript activation dependency in your fleet
Before you can migrate, you need to know what you are migrating. slmgr.vbs dependencies are notoriously easy to miss because they often live three layers deep in a ConfigMgr task sequence, a service desk runbook that was never updated, or a scheduled task that fires once a quarter and nobody looks at.
Start with these PowerShell commands to check the current device state:
# Check VBScript FoD status
Get-WindowsCapability -Online -Name 'VBSCRIPT*' |
Select-Object Name, State
# Check current activation status via CIM (no VBScript needed)
Get-CimInstance SoftwareLicensingProduct -Filter "Name like 'Windows%'" |
Where-Object { $_.PartialProductKey } |
Select-Object Name, LicenseStatus, PartialProductKey, GracePeriodRemaining
# Check current OS build (OSLicense requires UBR >= 9278)
$Build = Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion'
"Build: $($Build.CurrentBuildNumber).$($Build.UBR)"
# Test if OSLicense module is available
Get-Command -Name 'Get-OSLicenseInfo' -ErrorAction SilentlyContinue |
Select-Object Name, SourceFor a fleet-wide inventory, use this Microsoft Defender for Endpoint Advanced Hunting KQL query to identify every device that has run cscript.exe or wscript.exe with a .vbs file in the last 30 days:
// VBScript usage audit - slmgr and script host execution
// Timeframe: last 30 days
let lookback = 30d;
DeviceProcessEvents
| where Timestamp > ago(lookback)
| where FileName in~ ("wscript.exe", "cscript.exe")
| where ProcessCommandLine has_any ("slmgr", ".vbs", ".vbe")
or ProcessCommandLine contains "//E:vbscript"
| summarize
LastSeen = max(Timestamp),
RunCount = count(),
Commands = make_set(ProcessCommandLine, 10)
by DeviceName, AccountName, FileName
| sort by RunCount descAlso check these specific locations on your management infrastructure, not just endpoints:
- ConfigMgr/SCCM task sequences: export all task sequences to XML and search for slmgr
- MDT deployment shares: Get-ChildItem -Recurse \\mdt-server\DeploymentShare$ -Include *.vbs | Select-String slmgr
- Group Policy Preferences: Scheduled Tasks under User or Computer Configuration that reference cscript/wscript
- Intune proactive remediations: check all detection and remediation scripts in the Intune admin center for slmgr references
The fix: migrate to the OSLicense PowerShell module
The OSLicense module ships as part of Windows 11 starting from the September 2026 servicing update. It requires:
- Windows 11 23H2 / 24H2 / 25H2: build 26100.9278 or later (KB5120998 preview Aug 27, 2026, or KB5124008 September 2026 CU)
- Windows 11 26H1: build 26200.9278 or later (same update cycle)
- Windows Server: planned for the next major Windows Server release; validate on preview builds before relying on it
The command mapping is clean. Every common slmgr.vbs task has a direct OSLicense equivalent:
| Task | slmgr.vbs (deprecated) | OSLicense (replacement) |
|---|---|---|
| Activate Windows online | cscript slmgr.vbs /ato | Invoke-OSLicense -ActivateOnline |
| Install a product key | cscript slmgr.vbs /ipk <key> | Invoke-OSLicense -InstallProductKey <key> |
| View license details | cscript slmgr.vbs /dlv | Get-OSLicenseInfo |
| View extended details | cscript slmgr.vbs /dlv all | Get-OSLicenseInfo -All |
| Remove product key | cscript slmgr.vbs /upk | Invoke-OSLicense -UninstallProductKey |
| Display expiry date | cscript slmgr.vbs /xpr | Get-OSLicenseInfo (check ExpirationDate) |
Here is how a complete activation workflow looks using the new module, with proper error handling that slmgr.vbs never provided:
# Confirm OSLicense module is available before attempting activation
$Module = Get-Command -Name 'Get-OSLicenseInfo' -ErrorAction SilentlyContinue
if (-not $Module) {
Write-Warning "OSLicense module not available on this build. Apply September 2026 update."
exit 1
}
# Check current license status
$License = Get-OSLicenseInfo
Write-Host "Current status: $($License.LicenseStatus)"
# Only activate if not already licensed
if ($License.LicenseStatus -ne 'Licensed') {
Write-Host "Triggering online activation..."
Invoke-OSLicense -ActivateOnline
# Re-check status after activation attempt
$NewStatus = (Get-OSLicenseInfo).LicenseStatus
Write-Host "Post-activation status: $NewStatus"
if ($NewStatus -eq 'Licensed') {
Write-Host "Activation successful."
exit 0
} else {
Write-Warning "Activation did not complete. Status: $NewStatus"
exit 1
}
} else {
Write-Host "Device already licensed. No action required."
exit 0
}The critical advantage of the OSLicense module over slmgr.vbs is that it returns structured PowerShell objects, not plain text. Your scripts can check $License.LicenseStatus -eq 'Licensed' rather than parsing a string like "License Status: Licensed" from cscript output. Parsing slmgr.vbs output has been a source of bugs for years - the new module eliminates that entirely.
Step-by-step: Deploy replacement activation via Intune (Settings Catalog / Scripts)
- Sign in to the Intune admin center at intune.microsoft.com.
- Navigate to Devices › Scripts and remediations › Platform scripts.
- Select Add › Windows 10 and later.
- Give it a name such as "Windows Activation - OSLicense (slmgr.vbs replacement)".
- On the Script settings page, upload your Invoke-WindowsActivation-OSLicense.ps1 script. Set Run this script using the logged on credentials to No (run as SYSTEM - activation must run in the SYSTEM context). Set Enforce script signature check per your organisation's code signing policy.
- Select Next and assign to the target device group.
Deploy this as an Intune Proactive Remediation (OSLicense availability check)
Use the companion Proactive Remediation pair from GitHub to detect which devices in your fleet are not yet on a build that supports OSLicense, and trigger a Windows Update scan to queue the correct patch:
- Sign in to the Intune admin center.
- Go to Devices › Scripts and remediations › Proactive remediations.
- Select Create and name it "VBScript Migration - OSLicense Module Availability Check".
- On the Settings page, upload
Detect-OSLicenseModuleAvailable.ps1as the detection script. - Upload
Remediate-OSLicenseModuleAvailable.ps1as the remediation script. - Set Run this script using the logged-on credentials to No (SYSTEM context).
- Assign to your Windows 11 device group and set the schedule to Daily.
Reference: Software Licensing registry keys for manual verification
| Value (type) | Meaning | Healthy value |
|---|---|---|
| KeyManagementServiceName (REG_SZ) | KMS server hostname used for volume activation | Your KMS FQDN - absent if using HWID/MAK |
| KeyManagementServicePort (REG_SZ) | KMS TCP port | 1688 (default) - blank if not KMS |
| SkuId (REG_SZ) | Windows SKU GUID from the active license | Populated GUID matching installed edition |
| Activation\Manual (REG_DWORD) | Blocks automatic activation when set to 1 | 0 or absent - 1 blocks all auto-activation |
| Activation\NotificationDisabled (REG_DWORD) | Suppresses Windows activation toast notifications | 0 or absent - 1 hides activation warnings |
Reference: Software Protection Platform Event IDs
| Event ID | Level | Meaning |
|---|---|---|
| 12288 | Information | License acquisition in progress - activation is attempting to contact the Microsoft activation service or KMS server |
| 12289 | Information | Confirmed running with genuine software - activation succeeded, license is valid |
| 16384 | Information | Online license acquired successfully - device is now licensed |
| 16394 | Warning | Activation scheduled for retry - initial attempt failed, retrying automatically |
| 16385 | Error | Activation attempt failed - check subsequent events for the specific error code |
| 8193 | Error | License Activation (HWID) failed - common during VBScript migration if old scripts are conflicting with new ones |
| 8198 | Error | License Activation failed with code 0xC004F074 - KMS host not reachable or no KMS host found in DNS |
| 1003 | Information | Software protection service completed - activation service finished its scheduled run |
| 1006 | Information | License validation completed - periodic check passed, no action needed |
Proof it worked: confirm OSLicense activated successfully
After deploying the replacement script, verify activation using the OSLicense module itself - no VBScript required. Run the following on a target device to confirm a clean migration:
# Step 1 - Confirm OSLicense module is available
Get-Command Get-OSLicenseInfo -ErrorAction Stop
# Output: CommandType Name Version Source
# ----------- ---- ------- ------
# Cmdlet Get-OSLicenseInfo 1.0.0.0 OSLicense
# Step 2 - Check license status
$Info = Get-OSLicenseInfo
$Info | Select-Object LicenseStatus, ProductName, PartialProductKey, ExpirationDate
# Healthy output:
# LicenseStatus ProductName PartialProductKey ExpirationDate
# ------------- ----------- ----------------- --------------
# Licensed Windows 11 Enterprise XXXXX N/A
# Step 3 - Cross-verify via CIM (WMI - the same underlying API)
Get-CimInstance SoftwareLicensingProduct -Filter "Name like 'Windows%'" |
Where-Object { $_.PartialProductKey } |
Select-Object LicenseStatus, Name, GracePeriodRemaining
# LicenseStatus 1 = Licensed, 0 = Unlicensed, 5 = Notification modeAfter confirming OSLicense works and VBScript-based scripts have been replaced, check whether the VBScript FoD has been left installed on managed devices. It should be removed once it is no longer needed:
# Check VBScript FoD status
$FoD = Get-WindowsCapability -Online -Name 'VBSCRIPT*'
$FoD | Select-Object Name, State
# Remove VBScript FoD if it was installed (requires admin / SYSTEM context)
# Only run after confirming all slmgr.vbs dependencies have been migrated
if ($FoD.State -eq 'Installed') {
Write-Host "Removing VBScript FoD..." -ForegroundColor Yellow
Remove-WindowsCapability -Online -Name $FoD.Name
Write-Host "VBScript FoD removed. Reboot may be required." -ForegroundColor Green
} else {
Write-Host "VBScript FoD is already $($FoD.State). No action needed." -ForegroundColor Green
}Scripts for this post are in Imran76Awan/Windows-Patching-Scripts. Download and run in your own environment - no sign-in required. All scripts are read-only or trigger only standard Windows Update scans.
References
- Keep Windows activation automation working with PowerShell - Microsoft Windows IT Pro Blog
- VBScript deprecation: Detection strategies for Windows - Microsoft Windows IT Pro Blog
- VBScript deprecation: Timelines and next steps - Microsoft Windows IT Pro Blog
- OSLicense PowerShell module reference - Microsoft Learn
- Policy CSP - Licensing - Microsoft Learn
- KB5120998 - Windows 11 Preview Update Aug 2026 - Microsoft Support
Microsoft MVP community deep-dives
| Author | Post | What it adds |
|---|---|---|
| Mads Johansen | VBScript deprecation: Replacement for slmgr.vbs | Original Sept 2026 writeup that surfaced the OSLicense module and the clean command mapping table used in this post |