Welcome once again to the end of the week. Hopefully you spent some time in PowerShell. If not, perhaps this tidbit will be intriguing enough to give it a try. I always try to put the "fun" in function and today I have one that will enumerate all the WMI namespaces, but using Get-CimInstance, or the "modern" way to work with WMI. You probably know about the root\Cimv2 namespace but there are many others and if you explore you might find some other namespaces and classes that are useful.
ManageEngine ADManager Plus - Download Free Trial
Exclusive offer on ADManager Plus for US and UK regions. Claim now!
A WMI namespace is like a container for related classes. The namespace itself can be defined by a system class name of __namespace. That's 2 underscores in front of the name. You can use this name like any other class name.
So those would be the child namespaces under the default root\cimv2 namespace on my Windows 10 system. Of course, you can specify a different namespace. The top namespace is called root.
Naturally I can do the same thing for a remote computer.
The fun part comes in recursing through these namespaces. To do that we need to repeat this command with a constructed namespace for each new one. This is where we will need a function which you can find as a gist in my GitHub repo.
https://gist.github.com/jdhitsolutions/3f98b8f31d423e5fee49279a20652707
This function has 2 parts. There is an internal, private function called _EnumNamespace. This does the actual work of listing namespaces and recursing through each child.
$nspaces = Get-CimInstance @cimInst Write-Verbose "[$((Get-Date).timeOfDay)] Found $($nspaces.count) namespaces under $namespace" if ($nspaces.count -gt 0) { foreach ($nspace in $nspaces) { Write-Verbose "[$((Get-Date).timeOfDay)] Processing $($nspace.name)" $child = Join-Path -Path $Namespace -ChildPath $nspace.Name [pscustomobject]@{ Computername = $nspace.cimsystemproperties.servername Namespace = $child } if ($recurse -and $CimSession) { Write-Verbose "[$((Get-Date).timeOfDay)] Recursing and re-using cimsession" _EnumNamespace -namespace $child -Recurse -CimSession $cimSession } elseif ($recurse) { Write-Verbose "[$((Get-Date).timeOfDay)] Recursing" _EnumNamespace -namespace $child -Recurse } } #foreach
When I built this function I naturally wanted to be able to query a remote computer. I also wanted the ability to support alternate credentials. I knew I'd creating a CimSession inside the function anyway so that each recursive query would re-use the session.
The tricky part was cleaning up the session at the end. There's no way to know when any sort of recursion is complete so I created a shell function, which serves as the primary command for the user. The parameters get passed to the private function and when the private function is finished, the shell function can clean up the CimSession.
Here are some shots of the function in action.
You could even use this function to discover classes.
That's not perhaps the best approach because Get-CimClass is creating new CimSessions, but you get the idea.
I hope you'll give this a spin and let me know what interesting or useful nuggets of WMI awesomeness you discover.