Mapping what Folders are in use in ActiveSync with EWS and Powershell

Mapping what Folders are in use in ActiveSync with EWS and Powershell [***Ingo Gegenwarth has printed an higher model of this script that handles the modifications made not too long ago to ActiveSync on Change On-line see https://ingogegenwarth.wordpress.com/2018/01/03/eas-folder-mapping/ ]

I got here throughout an attention-grabbing Weblog submit this week from Jim Martin

http://blogs.technet.com/b/tips_from_the_inside/archive/2013/06/17/activesync-mapping-a-collection-id-to-a-mailbox-folder.aspx

which explains how the ActiveSync Folders situated below the gadget folder in ExchangeSyncData folder tree map again to the actual Mailbox folder that’s being synchronized or accessed through ActiveSync. This info is fairly helpful for a lot of issues so I assumed it will be helpful to place a script collectively to automate and create a report of those folder mapping utilizing EWS and Powershell.

The way it works is the ExchangeSyncData is situated within the NON_IPM_Subtree of a mailbox so just a few FindFolder calls are wanted to search out this folder after which get all of the Folders related to any ActiveSync units for the Mailbox. The 0x7C030102 property is about on ActiveSync Assortment folder and as in Jim’s submit in the event you take the primary byte and final byte off the worth from this property you’ve gotten the HexEntryId of the folder. In EWS you’ll be able to then use convertId to covert it to the ewsID of the Folder after which bind to the FolderId to work out which folder is being synced. Principally what you find yourself with is a report that appears like this

The LastModified column is the time the ActiveSync folder was final modified which ought to relate to the final time the folder was accessed over ActiveSync (from my commentary anyway). The System column simply comes from the DisplayName of the Root folder from the gadget

I’ve put a download of this script right here the code itself appears like

  1. ## Get the Mailbox to Entry from the 1st commandline argument  
  2.   
  3. $MailboxName = $args[0]  
  4. $AsFolderReport = @()  
  5.   
  6. ## Load Managed API dll    
  7. Add-Kind -Path “C:Program FilesMicrosoftExchangeWeb Services2.0Microsoft.Exchange.WebServices.dll”    
  8.     
  9. ## Set Change Model    
  10. $ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Change2010_SP2    
  11.     
  12. ## Create Change Service Object    
  13. $service = New-Object Microsoft.Change.WebServices.Knowledge.ExchangeService($ExchangeVersion)    
  14.     
  15. ## Set Credentials to use two choices are availible Option1 to use explict credentials or Choice 2 use the Default (logged On) credentials    
  16.     
  17. #Credentials Choice 1 utilizing UPN for the home windows Account    
  18. $psCred = Get-Credential    
  19. $creds = New-Object System.Internet.NetworkCredential($psCred.UserName.ToString(),$psCred.GetNetworkCredential().password.ToString())    
  20. $service.Credentials = $creds        
  21.     
  22. #Credentials Choice 2    
  23. #service.UseDefaultCredentials = $true    
  24.     
  25. ## Select to ignore any SSL Warning points induced by Self Signed Certificates    
  26.     
  27. ## Code From http://poshcode.org/624  
  28. ## Create a compilation atmosphere  
  29. $Supplier=New-Object Microsoft.CSharp.CSharpCodeProvider  
  30. $Compiler=$Supplier.CreateCompiler()  
  31. $Params=New-Object System.CodeDom.Compiler.CompilerParameters  
  32. $Params.GenerateExecutable=$False  
  33. $Params.GenerateInMemory=$True  
  34. $Params.IncludeDebugInformation=$False  
  35. $Params.ReferencedAssemblies.Add(“System.DLL”) | Out-Null  
  36.   
  37. $TASource[email protected] 
  38.   namespace Native.ToolkitExtensions.Internet.CertificatePolicy{ 
  39.     public class TrustAll : System.Internet.ICertificatePolicy { 
  40.       public TrustAll() {  
  41.       } 
  42.       public bool CheckValidationResult(System.Internet.ServicePoint sp, 
  43.         System.Safety.Cryptography.X509Certificates.X509Certificates cert,  
  44.         System.Internet.WebRequest req, int downside) { 
  45.         return true; 
  46.       } 
  47.     } 
  48.   } 
  49. @   
  50. $TAResults=$Supplier.CompileAssemblyFromSource($Params,$TASource)  
  51. $TAAssembly=$TAResults.CompiledAssembly  
  52.   
  53. ## We now create an occasion of the TrustAll and connect it to the ServicePointManager  
  54. $TrustAll=$TAAssembly.CreateInstance(“Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll”)  
  55. [System.Net.ServicePointManager]::CertificatePolicy=$TrustAll  
  56.   
  57. ## finish code from http://poshcode.org/624  
  58.     
  59. ## Set the URL of the CAS (Shopper Entry Server) to use two choices are availbe to use Autodiscover to discover the CAS URL or Hardcode the CAS to use    
  60.     
  61. #CAS URL Choice 1 Autodiscover    
  62. $service.AutodiscoverUrl($MailboxName,{$true})    
  63. “Using CAS Server : “ + $Service.url     
  64.      
  65. #CAS URL Choice 2 Hardcoded    
  66.     
  67. #$uri=[system.URI] “https://casservername/ews/exchange.asmx”    
  68. #$service.Url = $uri      
  69.     
  70. ## Elective part for Change Impersonation    
  71.     
  72. #$service.ImpersonatedUserId = new-object Microsoft.Change.WebServices.Knowledge.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $MailboxName)   
  73. # Bind to the MsgFolderRoot folder    
  74. $folderid= new-object Microsoft.Change.WebServices.Knowledge.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root,$MailboxName)     
  75. $MsgRoot = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)  
  76.   
  77. operate ConvertId{      
  78.     param (  
  79.             $HexId = “$( throw ‘HexId is a mandatory Parameter’ )”  
  80.           )  
  81.     course of{  
  82.         $aiItem = New-Object Microsoft.Change.WebServices.Knowledge.AlternateId        
  83.         $aiItem.Mailbox = $MailboxName        
  84.         $aiItem.UniqueId = $HexId     
  85.         $aiItem.Format = [Microsoft.Exchange.WebServices.Data.IdFormat]::HexEntryId        
  86.         $convertedId = $service.ConvertId($aiItem, [Microsoft.Exchange.WebServices.Data.IdFormat]::EwsId)   
  87.         return $convertedId.UniqueId  
  88.     }  
  89. }  
  90.   
  91. operate GetFolderPath{  
  92.     param (  
  93.         $EWSFolder = “$( throw ‘Folder is a mandatory Parameter’ )”  
  94.     )  
  95.     course of{  
  96.         $foldpathval = $null    
  97.         $PR_Folder_Path = new-object Microsoft.Change.WebServices.Knowledge.ExtendedPropertyDefinition(26293, [Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String);    
  98.         if ($EWSFolder.TryGetProperty($PR_Folder_Path,[ref] $foldpathval))    
  99.         {    
  100.             $binarry = [Text.Encoding]::UTF8.GetBytes($foldpathval)    
  101.             $hexArr = $binarry | ForEach-Object { $_.ToString(“X2”) }    
  102.             $hexString = $hexArr -join     
  103.         $hexString = $hexString.Substitute(“EFBFBE”“5C”)    
  104.             $fpath = ConvertToString($hexString)   
  105.         return $fpath  
  106.         }    
  107.     }  
  108. }  
  109. $fldMappingHash = @{}  
  110. #Outline the FolderView used for Export ought to not be any bigger then 1000 folders due to throttling    
  111. $fvFolderView =  New-Object Microsoft.Change.WebServices.Knowledge.FolderView(1)    
  112. #Deep Transval will guarantee all folders in the search path are returned    
  113. $fvFolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Shallow;    
  114. #The Search filter will exclude any Search Folders    
  115. $sfSearchFilter = new-object Microsoft.Change.WebServices.Knowledge.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,“ExchangeSyncData”)    
  116. $asFolderRoot = $Service.FindFolders($MsgRoot.Id,$sfSearchFilter,$fvFolderView)    
  117. if($asFolderRoot.Folders.Depend -eq 1){  
  118.     #Outline Perform to convert String to FolderPath    
  119.     operate ConvertToString($ipInputString){    
  120.         $Val1Text = “”    
  121.         for ($clInt=0;$clInt -lt $ipInputString.size;$clInt++){    
  122.                 $Val1Text = $Val1Text + [Convert]::ToString([Convert]::ToChar([Convert]::ToInt32($ipInputString.Substring($clInt,2),16)))    
  123.                 $clInt++    
  124.         }    
  125.         return $Val1Text    
  126.     }   
  127.       
  128.     #Outline Prolonged properties    
  129.     $PR_FOLDER_TYPE = new-object Microsoft.Change.WebServices.Knowledge.ExtendedPropertyDefinition(13825,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Integer);    
  130.     #Outline the FolderView used for Export ought to not be any bigger then 1000 folders due to throttling    
  131.     $fvFolderView =  New-Object Microsoft.Change.WebServices.Knowledge.FolderView(1000)    
  132.     #Deep Transval will guarantee all folders in the search path are returned    
  133.     $fvFolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep;    
  134.     $psPropertySet = new-object Microsoft.Change.WebServices.Knowledge.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)    
  135.     $PR_Folder_Path = new-object Microsoft.Change.WebServices.Knowledge.ExtendedPropertyDefinition(26293, [Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String);    
  136.     $CollectionIdProp = new-object Microsoft.Change.WebServices.Knowledge.ExtendedPropertyDefinition(0x7C03, [Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Binary)  
  137.     $LastModifiedTime = new-object Microsoft.Change.WebServices.Knowledge.ExtendedPropertyDefinition(0x3008, [Microsoft.Exchange.WebServices.Data.MapiPropertyType]::SystemTime)  
  138.     #Add Properties to the  Property Set    
  139.     $psPropertySet.Add($PR_Folder_Path);    
  140.     $psPropertySet.Add($CollectionIdProp);  
  141.     $psPropertySet.Add($LastModifiedTime);    
  142.     $fvFolderView.PropertySet = $psPropertySet;    
  143.     #The Search filter will exclude any Search Folders    
  144.     $sfSearchFilter = new-object Microsoft.Change.WebServices.Knowledge.SearchFilter+IsEqualTo($PR_FOLDER_TYPE,“1”)    
  145.     $fiResult = $null    
  146.     #The Do loop will deal with any paging that is required if there are extra the 1000 folders in a mailbox    
  147.     do {    
  148.         $fiResult = $Service.FindFolders($asFolderRoot.Folders[0].Id,$sfSearchFilter,$fvFolderView)    
  149.         foreach($ffFolder in $fiResult.Folders){   
  150.             if(!$fldMappingHash.ContainsKey($ffFolder.Id.UniqueId)){  
  151.                 $fldMappingHash.Add($ffFolder.Id.UniqueId,$ffFolder)  
  152.             }  
  153.             $asFolderPath = “”  
  154.             $asFolderPath = (GetFolderPath -EWSFolder $ffFolder)  
  155.             “FolderPath : “ + $asFolderPath  
  156.             $collectVal = $null  
  157.             if($ffFolder.TryGetProperty($CollectionIdProp,[ref]$collectVal)){  
  158.                 $HexEntryId = [System.BitConverter]::ToString($collectVal).Substitute(“-“,“”).Substring(2)  
  159.                 $ewsFolderId = ConvertId -HexId ($HexEntryId.SubString(0,($HexEntryId.Size-2)))  
  160.                 attempt{  
  161.                     $fldReport = “” | Choose Mailbox,System,AsFolderPath,MailboxFolderPath,LastModified  
  162.                     $fldReport.Mailbox = $MailboxName  
  163.                     $fldReport.System = $fldMappingHash[$ffFolder.ParentFolderId.UniqueId].DisplayName  
  164.                     $fldReport.AsFolderPath = $asFolderPath  
  165.                     $folderMapId= new-object Microsoft.Change.WebServices.Knowledge.FolderId($ewsFolderId)     
  166.                     $MappedFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderMapId,$psPropertySet)  
  167.                     $MappedFolderPath = (GetFolderPath -EWSFolder $MappedFolder)  
  168.                     $fldReport.MailboxFolderPath = $MappedFolderPath  
  169.                     $LastModifiedVal = $null  
  170.                     if($ffFolder.TryGetProperty($LastModifiedTime,[ref]$LastModifiedVal)){  
  171.                         Write-Host (“Last-Modified : “ +  $LastModifiedVal.ToLocalTime().ToString())  
  172.                         $fldReport.LastModified = $LastModifiedVal.ToLocalTime().ToString()  
  173.                     }  
  174.                     Write-Host $MappedFolderPath  
  175.                     $AsFolderReport += $fldReport  
  176.                 }  
  177.                 catch{  
  178.                       
  179.                 }  
  180.                 $ewsFolderId  
  181.             }  
  182.             #Course of folder right here  
  183.         }   
  184.         $fvFolderView.Offset += $fiResult.Folders.Depend  
  185.     }whereas($fiResult.MoreAvailable -eq $true)    
  186.       
  187.       
  188. }  
  189. $reportFile = “c:temp$MailboxName-asFolders.csv”  
  190. $AsFolderReport | Export-Csv -NoTypeInformation -Path $reportFile  
  191. Write-Host (“Report wrtten to “ + $reportFile)  

Tags:

Related Posts

Leave a Reply