Januar 6, 2025

PFmig-functions_onprem-only.ps1

# Authors: 
#   Alexander Zarenko, https://blog.zarenko.net
#   Glen Scales, https://github.com/gscales
#
# All functions originally created by Glen Scales
# Adapted for this use case by Alexander Zarenko
#
# Provided as-is, feel free to change and redistribute
# If you do, please include a short notice mentioning me (such as this).
#
# Use at you own risk!

function Get-PublicFolderItems{ 
    [CmdletBinding()] 
    param( 
    	[Parameter(Position=0, Mandatory=$true)] [string]$MailboxName,
		[Parameter(Position=1, Mandatory=$true)] [PSCredential]$Credentials,
		[Parameter(Position=2, Mandatory=$true)] [string]$PublicFolderPath,
		[Parameter(Position=3, Mandatory=$false)] [switch]$useImpersonation,
		[Parameter(Position=4, Mandatory=$false)] [string]$url,
        [string]$autodiscourl,
        [string]$targetMBX,
        [string]$parentpath,
        [string]$folderName,
        [string]$folderClass        
    )  
 	Begin
		 {

		if($useImpersonation.IsPresent)
		{
			$service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $MailboxName) 
		}        
        Get-PublicFolderRoutingHeader -service $service -Credentials $Credentials -MailboxName $MailboxName -Header "X-AnchorMailbox" -autodiscourl $autodiscourl
		$fldId = PublicFolderIdFromPath -FolderPath $PublicFolderPath  -SmtpAddress $MailboxName -service $Global:service -autodiscourl $autodiscourl
        $SubFolderId =  new-object Microsoft.Exchange.WebServices.Data.FolderId($fldId)
        
		#Define ItemView to retrive just 1000 Items    
		$ivItemView =  New-Object Microsoft.Exchange.WebServices.Data.ItemView(1000) 
		$ItemPropset= new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
		$ivItemView.PropertySet = $ItemPropset
		$fiItems = $null
        ############### Create folder in target mailbox
        Create-Folder -MailboxName $targetMBX -Credentials $Credentials -NewFolderName $folderName -ParentFolder $parentpath -FolderClass $folderClass
		$targetFolder = Get-FolderFromPath -FolderPath $PublicFolderPath -MailboxName $targetMBX -service $service
        if(-not ($DoNotCopyItems)){
            $totalprocessed=1
            do{
		        $fiItems = $service.FindItems($SubFolderId,$ivItemView)   
                $itemtotalcount=$fiItems.Items.Count
                $itemcount=1
                # load previous migration results
                if(Test-Path -Path .\$targetMBX.csv){
                    $alreadycopied = Import-Csv .\$targetMBX.csv -Encoding UTF8
                    Write-Host "Previous copy results imported" -ForegroundColor Cyan
                }
                else{
                    Write-Host "No file with previous copy results found" -ForegroundColor Yellow
                }
			    #
                Write-Host ("Found [" + $fiItems.Items.Count + "] items to copy.")
                # this is just for debugging purposes, feel free to ignore :)
                $copy="1"
                if($PSCmdlet.MyInvocation.BoundParameters["Debug"].IsPresent){$copy=Read-Host -Prompt "Enter 1 to copy or nothing to skip copying."}
                if($copy -eq "1"){
                    $wp=$false #wp = write-progress
		            foreach($Item in $fiItems.Items){
                        # take care of items with no subject    
                        if($Item.Subject -eq $null){$itemSubject = "#no subject#"}
                        else{$itemSubject = $Item.Subject}
                        Write-Host "Copying item [$itemSubject] to folder [$($targetFolder.DisplayName)] in MBX [$targetMBX]. Total count: $totalprocessed / $($fiItems.Totalcount)" 
                        $progress = $itemcount / $itemtotalcount *100 ;
                        Write-Progress -Activity "$itemcount/$itemtotalcount - Copying items to MBX [$targetMBX]" -Status "$itemSubject" -PercentComplete $progress
                        $wp=$true
                        if(-not ($DoNotCopyItems)){
                            ## skip copying if flag is set
                            if($alreadycopied.UniqueId -notcontains $Item.Id){
                                ## only copy new items
                                $Item.Copy($targetFolder.Id)
                                $newitem = $null
                                $newitem=$item.Id
                                # append the previous results CSV file
                                $newitem | export-csv .\$targetMBX.csv -NoTypeInformation -Encoding UTF8 -Append
                            }
                            Else{
                                Write-Host "`tItem already copied, skipping..." -ForegroundColor DarkGray
                            }
                        }
                        $itemcount = $itemcount + 1
                        $totalprocessed = $totalprocessed + 1
		            }

                }    
		        $ivItemView.Offset += $fiItems.Items.Count    
		    }while($fiItems.MoreAvailable -eq $true)
        } 
        if($wp){
            Write-Progress -Activity "$itemcount/$itemtotalcount - Copying items to MBX [$targetMBX]" -Status "$itemSubject" -PercentComplete $progress -Completed
        }
	}
}

function Connect-Exchange{ 
    param( 
    	[Parameter(Position=0, Mandatory=$true)] [string]$MailboxName,
		[Parameter(Position=1, Mandatory=$true)] [System.Management.Automation.PSCredential]$Credentials,
		[Parameter(Position=2, Mandatory=$false)] [string]$url
    )  
 	Begin
		 {
		Load-EWSManagedAPI
		
		## Set Exchange Version  
		$ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2
		  
		## Create Exchange Service Object  
		$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($ExchangeVersion)  
		  
		## Set Credentials to use two options are availible Option1 to use explict credentials or Option 2 use the Default (logged On) credentials  
		  
		#Credentials Option 1 using UPN for the windows Account  
		#$psCred = Get-Credential  
		$creds = New-Object System.Net.NetworkCredential($Credentials.UserName.ToString(),$Credentials.GetNetworkCredential().password.ToString())  
		$service.Credentials = $creds      
		#Credentials Option 2  
		#service.UseDefaultCredentials = $true  
		 #$service.TraceEnabled = $true
		## Choose to ignore any SSL Warning issues caused by Self Signed Certificates  
		  
		Handle-SSL	
		  
		## Set the URL of the CAS (Client Access Server) to use two options are availbe to use Autodiscover to find the CAS URL or Hardcode the CAS to use  
		  
		#CAS URL Option 1 Autodiscover  
		if($url){
			$uri=[system.URI] $url
			$service.Url = $uri    
		}
		else{
			$service.AutodiscoverUrl($MailboxName,{$true})  
		}
		Write-Verbose ("Using CAS Server : " + $Service.url)   
		   
		#CAS URL Option 2 Hardcoded  
		  
		#$uri=[system.URI] "https://casservername/ews/exchange.asmx"  
		#$service.Url = $uri    
		  
		## Optional section for Exchange Impersonation  
		  
		#$service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $MailboxName) 
		if(!$service.URL){
			throw "Error connecting to EWS"
		}
		else
		{		
			return $service
		}
	}
}

function Load-EWSManagedAPI{
    param( 
    )  
 	Begin
	{
		## Load Managed API dll  
		###CHECK FOR EWS MANAGED API, IF PRESENT IMPORT THE HIGHEST VERSION EWS DLL, ELSE EXIT
		$EWSDLL = (($(Get-ItemProperty -ErrorAction SilentlyContinue -Path Registry::$(Get-ChildItem -ErrorAction SilentlyContinue -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Web Services'|Sort-Object Name -Descending| Select-Object -First 1 -ExpandProperty Name)).'Install Directory') + "Microsoft.Exchange.WebServices.dll")
		if (Test-Path $EWSDLL)
		    {
		    Import-Module $EWSDLL
		    }
		else
		    {
		    "$(get-date -format yyyyMMddHHmmss):"
		    "This script requires the EWS Managed API 1.2 or later."
		    "Please download and install the current version of the EWS Managed API from"
		    "http://go.microsoft.com/fwlink/?LinkId=255472"
		    ""
		    "Exiting Script."
		    exit
		    } 
  	}
}

function Handle-SSL{
    param( 
    )  
 	Begin
	{
		## Code From http://poshcode.org/624
		## Create a compilation environment
		$Provider=New-Object Microsoft.CSharp.CSharpCodeProvider
		$Compiler=$Provider.CreateCompiler()
		$Params=New-Object System.CodeDom.Compiler.CompilerParameters
		$Params.GenerateExecutable=$False
		$Params.GenerateInMemory=$True
		$Params.IncludeDebugInformation=$False
		$Params.ReferencedAssemblies.Add("System.DLL") | Out-Null

$TASource=@'
  namespace Local.ToolkitExtensions.Net.CertificatePolicy{
    public class TrustAll : System.Net.ICertificatePolicy {
      public TrustAll() { 
      }
      public bool CheckValidationResult(System.Net.ServicePoint sp,
        System.Security.Cryptography.X509Certificates.X509Certificate cert, 
        System.Net.WebRequest req, int problem) {
        return true;
      }
    }
  }
'@ 
		$TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource)
		$TAAssembly=$TAResults.CompiledAssembly

		## We now create an instance of the TrustAll and attach it to the ServicePointManager
		$TrustAll=$TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll")
		[System.Net.ServicePointManager]::CertificatePolicy=$TrustAll

		## end code from http://poshcode.org/624

	}
}

function PublicFolderIdFromPath{
	param (
            [Parameter(Position=0, Mandatory=$true)] [Microsoft.Exchange.WebServices.Data.ExchangeService]$service,
            [Parameter(Position=1, Mandatory=$true)] [String]$FolderPath,
            [Parameter(Position=2, Mandatory=$true)] [String]$SmtpAddress,
            [string]$autodiscourl
		  )
	process{
		## Find and Bind to Folder based on Path  
		#Define the path to search should be seperated with \  
		#Bind to the MSGFolder Root  
		$folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::PublicFoldersRoot)   
        $psPropset= new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
        $PR_REPLICA_LIST = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(0x6698,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Binary); 
        $psPropset.Add($PR_REPLICA_LIST)
		$tfTargetFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid,$psPropset)  
        $PR_REPLICA_LIST_Value = $null
        if($tfTargetFolder.TryGetProperty($PR_REPLICA_LIST,[ref]$PR_REPLICA_LIST_Value)){
                 $GuidAsString = [System.Text.Encoding]::ASCII.GetString($PR_REPLICA_LIST_Value, 0, 36);
                 $HeaderAddress = new-object System.Net.Mail.MailAddress($service.HttpHeaders["X-AnchorMailbox"])
                 $pfHeader = $GuidAsString + "@" + $HeaderAddress.Host
                 Write-Verbose ("Root Public Folder Routing Information Header : " + $pfHeader )  
                 if(-not $service.HttpHeaders."X-PublicFolderMailbox"){$service.HttpHeaders.Add("X-PublicFolderMailbox", $pfHeader)}
        }
		#Split the Search path into an array  
		$fldArray = $FolderPath.Split("\") 
		 #Loop through the Split Array and do a Search for each level of folder 
		for ($lint = 1; $lint -lt $fldArray.Length; $lint++) { 
	        #Perform search based on the displayname of each folder level 
	        $fvFolderView = new-object Microsoft.Exchange.WebServices.Data.FolderView(1) 
            $fvFolderView.PropertySet = $psPropset
	        $SfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.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{ 
	            "Error Folder Not Found"  
	            $tfTargetFolder = $null  
	            break  
	        }     
	    }  
		if($tfTargetFolder -ne $null){
            $PR_REPLICA_LIST_Value = $null
            if($tfTargetFolder.TryGetProperty($PR_REPLICA_LIST,[ref]$PR_REPLICA_LIST_Value)){
                    $GuidAsString = [System.Text.Encoding]::ASCII.GetString($PR_REPLICA_LIST_Value, 0, 36);
                    $HeaderAddress = new-object System.Net.Mail.MailAddress($service.HttpHeaders["X-AnchorMailbox"])
                    $pfHeader = $GuidAsString + "@" + $HeaderAddress.Host
                    Write-Verbose ("Target Public Folder Routing Information Header : " + $pfHeader )  
                    Get-PublicFolderContentRoutingHeader -service $global:service -Credentials $Credentials -MailboxName $SmtpAddress -pfAddress $pfHeader -autodiscourl $autodiscourl
            }            
			return $tfTargetFolder.Id.UniqueId.ToString()
		}
		else{
			throw "Folder not found"
		}
	}
}

function Get-PublicFolderRoutingHeader{
    param (
	        [Parameter(Position=0, Mandatory=$true)] [Microsoft.Exchange.WebServices.Data.ExchangeService]$service,
            [Parameter(Position=1, Mandatory=$true)] [PSCredential]$Credentials,
		    [Parameter(Position=2, Mandatory=$true)] [string]$MailboxName,
            [Parameter(Position=3, Mandatory=$true)] [string]$Header,
            [string]$autodiscourl
          )
	process
    {
        $ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013_SP1
        $AutoDiscoverService =  New-Object  Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverService($ExchangeVersion);
        $creds = New-Object System.Net.NetworkCredential($Credentials.UserName.ToString(),$Credentials.GetNetworkCredential().password.ToString()) 
        $AutoDiscoverService.Credentials = $creds
        $AutoDiscoverService.EnableScpLookup = $false;
        $AutoDiscoverService.RedirectionUrlValidationCallback = {$true};
        $AutoDiscoverService.PreAuthenticate = $true;
        $AutoDiscoverService.KeepAlive = $false;    
        if($autodiscourl){$AutoDiscoverService.Url = $autodiscourl}
        if($Header -eq "X-AnchorMailbox")
        {
            $gsp = $AutoDiscoverService.GetUserSettings($MailboxName,[Microsoft.Exchange.WebServices.Autodiscover.UserSettingName]::PublicFolderInformation);
            $PublicFolderInformation = $null
            if ($gsp.Settings.TryGetValue([Microsoft.Exchange.WebServices.Autodiscover.UserSettingName]::PublicFolderInformation, [ref] $PublicFolderInformation))
            {
                Write-Verbose ("Public Folder Routing Information Header : " + $PublicFolderInformation)  
                if(-not $service.HttpHeaders.$Header){$service.HttpHeaders.Add($Header, $PublicFolderInformation)}
                        
            } 
            
        }

       
    }
    
}

function Get-PublicFolderContentRoutingHeader{

    param (
	        [Parameter(Position=0, Mandatory=$true)] [Microsoft.Exchange.WebServices.Data.ExchangeService]$service,
            [Parameter(Position=1, Mandatory=$true)] [PSCredential]$Credentials,
		    [Parameter(Position=2, Mandatory=$true)] [string]$MailboxName,
            [Parameter(Position=3, Mandatory=$true)] [string]$pfAddress,
            [string]$autodiscourl
     )
	process
    {
        $ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013_SP1
        $AutoDiscoverService =  New-Object  Microsoft.Exchange.WebServices.Autodiscover.AutodiscoverService($ExchangeVersion);
        $creds = New-Object System.Net.NetworkCredential($Credentials.UserName.ToString(),$Credentials.GetNetworkCredential().password.ToString()) 
        $AutoDiscoverService.Credentials = $creds
        $AutoDiscoverService.EnableScpLookup = $false;
        $AutoDiscoverService.RedirectionUrlValidationCallback = {$true};
        $AutoDiscoverService.PreAuthenticate = $true;
        $AutoDiscoverService.KeepAlive = $false;      
        if($autodiscourl){$AutoDiscoverService.Url = $autodiscourl}
        $gsp = $AutoDiscoverService.GetUserSettings($MailboxName,[Microsoft.Exchange.WebServices.Autodiscover.UserSettingName]::AutoDiscoverSMTPAddress);
        #Write-Host $AutoDiscoverService.url
        $auDisXML = "<Autodiscover xmlns=`"http://schemas.microsoft.com/exchange/autodiscover/outlook/requestschema/2006`"><Request>`r`n" +
        "<EMailAddress>" + $pfAddress + "</EMailAddress>`r`n" +
        "<AcceptableResponseSchema>http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a</AcceptableResponseSchema>`r`n" +
        "</Request>`r`n" +
        "</Autodiscover>`r`n";
        $AutoDiscoverRequest = [System.Net.HttpWebRequest]::Create($AutoDiscoverService.url.ToString().replace(".svc",".xml"));
        $bytes = [System.Text.Encoding]::UTF8.GetBytes($auDisXML);
        $AutoDiscoverRequest.ContentLength = $bytes.Length;
        $AutoDiscoverRequest.ContentType = "text/xml";
        $AutoDiscoverRequest.UserAgent = "Microsoft Office/16.0 (Windows NT 6.3; Microsoft Outlook 16.0.6001; Pro)";            
        $AutoDiscoverRequest.Headers.Add("Translate", "F");
        $AutoDiscoverRequest.Method = "POST";
        $AutoDiscoverRequest.Credentials = $creds;
        $RequestStream = $AutoDiscoverRequest.GetRequestStream();
        $RequestStream.Write($bytes, 0, $bytes.Length);
        $RequestStream.Close();
        $AutoDiscoverRequest.AllowAutoRedirect = $truee;
        $Response = $AutoDiscoverRequest.GetResponse().GetResponseStream()
        $sr = New-Object System.IO.StreamReader($Response)
        [XML]$xmlReposne = $sr.ReadToEnd()
        if($xmlReposne.Autodiscover.Response.User.AutoDiscoverSMTPAddress -ne $null)
        {
            Write-Verbose ("Public Folder Content Routing Information Header : " + $xmlReposne.Autodiscover.Response.User.AutoDiscoverSMTPAddress)  
            $service.HttpHeaders["X-AnchorMailbox"] = $xmlReposne.Autodiscover.Response.User.AutoDiscoverSMTPAddress    
            $service.HttpHeaders["X-PublicFolderMailbox"] = $xmlReposne.Autodiscover.Response.User.AutoDiscoverSMTPAddress              
        }
    }
}    

function Get-FolderFromPath{
	param (
			[Parameter(Position=0, Mandatory=$true)] [string]$FolderPath,
			[Parameter(Position=1, Mandatory=$true)] [string]$MailboxName,
			[Parameter(Position=2, Mandatory=$true)] [Microsoft.Exchange.WebServices.Data.ExchangeService]$service,
			[Parameter(Position=3, Mandatory=$false)] [Microsoft.Exchange.WebServices.Data.PropertySet]$PropertySet
		  )
	process{
        
		#Bind to the MSGFolder Root  
        $folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$MailboxName)   
		$tfTargetFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)  
		
        #Split the Search path into an array to get the folder names 
		$fldArray = $FolderPath.Split("\") 
		#Loop through the Split Array and do a Search for each level of folder 
		for ($lint = 1; $lint -lt $fldArray.Length; $lint++) { 
	        #Perform search based on the displayname of each folder level 
	        $fvFolderView = new-object Microsoft.Exchange.WebServices.Data.FolderView(1) 
			if(![string]::IsNullOrEmpty($PropertySet)){
				$fvFolderView.PropertySet = $PropertySet
			}
	        $SfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.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($FolderPath -eq "\"){$tfTargetFolder =  [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)}
		if($tfTargetFolder -ne $null){
			return [Microsoft.Exchange.WebServices.Data.Folder]$tfTargetFolder
		}
		else{
			throw ("Folder Not found")
		}
	}
}

function Create-Folder{
    param( 
    	[Parameter(Position=0, Mandatory=$true)] [string]$MailboxName,
		[Parameter(Position=1, Mandatory=$true)] [System.Management.Automation.PSCredential]$Credentials,
		[Parameter(Position=2, Mandatory=$true)] [String]$NewFolderName,
		[Parameter(Position=3, Mandatory=$false)] [String]$ParentFolder,
		[Parameter(Position=4, Mandatory=$false)] [String]$FolderClass,
		[Parameter(Position=5, Mandatory=$false)] [switch]$useImpersonation        
    )  
 	Begin
	 {
        $service = $Global:service

        if($useImpersonation.IsPresent){
	        $service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $MailboxName)
        }

		$NewFolder = new-object Microsoft.Exchange.WebServices.Data.Folder($service)  
		$NewFolder.DisplayName = $NewFolderName 
		if(([string]::IsNullOrEmpty($folderClass))){
			$NewFolder.FolderClass = "IPF.Note"
		}
		else{
			$NewFolder.FolderClass = $folderClass
		}
		$EWSParentFolder = $null
		if(([string]::IsNullOrEmpty($ParentFolder))){
			# Bind to the MsgFolderRoot folder  
			$folderid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$MailboxName)   
			$EWSParentFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
		}
		else{
            write-host "Check if the parent folder [$parentfolder] of folder [$NewFolderName] is present in MBX [$MailboxName]"
            ### use it as search base to verify if the tobecreated folder is already present
			$EWSParentFolder =  Get-FolderFromPath -MailboxName $MailboxName -service $service -FolderPath $ParentFolder
		}
		#Define Folder View - only want to return one object  
		$fvFolderView = new-object Microsoft.Exchange.WebServices.Data.FolderView(1)  
		#Define a Search folder that is going to do a search based on the DisplayName of the folder  
		$SfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,$NewFolderName)  
		#Do the Search  
		$findFolderResults = $service.FindFolders($EWSParentFolder.Id,$SfSearchFilter,$fvFolderView)  
		if ($findFolderResults.TotalCount -eq 0){  
		    Write-host ("Folder Doesn't Exist")  
			$NewFolder.Save($EWSParentFolder.Id)  
			Write-host -ForegroundColor Green ("Folder [$NewFolderName] Created")  
		}  
		else{  
		    Write-host -ForegroundColor DarkGray ("Folder [$NewFolderName] already exists.")  
		}				
	 }
}