Troubleshoot Outlook Problems with PowerShell

Doctor Scripto

Summary: Microsoft Scripting Guy Ed Wilson teaches how to use Windows PowerShell to troubleshoot Microsoft Outlook problems.

 

Hey, Scripting Guy! QuestionHey, Scripting Guy! I have a problem with Microsoft Outlook on my laptop. It seems that it goes to sleep or something. I will be working, go to check my email, and nothing appears. But if I look at my Windows 7 mobile phone, it shows that new email is in my inbox. I am thinking that I have a problem with Outlook.

—BT

 

Hey, Scripting Guy! AnswerHello BT,

Microsoft Scripting Guy Ed Wilson here. The Scripting Wife and I had a wonderful time at the Geek Ready conference. She knows many of the Microsoft premier field engineers (PFEs) because she has met them at various Windows PowerShell User group meetings, at conferences, or just from hanging around me. She had a chance to meet several PFEs who have written guest Hey, Scripting Guy! Blog articles, but that she had never met in person. It really was awesome. We were up late on several nights having “Windows PowerShell side meetings” with various PFEs, and on a couple occasions, we ended up having impromptu script club meetings. The results of all this engagement will be appearing for months to come on the Hey, Scripting Guy! Blog, so stay tuned.

Anyway, with all the geeks taking over the hotel where we were staying, poor Microsoft Outlook was struggling. In fact, Internet connectivity was spotty most of the time, just due to the sheer magnitude of the demands placed on the infrastructure by us. The nice thing is that, by using Windows PowerShell, I can do an awful lot of discovery.

When I am doing event log exploration, things go a whole lot faster if I store the particular lot in a variable. So that is what I am going to. Microsoft Outlook writes events to the application log using the source id of outlook. I therefore use the Get-EventLog cmdlet and gather up all the entries that have a source of outlook. I store these EventLogEntry objects in a variable I call $log. The EventLogEntry .NET Framework class appears in the System.Diagnostics namespace, and documentation appears on MSDN. This command is shown here:

$log = Get-EventLog application -Source outlook

Once I have all of the outlook entries in a variable, I can begin to examine them. I am curious about how many entries I have, so I use the count property to see. This command and output are shown here:

PS C:\> $log = Get-EventLog application -Source outlook

PS C:\> $log.count

280

Next, I want to see what type of structure I am dealing with, so I index into the array of records, and pick off one record to examine and pipe the results to the Format-List cmdlet (fl is an alias for the Format-List cmdlet). Here is the command I use:

$log[0] | fl * -Force

This command and the associated output appear in the following figure.

Image of command and associated output

Wow, as it turns out, that was a bad example because it goes on and on and on. It can be useful, however, because this shows me all of the add-ins that Microsoft loads. Remember, seeing the Microsoft Outlook splash screen that shows how many add-ins it is loading? It looks like EventID 45 tells me about loading add-ins.

A better event log entry is the one that is shown in the following figure. The reason this event log entry is better is that it allows me to see representative data from all of the different properties in a single screen shot.

Image of better event log entry

Event ID 26 looks like it tells me when Microsoft Outlook has lost connectivity to the Microsoft Exchange server. Hmmm, that might be useful. Let me look at all event ID 26s and see what they say. To do this, I pipe the collection of event log entries that are stored in the $log variable to the Where-Object cmdlet (? Is an alias for Where-Object). In the script block associated with the Where-Object cmdlet, I look for eventid that is equal (-eq) to 26. This command is shown here:

$log | ? {$_.eventid -eq 26}

My screen quickly floods with entries. Interestingly enough, it seems that Event ID 26 reports lost connectivity as well as restored connectivity. This can actually be a useful thing. What I can do first is look at how many disconnects and how many connection restored messages there are. This command is shown here:

PS C:\> $log | ? {$_.eventid -eq 26} | group message -NoElement | select name, count | ft -AutoSize

Name                                                                                               Count

—-                                                                                               —–

Connection to Microsoft Exchange has been lost. Outlook will restore the connection when possible.    36

Connection to Microsoft Exchange has been restored.                                                   34

Now that I see that there are a significant number of times when the connection to the Microsoft Exchange server dropped, I would really like to see when this is happening. To do this, I want to focus on the timewritten property from the eventlog. The problem is that if I find my events, and group by the timewritten property, the result will be 70 separate lines and no real grouping because each timewritten record will be unique. Therefore, nothing exists to group on. The command is shown here:

$log | ? {$_.eventid -eq 26} | group timewritten

The command and output are shown in the following figure.

Image of command and output

The trick is to realize that the timewritten property contains a DateTime object. This is important because I know that an instance of the DateTime object exposes a day property. I can then use the Group-Object cmdlet to organize the eventlog records by day. I used the Get-Member cmdlet (gm is an alias) to discover that the timegenerated property contains a DateTime object. This command and output are shown here:

PS C:\> $log[0] | gm timegenerated

   TypeName: System.Diagnostics.EventLogEntry#application/Outlook/1073741869

 

Name          MemberType Definition

—-          ———- ———-

TimeGenerated Property   System.DateTime TimeGenerated {get;}

 

The problem is exposing that DateTime object to the Group-Object cmdlet. For example, the following command attempts to use dotted notation to directly access the day property of the DateTime object:

$log | ? {$_.eventid -eq 26} | group timewritten.day

The command and output are shown here (they are not impressive):

PS C:\> $log | ? {$_.eventid -eq 26} | group timewritten.day

Count Name                      Group

—– —-                      —–

   70                           {System.Diagnostics.EventLogEntry, System.Diagnostics.EventLogEntry,

The following commands also do not work. In fact, some generate errors:

$log | ? {$_.eventid -eq 26} | group (timewritten).day

$log | ? {$_.eventid -eq 26} | group $(timewritten).day

$log | ? {$_.eventid -eq 26} | group $_.timewritten.day

The trick is to use the Select-Object cmdlet with the expandproperty parameter to expand the timewritten property from the Get-EventLog. In this way, I can then use the Group-Object cmdlet to group the eventlog records by day. I decided to leave the details because they let me see which days I am having problems. The command is shown here:

$log | ? {$_.eventid -eq 26} | select -expandproperty timewritten | group day

The command and associated output are shown in the following figure.

Image of command and associated output

It is obvious from the preceding figure, that there were problems on November 4 and October 16. This is great information because I could work with a customer, or someone who says, “I had a problem with Outlook last week sometime. I don’t really remember when, but it seemed like it kept dropping off, and not working.” And with Windows PowerShell and the Get-EventLog cmdlet, I can actually connect remotely to their computer and retrieve the information I need. And then I can say, “Yes, I see you had a problem on November 4, but we were applying patches to the Exchange server that day, and it was up and down all day. So, no, there is no problem with Outlook.”

But what if we look back, and we were not performing maintenance? Maybe, instead I want to see if there is a pattern by hour. I also know that the DateTime object contains an hour property. Therefore, using my trick from earlier, I come up with the following command:

$log | ? {$_.eventid -eq 26} | select -expandproperty timewritten | group hour

The command and associated output follow. It is very revealing. Thirty-six of the disconnects occurred between the hours of 20:00 (8:00 P.M.) and 22:00 (10:00 P.M.).

Image of command and associated output showing disconnects

 

BT, that is all there is to using Windows PowerShell to assist in troubleshooting Microsoft Outlook problems. Join me tomorrow for more cool Windows PowerShell things.  

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

 

 

0 comments

Discussion is closed.

Feedback usabilla icon