October 8th, 2010

Use PowerShell to Identify Causes of Internet Explorer Crashes

Summary: The Microsoft Scripting Guys show how to use Windows PowerShell to identify applications that cause Internet Explorer to crash.

 

Hey, Scripting Guy! Question Hey, Scripting Guy! I am the network administrator where I work. I do mean the network administrator. I do everything from server configuration and installation, to user help desktop support. Our network is something I am proud of, with its dozen servers all running Windows Server 2008 R2, and 250 desktops that all run Windows 7 Professional. Management backs me up, and I use Group Policy to manage the desktops. I have been doing Windows PowerShell for two years since you started blogging about it on a regular basis. It is cool stuff.

Now for my problem. Recently I have been getting reports from some of my users that their computer is “acting strange.” By strange, they do not mean that the computer gets up and runs around their desk. Instead, it seems that Internet Explorer has been “acting up.” They go to a particular web page, and Internet Explorer quits working, generates a trouble report, and recovers itself. It is great that the browser automatically recovers itself, but it would be better if it did not happen at all. The strange thing is that all the systems are the same, and this only happens on a few computers. I think it may have something to do with poorly programmed websites, but I am not sure. Is there something I can check, preferably via script, to chase this down to its root cause?

— DB

 

Hey, Scripting Guy! Answer Hello DB,

Microsoft Scripting Guy Ed Wilson here. A couple of weeks ago I downloaded and installed the Internet Explorer 9 beta, and while that is not something I would recommend that you deploy to your well-managed network, it is an awesome product. The reason I mention it is that I was also running into problems with Internet Explorer on my laptop. When I upgraded to Internet Explorer 9 beta, it mentioned I was having problems with some plug-ins, and disabled them. I have not had any problems since then.

The reason I do not recommend deploying it to your user base is that you cannot get support for beta software. As a network administrator, you know that access to support is vital when users report problems. In fact, when I was a network administrator I made it a point to keep my desktop machine at the same level of software as the majority of my user base. In this way, I could possibly anticipate problems they might experience. Another advantage was that if difficulty arose, I could use my computer to try to reproduce the problem.

Note: The reliability provider has been discussed all this week. See Monday’s post for a general introduction. The provider is available only on Windows 7 and later. It is not enabled on Windows Server 2008 R2 by default. See Tuesday’s post for information about this.

The WMI classes supported by the reliability provider are Win32_ReliabilityStabilityMetrics and Win32_ReliabilityRecords. These classes provide a detailed look at the health of your computer. The Win32_ReliabilityStabilityMetrics WMI class provides a numeric measure of your system reliability. The systemStabilityIndex property is a number between 1 and 10 that indicates the relative stability of your system. The higher the number, the better your stability, with 10 being perfect stability and 1 being the least stable. The reliability provider computes this value on a regular basis, multiple times a day, and it is likely your computer has thousands of entries. You can pipe the results into the Measure-Object cmdlet for a great system overview. (I use the alias, gwmi, for the Get-WmiObject cmdlet. The backtick character “`” indicates line continuation. You would not need it in normal circumstances. I have added it here because of line length constraints on the blog. I typed this as a single line command on my laptop.)

PS C:\> gwmi Win32_ReliabilityStabilityMetrics | Measure-Object -Average -Maximum  `
-Minimum -Property systemStabilityIndex

Count    : 8858
Average  : 5.56871246331002
Sum      :
Maximum  : 9.262
Minimum  : 1.089
Property : systemStabilityIndex

PS C:\>

As a point of comparison, I decided to run the command on my desktop. Here are the results I obtained:

PS C:\> gwmi Win32_ReliabilityStabilityMetrics | Measure-Object -Average -Maximum  `
&#1 60;
-Minimum -Property systemStabilityIndex

Count    : 8273
Average  : 8.60750586244404
Sum      :
Maximum  : 10
Minimum  : 1.193
Property : systemStabilityIndex

PS C:\>

You can see that my laptop is not nearly as stable. It has a 5.6, and my desktop has an average of 8.6. The best my laptop ever reported was 9.2; however, my desktop actually reached 10—a perfect score. They both reached a minimum of 1 on the stability index when they were having problems. Now it is time to dig into the Win32_ReliabilityRecords WMI class. The script I use to perform this initial query is shown here.

GetIEAppCrashesByFaultingModuleUniqueProduct.ps1

(Get-WmiObject -Class win32_reliabilityRecords -Filter `
"ProductName = ‘iexplore.exe’"
) |
 
Foreach-Object `
 
{ 
  
[regex]::matches($_.message, "Faulting module path: [a-zA-Z:0-9()\\\s]*") 
 
} |
Sort-Object -Property value -Unique |
Select-Object -Property value

In the GetIEAppCrashesByFaultingModuleUniqueProduct script, I query the Win32_ReliabilityRecords WMI class, and filter only on the product iexplore.exe. Each record that is returned is passed through a regular expression pattern that looks for the faulting module path. I then sort the returned records by the value and choose unique patterns, and again select the value property. The results from running the script are shown in the following image.

Image of results of running script

Now that I have an idea of where to look, I decide to count the instances of each of the applications that are causing Internet Explorer to crash. To do this, I use the script shown here.

GetIEAppCrashesByFaultingModuleGroupbyProduct.ps1

(Get-WmiObject -Class win32_reliabilityRecords -Filter `
"ProductName = ‘iexplore.exe’"
) |
 
Foreach-Object `
 
{ 
  
[regex]::matches($_.message, "Faulting module path: [a-zA-Z:0-9()\\\s]*") 
 
} |
Sort-Object -Property value |
Group-Object -Property value |
Sort-Object -property count -Descending

Basically the script is the same as the previous one. The di fference is that the sorting does not return unique values. When the items are sorted, they are grouped according to their value, and then sorted once again in a descending fashion. This produces the output shown in the following image.

Image of output

I have now honed in on two applications that are causing most of the Internet Explorer crashes. Because I noticed that some records are for different versions of the same application, I decided to group all versions of the same application into a report. The CountIEHangsbyApplication.ps1 script is shown here.

CountIEHangsbyApplication.ps1

$wmi = Get-WmiObject -Class Win32_ReliabilityRecords -Filter `
  "ProductName = ‘iexplore.exe’"
"Total IE hangs"
+ ($wmi |  Measure-Object).count
"Skype hangs"
+ 
 
($wmi | Where-Object { $_.message -match ‘skype’} | Measure-Object).count
"Flash Hangs"
+
 
($wmi | Where-Object { $_.message -match ‘flash’} | Measure-Object).count

Because I am only interested in totals for each of the selected applications, I return only the count property from the Measure-Object cmdlet. The output is shown here.

Image of output of count property from Measure-Object cmdlet

Finally I decided to see if there were any faults occurring in the past week. To do this, I used the SearchReliabilityFaultingApplicationsByDate.ps1 script. This script is shown here.

SearchReliabilityFaultingApplicationsByDate.ps1

Param([int]$numberDays = 7)
$dte =  [Management.ManagementDatetimeConverter]::ToDmtfDateTime(
 
$(get-date).addDays(-$numberDays))
Get-WmiObject -Class Win32_ReliabilityRecords -Filter `
  "TimeGenerated > ‘$dte’ AND sourceName like ‘%Application Error%’ "
| 
Sort-Object productName | 
Format-list -Property message, productName, TimeGenerated

When the script runs, the output appears is shown in the following image.

Image of output from running script

 

DB, that is all there is to using Windows PowerShell and the WMI reliability classes. Keep in mind that the scripts I generated are all quick scripts and could have been optimized. The point was to show you different ways of obtaining information from the WMI reliability records. Slicing and dicing of retrieved information is something that is a good skill to possess. It is also one of the strengths of Windows PowerShell. This also concludes Reliability Week. Join us tomorrow for Weekend Scripter.

We invite you to follow us on Twitter and Facebook. If you have any questions, send email to us at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

 

Ed Wilson and Craig Liebendorfer, Scripting Guys

Author

0 comments

Discussion are closed.