We're running a PowerShell script that uses EWS to check the content of a mailbox. This worked flawlessly for over a year and now, all of a sudden, it is throwing the following error:
Exception calling "FindItems" with "3" argument(s): "An internal server error occurred. The operation failed."
At line:1 char:1+
$Service.FindItems($Inbox.Id,$Filter,$View)
The code we use:
Param (
[String]$Mailbox = 'User@domain.com',
[Int]$HoursAgo = '192',
[String]$UserName = 'AdminUser',
[String]$Password = 'S:\Input\Passwords\Password.txt',
[String]$MailboxFolderInbox = '\PowerShell',
[ValidateSet('Exchange2007_SP1','Exchange2010','Exchange2010_SP1','Exchange2010_SP2','Exchange2013','Exchange2013_SP1')]
[String]$ExchangeVersion = 'Exchange2007_SP1',
[String]$EWS = 'C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll'
)
Function Find-MailboxFolderIDHC {
<#
.SYNOPSIS
Search for the folder ID of a specific folder in a mailbox.
.DESCRIPTION
Search for the folder ID of a specific folder in a mailbox.
.PARAMETER Path
The path to search for within the mailbox. When searching for an exact path this should be split with '\'.
Example: '\PowerShell\Tickets SENT' or 'PowerShell''
.PARAMETER Mailbox
E-mail address
.PARAMETER Service
The Exchange Webservice object used to authenticate ourselfs
.EXAMPLE
Find-MailboxFolderIDHC -Path '\Inbox\PowerShell\Expiring users OUT' -Mailbox 'Jos@brink.nl' -Service $Service
Searches for the folder 'Expiring users Out' under the root 'Inbox\PowerShell' of the mailbox 'Jos@brink.nl'
#
[CmdLetBinding()]
Param (
[Parameter(Mandatory)]
[String]$Path,
[Parameter(Mandatory)]
[String]$Mailbox,
[Parameter(Mandatory)]
[Object]$Service
)
Try {
$FolderID = New-Object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$Mailbox)
$DataFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service,$FolderID)
}
Catch {
throw "Folder '$Path' not found in mailbox '$Mailbox'. Maybe this is a distribution list instead or the mailbox is not correctly configed with 'Full control'. In this case ask SDO Exchange team to run the 'Add-MailboxPermission' CmdLet as described in 'https://support.microsoft.com/en-us/kb/940846': $_"
}
$Array = $Path.Split('\')
for ($i=1; $i -lt $Array.Length; $i++) {
$FolderView = New-Object Microsoft.Exchange.WebServices.Data.FolderView(1)
$SearchFilter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,$Array[$i])
$Results = $service.FindFolders($DataFolder.Id,$SearchFilter,$FolderView)
if ($Results.TotalCount -gt 0) {
foreach ($R in $Results.Folders) {
$DataFolder = $R
}
}
else {
$NotFound = $true
}
}
if ($NotFound) {
if ($ErrorActionPreference -eq 'Ignore') {
Write-Verbose "Folder path '$Path' not found in the mailbox '$Mailbox'"
}
else {
throw "Folder path '$Path' not found in the mailbox '$Mailbox'"
}
}
else {
$DataFolder.Id
Write-Verbose "Found folder '$Path' in '$Mailbox' with ID '$($DataFolder.Id.UniqueId)'"
}
}
Function Import-CredentialsHC {
<#
.SYNOPSIS
Create a PSCredential object.
.DESCRIPTION
Create a PSCredential object with a user name and password that can be used for authentication via 'Credssp'.
.PARAMETER SamAccountName
The SAM Account Name used to logon to the domain.
.PARAMETER Password
Plain text or a hashed file. Keep in mind that the hashed file can only be decrypted by the user that hashed it. A part of the Windows profile is used to decypher the hash.
.EXAMPLE
$Creds = Import-CredentialsHC -SamAccountName 'test' -Password 'Welkom'
Creates the PSCredential object '$Creds' for the user 'test' with his password 'Welkom'.
#>
[CmdletBinding()]
Param (
[parameter(Mandatory,Position=0)]
[ValidateNotNullOrEmpty()]
[String]$SamAccountName,
[parameter(Mandatory,Position=1)]
[ValidateNotNullOrEmpty()]
[String]$Password
)
Process {
If (-not (Get-ADUser -Filter {SamAccountName -eq $SamAccountName})) {
throw "Import-CredentialsHC: The SamAccountName '$SamAccountName' is incorrect"
}
if (-not ((Get-ADUser -Identity $SamAccountName).Enabled)) {
throw "Import-CredentialsHC: The account '$SamAccountName' is disabled"
}
if ((Get-ADUser -identity $SamAccountName -Properties LockedOut).LockedOut) {
throw "Import-CredentialsHC: The account '$SamAccountName' is locked-out"
}
if (Test-Path $Password -PathType Leaf) {
try {
$Pwd = Get-Content $Password | ConvertTo-SecureString -Force -EA Stop
$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $SamAccountName,$Pwd
}
catch {
throw "Import-CredentialsHC: The password has been hashed with another Windows profile (user) then the Windows account now in use
(all 3 users/owners need to be the same)
- Script account :`t $env:USERNAME
- SamAccountName :`t $SamAccountName
- Password file :`t $Password"
}
}
else {
$Pwd = $Password | ConvertTo-SecureString -asPlainText -Force
$Credentials = New-Object System.Management.Automation.PSCredential -ArgumentList $SamAccountName,$Pwd
}
if ((New-Object directoryservices.directoryentry "",$SamAccountName,$($Credentials.GetNetworkCredential().Password)).psbase.name -ne $null) {
Write-Output $Credentials
}
else {
throw "Import-CredentialsHC: The password for the user '$SamAccountName' is not valid"
}
}
}
Import-Module -Name $EWS -EA Stop
$Credentials = Import-CredentialsHC -SamAccountName $UserName -Password $Password
$Service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList $ExchangeVersion
$Service.UseDefaultCredentials = $false
$Service.Credentials = $Credentials.GetNetworkCredential()
#$Service.UseDefaultCredentials = $true
$Service.AutodiscoverUrl($Mailbox)
$FindMailParams = @{
Mailbox = $Mailbox
Service = $Service
}
$PowerShellPathId = Find-MailboxFolderIDHC @FindMailParams -Path $MailboxFolderInbox
$Inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service,$PowerShellPathId)
$Props = [Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties
$PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet($Props)
$PropertySet.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text
$PropertySet.Add([Microsoft.Exchange.WebServices.Data.ItemSchema]::MimeContent)
$Date = [Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived
$TimeSpan = (Get-Date).AddHours(-$HoursAgo)
$Filter = New-Object -TypeName Microsoft.Exchange.WebServices.Data.SearchFilter+IsGreaterThan -ArgumentList $Date,$TimeSpan
$View = New-Object Microsoft.Exchange.WebServices.Data.ItemView(100)
$View.OrderBy.add([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived,
[Microsoft.Exchange.WebServices.Data.SortDirection]::Ascending)
$Service.FindItems($Inbox.Id,$Filter,$View)
When I check the $Service object it seems to be ok, but FindItems always fails:
$Service
Url : https://mymailbox.company.com/ews/exchange.asmx
ImpersonatedUserId :
ManagementRoles :
PreferredCulture :
DateTimePrecision : Default
FileAttachmentContentHandler :
TimeZone : (UTC+01:00) Brussels, Copenhagen, Madrid, Paris
UnifiedMessaging : Microsoft.Exchange.WebServices.Data.UnifiedMessaging
EnableScpLookup : True
TraceEnablePrettyPrinting : True
CookieContainer : System.Net.CookieContainer
SendClientLatencies : True
TraceEnabled : False
TraceFlags : All
TraceListener : Microsoft.Exchange.WebServices.Data.EwsTraceListener
Credentials : Microsoft.Exchange.WebServices.Data.WebCredentials
UseDefaultCredentials : False
Timeout : 100000
PreAuthenticate : False
AcceptGzipEncoding : True
RequestedServerVersion : Exchange2007_SP1
UserAgent : ExchangeServicesClient/15.00.0913.015
ServerInfo : 15.00.1178.002
WebProxy :
KeepAlive : True
ConnectionGroupName :
ClientRequestId :
ReturnClientRequestId : False
HttpHeaders : {}
HttpResponseHeaders : {[Transfer-Encoding, chunked], [Content-Encoding, gzip], [Vary, Accept-Encoding], [request
-id, 960d1ecd-c292-4e43-9b74-2d25f1e96560]...}
Thank you for your help as we're seriously stuck here and out of ideas on how to solve this. I've tried with Exchange version 2013 but this throws another error of incompatible Exchange versions. I thought they might have moved to a new Exchange version
in our environment.