# encoding: ascii
# api: powershell
# title: Find-FolderUniqueID
# description: Finds exchange mailbox folder unique ID for use with Exchange Web Service Managed API.  At times you may want to work with a folder that is NOT a well known folder (Inbox,Sent Items, etc).  This will get you the unique ID required to bind to that folder.
# version: 0.1
# type: function
# author: Chad C
# license: CC0
# function: Find-FolderUniqueID
# x-poshcode-id: 5919
# x-archived: 2016-10-27T12:28:38
# x-published: 2016-07-06T23:21:00
#
# Requires Exchange Web Service Managed API Libraries.
# Requires Exchange Environment.
#
function Find-FolderUniqueID
{
       
       <#
       .SYNOPSIS
              Find exchange folder unique ID for use in Exchange Web Service Managed API
       
       .EXAMPLE
              Find-FolderUniqueID -MailBox "joeschmoe@exchange.com" -FolderName "Special_Folder"

       .EXAMPLE
              Find-FolderUniqueID -Mailbox "joeschmoe@exchange.com" -FolderName "Special_Folder" -ExchangeVersion Exchange2013

       .EXAMPLE
              Find-FolderUniqueID -Mailbox "joeschmoe@exchange.com" -FolderName "Special_Folder" -AlternateCreds | Format-List *

       .PARAMETER MailBox
              Specify Mailbox you want to connect to.
       
       .PARAMETER FolderName
              Specify folder name to search for.
       
       .PARAMETER AlternateCreds
              Specify alternate credentials.

       .PARAMETER ExchangeVersion
              Specify your exchange environment version.

        .NOTES
        Requires EWS Managed API libraries
        Requires Exchange Environment
              
        .LINK
            http://www.microsoft.com/en-us/download/details.aspx?id=35371
            https://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.exchangeversion(v=exchg.80).aspx
       #>
       
       [CmdletBinding()]
       [OutputType([psobject])]
       param
       (
              [Parameter(Mandatory = $true,
              ValueFromPipeline = $false)]
              [string]$MailBox,
              [Parameter(Mandatory = $true)]
              [string]$FolderName,
              [Parameter(Mandatory = $false)]
              [switch]$AlternateCreds,
              [Parameter(Mandatory = $false)]
              [ValidateSet('Exchange2007_SP1','Exchange2010','Exchange2010_SP1','Exchange2010_SP2','Exchange2013','Exchange2013_SP1')]
              [string]$ExchangeVersion = 'Exchange2010_SP2'
       )
       
       $ewsPath = "C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll"
       Add-Type -Path $ewsPath
       $ews = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList $ExchangeVersion
       
       if ($AlternateCreds)
       {
              $cred = (Get-Credential).GetNetworkCredential()
              $ews.Credentials = New-Object System.Net.NetworkCredential -ArgumentList $cred.UserName, $cred.Password, $cred.Domain
       }
       else
       {
              $ews.UseDefaultCredentials = $true
       }
       $ews.AutodiscoverUrl($MailBox)
       
       $view = New-Object Microsoft.Exchange.WebServices.Data.FolderView(100)
       $view.PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.Webservices.Data.BasePropertySet]::FirstClassProperties)
       $view.PropertySet.Add([Microsoft.Exchange.Webservices.Data.FolderSchema]::DisplayName)
       $view.Traversal = [Microsoft.Exchange.Webservices.Data.FolderTraversal]::Deep
       
       $folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot, "$MailBox")
       
       $findResults = $ews.FindFolders($folderid, $view)
       
       
       $output = @()
       
       foreach ($f in $findResults)
       {
              if ($f.DisplayName -match $FolderName)
              {
                     $data = @{
                           Mailbox = $MailBox
                           FolderName = $f.DisplayName
                           FolderID = $f.Id.UniqueId
                     }
                     $output += New-Object -TypeName PSObject -Property $data
                     
              }
       }
       
       $output
}
