How to check an exchange mailbox via powershell?
Solution 1:
UPDATE, 18 Jan 2022: EWS is being / has been phased out. See these links:
- Nuget - has download link but not updated since 2015
- GitHub - has download link
- Microsoft
Firstly, apologies that this reply is nearly two years after the question, but I also wanted to check email using Powershell and found this question. Hopefully my code will serve as a reference/starting point for someone else looking to mine outlook from Powershell. I plan to enhance this myself to make it more usable.
I'm pretty new to Powershell, so my scripts are predominantly Frankenstein-ed from various articles, blog posts and StackOverflow Q&A's of course, the script below being no exception!
Following on from Chris' response, I did a little further digging around the internet and cobbled together a few snippets of Powershell to allow me to display a few key pieces of information from emails.
It's sadly lacking in any 'proper' style and I'm sure that any Powershell gurus will cringe at this. But what this code does do is
- show how to use EWS & Powershell to read emails
- address George's last question re: the body being blank - the
FindItems
method doesn't return the full mail item, you have to make another round-trip to get the extra information you need. - remove the requirement for you to use username/password/domain by using your current credentials
- remove the requirement to 'install' EWS, simply extract the MSI and reference the dll
To use...
Download the EWS from here then extract somewhere, e.g.
msiexec /a C:\Path\To\Downloads\EwsManagedApi.msi /qb TARGETDIR=C:\Progs\EwsManagedApi
then call this script using dot-source, e.g.
. C:\Path\To\Script\Outlook_ReadInbox.ps1
which allows you to reference the objects/variables from the script after it has executed.
The code has a limited comments throughout, as well as a few links at the end, which I referenced when cobbling the script together.
Here's my alpha draft of code to read in the first 5 emails, display whether read/unread and show the first 100 characters of the email body on one line with white-space removed.
# work with exchange server to retrieve messages
# see this SO answer: http://stackoverflow.com/a/4866894
# call this script using dot-source (see http://technet.microsoft.com/en-us/library/ee176949.aspx)
# to allow continued use of the objects, specifically, reading our inbox
# e.g...
# . C:\Path\To\Script\Outlook_ReadInbox.ps1
# replace with your email address
$email = "[email protected]"
# only need to populate these if you're impersonating...
$username = "YOUR_USER_NAME"
$password = "YOUR_LAN_PASSWORD"
$domain = "YOUR_DOMAIN"
# to allow us to write multi-coloured lines
# see http://stackoverflow.com/a/2688572
# usage: Write-Color -Text Red,White,Blue -Color Red,White,Blue
# usage: Write-Color Red,White,Blue Red,White,Blue
function Write-Color([String[]]$Text, [ConsoleColor[]]$Color) {
for ($i = 0; $i -lt $Text.Length; $i++) {
Write-Host $Text[$i] -Foreground $Color[$i] -NoNewLine
}
Write-Host
}
# load the assembly
[void] [Reflection.Assembly]::LoadFile("C:\Progs\EwsManagedApi\Microsoft.Exchange.WebServices.dll")
# set ref to exchange, first references 2007, 2nd is 2010 (default)
$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
#$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService
# use first option if you want to impersonate, otherwise, grab your own credentials
#$s.Credentials = New-Object Net.NetworkCredential($username, $password, $domain)
#$s.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
$s.UseDefaultCredentials = $true
# discover the url from your email address
$s.AutodiscoverUrl($email)
# get a handle to the inbox
$inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
#create a property set (to let us access the body & other details not available from the FindItems call)
$psPropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
$psPropertySet.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text;
$items = $inbox.FindItems(5)
#set colours for Write-Color output
$colorsread = "Yellow","White"
$colorsunread = "Red","White"
# output unread count
Write-Color -Text "Unread count: ",$inbox.UnreadCount -Color $colorsread
foreach ($item in $items.Items)
{
# load the property set to allow us to get to the body
$item.load($psPropertySet)
# colour our output
If ($item.IsRead) { $colors = $colorsread } Else { $colors = $colorsunread }
#format our body
#replace any whitespace with a single space then get the 1st 100 chars
$bod = $item.Body.Text -replace '\s+', ' '
$bodCutOff = (100,$bod.Length | Measure-Object -Minimum).Minimum
$bod = $bod.Substring(0,$bodCutOff)
$bod = "$bod..."
# output the results - first of all the From, Subject, References and Message ID
write-host "====================================================================" -foregroundcolor White
Write-Color "From: ",$($item.From.Name) $colors
Write-Color "Subject: ",$($item.Subject) $colors
Write-Color "Body: ",$($bod) $colors
write-host "====================================================================" -foregroundcolor White
""
}
# display the newest 5 items
#$inbox.FindItems(5)
# display the unread items from the newest 5
#$inbox.FindItems(5) | ?{$_.IsRead -eq $False} | Select Subject, Sender, DateTimeSent | Format-Table -auto
# returns the number of unread items
# $inbox.UnreadCount
#see these URLs for more info
# EWS
# folder members: https://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.folder_members%28v=exchg.80%29.aspx
# exporting headers: http://www.stevieg.org/tag/how-to/
# read emails with EWS: https://social.technet.microsoft.com/Forums/en-US/3fbf8348-2945-43aa-a0bc-f3b1d34da27c/read-emails-with-ews?forum=exchangesvrdevelopment
# Powershell
# multi-color lines: http://stackoverflow.com/a/2688572
# download the Exchange Web Services Managed API 1.2.1 from
# http://www.microsoft.com/en-us/download/details.aspx?id=30141
# extract somewhere, e.g. ...
# msiexec /a C:\Users\YourUsername\Downloads\EwsManagedApi.msi /qb TARGETDIR=C:\Progs\EwsManagedApi
Solution 2:
You'll need to have the EWS API installed, and you'll need to check the path to the DLL in the Reflection Assembly load portion.
This should get you to the point where you're able to work with the $inbox.FindItems(5) statement and filter the results you want out of that.
[Reflection.Assembly]::LoadFile("C:\Program Files\Microsoft\Exchange\Web Services\1.0\Microsoft.Exchange.WebServices.dll")
$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
$s.Credentials = New-Object Net.NetworkCredential('user', 'pass', 'domain')
$s.AutodiscoverUrl("[email protected]")
$inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
$inbox.FindItems(5)