title: How to search for emails in a non standard exchange folder using EWS and powershell
body: <p>I want use powershell and EWS (see <a href="https://msdn.microsoft.com/en-us/library/office/dd633710(v=exchg.80).aspx" rel="nofollow noreferrer">https://msdn.microsoft.com/en-us/library/office/dd633710(v=exchg.80).aspx</a>) to search for emails that contain a particular string in the subject line.</p>
  
  <p>My problem is that the emails reside in a user-defined folder in the inbox, rather than in one of the folders listed in the WellKnownFolderName enumeration (see <a href="https://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.wellknownfoldername(v=exchg.80).aspx" rel="nofollow noreferrer">https://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.wellknownfoldername(v=exchg.80).aspx</a>)</p>
  
  <p>The example code that I have found to search for emails all wants to search in one of these well-known folder names rather than in an arbitrary user-specified folder.</p>
  
  <p>does anyone have some example code that i can use as a reference to figure out how to do this [or does EWS limit you to searching for emails using a well-known folder name only].</p>
  
  <p>My code so far is thus:</p>
  
  <pre><code>$email    = "myemail@someplace.com"
  $username = "myusername" 
  $password = "*****"
  $domain   = "mydomain"
  $USER_DEFINED_FOLDER_IN_MAILBOX = "myRandomFolder"
  
  $EXCHANGE_WEB_SERVICE_DLL = "C:\Program Files (x86)\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll"
  # load the assembly
  [void] [Reflection.Assembly]::LoadFile($EXCHANGE_WEB_SERVICE_DLL)
  
  # set ref to exchange
  $s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService
  
  # use first option if you want to impersonate, otherwise, grab your own credentials
  $s.Credentials = New-Object Net.NetworkCredential($username, $password, $domain)
  
  # discover the url from your email address
  $s.AutodiscoverUrl($email)
  
  # get a handle to the inbox
  $inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)
  
  $MailboxRootid = new-object  Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root, $email) # selection and creation of new root
  $MailboxRoot = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,$MailboxRootid)
  
  $fvFolderView = new-object Microsoft.Exchange.WebServices.Data.FolderView(100) #page size for displayed folders
  $fvFolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep; #Search traversal selection Deep = recursively
  $SfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::Displayname,$NAME_OF_ARCHIVE_FOLDER_IN_MAILBOX) #for each folder in mailbox define search
  $findFolderResults = $MailboxRoot.FindFolders($SfSearchFilter,$fvFolderView) 
  
  $ArchiveFolder = ""
  
  # This next loop successfully finds my folder, but it is an inefficient way 
  # to do it.  It's ok, because there's not that many folders, but there's tens 
  # of thousands of emails to search through in the folder itself, and that will
  # need a more efficient search.
  foreach ($Fdr in $findFolderResults.Folders)
  {
      $theDisplayName = $Fdr.DisplayName
      if($theDisplayName -eq $USER_DEFINED_FOLDER_IN_MAILBOX)
      {
          $ArchiveFolder = $Fdr
      }
  }
  
  # Now to actually try and search through the emails in my $ArchiveFolder (the hard way)
  $textToFindInSubject = "TEST"
  
  $emailsInFolder = $ArchiveFolder.FindItems(9999)   # &lt;-- Successfully finds ALL emails with no filtering, requiring iterative code to find the ones I want.
  foreach($individualEmail in $emailsInFolder.Items)
  {
      if($individualEmail.Subject -match "$textToFindInSubject")
      {       
          # found the email i want -  but a super inefficient
          # way to do it
          echo "Successfully found the email!"
      }
  }
  
  # Attempt 1 to get the emails with a more refined search
  $emailSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+ContainsSubstring([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::Subject,$textToFindInSubject) 
  $emailsInFolder1 = $ArchiveFolder.FindItems($emailSearchFilter)  # &lt;-- Fails to return an object
  
  # Attempt 2 to get the emails with a more refined search
  $iv = new-object Microsoft.Exchange.WebServices.Data.ItemView(2000)
  $emailsInFolder2 = $s.FindItems($ArchiveFolder,  $emailSearchFilter, $iv)   # &lt;-- Also fails to return an object
  
  echo "Done."
  </code></pre>
  
  <p>Thanks heaps :-)</p>