Skip to content

Instantly share code, notes, and snippets.

@bill-long
Last active February 1, 2017 19:47
Show Gist options
  • Save bill-long/d6cb9c8507f89f0b3a42 to your computer and use it in GitHub Desktop.
Save bill-long/d6cb9c8507f89f0b3a42 to your computer and use it in GitHub Desktop.
Example of how to find an item by PR_SOURCE_KEY value in EWS Managed API from Powershell
# FindItemBySourceKey.ps1
param([string]$HostName, [string]$UserName, [string]$Mailbox, [Parameter(Mandatory=$True)][string]$PrSourceKey)
#########################################
# Update the path below to match the actual path to the EWS managed API DLL.
#
Import-Module -Name "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll"
#
#########################################
$prSourceKeyString = $PrSourceKey
if ($Mailbox -eq "")
{
$Mailbox = Read-Host "Mailbox to process"
}
if ($HostName -eq "")
{
$HostName = Read-Host "Hostname for EWS endpoint (leave blank to attempt Autodiscover)"
}
if ($UserName -eq "")
{
$UserName = Read-Host "User (UPN format)"
}
$password = $host.ui.PromptForCredential("Credentials", "Please enter your password to authenticate to EWS.", $UserName, "").GetNetworkCredential().Password
# If a URL was specified we'll use that; otherwise we'll use Autodiscover
$exchService = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010)
$exchService.Credentials = new-object System.Net.NetworkCredential($UserName, $password, "")
if ($HostName -ne "")
{
("Using EWS URL " + "https://" + $HostName + "/EWS/Exchange.asmx")
$exchService.Url = new-object System.Uri(("https://" + $HostName + "/EWS/Exchange.asmx"))
}
else
{
("Autodiscovering " + $Mailbox + "...")
$exchService.AutoDiscoverUrl($Mailbox, {$true})
}
if ($exchService.Url -eq $null)
{
return
}
function DoMailbox($thisMailbox)
{
$rootName = [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root
$rootId = new-object Microsoft.Exchange.WebServices.Data.FolderId($rootName, $mbx)
$root = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($exchService, $rootId)
if ($root -eq $null)
{
("Error. Could not open mailbox.")
return
}
"Opened mailbox: " + $Mailbox
# We use the AllItems search folder for this, because that's the easiest way
# to check all items in all folders. Note that AllItems may not exist if you
# haven't logged on to the mailbox with Outlook.
$allItemsFilter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName, "AllItems")
$folderView = New-Object Microsoft.Exchange.WebServices.Data.FolderView(1)
$allItemsFolderResult = $root.FindFolders($allItemsFilter, $folderView)
if ($allItemsFolderResult.Folders.Count -lt 1)
{
"Could not find AllItems search folder."
return
}
# Now convert the string passed at the command line into a byte array
$prSourceKeyBinary = [Byte[]]@()
for ($x = 0; $x -lt $prSourceKeyString.Length; $x += 2)
{
$thisByte = [Byte]::Parse($prSourceKeyString.Substring($x, 2), [System.Globalization.NumberStyles]::AllowHexSpecifier)
$prSourceKeyBinary += $thisByte
}
# And now turn the byte array into a base64 string
$prSourceKeyBase64 = [System.Convert]::ToBase64String($prSourceKeyBinary)
# Bind to AllItems search folder
$allItemsFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($exchService, $allItemsFolderResult.Folders[0].Id)
# Set up the filter
$prSourceKeyProperty = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x65e0, [Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Binary)
$itemFilter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo($prSourceKeyProperty, $prSourceKeyBase64)
# Set up the view. Note that we only return one result at most.
$subjectProperty = [Microsoft.Exchange.WebServices.Data.ItemSchema]::Subject
$itemViewPropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties, $subjectProperty, $prSourceKeyProperty)
$itemView = New-Object Microsoft.Exchange.WebServices.Data.ItemView(1)
$itemView.PropertySet = $itemViewPropertySet
# Make the FindItems call
$findItemsResults = $allItemsFolder.FindItems($itemFilter, $itemView)
if ($findItemsResults.Items.Count -lt 1)
{
"Could not find any matching item."
return
}
""
$matchingItem = $findItemsResults.Items[0]
$parentFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($exchService, $matchingItem.ParentFolderId)
"Parent Folder: " + $parentFolder.DisplayName
" Subject: " + $matchingItem.Subject
" Received: " + $matchingItem.DateTimeReceived
" Sent: " + $matchingItem.DateTimeSent
}
$mbx = new-object Microsoft.Exchange.WebServices.Data.Mailbox($Mailbox)
DoMailbox($mbx)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment