Finding WMI Usage Before Microsoft Finds It For You

Microsoft has a habit of deprecating things we've been using for years, and this time they're coming for WMI. Well, not WMI itself—just the way we've been accessing it. Starting with Windows 11 version 25H2, the WMIC command-line tool and those trusty old PowerShell WMI cmdlets are getting the axe.

If you're anything like me, you've probably got years worth of scripts littered with Get-WmiObject calls, some gwmi aliases for "efficiency," and maybe even a few wmic commands that you've been copy-pasting since the Windows 7 days. Time to find them all before your scripts start breaking in production.

The Problem

Here's the thing: we've all known CIM cmdlets were the "right" way to do things for a while now. Get-CimInstance is better than Get-WmiObject in basically every way—faster, firewall-friendly, cross-platform. But switching requires actually finding all those legacy calls first.

And it's not just cmdlets. There are:

  • Those WMI aliases you typed quickly at 2am (gwmiiwmi, etc.)
  • The wmic commands in your ancient batch files
  • .NET ManagementClass references buried in your PowerShell modules
  • COM objects like SWbemLocator that someone thought was a good idea in 2008

Manually grepping for all of these? That's a recipe for missing stuff.

The Solution (Or: I Made a Thing)

I built Find-WmiUsage to scan codebases and surface every instance of legacy WMI usage. It's a PowerShell 7 function that leverages parallel processing to tear through thousands of files and tell you exactly where your tech debt is hiding.

What Makes It Useful

It catches everything. The scanner looks for 15 different WMI patterns:

  • All five legacy WMI cmdlets and their aliases
  • The wmic command
  • .NET classes from System.Management
  • COM objects from the WMI scripting library

It's fast. Using PowerShell 7's ForEach-Object -Parallel, it processes multiple files concurrently. Scanning a repository with hundreds of scripts takes seconds, not minutes.

It gives you context. Results include the file path, line number, pattern matched, and the actual line of code. No hunting through files wondering what triggered a match.

Quick Example

Scan your scripts directory:

git clone https://github.com/jorgeasaurus/Find-WmiUsage.git
cd Find-WmiUsage
. .\Find-WmiUsage.ps1
Find-WmiUsage -Path C:\Scripts

Output tells you exactly what needs fixing:

File                              LineNumber Pattern              LineText
----                              ---------- -------              --------
C:\Scripts\inventory.ps1                  12 (?i)\bGet-WmiObject\b Get-WmiObject -Class Win32_ComputerSystem
C:\Scripts\inventory.ps1                  45 (?i)\bgwmi\b          gwmi Win32_Service -Filter "State='Running'"
C:\Scripts\legacy-report.ps1              8 (?i)\bwmic\b           wmic process list brief

Need audit-friendly output? Export to CSV or JSON:

Find-WmiUsage -Path C:\MyModules -Output CSV -OutFile .\wmi-audit.csv

Why This Matters Now

Microsoft isn't playing around with this deprecation:

  • Windows 11 24H2: New installations already ship without WMIC
  • Windows 11 25H2: Complete removal, no going back
  • Legacy WMI cmdlets: Deprecated, with CIM as the official path forward

If you're managing enterprise environments, you've got scripts running on dozens (or hundreds) of systems. Finding and migrating legacy WMI usage before it becomes a breaking change is the difference between a planned migration and a production fire drill.

The Migration Path

Once you've found your legacy WMI calls, here's the cheat sheet:

LegacyModern
Get-WmiObjectGet-CimInstance
Invoke-WmiMethodInvoke-CimMethod
Set-WmiInstanceSet-CimInstance
Remove-WmiObjectRemove-CimInstance
wmic process listGet-CimInstance Win32_Process

The syntax is slightly different, but the migration is usually straightforward:

Before:

Get-WmiObject -Class Win32_ComputerSystem

After:

Get-CimInstance -ClassName Win32_ComputerSystem

Get It

The tool is available on GitHub with full source, comprehensive Pester tests (40 of them, all passing), and documentation.

Key features:

  • Scans .ps1.psm1.psd1 files by default (customizable)
  • Can include or ignore commented lines
  • Adjustable parallelism for large codebases
  • Outputs to table, CSV, or JSON

Requirements:

  • PowerShell 7.0+ (uses ForEach-Object -Parallel)
  • Pester 5.0+ if you want to run the tests

Final Thoughts

Look, we all have legacy code. That's not the problem. The problem is not knowing where it is when Microsoft decides to deprecate it.

Find-WmiUsage gives you visibility. Run it against your repositories, generate reports, hand them to your team, and start migrating before you're forced to. Your future self (and your incident response team) will thank you.


Links: