Skip to content

Instantly share code, notes, and snippets.

@chrisbrownie
Created April 3, 2017 03:26
Show Gist options
  • Save chrisbrownie/1391d27c24663db752912ac803bdadfc to your computer and use it in GitHub Desktop.
Save chrisbrownie/1391d27c24663db752912ac803bdadfc to your computer and use it in GitHub Desktop.
Returns a count of mailbox items of the specified class.
<#
.SYNOPSIS
Get-MailboxItemsByClass.ps1 - Returns a count of mailbox items of the specified class.
.DESCRIPTION
This function will return a count of the number of items in a mailbox matching the specified class.
Uses EWS Managed API to perform the check
.EXAMPLE
.\Get-MailboxItemsByClass.ps1 -MailboxToSearch [email protected] -ItemStubClass IPM.Note -StoredCredentialUsername [email protected]
.LINK
https://flamingkeys.com/
.NOTES
Written by: Chris Brown
Find me on:
* My Blog: https://flamingkeys.com
* Twitter: https://twitter.com/chrisbrownie
* GitHub: https://github.com/chrisbrownie
Thanks to Paul Cunningham for his excellent PowerShell-Stored-Credentials
code used in this script:
https://github.com/cunninghamp/PowerShell-Stored-Credentials
#>
Param(
[string]$MailboxToSearch,
[string]$ItemStubClass = "IPM.Note",
[string]$StoredCredentialUserName
)
Function New-StoredCredential {
<#
.SYNOPSIS
New-StoredCredential - Create a new stored credential
.DESCRIPTION
This function will save a new stored credential to a .cred file.
.EXAMPLE
New-StoredCredential
.LINK
https://practical365.com/saving-credentials-for-office-365-powershell-scripts-and-scheduled-tasks
.NOTES
Written by: Paul Cunningham
Find me on:
* My Blog: http://paulcunningham.me
* Twitter: https://twitter.com/paulcunningham
* LinkedIn: http://au.linkedin.com/in/cunninghamp/
* Github: https://github.com/cunninghamp
For more Office 365 tips, tricks and news
check out Practical 365.
* Website: https://practical365.com
* Twitter: https://twitter.com/practical365
#>
if (!(Test-Path Variable:\KeyPath)) {
Write-Warning "The `$KeyPath variable has not been set. Consider adding `$KeyPath to your PowerShell profile to avoid this prompt."
$path = Read-Host -Prompt "Enter a path for stored credentials"
Set-Variable -Name KeyPath -Scope Global -Value $path
if (!(Test-Path $KeyPath)) {
try {
New-Item -ItemType Directory -Path $KeyPath -ErrorAction STOP | Out-Null
}
catch {
throw $_.Exception.Message
}
}
}
$Credential = Get-Credential -Message "Enter a user name and password"
$Credential.Password | ConvertFrom-SecureString | Out-File "$($KeyPath)\$($Credential.Username).cred" -Force
# Return a PSCredential object (with no password) so the caller knows what credential username was entered for future recalls
New-Object -TypeName System.Management.Automation.PSCredential($Credential.Username,(new-object System.Security.SecureString))
}
Function Get-StoredCredential {
<#
.SYNOPSIS
Get-StoredCredential - Retrieve or list stored credentials
.DESCRIPTION
This function can be used to list available credentials on
the computer, or to retrieve a credential for use in a script
or command.
.PARAMETER UserName
Get the stored credential for the username
.PARAMETER List
List the stored credentials on the computer
.EXAMPLE
Get-StoredCredential -List
.EXAMPLE
$credential = Get-StoredCredential -UserName [email protected]
.EXAMPLE
Get-StoredCredential -List
.LINK
https://practical365.com/saving-credentials-for-office-365-powershell-scripts-and-scheduled-tasks
.NOTES
Written by: Paul Cunningham
Find me on:
* My Blog: http://paulcunningham.me
* Twitter: https://twitter.com/paulcunningham
* LinkedIn: http://au.linkedin.com/in/cunninghamp/
* Github: https://github.com/cunninghamp
For more Office 365 tips, tricks and news
check out Practical 365.
* Website: https://practical365.com
* Twitter: https://twitter.com/practical365
#>
param(
[Parameter(Mandatory=$false, ParameterSetName="Get")]
[string]$UserName,
[Parameter(Mandatory=$false, ParameterSetName="List")]
[switch]$List
)
if (!(Test-Path Variable:\KeyPath)) {
Write-Warning "The `$KeyPath variable has not been set. Consider adding `$KeyPath to your PowerShell profile to avoid this prompt."
$path = Read-Host -Prompt "Enter a path for stored credentials"
Set-Variable -Name KeyPath -Scope Global -Value $path
}
if ($List) {
try {
$CredentialList = @(Get-ChildItem -Path $keypath -Filter *.cred -ErrorAction STOP)
foreach ($Cred in $CredentialList) {
Write-Host "Username: $($Cred.BaseName)"
}
}
catch {
Write-Warning $_.Exception.Message
}
}
if ($UserName) {
if (Test-Path "$($KeyPath)\$($Username).cred") {
$PwdSecureString = Get-Content "$($KeyPath)\$($Username).cred" | ConvertTo-SecureString
$Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $Username, $PwdSecureString
}
else {
throw "Unable to locate a credential for $($Username)"
}
return $Credential
}
}
function CountItemsInMailboxByClass {
Param(
$mailbox,
$ItemClass,
$ExchangeCredentials
)
$ewsDll = "C:\Program Files\Microsoft\Exchange\Web Services\2.2\Microsoft.Exchange.WebServices.dll"
if ((Test-Path $ewsDll) -eq $false) {
throw "Could not find the EWS DLL! Ensure the Exchange Web Services Managed API is installed. `nGet it here: http://www.microsoft.com/download/details.aspx?id=42951"
}
[void][Reflection.Assembly]::LoadFile($ewsDll)
$ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010
if (-not $ExchangeService) {
$ExchangeService = New-Object -TypeName Microsoft.Exchange.WebServices.Data.ExchangeService($ExchangeVersion)
}
$ExchangeService.Credentials = New-Object System.Net.NetworkCredential( `
$ExchangeCredentials.UserName.ToString(), `
$ExchangeCredentials.GetNetworkCredential().password.ToString() `
)
$ExchangeService.AutodiscoverUrl($mailbox,{$true})
# Create a SearchFilter defining objects of the ItemClass class
$isTargetItem = New-Object -TypeName Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass,$ItemClass)
# Return only the first million results
$view = New-Object -TypeName Microsoft.Exchange.WebServices.Data.ItemView(1000000)
$view.PropertySet = New-Object -TypeName Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
$view.OrderBy.Add([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived,[Microsoft.Exchange.WebServices.Data.SortDirection]::Ascending)
# Define the folder to be searched
$folderToSearch = New-Object -TypeName Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$mailboxToSearch)
try {
$items = $ExchangeService.FindItems($folderToSearch, $isTargetItem, $view)
$(@($items).Count)
} catch [System.Management.Automation.MethodInvocationException] {
if ($_.Exception.Message.ToString() -ilike "*The specified object was not found in the store*") {
# Could not get any objects, probably don't have access to the mailbox
throw "Unable to retrieve the items from the mailbox! Ensure the current account has access"
} else {
throw $_
}
} catch {
throw $_
}
}
if (-not (Get-Variable KeyPath -ErrorAction SilentlyContinue)) {
# $KeyPath is not set, so try the current directory
$KeyPath = $pwd
}
try {
$ExchangeCredentials = Get-StoredCredential -UserName $StoredCredentialUserName
} catch {
# Prompt the user to create a credential
$cred = New-StoredCredential
$ExchangeCredentials = Get-StoredCredential -UserName $cred.Username
}
CountItemsInMailboxByClass -mailbox $mailboxToSearch -ItemClass $ItemStubClass -ExchangeCredentials $ExchangeCredentials
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment