powershell - Detect corrupted WMI

16
2014-04
  • Lars Tackmann

    When WMI is corrupted it will fail in the strangest ways, certain queries (most of them) will work, some will throw exceptions, others will time out and a few will simply return no (or partial/erroneous) results.

    As I have a complicated important WMI system monitoring job I would like to be able to spot a corrupted WMI repository before I run the script. Determining it from the script behaviour is hard (due to the many ways WMI might fail) and often one can spend considerable time figuring out if its a system or WMI error.

    I am essentially looking for a method tI can execute in the beginning of from my PowerShell script to determine beforehand if WMI is corrupted.

  • Answers
  • GAThrawn

    There is a script given away by Microsoft's Product Support Services team that's specifically designed to spot and diagnose corrupted WMI databases, the WMI Diagnostics Utility.

    More info on how to use this at Troubleshooting WMI With WMIDiag.

    Unfortunately I'm not too sure how useful this is going to be for you if you want to run this at the start of running a job, it's more the sort of thing that people tend to set to automatically run across their estate on a regular basis to report back on machines that need looking at.

  • gWaldo

    One way to do it (if you set your script failure behaviour to 'ignore') would be to assign the gwmi statement to a variable, then check the variable of that variable.

    $connectToWMI = gwmi win32_service -computername [computername]
    

    then check the status or value of the variable (using write-host to see what to expect on a successful connection and a failure)

    It also looks like you may be able to set Traps for error checking, but I've not used it. It goes something like this:

    trap [Exception] {continue}
    
  • mfinni

    I don't have an answer for the specific question, but why does it matter? You get a notification from your script that it failed, and you then have to manually fix it. This notification is happening because the script failed. If you added extra code into the script to first check for corrupted WMI, the workflow would still be exactly the same.

    /edit - OK - so you have different, potentially unknown ways that WMI can fail if it's corrupted? And you're asking for a single method to check if it's corrupted? Then you're SOL. I will notice that you say

    "(and the afterwords spending time figuring out if it failed for important system reasons or if its simply due to corrupted WMI)"

    Well, then you need better return codes and perhaps better functional design in your script. If your script isn't telling you why it failed, fix it. gWaldo has a good suggestion below about trapping. At this point, I think you'd do better to re-think what you're doing and then spend some time on StackOverflow.


  • Related Question

    scripting - Powershell recursive WMI query
  • quux

    I'd like to start at the top of a WMI namespace, recurse through all the objects, then recurse through each object's property list, filtering out and returning to console only those properties that have mem in their names.

    This is what I have so far:

    gwmi -namespace "root\cimv2" -list |???? |get-Member -MemberType property | Where-Object { $_.name -match 'mem'}
    

    Notice the big |???? in the middle there. If I remove that, the the command seems to run, but fails to find properties I know should be found. Why? I think it is because I get different output from the following two commands:

    gwmi "Win32_operatingSystem"  |get-Member -MemberType property (73 lines of output)
    gwmi -namespace "root\cimv2" -list  |where-object { $_.Name -eq 'Win32_OperatingSystem' } |get-Member -MemberType property (10 lines of output)
    


    What I want is a one-liner that recursively concatenates this process:

    gwmi -namespace "root\cimv2" -list
    (manual selection of a WMI class from the list of 1000+ which appear) 
    gwmi "win32_OperatingSystem" | get-Member -MemberType property | Where-Object { $_.Definition -match 'mem' }
    

    Thanks, and if a working answer is given, I will accept and upvote it (annoying when people never do that, isn't it?).

    Note added 2009/11/14: I haven't awarded the answer yet because no one has yet provided a one-liner which solves the problem.


  • Related Answers
  • Andy Schneider

    I think this will do what you are looking for in one line. the CIMV2 namespace is there by default but if you wanted to select a different one, you can use gwmi -namesapce.

    The "trick" is nesting a where-object in side the foreach-object

    gwmi -list | % {$_.Properties | ? {$_.Name.Contains('Memory')}} | select Origin,Name
    
  • Roman

    It looks like that this:

    gwmi -namespace "root\cimv2" -list

    returns an array of ManagementClass .Net objects, so you can use ManagementClass.Properties collection to select properties that have a certain string in their names. Here is my PowerShell script:

    foreach($class in gwmi -namespace "root\cimv2" -list)
    {
        foreach($property in $class.Properties)
        {
            if($property.Name.Contains('Memory'))
            {
                $class.Name  + ' --- ' + $property.Name
            }
        }
    }
    

    As you can see I am a PowerShell beginner, but I think you can make a 'one-liner' from that.

  • Zypher

    It's a little late here, but i'm pretty sure the below will get you to where you are looking to get - that is a listing of all the properties in the WMI namespace that have "mem" in thier name

    foreach ($i in gwmi -namespace "root\cimv2" -list ){$i.properties | where-object {$_.name -match 'mem'}| format-table origin,name}
    
  • gWaldo

    Download Microsoft's Scriptomatic2 and PowershellScriptomatic. They're both hta apps, so you can view them as plain text to see how they do it.