This is the first of (another) series of articles covering PowerShell alongside another technology. In this case it is Microsoft Outlook.
I’ve scripted Outlook using a variety of technologies over the years, so it only seems right to add PowerShell to the toolbox. Most of the techniques I’ve used in the past have analogues in the PowerShell world.
Outlook is a complex beast, combining Email, Calendaring and Tasks into one application. It can connect to a variety of email sources and has its own set of terminology. See MSDN for full details, but here are some highlights:
Application – This is Outlook itself
Namespace – A way of connecting to email sources. The only supported namespace is MAPI .
Folder – An object containing other objects
Item – Outlook doesn’t have separate objects for email, calendar items, tasks etc. All of these are just Items.
Automating Outlook via PowerShell uses COM objects. First we need to add the support libraries to our session:
Add-Type -AssemblyName "Microsoft.Office.Interop.Outlook"
Next we create an instance of Outlook to automate:
$outlook = New-Object -ComObject Outlook.Application
Now we need a reference to the MAPI namespace:
$namespace = $outlook.GetNameSpace("MAPI")
From here we have access to everything in the current Outlook profile.
At this point I feel I ought to make a point about performance. Outlook can be connected to a number of different email sources including IMAP, POP3 and various flavours of Microsoft Exchange. In some instances your Outlook settings and how Outlook interacts with your mail source may result in you seeing fewer messages, calendar items etc. than you were expecting. If my experience is anything to go by check your Outlook settings before you decide that something is wrong with you code.
So, having said all that, what can we do with Outlook now that we are connected to the MAPI namespace? Well let’s have a look at our unread messages.
Let’s connect to our InBox. It could be referred to by many names depending on language settings etc. so Microsoft have made it possible to refer to it via an enumeration:
So we can get a reference to our InBox by using:
$inbox = $namespace.GetDefaultFolder([Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderInbox)
To find the number of unread message we access the UnReadItemCount property.
Because Outlook presents us with a proper COM object, we can use Get-Member to view the Properties and Methods of the InBox. There are some obvious and not so obvious entries in the list. The key one for us at the moment is the Items property, which unsurprisingly gives us access to the Items in the InBox. Let’s look at the first message in the InBox:
Oops, that didn’t work. How about (assuming you have 100 messages):
Nope. It seems that Items are not automatically stored in a sorted way. A little research on MSDN turns up the following statement:
The index for the Items collection starts at 1, and the items in the Items collection object are not guaranteed to be in any particular order.
Ok – so that gives us something to look at for part 2!