Summary: Learn how to use Windows PowerShell to troubleshoot and repair WMI errors.
Microsoft Scripting Guy, Ed Wilson, is here. Tomorrow is the New York City TechStravaganza. The Scripting Wife and I will be there, and we are looking forward to hanging out with Microsoft PowerShell MVPs such as Tome, Brandon, and Aleksandar. Anyway, it was late when we got to the hotel, and I was looking forward to reading a story collection by Raymond Chandler and calling it a day. I had just started on the third story in the collection, when above the constant hum of Times Square, I heard the Scripting Wife.
“Why do I always get these errors,” she exclaimed with obvious annoyance.
“Probably because you are doing something wrong,” I said not really helping the situation.
“No. In the event log. Here take a look,” she said turning her laptop to me.
The error to which she referred is shown here.
“How do you know you are always getting this error,” I asked.
“Because I always see it every time I open the Application log on my computer,” she replied.
“Well, let’s see how many times you really are getting this error,” I suggested, “Open the Windows PowerShell console, and let’s use the Get-WinEvent cmdlet to retrieve every Event 10 from Windows Management Instrumentation.”
“OK. But you are going to have to help me a bit,” she said.
“But of course. We will use a filter hash table so that we only retrieve the events from Windows Management Instrumentation that are Event 10 in the Application log. The first thing is to type the Get-WinEvent cmdlet, and call the FilterHashTable parameter. But do not press ENTER because we will build the command.”
The Scripting Wife thought for a bit, and then typed the following (she used tab expansion to complete the FilterHashTable parameter name).
Get-WinEvent -FilterHashtable
“Now we need to create the hash table for the filter. Remember that a hash table begins with the ‘at’ sign (@). Then it is the key equals the value. Each pair gets a semicolon separator,” I said.
“OK,” she said as she typed the “at” sign, and opened a pair of curly braces, “Now what?”
“The first pair is LogName equals Application. Put the word ‘application’ in quotation marks,” I said.
The following is what the Scripting wife typed.
@{logname='application'
“Now the next pair is ID equals 10. There is no need for quotation marks around the number ten. Remember, that each key value pair receives the semicolon separator.”
The Scripting Wife was all business. The she typed the following.
;id=10;
“The good thing is that the ProviderName will accept a wild card. So all you need to do is use the asterisk with the letters wmi. Make sure you also put them in quotation marks and close the curly bracket,” I said.
Here is what she typed.
providername='*wmi*'}
“Great. You are almost done. Pipe the whole thing to the Measure-Object cmdlet. You can use the alias measure for that cmdlet,” I instructed.
The following is the Scripting Wife’s completed command.
Get-WinEvent -FilterHashtable @{logname='application';id=10;providername='*wmi*'} | measure
“Cool, it works,” the Scripting Wife exclaimed, “Here take a look.”
As she turned her laptop monitor so I could see the following output in her Windows PowerShell console.
“How would I know how to do this if you were not around?” she asked.
“You could use the Get-EventLog cmdlet to do this, but you would need to pipe the results to the Where-Object cmdlet to help with the filtering. This command is more efficient. Besides, I wrote a great Hey, Scripting Guy! blog last year about using the FilterHashTable parameter. It is titled How to Improve the Performance of a PowerShell Event Log Query,” I said.
“So what does all this mean anyway?” she asked.
“What does what mean?” I asked.
“What is Event 10 from Windows Management Instrumentation, and why is it littering my Application log with meaningless events?” she asked.
“Actually it is not meaningless. It means that some permanent event does not have permission to run. That is what the error code 0x80041003 means. Why it does not have permission is another issue. Let me check with Bing to find out,” I said.
Within less than a minute, I had retrieved a support article describing the situation. Interestingly enough, this issue also has a Microsoft Fix It solution attached to it. “Cool.” I thought. Then I thought this would be a great opportunity to talk to the Scripting Wife about permanent event consumers.
“Do you remember when Trevor wrote Use a PowerShell Module to Work with WMI Permanent Events?” I asked.
“Sure. I thought it was great,” she replied.
“Well, before that blog, I talked about working with permanent events and I discussed the technology that was behind them in Use PowerShell to Monitor and Respond to Events on Your Server,” I said.
“Uh. Sure, if you say so. I don’t remember that far back,” I said.
I started to say something like she remembered Trevor’s module, but then I decided to keep my mouth shut for a change. Then I changed my mind.
“Well, this is your lucky day. Because we are going to do a refresher course,” I said.
“Oh, come on. It is late, and tomorrow is the TechStravaganza,” she whined.
The first thing I did was create a simple script that I called Get-BVTFilterandConsumer.ps1. This script is shown here. (Note: The second line uses the back tick character for line continuation. GWMI is an alias for the Get-WmiObject cmdlet. Remember, this is a quick script, and it is late at night.)
Get-BVTFilterandConsumer.ps1
gwmi __EventFilter -Namespace root\subscription -Filter "name = 'bvtfilter'"
gwmi __FilterToConsumerBinding -Namespace root\subscription `
-filter "filter = '__EventFilter.Name=""bvtFilter""'"
“Now I want you to run the script. It will retrieve instances of the __EventFilter Windows Management Instrumentation class that are named bvtFilter. It will also retrieve instances of the __FilterToConsumerBinding Windows Management Instrumentation class—but only instances that are associated with the filter named bvtFilter. It sounds complicated, but really it is not,” I said.
“If you say so. But sometimes I wonder if your idea of complicated and my idea of complicated are the same thing,” she said as she ran the script. The output from the script is shown in the image that follows.
“Now what we need to do is to delete both the bvtFilter and the filter to consumer binding. This part is really easy because all we need to do is to pipe the objects from the previous script to Remove-WmiObject,” I said.
“That is the first thing you have said that makes sense,” she said, “Shouldn’t we back up the computer first?”
“We do not need to back up the entire computer, but it does not hurt to back up system state. To do this, use the CheckPoint-Computer cmdlet,” I said.
The Scripting Wife copied the code from the Get-BVTFilterandConsumer.ps1 script, and at the end of each line she added a pipe character, and sent the objects to the Remove-WMIObject cmdlet. Then she backed up and went to the top of the script and added the Checkpoint-Computer command. The resulting script, which she named BackupComputerAndRemoveBVTFilter.ps1, is shown here.
BackupComputerAndRemoveBVTFilter.ps1
Checkpoint-Computer -Description "prior to fixing event 10 from wmi" `
-RestorePointType MODIFY_SETTINGS
gwmi __EventFilter -Namespace root\subscription -Filter "name = 'bvtfilter'" |
Remove-WmiObject
gwmi __FilterToConsumerBinding -Namespace root\subscription `
-filter "filter = '__EventFilter.Name=""bvtFilter""'" |
Remove-WmiObject
When the Scripting Wife pressed the green triangle to run the script, the dialog box shown here appeared.
Other than the dialog box, there was no output from the script.
“So how do I know that it worked?” she asked.
“For one thing, you can run my Get-BVTFilterandConsumer.ps1 script. But with no instances, it will not display any output either. Another thing you can do is to open WbemTest, change your namespace to root\subscription and open the __FilterToConsumerBinding Windows Management Instrumentation class,” I said.
The Scripting Wife typed wbemtest into the Windows PowerShell console, and when the Windows Management Instrumentation Tester opened, she set the namespace to root\subscription and opened the __FilterToConsumerBinding Windows Management Instrumentation class. She then pressed the Instances button and the following dialog box appeared.
“You might also want to look for instances of the __EventFilter Windows Management Instrumentation class,” I suggested.
The Scripting Wife closed the previous dialog box, and opened the __EventFilter class. Next she looked for instances. The results are shown here.
“OK. That’s enough. You are making my head hurt, and I need to catch up with people on Facebook,” the Scripting Wife said.
And with that, I was effectively dismissed. 2012 Scripting Games Prep Week will continue tomorrow when we will have a guest blog post from Boe Prox.
I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.
Ed Wilson, Microsoft Scripting Guy