by

Discovering RMS Objects in a Mailbox utilizing EWS

Discovering RMS Objects in a Mailbox utilizing EWS If you wish to seek for emails which have been protected utilizing AD Rights Managed Service utilizing EWS there are just a few challenges. How RMS works with E mail it’s documented within the following Alternate Protocol doc https://msdn.microsoft.com/en-us/library/cc463909(v=exchg.80).aspx. The essential half in relation to looking is PidNameContentClass property https://msdn.microsoft.com/en-us/library/workplace/cc839681.aspx which on RMS messages will get set to rpmsg.message. So to seek for this Web Header you should utilize a SearchFilter like the next to outline the ExtendProperty to look folder

$contentclassIh = New-Object Microsoft.Alternate.WebServices.Information.ExtendedPropertyDefinition([Microsoft.Exchange.WebServices.Data.DefaultExtendedPropertySet]::InternetHeaders,"content-class",[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String);  
$sfItemSearchFilter = new-object Microsoft.Alternate.WebServices.Information.SearchFilter+IsEqualTo($contentclassIh,"rpmsg.message")

Placing it collectively in a script that searches a Folder in a Mailbox primarily based on a MailboxName and FolderPath This script is on GitHub https://github.com/gscales/Powershell-Scripts/blob/grasp/GetRMSItems.ps1  (An essential level to notice whereas you’ll find e-mail that has been protected utilizing RMS with EWS you will not be capable of learn the encrypted contents utilizing EWS).

operate Get-RMSItems{
param
(
[Parameter(Place=0, Obligatory=$true)] [string]$MailboxName,
[Parameter(Place=1, Obligatory=$true)] [System.Management.Automation.PSCredential]$Credentials,
[Parameter(Place=2, Obligatory=$true)] [String]$FolderPath

)
start
{
$service = connect-exchange -Mailbox $MailboxName -Credentials $Credentials
$Folder = Get-FolderFromPath -FolderPath $FolderPath -MailboxName $MailboxName -service $service
$contentclassIh = New-Object Microsoft.Alternate.WebServices.Information.ExtendedPropertyDefinition([Microsoft.Exchange.WebServices.Data.DefaultExtendedPropertySet]::InternetHeaders,"content-class",[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String);
$sfItemSearchFilter = new-object Microsoft.Alternate.WebServices.Information.SearchFilter+IsEqualTo($contentclassIh,"rpmsg.message")
#Outline ItemView to retrive simply 1000 Objects
$ivItemView = New-Object Microsoft.Alternate.WebServices.Information.ItemView(1000)
$fiItems = $null
do{
$fiItems = $service.FindItems($Folder.Id,$sfItemSearchFilter,$ivItemView)
#[Void]$service.LoadPropertiesForItems($fiItems,$psPropset)
foreach($Merchandise in $fiItems.Objects){
Write-Output $Merchandise
}
$ivItemView.Offset += $fiItems.Objects.Rely
}whereas($fiItems.MoreAvailable -eq $true)

}
}

operate Get-FolderFromPath{
param (
[Parameter(Place=0, Obligatory=$true)] [string]$FolderPath,
[Parameter(Place=1, Obligatory=$true)] [string]$MailboxName,
[Parameter(Place=2, Obligatory=$true)] [Microsoft.Exchange.WebServices.Data.ExchangeService]$service,
[Parameter(Place=3, Obligatory=$false)] [Microsoft.Exchange.WebServices.Data.PropertySet]$PropertySet
)
course of{
## Discover and Bind to Folder primarily based on Path
#Outline the trail to look ought to be seperated with
#Bind to the MSGFolder Root
$folderid = new-object Microsoft.Alternate.WebServices.Information.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$MailboxName)
$tfTargetFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
#Cut up the Search path into an array
$fldArray = $FolderPath.Cut up("")
#Loop by means of the Cut up Array and do a Seek for every degree of folder
for ($lint = 1; $lint -lt $fldArray.Size; $lint++) {
#Carry out search primarily based on the displayname of every folder degree
$fvFolderView = new-object Microsoft.Alternate.WebServices.Information.FolderView(1)
if(![string]::IsNullOrEmpty($PropertySet)){
$fvFolderView.PropertySet = $PropertySet
}
$SfSearchFilter = new-object Microsoft.Alternate.WebServices.Information.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,$fldArray[$lint])
$findFolderResults = $service.FindFolders($tfTargetFolder.Id,$SfSearchFilter,$fvFolderView)
if ($findFolderResults.TotalCount -gt 0){
foreach($folder in $findFolderResults.Folders){
$tfTargetFolder = $folder
}
}
else{
Write-host ("Error Folder Not Found check path and try again")
$tfTargetFolder = $null
break
}
}
if($tfTargetFolder -ne $null){
return [Microsoft.Exchange.WebServices.Data.Folder]$tfTargetFolder
}
else{
throw ("Folder Not found")
}
}
}

operate ConvertToString($ipInputString){
$Val1Text = ""
for ($clInt=0;$clInt -lt $ipInputString.size;$clInt++){
$Val1Text = $Val1Text + [Convert]::ToString([Convert]::ToChar([Convert]::ToInt32($ipInputString.Substring($clInt,2),16)))
$clInt++
}
return $Val1Text
}

One final pattern that does a statistics report of all RMS gadgets in a Mailbox utilizing a SearchFilter on the AllItems Search Folder (which is created by the Outlook Desktop consumer) this outputs a report of the RMS Objects and the scale of these merchandise in every folder that appears like

This script is on GitHub at https://github.com/gscales/Powershell-Scripts/blob/grasp/GetRMSItems.ps1

operate ConvertToString($ipInputString){  
$Val1Text = ""
for ($clInt=0;$clInt -lt $ipInputString.size;$clInt++){
$Val1Text = $Val1Text + [Convert]::ToString([Convert]::ToChar([Convert]::ToInt32($ipInputString.Substring($clInt,2),16)))
$clInt++
}
return $Val1Text
}

operate Get-RMSItems-AllItemSearch{
param
(
[Parameter(Place=0, Obligatory=$true)] [string]$MailboxName,
[Parameter(Place=1, Obligatory=$true)] [System.Management.Automation.PSCredential]$Credentials

)
start
{
$FolderCache = @{}
$service = connect-exchange -Mailbox $MailboxName -Credentials $Credentials
$folderid= new-object Microsoft.Alternate.WebServices.Information.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$MailboxName)
$MsgRoot = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
GetFolderPaths -FolderCache $FolderCache -service $service -rootFolderId $MsgRoot.Id
$PR_FOLDER_TYPE = new-object Microsoft.Alternate.WebServices.Information.ExtendedPropertyDefinition(13825,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Integer);
$folderidcnt = new-object Microsoft.Alternate.WebServices.Information.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root,$MailboxName)
$fvFolderView = New-Object Microsoft.Alternate.WebServices.Information.FolderView(1000)
$fvFolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Shallow;
$sf1 = new-object Microsoft.Alternate.WebServices.Information.SearchFilter+IsEqualTo($PR_FOLDER_TYPE,"2")
$sf2 = new-object Microsoft.Alternate.WebServices.Information.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,"allitems")
$sfSearchFilterCol = new-object Microsoft.Alternate.WebServices.Information.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::And)
$sfSearchFilterCol.Add($sf1)
$sfSearchFilterCol.Add($sf2)
$fiResult = $Service.FindFolders($folderidcnt,$sfSearchFilterCol,$fvFolderView)
$fiItems = $null
$RptCollection = @{}
$ItemView = New-Object Microsoft.Alternate.WebServices.Information.ItemView(1000)
if($fiResult.Folders.Rely -eq 1)
{
$Folder = $fiResult.Folders[0]
$contentclassIh = New-Object Microsoft.Alternate.WebServices.Information.ExtendedPropertyDefinition([Microsoft.Exchange.WebServices.Data.DefaultExtendedPropertySet]::InternetHeaders,"content-class",[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String);
$sfItemSearchFilter = new-object Microsoft.Alternate.WebServices.Information.SearchFilter+IsEqualTo($contentclassIh,"rpmsg.message")
#Outline ItemView to retrive simply 1000 Objects
$ivItemView = New-Object Microsoft.Alternate.WebServices.Information.ItemView(1000)
$fiItems = $null
do{
$fiItems = $service.FindItems($Folder.Id,$sfItemSearchFilter,$ivItemView)
#[Void]$service.LoadPropertiesForItems($fiItems,$psPropset)
foreach($Merchandise in $fiItems.Objects){
if($FolderCache.ContainsKey($Merchandise.ParentFolderId.UniqueId))
{
if($RptCollection.ContainsKey($FolderCache[$Merchandise.ParentFolderId.UniqueId]))
{
$RptCollection[$FolderCache[$Merchandise.ParentFolderId.UniqueId]].TotalItems++
$RptCollection[$FolderCache[$Merchandise.ParentFolderId.UniqueId]].TotalSize+= $Merchandise.Measurement
}
else
Choose FolderName,TotalItems,TotalSize
$fldRptobj.FolderName = $FolderCache[$Merchandise.ParentFolderId.UniqueId]
$fldRptobj.TotalItems = 1
$fldRptobj.TotalSize = $Merchandise.Measurement
$RptCollection.Add($fldRptobj.FolderName,$fldRptobj)

}
}
$ivItemView.Offset += $fiItems.Objects.Rely
}whereas($fiItems.MoreAvailable -eq $true)

}
write-output $RptCollection.Values
}


}

operate GetFolderPaths
{
param (
[Parameter(Place=0, Obligatory=$true)] [Microsoft.Exchange.WebServices.Data.FolderId]$rootFolderId,
[Parameter(Place=1, Obligatory=$true)] [Microsoft.Exchange.WebServices.Data.ExchangeService]$service,
[Parameter(Place=2, Obligatory=$true)] [PSObject]$FolderCache,
[Parameter(Place=3, Obligatory=$false)] [String]$FolderPrefix
)
course of{
#Outline Prolonged properties
$PR_FOLDER_TYPE = new-object Microsoft.Alternate.WebServices.Information.ExtendedPropertyDefinition(13825,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Integer);
$PR_MESSAGE_SIZE_EXTENDED = new-object Microsoft.Alternate.WebServices.Information.ExtendedPropertyDefinition(3592, [Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Lengthy);
#Outline the FolderView used for Export shouldn't be any bigger then 1000 folders as a consequence of throttling
$fvFolderView = New-Object Microsoft.Alternate.WebServices.Information.FolderView(1000)
#Deep Transval will guarantee all folders within the search path are returned
$fvFolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep;
$psPropertySet = new-object Microsoft.Alternate.WebServices.Information.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
$PR_Folder_Path = new-object Microsoft.Alternate.WebServices.Information.ExtendedPropertyDefinition(26293, [Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String);
#Add Properties to the Property Set
$psPropertySet.Add($PR_Folder_Path);
$psPropertySet.Add($PR_MESSAGE_SIZE_EXTENDED)
$fvFolderView.PropertySet = $psPropertySet;
#The Search filter will exclude any Search Folders
$sfSearchFilter = new-object Microsoft.Alternate.WebServices.Information.SearchFilter+IsEqualTo($PR_FOLDER_TYPE,"1")
$fiResult = $null
#The Do loop will deal with any paging that's required if there are extra the 1000 folders in a mailbox
do
{
$fiResult = $service.FindFolders($rootFolderId,$sfSearchFilter,$fvFolderView)
foreach($ffFolder in $fiResult.Folders){
#Attempt to get the FolderPath Worth after which covert it to a usable String
$foldpathval = $null
if ($ffFolder.TryGetProperty($PR_Folder_Path,[ref] $foldpathval))
{
$binarry = [Text.Encoding]::UTF8.GetBytes($foldpathval)
$hexArr = $binarry | ForEach-Object { $_.ToString("X2") }
$hexString = $hexArr -join ''
$hexString = $hexString.Substitute("FEFF", "5C00")
$fpath = ConvertToString($hexString)
}
if($FolderCache.ContainsKey($ffFolder.Id.UniqueId) -eq $false)
{
if ([string]::IsNullOrEmpty($FolderPrefix)){
$FolderCache.Add($ffFolder.Id.UniqueId,($fpath))
}
else
{
$FolderCache.Add($ffFolder.Id.UniqueId,("" + $FolderPrefix + $fpath))
}
}
}
$fvFolderView.Offset += $fiResult.Folders.Rely
}whereas($fiResult.MoreAvailable -eq $true)
}
}