ewsgui.psm1

$script:ModuleRoot = $PSScriptRoot
$script:ModuleVersion = (Import-PowerShellDataFile -Path "$($script:ModuleRoot)\EWSGui.psd1").ModuleVersion

# Detect whether at some level dotsourcing was enforced
$script:doDotSource = Get-PSFConfigValue -FullName EWSGui.Import.DoDotSource -Fallback $false
if ($EWSGui_dotsourcemodule) { $script:doDotSource = $true }

<#
Note on Resolve-Path:
All paths are sent through Resolve-Path/Resolve-PSFPath in order to convert them to the correct path separator.
This allows ignoring path separators throughout the import sequence, which could otherwise cause trouble depending on OS.
Resolve-Path can only be used for paths that already exist, Resolve-PSFPath can accept that the last leaf my not exist.
This is important when testing for paths.
#>


# Detect whether at some level loading individual module files, rather than the compiled module was enforced
$importIndividualFiles = Get-PSFConfigValue -FullName EWSGui.Import.IndividualFiles -Fallback $false
if ($EWSGui_importIndividualFiles) { $importIndividualFiles = $true }
if (Test-Path (Resolve-PSFPath -Path "$($script:ModuleRoot)\..\.git" -SingleItem -NewChild)) { $importIndividualFiles = $true }
if ("<was compiled>" -eq '<was not compiled>') { $importIndividualFiles = $true }
    
function Import-ModuleFile
{
    <#
        .SYNOPSIS
            Loads files into the module on module import.
         
        .DESCRIPTION
            This helper function is used during module initialization.
            It should always be dotsourced itself, in order to proper function.
             
            This provides a central location to react to files being imported, if later desired
         
        .PARAMETER Path
            The path to the file to load
         
        .EXAMPLE
            PS C:\> . Import-ModuleFile -File $function.FullName
     
            Imports the file stored in $function according to import policy
    #>

    [CmdletBinding()]
    Param (
        [string]
        $Path
    )
    
    $resolvedPath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($Path).ProviderPath
    if ($doDotSource) { . $resolvedPath }
    else { $ExecutionContext.InvokeCommand.InvokeScript($false, ([scriptblock]::Create([io.file]::ReadAllText($resolvedPath))), $null, $null) }
}

#region Load individual files
if ($importIndividualFiles)
{
    # Execute Preimport actions
    foreach ($path in (& "$ModuleRoot\internal\scripts\preimport.ps1")) {
        . Import-ModuleFile -Path $path
    }
    
    # Import all internal functions
    foreach ($function in (Get-ChildItem "$ModuleRoot\internal\functions" -Filter "*.ps1" -Recurse -ErrorAction Ignore))
    {
        . Import-ModuleFile -Path $function.FullName
    }
    
    # Import all public functions
    foreach ($function in (Get-ChildItem "$ModuleRoot\functions" -Filter "*.ps1" -Recurse -ErrorAction Ignore))
    {
        . Import-ModuleFile -Path $function.FullName
    }
    
    # Execute Postimport actions
    foreach ($path in (& "$ModuleRoot\internal\scripts\postimport.ps1")) {
        . Import-ModuleFile -Path $path
    }
    
    # End it here, do not load compiled code below
    return
}
#endregion Load individual files

#region Load compiled code
<#
This file loads the strings documents from the respective language folders.
This allows localizing messages and errors.
Load psd1 language files for each language you wish to support.
Partial translations are acceptable - when missing a current language message,
it will fallback to English or another available language.
#>

Import-PSFLocalizedString -Path "$($script:ModuleRoot)\en-us\*.psd1" -Module 'EWSGui' -Language 'en-US'

Function Connect-EWSService {
    <#
    .SYNOPSIS
    Function to Create service object and authenticate the user.
     
    .DESCRIPTION
    This function will create the service object.
    Will opt to the user to select connection either to On-premises or Exchange Online.
        Will use basic auth to connect to on-premises. Endpoint will be discovered using Autodiscover.
        Will use modern auth to connect to Exchange Online. Endpoint is hard-coded to EXO EWS URL.
     
    .EXAMPLE
    PS C:\> Connect-EWSService
    Creates service object and authenticate the user.
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidGlobalVars", "")]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments", "")]
    [Cmdletbinding()]
    param(
        # Parameters
    )
    # Choosing if connection is to Office 365 or an Exchange on-premises
    $PremiseForm.Controls.Add($radiobutton1)
    $PremiseForm.Controls.Add($radiobutton2)
    $PremiseForm.Controls.Add($radiobutton3)
    $PremiseForm.ClientSize = New-Object System.Drawing.Size(250, 160)
    $PremiseForm.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $PremiseForm.Name = "form1"
    $PremiseForm.Text = "Choose your Exchange version"
    #
    # radiobutton1
    #
    $radiobutton1.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton1.Location = New-Object System.Drawing.Point(20, 20)
    $radiobutton1.Size = New-Object System.Drawing.Size(150, 25)
    $radiobutton1.TabStop = $True
    $radiobutton1.Text = "Exchange 2010"
    $radioButton1.Checked = $true
    $radiobutton1.UseVisualStyleBackColor = $True
    #
    # radiobutton2
    #
    $radiobutton2.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton2.Location = New-Object System.Drawing.Point(20, 55)
    $radiobutton2.Size = New-Object System.Drawing.Size(150, 30)
    $radiobutton2.TabStop = $True
    $radiobutton2.Text = "Exchange 2013/2016/2019"
    $radioButton2.Checked = $false
    $radiobutton2.UseVisualStyleBackColor = $True
    #
    # radiobutton3
    #
    $radiobutton3.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton3.Location = New-Object System.Drawing.Point(20, 95)
    $radiobutton3.Size = New-Object System.Drawing.Size(150, 25)
    $radiobutton3.TabStop = $True
    $radiobutton3.Text = "Office365"
    $radiobutton3.Checked = $false
    $radiobutton3.UseVisualStyleBackColor = $True

    #"Go" button
    $buttonGo.DataBindings.DefaultDataSourceUpdateMode = 0
    $buttonGo.ForeColor = [System.Drawing.Color]::FromArgb(255, 0, 0, 0)
    $System_Drawing_Point = New-Object System.Drawing.Point
    $System_Drawing_Point.X = 170
    $System_Drawing_Point.Y = 20
    $buttonGo.Location = $System_Drawing_Point
    $buttonGo.Name = "Go"
    $System_Drawing_Size = New-Object System.Drawing.Size
    $System_Drawing_Size.Height = 25
    $System_Drawing_Size.Width = 50
    $buttonGo.Size = $System_Drawing_Size
    $buttonGo.Text = "Go"
    $buttonGo.UseVisualStyleBackColor = $True
    $buttonGo.add_Click( {
            if ($radiobutton1.Checked) { $Global:option = "Exchange2010_SP2" }
            elseif ($radiobutton2.Checked) { $Global:option = "Exchange2013_SP1" }
            elseif ($radiobutton3.Checked) { $Global:option = "Exchange2016" }
            $PremiseForm.Hide()
        })
    $PremiseForm.Controls.Add($buttonGo)

    #"Exit" button
    $buttonExit.DataBindings.DefaultDataSourceUpdateMode = 0
    $buttonExit.ForeColor = [System.Drawing.Color]::FromArgb(255, 0, 0, 0)
    $System_Drawing_Point = New-Object System.Drawing.Point
    $System_Drawing_Point.X = 170
    $System_Drawing_Point.Y = 50
    $buttonExit.Location = $System_Drawing_Point
    $buttonExit.Name = "Exit"
    $System_Drawing_Size = New-Object System.Drawing.Size
    $System_Drawing_Size.Height = 25
    $System_Drawing_Size.Width = 50
    $buttonExit.Size = $System_Drawing_Size
    $buttonExit.Text = "Exit"
    $buttonExit.UseVisualStyleBackColor = $True
    $buttonExit.add_Click( { $PremiseForm.Close() ; $buttonExit.Dispose() })
    $PremiseForm.Controls.Add($buttonExit)

    #Show Form
    $PremiseForm.Add_Shown( { $PremiseForm.Activate() })
    $PremiseForm.ShowDialog() | Out-Null
    #exit if 'Exit' button is pushed
    if ($buttonExit.IsDisposed) { return }

    #creating service object
    $ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::$option
  $service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($ExchangeVersion)
 
    if ($radiobutton3.Checked) {
  #Getting oauth credentials
        ############################################################
        # PREVIOUS ADAL AUTHENTICATION FLOW
        <#
        if ( !(Get-Module AzureAD -ListAvailable) -and !(Get-Module AzureAD) ) {
            Install-Module AzureAD -Force -ErrorAction Stop
        }
        $Folderpath = (Get-Module azuread -ListAvailable | Sort-Object Version -Descending)[0].Path
        $path = join-path (split-path $Folderpath -parent) 'Microsoft.IdentityModel.Clients.ActiveDirectory.dll'
        Add-Type -Path $path
 
        $authenticationContext = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.AuthenticationContext("https://login.windows.net/common", $False)
        $platformParameters = New-Object Microsoft.IdentityModel.Clients.ActiveDirectory.PlatformParameters([Microsoft.IdentityModel.Clients.ActiveDirectory.PromptBehavior]::Always)
        $resourceUri = "https://outlook.office365.com"
        $AppId = "8799ab60-ace5-4bda-b31f-621c9f6668db"
        $redirectUri = New-Object Uri("http://localhost/code")
 
        Write-PSFMessage -Level Verbose -FunctionName "EWSGui" -Message "Looking in token cache"
        $authenticationResult = $authenticationContext.AcquireTokenSilentAsync($resourceUri, $AppId)
 
        while ($authenticationResult.IsCompleted -ne $true) { Start-Sleep -Milliseconds 500; Write-PSFMessage -Level Verbose -FunctionName "EWSGui" -Message "sleep" }
 
        # Check if we failed to get the token
        if (!($authenticationResult.IsFaulted -eq $false)) {
 
            Write-PSFMessage -Level Warning -Message "Acquire token silent failed"
            switch ($authenticationResult.Exception.InnerException.ErrorCode) {
                failed_to_acquire_token_silently {
                    # do nothing since we pretty much expect this to fail
                    Write-PSFMessage -Level Verbose -FunctionName "EWSGui" -Message "Cache miss, asking for credentials"
                    $authenticationResult = $authenticationContext.AcquireTokenAsync($resourceUri, $AppId, $redirectUri, $platformParameters)
 
                    while ($authenticationResult.IsCompleted -ne $true) { Start-Sleep -Milliseconds 500; Write-PSFMessage -Level Verbose -FunctionName "EWSGui" -Message "sleep" }
                }
                multiple_matching_tokens_detected {
                    # we could clear the cache here since we don't have a UPN, but we are just going to move on to prompting
                    Write-PSFMessage -Level Verbose -FunctionName "EWSGui" -Message "Multiple matching entries found, asking for credentials"
                    $authenticationResult = $authenticationContext.AcquireTokenAsync($resourceUri, $AppId, $redirectUri, $platformParameters)
 
                    while ($authenticationResult.IsCompleted -ne $true) { Start-Sleep -Milliseconds 500; Write-PSFMessage -Level Verbose -FunctionName "EWSGui" -Message "sleep" }
                }
                Default { Write-PSFMessage -Level Warning -Message "Unknown Token Error $authenticationResult.Exception.InnerException.ErrorCode" -ErrorRecord $_ }
            }
        }
        $Global:email = $authenticationResult.Result.UserInfo.DisplayableId
        $exchangeCredentials = New-Object Microsoft.Exchange.WebServices.Data.OAuthCredentials($authenticationResult.Result.AccessToken)
        $service.Url = New-Object Uri("https://outlook.office365.com/ews/exchange.asmx")
        #>

        ############################################################
        # NEW MSAL AUTHENTICATION FLOW
        $AppId = "8799ab60-ace5-4bda-b31f-621c9f6668db"
        $pcaOptions = [Microsoft.Identity.Client.PublicClientApplicationOptions]::new()
        $pcaOptions.ClientId = $AppId
        $pcaOptions.RedirectUri = "http://localhost/code"
        $pcaBuilder = [Microsoft.Identity.Client.PublicClientApplicationBuilder]::CreateWithApplicationOptions($pcaOptions)
        $pca = $pcaBuilder.Build()
        $scopes = New-Object System.Collections.Generic.List[string]
        $scopes.Add("https://outlook.office365.com/.default")
        #$scopes.Add("https://outlook.office.com/EWS.AccessAsUser.All")
        $authResult = $pca.AcquireTokenInteractive($scopes)
        $token = $authResult.ExecuteAsync()
        $exchangeCredentials = New-Object Microsoft.Exchange.WebServices.Data.OAuthCredentials($Token.Result.AccessToken)
        $Global:email = $Token.Result.Account.Username
        $service.Url = New-Object Uri("https://outlook.office365.com/ews/exchange.asmx")
    }
    else {
        $psCred = Get-Credential -Message "Type your credentials or Administrator credentials"
        $Global:email = $psCred.UserName
        $exchangeCredentials = New-Object System.Net.NetworkCredential($psCred.UserName.ToString(),$psCred.GetNetworkCredential().password.ToString())
        # setting Autodiscover endpoint
        $service.EnableScpLookup = $True
        $service.AutodiscoverUrl($email,{$true})
    }
    $Service.Credentials = $exchangeCredentials

    return $service
}

Function Method10 {
    <#
    .SYNOPSIS
    Method to get user's Inbox Rules.
     
    .DESCRIPTION
    Method to get user's Inbox Rules.
     
    .EXAMPLE
    PS C:\> Method10
    Method to get user's Inbox Rules.
 
    #>

    [CmdletBinding()]
    param(
        # Parameters
    )
    $statusBarLabel.text = "Running..."
    $txtBoxResults.Text = "This method is still under construction."
    $dgResults.Visible = $False
    $txtBoxResults.Visible = $True
    $PremiseForm.refresh()
    $statusBarLabel.text = "Ready..."
    
    <#
    $rules = $service.GetInboxRules()
    $array = New-Object System.Collections.ArrayList
    foreach ( $rule in $rules )
    {
        $output = $rule | select DisplayName, Conditions, Actions, Exceptions
        $array.Add($output)
    }
    $dgResults.datasource = $array
    $dgResults.AutoResizeColumns()
    $dgResults.Visible = $True
    $txtBoxResults.Visible = $False
    $PremiseForm.refresh()
    $statusBarLabel.text = "Ready..."
    Write-PSFMessage -Level Host -Message "Task finished succesfully" -FunctionName "Method 10"
    #>

}

Function Method11 {
    <#
    .SYNOPSIS
    Method to get user's OOF Settings.
     
    .DESCRIPTION
    Method to get user's OOF Settings.
     
    .EXAMPLE
    PS C:\> Method11
    Method to get user's OOF Settings.
 
    #>

    [CmdletBinding()]
    param(
        # Parameters
    )
    $statusBarLabel.text = "Running..."
    $array = New-Object System.Collections.ArrayList
    $output = $service.GetUserOofSettings($email) | Select-Object `
        State, `
        ExternalAudience, `
        @{ Name = "StartTime" ; Expression = { $service.GetUserOofSettings($email).Duration.StartTime.ToString() } }, `
        @{ Name = "EndTime" ; Expression = { $service.GetUserOofSettings($email).Duration.EndTime.ToString() } }, `
        @{ Name = "InternalReply" ; Expression = { $service.GetUserOofSettings($email).InternalReply.Message } }, `
        @{ Name = "ExternalReply" ; Expression = { $service.GetUserOofSettings($email).ExternalReply.Message } }, `
        AllowExternalOof
    $array.Add($output)

    $dgResults.datasource = $array
    $dgResults.AutoResizeColumns()
    $dgResults.Visible = $True
    $txtBoxResults.Visible = $False
    $PremiseForm.refresh()
    $statusBarLabel.text = "Ready..."
    Write-PSFMessage -Level Host -Message "Task finished succesfully" -FunctionName "Method 11"
}

Function Method12 {
    <#
    .SYNOPSIS
    Method to move items between folders.
     
    .DESCRIPTION
    Method to move items between folders by using FolderID values.
     
    .EXAMPLE
    PS C:\> Method12
    Method to move items between folders.
 
    #>

    [CmdletBinding()]
    param(
        # Parameters
    )
    $statusBarLabel.text = "Running..."
    if ( $txtBoxFolderID.Text -ne "")
    {
        # Creating Filter variables
        $FolderID = new-object Microsoft.Exchange.WebServices.Data.FolderId($txtBoxFolderID.Text)
        $Folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$FolderID)
        $TargetFolderId = new-object Microsoft.Exchange.WebServices.Data.FolderId($txtBoxTargetFolderID.Text)
        $StartDate = $FromDatePicker.Value
        $EndDate = $ToDatePicker.Value
        $MsgSubject = $txtBoxSubject.text
        [int]$i = 0

        # Combining Filters into a single Collection
        $filters = @()
        if ( $MsgSubject -ne "" )
        {
            $Filter1 = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+ContainsSubstring([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::Subject,$MsgSubject, [Microsoft.Exchange.WebServices.Data.ContainmentMode]::ExactPhrase, [Microsoft.Exchange.WebServices.Data.ComparisonMode]::IgnoreCase)
            $filters += $Filter1
        }
        if ( $StartDate -ne "" )
        {
            $Filter2 = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsGreaterThanOrEqualTo([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived,[DateTime]$StartDate)
            $filters += $Filter2
        }
        if ( $EndDate -ne "" )
        {
            $Filter3 = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsLessThanOrEqualTo([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived,[DateTime]$EndDate)
            $filters += $Filter3
        }

        $searchFilter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::AND,$filters)

        if ( $filters.Length -eq 0 )
        {
            $searchFilter = $Null
        }

        $ivItemView =  New-Object Microsoft.Exchange.WebServices.Data.ItemView(250)
        $fiItems = $null
        $array = New-Object System.Collections.ArrayList
        do{
            $fiItems = $service.FindItems($Folder.Id, $searchFilter, $ivItemView)
            foreach ( $Item in $fiItems.Items )
            {
                $i++
                $output = $Item | Select-Object @{Name="Action";Expression={"Moving Item"}}, DateTimeReceived, Subject
                $array.Add($output)
                $tempItem = [Microsoft.Exchange.WebServices.Data.Item]::Bind($service,$Item.Id)
                $tempItem.Move($TargetFolderId) | Out-Null
            }
            $ivItemView.Offset += $fiItems.Items.Count
            Start-Sleep -Milliseconds 500
        } while ( $fiItems.MoreAvailable -eq $true )
        $dgResults.datasource = $array
        $dgResults.AutoResizeColumns()
        $dgResults.Visible = $True
        $txtBoxResults.Visible = $False
        $PremiseForm.refresh()
        $statusBarLabel.text = "Ready. Moved Items: $i"
        Write-PSFMessage -Level Host -Message "Task finished succesfully" -FunctionName "Method 12"
    }
    else
    {
        [Microsoft.VisualBasic.Interaction]::MsgBox("FolderID textbox is empty. Check and try again",[Microsoft.VisualBasic.MsgBoxStyle]::Okonly,"Information Message")
        $statusBarLabel.text = "Process finished with warnings/errors"
    }
}

Function Method13 {
    <#
    .SYNOPSIS
    Method to Delete a subset of items in a folder.
     
    .DESCRIPTION
    Method to Delete a subset of items in a folder using Date Filters and/or subject.
     
    .EXAMPLE
    PS C:\> Method13
    Method to Delete a subset of items in a folder.
 
    #>

    [CmdletBinding()]
    param(
        # Parameters
    )
    $statusBarLabel.text = "Running..."
    if ( $txtBoxFolderID.Text -ne "" )
    {
        # Creating Filter variables
        $FolderID = new-object Microsoft.Exchange.WebServices.Data.FolderId($txtBoxFolderID.Text)
        $Folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$FolderID)
        $StartDate = $FromDatePicker.Value
  $EndDate = $ToDatePicker.Value
  $MsgSubject = $txtBoxSubject.text
        [int]$i = 0
        
        # Combining Filters into a single Collection
        $filters = @()
        if ( $MsgSubject -ne "" )
        {
            $Filter1 = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+ContainsSubstring([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::Subject,$MsgSubject, [Microsoft.Exchange.WebServices.Data.ContainmentMode]::ExactPhrase, [Microsoft.Exchange.WebServices.Data.ComparisonMode]::IgnoreCase)
            $filters += $Filter1
        }
        if ( $StartDate -ne "" )
        {
            $Filter2 = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsGreaterThanOrEqualTo([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived,[DateTime]$StartDate)
            $filters += $Filter2
        }
        if ( $EndDate -ne "" )
        {
            $Filter3 = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsLessThanOrEqualTo([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived,[DateTime]$EndDate)
            $filters += $Filter3
        }

        $searchFilter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::AND,$filters)

        if ( $filters.Length -eq 0 )
        {
            $searchFilter = $Null
        }

        $ivItemView =  New-Object Microsoft.Exchange.WebServices.Data.ItemView(250)
  $fiItems = $null

        $array = New-Object System.Collections.ArrayList
        do {
            $fiItems = $service.FindItems($Folder.Id, $searchFilter, $ivItemView)
            foreach ( $Item in $fiItems.Items )
            {
                $i++
                $output = $Item | Select-Object @{Name="Action";Expression={"Deleting Item"}}, DateTimeReceived, Subject
                $array.Add($output)
            
                $tempItem = [Microsoft.Exchange.WebServices.Data.Item]::Bind($service,$Item.Id)
                $tempItem.Delete($ComboOption, $True)
            }
            $ivItemView.Offset += $fiItems.Items.Count
            Start-Sleep -Milliseconds 500
        } while ( $fiItems.MoreAvailable -eq $true )
        $dgResults.datasource = $array
        $dgResults.AutoResizeColumns()
        $dgResults.Visible = $True
        $txtBoxResults.Visible = $False
        $PremiseForm.refresh()
        $statusBarLabel.text = "Ready. Deleted items: $i"
        Write-PSFMessage -Level Host -Message "Task finished succesfully" -FunctionName "Method 13"
    }
    else
    {
        [Microsoft.VisualBasic.Interaction]::MsgBox("FolderID textbox is empty. Check and try again",[Microsoft.VisualBasic.MsgBoxStyle]::Okonly,"Information Message")
        $statusBarLabel.text = "Process finished with warnings/errors"
    }
}

Function Method14 {
    <#
    .SYNOPSIS
    Get user's Delegates information
     
    .DESCRIPTION
    Get user's Delegates information
     
    .EXAMPLE
    PS C:\> Method14
    Get user's Delegates information
 
    #>

    [CmdletBinding()]
    param(
        # Parameters
    )
    $statusBarLabel.text = "Running..."
    # Create a mailbox object that represents the user in case we are impersonating.
    $mailbox = New-Object Microsoft.Exchange.WebServices.Data.Mailbox($email);
    # Call the GetDelegates method to get the delegates of the mailbox object.
    $delegates = $service.GetDelegates($mailbox , $true)
    $Collection = @()
    foreach( $Delegate in $delegates.DelegateUserResponses )
    {
        $Obj = "" | Select-Object EmailAddress,Inbox,Calendar,Contacts,Tasks,Notes,Journal,MeetingMessages,ViewPrivateItems
        $Obj.EmailAddress = $Delegate.DelegateUser.UserId.PrimarySmtpAddress
        $Obj.Inbox = $Delegate.DelegateUser.Permissions.InboxFolderPermissionLevel
        $Obj.Calendar = $Delegate.DelegateUser.Permissions.CalendarFolderPermissionLevel
        $Obj.Contacts = $Delegate.DelegateUser.Permissions.ContactsFolderPermissionLevel
        $Obj.Tasks = $Delegate.DelegateUser.Permissions.TasksFolderPermissionLevel
        $Obj.Notes = $Delegate.DelegateUser.Permissions.NotesFolderPermissionLevel
        $Obj.Journal = $Delegate.DelegateUser.Permissions.JournalFolderPermissionLevel
        $Obj.ViewPrivateItems = $Delegate.DelegateUser.ViewPrivateItems
        $Obj.MeetingMessages = $Delegate.DelegateUser.ReceiveCopiesOfMeetingMessages
        $Collection += $Obj
    }
    $array = New-Object System.Collections.ArrayList
    [int]$i = 0
    foreach ( $Del in $Collection )
    {
        $i++
        $output = $Del | Select-Object EmailAddress, Inbox, Calendar, Tasks, Notes, Journal, ViewPrivateItems, MeetingMessages
        $array.Add($output)
    }
    $dgResults.datasource = $array
    $dgResults.AutoResizeColumns()
    $dgResults.Visible = $True
    $txtBoxResults.Visible = $False
    $PremiseForm.refresh()
    $statusBarLabel.text = "Ready. Amount of Delegates: $i"
    Write-PSFMessage -Level Host -Message "Task finished succesfully" -FunctionName "Method 14"
}

Function Method15 {
    <#
    .SYNOPSIS
    Method to change sensitivity to items in a folder.
     
    .DESCRIPTION
    Method to change sensitivity to items in a folder.
     
    .EXAMPLE
    PS C:\> Method15
    Method to change sensitivity to items in a folder.
 
    #>

    [CmdletBinding()]
    param(
        # Parameters
    )
    $statusBarLabel.text = "Running..."
    if ( $txtBoxFolderID.Text -ne "" )
    {
        # Creating Filter variables
        $FolderID = new-object Microsoft.Exchange.WebServices.Data.FolderId($txtBoxFolderID.Text)
        $Folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$FolderID)
        $StartDate = $FromDatePicker.Value
  $EndDate = $ToDatePicker.Value
  $MsgSubject = $txtBoxSubject.text
        [int]$i = 0

        # Combining Filters into a single Collection
        $filters = @()
        if ( $MsgSubject -ne "" )
        {
            $Filter1 = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+ContainsSubstring([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::Subject,$MsgSubject, [Microsoft.Exchange.WebServices.Data.ContainmentMode]::ExactPhrase, [Microsoft.Exchange.WebServices.Data.ComparisonMode]::IgnoreCase)
            $filters += $Filter1
        }
        if ( $StartDate -ne "" )
        {
            $Filter2 = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsGreaterThanOrEqualTo([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived,[DateTime]$StartDate)
            $filters += $Filter2
        }
        if ( $EndDate -ne "" )
        {
            $Filter3 = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsLessThanOrEqualTo([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived,[DateTime]$EndDate)
            $filters += $Filter3
        }
        $searchFilter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::AND,$filters)

        if ( $filters.Length -eq 0 )
        {
            $searchFilter = $Null
        }

        $ivItemView =  New-Object Microsoft.Exchange.WebServices.Data.ItemView(250)
        $fiItems = $null
        $array = New-Object System.Collections.ArrayList
        do {
            $fiItems = $service.FindItems($Folder.Id, $searchFilter, $ivItemView)
            foreach ( $Item in $fiItems.Items )
            {
                $i++
                $output = $Item | Select-Object @{Name="Action";Expression={"Applying Sensitivity" + $DeleteOpt}}, DateTimeReceived, Subject
                $array.Add($output)

                $tempItem = [Microsoft.Exchange.WebServices.Data.Item]::Bind($service,$Item.Id)
                $tempItem.Sensitivity = $DeleteOpt
                $tempItem.Update([Microsoft.Exchange.WebServices.Data.ConflictResolutionMode]::AlwaysOverwrite)
            }
            $ivItemView.Offset += $fiItems.Items.Count
            Start-Sleep -Milliseconds 500
        } while ( $fiItems.MoreAvailable -eq $true )
        $dgResults.datasource = $array
        $dgResults.AutoResizeColumns()
        $dgResults.Visible = $True
        $txtBoxResults.Visible = $False
        $PremiseForm.refresh()
        $statusBarLabel.text = "Ready. Items changed: $i"
        Write-PSFMessage -Level Host -Message "Task finished succesfully" -FunctionName "Method 15"
    }
    else
    {
        [Microsoft.VisualBasic.Interaction]::MsgBox("FolderID textbox is empty. Check and try again",[Microsoft.VisualBasic.MsgBoxStyle]::Okonly,"Information Message")
        $statusBarLabel.text = "Process finished with warnings/errors"
    }
}

Function Method16 {
    <#
    .SYNOPSIS
    Method to remove OWA configurations.
     
    .DESCRIPTION
    Method to remove OWA configurations.
     
    .EXAMPLE
    PS C:\> Method16
    Method to remove OWA configurations.
 
    #>

    [CmdletBinding()]
    param(
        # Parameters
    )
    $statusBarLabel.text = "Running..."
    $output = "Checking" + $ComboOption2
    $txtBoxResults.Text = $output
    $txtBoxResults.Visible = $True
    $PremiseForm.Refresh()

    $fid = $null
    if ( $ComboOption1 -eq "Root" )
    {
        $fid = New-Object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root, $email)
    }
    elseif ( $ComboOption1 -eq "Calendar" )
    {
        $fid = New-Object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar, $email)
    }
    elseif ( $ComboOption1 -eq "Inbox" )
    {
        $fid = New-Object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox, $email)
    }
    
    if ( $ComboOption2 -ne "CleanFinders" )
    {
        try
        {
            $Config = [Microsoft.Exchange.WebServices.Data.UserConfiguration]::Bind($Service, $ComboOption2, $fid, [Microsoft.Exchange.WebServices.Data.UserConfigurationProperties]::All)
            $Config.Delete();
            $output = $output + $nl + "Deleted $ComboOption2"
        }
        catch
        {
            $output = $output + $nl + "$ComboOption2 doesn't exist"
        }
        $statusBarLabel.text = "Ready..."
        Write-PSFMessage -Level Host -Message "Task finished succesfully" -FunctionName "Method 16"
        $txtBoxResults.Text = $output
        $txtBoxResults.Visible = $True
        $PremiseForm.Refresh()

    }
    else
    {
        # Creating folder object (SearchFolders also know as Finder)
        $folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::SearchFolders,$SmtpAddress)

        # Opening the bind to user Folder Finder
        $output = $output + $nl + "Opening Mailbox: $email"
        try
        {
            $finderFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($Service,$folderid)
            $output = $output + $nl + "Cleaning SearchFolder (same as Outlook /Cleanfinders)"

            # If the bind was created, clean the folder Finder
            Try
            {
                $finderFolder.Empty([Microsoft.Exchange.WebServices.Data.DeleteMode]::SoftDelete, $true)
                $output = $output + $nl + "The Cleanup process for the Mailbox: $email Succeed!"
            }
            catch
            {
                $output = $output + $nl + "Fail to clean Search folder Mailbox: $email"
            }
        }
        catch
        {
            $output = $output + $nl + "Fail to open Mailbox: $email"
        }
        $txtBoxResults.Text = $output
        $txtBoxResults.Visible = $True
        $statusBarLabel.text = "Ready..."
        Write-PSFMessage -Level Host -Message "Task finished succesfully" -FunctionName "Method 16"
        $PremiseForm.Refresh()

        #Cleaning Variables
        $SmtpAddress = $null
        $finderFolder = $null
        $folderid = $null
    }
}

Function Method17 {
    <#
    .SYNOPSIS
    Method to switch to another mailbox.
     
    .DESCRIPTION
    Method to switch to another mailbox.
     
    .EXAMPLE
    PS C:\> Method17
    Method to switch to another mailbox.
 
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidGlobalVars", "")]
    [CmdletBinding()]
    param(
        # Parameters
    )
    $statusBarLabel.text = "Running..."
    if ( $txtBoxFolderID.Text -ne "" )
    {
        $TargetSmtpAddress = $txtBoxFolderID.Text
        $service.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $TargetSmtpAddress)
        $service.HttpHeaders.Clear()
        $service.HttpHeaders.Add("X-AnchorMailbox", $TargetSmtpAddress)
        $Global:email = $TargetSmtpAddress

        $labImpersonation.Location = New-Object System.Drawing.Point(575,231)
        $labImpersonation.Size = New-Object System.Drawing.Size(250,20)
        $labImpersonation.Name = "labImpersonation"
        $labImpersonation.ForeColor = "Blue"
        $PremiseForm.Controls.Add($labImpersonation)
        $labImpersonation.Text = $Global:email
        $PremiseForm.Text = "Managing user: " + $Global:email + ". Choose your Option"

        Write-PSFMessage -Level Host -Message "Task finished succesfully" -FunctionName "Method 17"
        $statusBarLabel.text = "Ready..."
        $PremiseForm.Refresh()
    }
    else
    {
        [Microsoft.VisualBasic.Interaction]::MsgBox("Email Address textbox is empty. Check and try again",[Microsoft.VisualBasic.MsgBoxStyle]::Okonly,"Information Message")
        $statusBarLabel.text = "Process finished with warnings/errors"
    }
}

Function Method1to6 {
    <#
    .SYNOPSIS
    Method to list folders in the user mailbox.
     
    .DESCRIPTION
    Method to list folders in the user mailbox, showing Folder name, FolderId, Number of items, and number of subfolders.
     
    .EXAMPLE
    PS C:\> Method1to6
    lists folders in the user mailbox.
 
    #>

    [CmdletBinding()]
    param(
        # Parameters
    )
    $statusBarLabel.Text = "Running..."
        if($radiobutton1.Checked){$Wellknownfolder = "MsgFolderRoot"}
        elseif($radiobutton2.Checked){$Wellknownfolder = "ArchiveMsgFolderRoot"}
        elseif($radiobutton3.Checked){$Wellknownfolder = "PublicFoldersRoot"}
        elseif($radiobutton5.Checked){$Wellknownfolder = "RecoverableItemsRoot"}
        elseif($radiobutton6.Checked){$Wellknownfolder = "ArchiveRecoverableItemsRoot"}
        elseif($radiobutton4.Checked){$Wellknownfolder = $txtBoxFolderID.Text}

        #listing all available folders in the mailbox
        $FolderView = New-Object Microsoft.Exchange.WebServices.Data.FolderView(100)
        if($radiobutton4.Checked)
        {
            $sourceFolderId = new-object Microsoft.Exchange.WebServices.Data.FolderId($Wellknownfolder)
            $rootfolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$sourceFolderId)
        }
        else
        {
            $rootfolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service, [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::$Wellknownfolder)
        }
        
        $rootfolder.load()
        $array = New-Object System.Collections.ArrayList
        foreach ($folder in $rootfolder.FindFolders($FolderView) )
        {
            $i++
            $output = $folder | Select-Object DisplayName, @{N="TotalItemsCount";E={$_.TotalCount}}, @{N="# of Subfolders";E={$_.ChildFolderCount}},Id
            $array.Add($output)
            }
        $dgResults.datasource = $array
        $dgResults.AutoResizeColumns()
        $dgResults.Visible = $True
        $txtBoxResults.Visible = $False
        $PremiseForm.refresh()
        $statusBarLabel.Text = "Ready. Folders found: $i"
        Write-PSFMessage -Level Output -Message "Task finished succesfully" -FunctionName "Method 1-6"
}

Function Method7 {
    <#
    .SYNOPSIS
    Method to list items in a specific folders in the user mailbox.
     
    .DESCRIPTION
    Method to list items in a specific folders in the user mailbox.
     
    .EXAMPLE
    PS C:\> Method7
    Method to list items in a specific folders in the user mailbox.
 
    #>

    [CmdletBinding()]
    param(
        # Parameters
    )
    $statusBarLabel.Text = "Running..."
    if ( $txtBoxFolderID.Text -ne "" )
    {
        # Creating Filter variables
        $FolderID = new-object Microsoft.Exchange.WebServices.Data.FolderId($txtBoxFolderID.Text)
        $Folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$FolderID)
        $StartDate = $FromDatePicker.Value
        $EndDate = $ToDatePicker.Value
        $MsgSubject = $txtBoxSubject.text
        [int]$i=0

        # Combining Filters into a single Collection
        $filters = @()
        if ( $MsgSubject -ne "" )
        {
            $Filter1 = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+ContainsSubstring([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::Subject,$MsgSubject, [Microsoft.Exchange.WebServices.Data.ContainmentMode]::ExactPhrase, [Microsoft.Exchange.WebServices.Data.ComparisonMode]::IgnoreCase)
            $filters += $Filter1
        }
        if ( $StartDate -ne "" )
        {
            $Filter2 = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsGreaterThanOrEqualTo([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived,[DateTime]$StartDate)
            $filters += $Filter2
        }
        if ( $EndDate -ne "" )
        {
            $Filter3 = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsLessThanOrEqualTo([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived,[DateTime]$EndDate)
            $filters += $Filter3
        }

        $searchFilter = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection([Microsoft.Exchange.WebServices.Data.LogicalOperator]::AND,$filters)

        if ( $filters.Length -eq 0 )
        {
            $searchFilter = $Null
        }
 
        $ivItemView =  New-Object Microsoft.Exchange.WebServices.Data.ItemView(250)
 
        $fiItems = $null
        $array = New-Object System.Collections.ArrayList
        do {
            $fiItems = $service.FindItems($Folder.Id, $searchFilter, $ivItemView)
            foreach ( $Item in $fiItems.Items )
            {
                $i++
                $output = $Item | Select-Object Subject, Sender, DateTimeReceived, Size
                $array.Add($output)
            }
            $ivItemView.Offset += $fiItems.Items.Count
        } while ( $fiItems.MoreAvailable -eq $true )

        $dgResults.datasource = $array
        $dgResults.AutoResizeColumns()
        $dgResults.Visible = $True
        $txtBoxResults.Visible = $False
        $PremiseForm.refresh()
        $statusBarLabel.text = "Ready. Items found: $i"
        Write-PSFMessage -Level Output -Message "Task finished succesfully" -FunctionName "Method 7"
    }
    else
    {
        [Microsoft.VisualBasic.Interaction]::MsgBox("FolderID textbox is empty. Check and try again",[Microsoft.VisualBasic.MsgBoxStyle]::Okonly,"Information Message")
        $statusBarLabel.text = "Process finished with warnings/errors"
    }
}

Function Method8 {
    <#
    .SYNOPSIS
    Method to create a custom folder in mailbox's Root.
     
    .DESCRIPTION
    Method to create a custom folder in mailbox's Root.
     
    .EXAMPLE
    PS C:\> Method8
    Method to create a custom folder in mailbox's Root.
 
    #>

    [CmdletBinding()]
    param(
        # Parameters
    )
    if ( $txtBoxFolderID.Text -ne "" )
    {
        $statusBarLabel.text = "Running..."
        $folder = new-object Microsoft.Exchange.WebServices.Data.Folder($service)
        $folder.DisplayName = $txtBoxFolderID.Text
        $folder.Save([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot)

        Write-PSFMessage -Level Host -Message "Task finished succesfully. Folder Created: $($txtBoxFolderID.Text)" -FunctionName "Method 8"
        $statusBarLabel.text = "Ready..."
        $PremiseForm.Refresh()
    }
    else
    {
        [Microsoft.VisualBasic.Interaction]::MsgBox("FolderID textbox is empty. Check and try again",[Microsoft.VisualBasic.MsgBoxStyle]::Okonly,"Information Message")
        $statusBarLabel.text = "Method 8 finished with warnings/errors"
    }
}

Function Method9 {
    <#
    .SYNOPSIS
    Method to delete a specific folder in the user mailbox.
     
    .DESCRIPTION
    Method to delete a specific folder in the user mailbox with 3 different deletion methods.
     
    .EXAMPLE
    PS C:\> Method9
    Method to delete a specific folder in the user mailbox.
 
    #>

    [CmdletBinding()]
    param(
        # Parameters
    )
    $statusBarLabel.text = "Running..."
        if ( $txtBoxFolderID.Text -ne "" )
        {
            $sourceFolderId = new-object Microsoft.Exchange.WebServices.Data.FolderId($txtBoxFolderID.Text)
            $SourceFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$sourceFolderId)
            $sourceFolder.Delete($ComboOption)

            Write-PSFMessage -Level Host -Message "Task finished succesfully" -FunctionName "Method 9"
            $statusBarLabel.text = "Ready..."
            $PremiseForm.Refresh()
        }
        else
        {
            [Microsoft.VisualBasic.Interaction]::MsgBox("FolderID textbox is empty. Check and try again",[Microsoft.VisualBasic.MsgBoxStyle]::Okonly,"Information Message")
            $statusBarLabel.text = "Process finished with warnings/errors"
        }
}

Function Register-EWSGuiApp {
    <#
    .SYNOPSIS
    Registers EWS API Application into AzureAD
     
    .DESCRIPTION
    Registers EWS API Application into AzureAD and grant Admin consent on behalf of the Organization.
     
    .EXAMPLE
    PS C:\> Regiser-EWSGuiApp
    Registers EWS API Application into AzureAD
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments", "")]
    [Cmdletbinding()]
    param(
        # Parameters
    )
    Invoke-PSFProtectedCommand -Action "Connecting to AzureAD" -Target "AzureAD" -ScriptBlock {
        Write-PSFHostColor -String "[$((Get-Date).ToString("HH:mm:ss"))] Connecting to AzureAD"
        if ( !(Get-Module AzureAD -ListAvailable) -and !(Get-Module AzureAD) ) {
            Install-Module AzureAD -Force -ErrorAction Stop
        }
        try {
            Import-module AzureAD
            Write-PSFHostColor -String "[$((Get-Date).ToString("HH:mm:ss"))] We will connect to AzureAD to allow this app to connect to your tenant using OAUTH"
            $ConnStatus = Connect-AzureAD -ErrorAction Stop
        }
        catch {
            return $_
        }
    } -EnableException $true -PSCmdlet $PSCmdlet

    # register "PowerShellEWSScripts" as Enterprise App, by creating servicePrincipal (if not created)
    Write-PSFHostColor -String "[$((Get-Date).ToString("HH:mm:ss"))] Register `"PowerShellEWSScripts`" as Enterprise App, by creating servicePrincipal (if not created)"
    if ( $null -eq ( Get-AzureADServicePrincipal -All:$True | Where-object { $_.displayname -eq "PowerShellEWSScripts" } ) ) {
        $AzureADServicePrincipalParams = @{
            AccountEnabled            = $True
            AppId                     = "8799ab60-ace5-4bda-b31f-621c9f6668db"
            ServicePrincipalNames     = "8799ab60-ace5-4bda-b31f-621c9f6668db"
            AppRoleAssignmentRequired = $False
            DisplayName               = "PowerShellEWSScripts"
            PublisherName             = "Microsoft"
            ReplyUrls                 = "http://localhost/code"
            ServicePrincipalType      = "Application"
            Tags                      = "WindowsAzureActiveDirectoryIntegratedApp"
            ErrorAction               = "Stop"
        }
        $AppDetails = New-AzureADServicePrincipal @AzureADServicePrincipalParams
    }
    else {
        $AppDetails = Get-AzureADServicePrincipal -All:$True | Where-object { $_.displayname -eq "PowerShellEWSScripts" }
    }

    # register Service Principal Assignment between Global admin and the registered app:
    $AdminObjectId = (Get-AzureAdUser -Filter "userprincipalname eq '$($ConnStatus.Account.id)'").ObjectId
    if ( -not (Get-AzureADServiceAppRoleAssignment -ObjectId $AppDetails.ObjectId -All:$true | Where-Object { $_.PrincipalId -eq $AdminObjectId }) ) {
        $null = $appDetails | New-AzureADServiceAppRoleAssignment -PrincipalId $AdminObjectId -ResourceId $AppDetails.ObjectId -id "00000000-0000-0000-0000-000000000000" -ErrorAction Stop
    }

    # Grant consent to the App to access EXO and Windows Azure AD to sign in on behalf of the whole tenant (no user consent will be needed afterwards)
    Write-PSFHostColor -String "[$((Get-Date).ToString("HH:mm:ss"))] Grant consent to the App to access EXO and AzureAD to sign-in on behalf of the users"
    if ( -not (Get-AzureADServicePrincipalOAuth2PermissionGrant -ObjectId $AppDetails.ObjectId -All:$True | Where-Object { ($_.Scope -eq "User.Read" -and $_.ResourceID -eq "525065a3-df7d-474d-be08-90fa1d62d4bb") -or ($_.Scope -eq "EWS.AccessAsUser.All" -and $_.ResourceID -eq "8b951d63-7dd0-46e8-a326-15e3f6a26353") }) ) {
        $TenantId = (Get-AzureADTenantDetail).objectid
        $context = Get-AzContext
        $refreshToken = @($context.TokenCache.ReadItems() | Where-Object { $_.tenantId -eq $tenantId -and $_.ExpiresOn -gt (Get-Date) })[0].RefreshToken
        $body = "grant_type=refresh_token&refresh_token=$($refreshToken)&resource=74658136-14ec-4630-ad9b-26e160ff0fc6"
        $apiToken = Invoke-RestMethod "https://login.windows.net/$tenantId/oauth2/token" -Method POST -Body $body -ContentType 'application/x-www-form-urlencoded' -ErrorAction Stop
        $header = @{
            'Authorization'          = 'Bearer ' + $apiToken.access_token
            'X-Requested-With'       = 'XMLHttpRequest'
            'x-ms-client-request-id' = [guid]::NewGuid()
            'x-ms-correlation-id'    = [guid]::NewGuid()
        }
        $url = "https://main.iam.ad.ext.azure.com/api/RegisteredApplications/$($AppDetails.AppId)/Consent?onBehalfOfAll=true"
        Invoke-RestMethod â€“Uri $url â€“Headers $header â€“Method POST -ErrorAction Stop
    }
}

Function Start-ModuleUpdate {
    <#
    .SYNOPSIS
    Function to start checking for updates on this module.
     
    .DESCRIPTION
    Function to start checking for updates on this module.
     
    .PARAMETER ModuleRoot
    Modules root path.
 
    .PARAMETER Confirm
    If this switch is enabled, you will be prompted for confirmation before executing any operations that change state.
 
    .PARAMETER WhatIf
    If this switch is enabled, no actions are performed but informational messages will be displayed that explain what would happen if the command were to run.
     
    .EXAMPLE
    PS C:\> Start-ModuleUpdate -ModuleRoot "C:\Temp"
    Runs the function to start checking for update for current module in "C:\Temp"
    #>

    [CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Low')]
    Param (
        [String]$ModuleRoot
    )

    $ScriptBlock = {
        Param (
            [String]$ModuleRoot
        )
        $moduleManifest = (Import-PowerShellDataFile -Path "$((Get-ChildItem -Path $ModuleRoot -Filter *.psd1).Fullname)")
        $moduleFileName = $moduleManifest.RootModule
        $moduleName = $ModuleFileName.Substring(0, $ModuleFileName.IndexOf("."))
        $script:ModuleVersion = $moduleManifest.ModuleVersion -as [version]

        $GalleryModule = Find-Module -Name $ModuleName -Repository PSGallery
        if ( $script:ModuleVersion -lt $GalleryModule.version ) {
            $bt = New-BTButton -Content "Get Update" -Arguments "$($moduleManifest.PrivateData.PSData.ProjectUri)#installation"
            New-BurntToastNotification -Text "$ModuleName Update found", 'There is a new version of this module available.' -Button $bt
        }
    }

    # Create Runspace, set maximum threads
    $pool = [RunspaceFactory]::CreateRunspacePool(1, 1)
    $pool.ApartmentState = "MTA"
    $pool.Open()

    $runspace = [PowerShell]::Create()
    $runspace.Runspace.Name = "$ModuleName.Update"
    $null = $runspace.AddScript( $ScriptBlock )
    $null = $runspace.AddArgument( $ModuleRoot )
    $runspace.RunspacePool = $pool

    [PSCustomObject]@{
        Pipe   = $runspace
        Status = $runspace.BeginInvoke()
        Pool   = $pool
    }
}

Function Stop-ModuleUpdate {
    <#
    .SYNOPSIS
    Function to stop checking for updates on this module and clear runspaces.
     
    .DESCRIPTION
    Function to stop checking for updates on this module and clear runspaces.
     
    .PARAMETER RunspaceData
    Runspace data retrieved from intial Start-ModuleUpdate function.
 
    .PARAMETER Confirm
    If this switch is enabled, you will be prompted for confirmation before executing any operations that change state.
 
    .PARAMETER WhatIf
    If this switch is enabled, no actions are performed but informational messages will be displayed that explain what would happen if the command were to run.
     
    .EXAMPLE
    PS C:\> Stop-ModuleUpdate -RunspaceData $data
    Runs the function to stop checking for update on this module and clear runspaces.
    #>

    [CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Low')]
    Param(
        $RunspaceData
    )
    # Receive Results and cleanup
    $null = $RunspaceData.Pipe.EndInvoke($RunspaceData.Status)
    $RunspaceData.Pipe.Dispose()

    # Cleanup Runspace Pool
    $RunspaceData.pool.Close()
    $RunspaceData.pool.Dispose()
}

Function Start-EWSGui {
    <#
    .SYNOPSIS
        Allows to perform 16 different operations using EWS API.
 
    .DESCRIPTION
        Allows to perform 16 different operations using EWS API:
        1) List Folders in Root
        2) List Folders in Archive Root
        3) List Folders in Public Folder Root
        4) List subFolders from a desired Parent Folder
        5) List folders in Recoverable Items Root folder
        6) List folders in Recoverable Items folder in Archive
        7) List Items in a desired Folder
        8) Create a custom Folder in Root
        9) Delete a Folder
        10) Get user's Inbox Rules
        11) Get user's OOF Settings
        12) Move items between folders
        13) Delete a subset of items in a folder
        14) Get user's Delegate information
        15) Change sensitivity to items in a folder
        16) Remove OWA configurations
        17) Switch to another Mailbox
     
    .PARAMETER Confirm
    If this switch is enabled, you will be prompted for confirmation before executing any operations that change state.
 
    .PARAMETER WhatIf
    If this switch is enabled, no actions are performed but informational messages will be displayed that explain what would happen if the command were to run.
 
    .EXAMPLE
    PS C:\ Start-Ewsgui.ps1
    Runs the GUI tool to use EWS with Exchange server and Online.
 
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidGlobalVars", "")]
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseDeclaredVarsMoreThanAssignments", "")]
    [CmdletBinding(SupportsShouldProcess = $True, ConfirmImpact = 'Low')]
    param(
        # Parameters
    )
    $script:nl = "`r`n"
    $ProgressPreference = "SilentlyContinue"

    $runspaceData = Start-ModuleUpdate -ModuleRoot $script:ModuleRoot
    function GenerateForm {
   
    #region Import the Assemblies
    Add-Type -AssemblyName System.Windows.Forms
    Add-Type -AssemblyName System.Drawing
    Add-Type -AssemblyName Microsoft.VisualBasic
    [System.Windows.Forms.Application]::EnableVisualStyles()
    #endregion
 
    #region Generated Form Objects
    $Global:PremiseForm = New-Object System.Windows.Forms.Form
    $Global:radiobutton1 = New-Object System.Windows.Forms.RadioButton
    $Global:radiobutton2 = New-Object System.Windows.Forms.RadioButton
    $Global:radiobutton3 = New-Object System.Windows.Forms.RadioButton
    $Global:radiobutton4 = New-Object System.Windows.Forms.RadioButton
    $Global:radiobutton5 = New-Object System.Windows.Forms.RadioButton
    $Global:radiobutton6 = New-Object System.Windows.Forms.RadioButton
    $Global:radiobutton7 = New-Object System.Windows.Forms.RadioButton
    $Global:radiobutton8 = New-Object System.Windows.Forms.RadioButton
    $Global:radiobutton9 = New-Object System.Windows.Forms.RadioButton
    $Global:radiobutton10 = New-Object System.Windows.Forms.RadioButton
    $Global:radiobutton11 = New-Object System.Windows.Forms.RadioButton
    $Global:radiobutton12 = New-Object System.Windows.Forms.RadioButton
    $Global:radiobutton13 = New-Object System.Windows.Forms.RadioButton
    $Global:radiobutton14 = New-Object System.Windows.Forms.RadioButton
    $Global:radiobutton15 = New-Object System.Windows.Forms.RadioButton
    $Global:radiobutton16 = New-Object System.Windows.Forms.RadioButton
    $Global:radiobutton17 = New-Object System.Windows.Forms.RadioButton
    $Global:labImpersonation = New-Object System.Windows.Forms.Label
    $labImpersonationHelp = New-Object System.Windows.Forms.Label
    $Global:buttonGo = New-Object System.Windows.Forms.Button
    $Global:buttonExit = New-Object System.Windows.Forms.Button

    $Global:dgResults = New-Object System.Windows.Forms.DataGridView
    $Global:txtBoxResults = New-Object System.Windows.Forms.Label
    $Global:InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState
    [String]$Global:email = $null
    #endregion Generated Form Objects

    # registering EWS API as an Enterprise App in Azure AD
    # Register-EWSGuiApp

    # Connecting to EWS and creating service object
    $service = Connect-EWSService

    $ExpandFilters = {
    # Removing all controls, in order to reload the screen appropiately for each selection
    $PremiseForm.Controls.RemoveByKey("FromDate")
    $PremiseForm.Controls.RemoveByKey("FromDatePicker")
    $PremiseForm.Controls.RemoveByKey("ToDate")
    $PremiseForm.Controls.RemoveByKey("ToDatePicker")
    $PremiseForm.Controls.RemoveByKey("labSubject")
    $PremiseForm.Controls.RemoveByKey("txtBoxSubject")
    $PremiseForm.Controls.RemoveByKey("labFolderID")
    $PremiseForm.Controls.RemoveByKey("txtBoxFolderID")
    $PremiseForm.Controls.RemoveByKey("txtBoxTargetFolderID")
    $PremiseForm.Controls.RemoveByKey("labTargetFolderID")
    $PremiseForm.Controls.RemoveByKey("labelCombobox")
    $PremiseForm.Controls.RemoveByKey("comboBoxMenu")
    $PremiseForm.Controls.RemoveByKey("labelComboboxFolder")
    $PremiseForm.Controls.RemoveByKey("comboBoxFolder")
    $PremiseForm.Controls.RemoveByKey("labelComboboxConfig")
    $PremiseForm.Controls.RemoveByKey("comboBoxConfig")

    $Global:labFromDate = New-Object System.Windows.Forms.Label
    $Global:FromDatePicker = New-Object System.Windows.Forms.DateTimePicker
    $Global:labToDate = New-Object System.Windows.Forms.Label
    $Global:ToDatePicker = New-Object System.Windows.Forms.DateTimePicker
    $Global:labSubject = New-Object System.Windows.Forms.Label
    $Global:txtBoxSubject = New-Object System.Windows.Forms.TextBox
    $Global:labFolderID = New-Object System.Windows.Forms.Label
    $Global:txtBoxFolderID = New-Object System.Windows.Forms.TextBox
    $Global:labTargetFolderID = New-Object System.Windows.Forms.Label
    $Global:txtBoxTargetFolderID = New-Object System.Windows.Forms.TextBox
    $Global:labelCombobox = New-Object System.Windows.Forms.Label
    $Global:comboBoxMenu = New-Object System.Windows.Forms.ComboBox
    $Global:labelComboboxFolder = New-Object System.Windows.Forms.Label
    $Global:comboBoxFolder = New-Object System.Windows.Forms.ComboBox
    $Global:labelComboboxConfig = New-Object System.Windows.Forms.Label
    $Global:comboBoxConfig = New-Object System.Windows.Forms.ComboBox

    #Label FromDate
    $labFromDate.Location = New-Object System.Drawing.Point(5,285)
    $labFromDate.Size = New-Object System.Drawing.Size(80,35)
    $labFromDate.Name = "FromDate"
    $labFromDate.Text = "From or greater than"

    # FromDate Date Picker
    $FromDatePicker.DataBindings.DefaultDataSourceUpdateMode = 0
    $FromDatePicker.Location = New-Object System.Drawing.Point(100,285)
    $FromDatePicker.Name = "FromDatePicker"
    $FromDatePicker.Text = ""

    #Label ToDate
    $labToDate.Location = New-Object System.Drawing.Point(5,330)
    $labToDate.Name = "ToDate"
    $labToDate.Size = New-Object System.Drawing.Size(80,40)
    $labToDate.Text = "To or less than"

    # ToDate Date Picker
    $ToDatePicker.DataBindings.DefaultDataSourceUpdateMode = 0
    $ToDatePicker.Location = New-Object System.Drawing.Point(100,330)
    $ToDatePicker.Name = "ToDatePicker"
    $ToDatePicker.Text = ""

    #Label Subject
    $labSubject.Location = New-Object System.Drawing.Point(5,370)
    $labSubject.Size = New-Object System.Drawing.Size(50,20)
    $labSubject.Name = "labSubject"
    $labSubject.Text = "Subject: "
 
    #TextBox Subject
    $txtBoxSubject.Location = New-Object System.Drawing.Point(100,370)
    $txtBoxSubject.Size = New-Object System.Drawing.Size(280,20)
    $txtBoxSubject.Name = "txtBoxSubject"
    $txtBoxSubject.Text = ""

    #Label FolderID
    $labFolderID.Location = New-Object System.Drawing.Point(5,400)
    $labFolderID.Size = New-Object System.Drawing.Size(55,20)
    $labFolderID.Name = "labFolderID"
    $labFolderID.Text = "FolderID:"

    #TextBox FolderID
    $txtBoxFolderID.Location = New-Object System.Drawing.Point(100,400)
    $txtBoxFolderID.Size = New-Object System.Drawing.Size(280,20)
    $txtBoxFolderID.Name = "txtBoxFolderID"
    $txtBoxFolderID.Text = ""

    #Adapting FolderID and TxtBoxFolderID based on the selection
    if($radiobutton4.Checked -or $radiobutton8.Checked -or $radiobutton9.Checked){
        $labFolderID.Location = New-Object System.Drawing.Point(5,285)
        $txtBoxFolderID.Location = New-Object System.Drawing.Point(100,285)
    }
    elseif($radiobutton12.Checked){
        $labFolderID.Size = New-Object System.Drawing.Size(95,20)
        $labFolderID.Text = "SourceFolderID:"
    }
    elseif($radiobutton17.Checked){
        $labFolderID.Location = New-Object System.Drawing.Point(5,285)
        $labFolderID.Size = New-Object System.Drawing.Size(95,20)
        $labFolderID.Text = "E-mail Address:"
        $txtBoxFolderID.Location = New-Object System.Drawing.Point(100,285)
    }

    #Label Target FolderID
    $labTargetFolderID.Location = New-Object System.Drawing.Point(5,430)
    $labTargetFolderID.Size = New-Object System.Drawing.Size(95,20)
    $labTargetFolderID.Name = "labTargetFolderID"
    $labTargetFolderID.Text = "TargetFolderID:"

    #TextBox Target FolderID
    $txtBoxTargetFolderID.Location = New-Object System.Drawing.Point(100,430)
    $txtBoxTargetFolderID.Size = New-Object System.Drawing.Size(280,20)
    $txtBoxTargetFolderID.Name = "txtBoxTargetFolderID"
    $txtBoxTargetFolderID.Text = ""

    #Label Combobox
    $labelCombobox.Location = New-Object System.Drawing.Point(400,285)
    $labelCombobox.Size = New-Object System.Drawing.Size(80,35)
    $labelCombobox.Name = "labelCombobox"
    $labelCombobox.Text = "Delete Option"

    #ComboBox Menu
    $comboBoxMenu.DataBindings.DefaultDataSourceUpdateMode = 0
    $comboBoxMenu.FormattingEnabled = $True
    $comboBoxMenu.Location = New-Object System.Drawing.Point(485,285)
    $comboBoxMenu.Name = "comboBoxMenu"
    $comboBoxMenu.add_SelectedIndexChanged($handler_comboBoxMenu_SelectedIndexChanged)

    #Label ComboboxFolder
    $labelComboboxFolder.Location = New-Object System.Drawing.Point(5,285)
    $labelComboboxFolder.Size = New-Object System.Drawing.Size(50,35)
    $labelComboboxFolder.Name = "labelComboboxFolder"
    $labelComboboxFolder.Text = "Folder:"

    #ComboBoxFolder
    $comboBoxFolder.DataBindings.DefaultDataSourceUpdateMode = 0
    $comboBoxFolder.FormattingEnabled = $True
    $comboBoxFolder.Location = New-Object System.Drawing.Point(55,285)
    $comboBoxFolder.Size = New-Object System.Drawing.Size(70,35)
    $comboBoxFolder.Name = "comboBoxFolder"
    $comboBoxFolder.Items.Add("")|Out-Null
    $comboBoxFolder.Items.Add("Root")|Out-Null
    $comboBoxFolder.Items.Add("Calendar")|Out-Null
    $comboBoxFolder.Items.Add("Inbox")|Out-Null
    $comboBoxFolder.add_SelectedIndexChanged($handler_comboBoxFolder_SelectedIndexChanged)

    #Label ComboboxConfig
    $labelComboboxConfig.Location = New-Object System.Drawing.Point(145,285)
    $labelComboboxConfig.Size = New-Object System.Drawing.Size(75,35)
    $labelComboboxConfig.Name = "labelComboboxConfig"
    $labelComboboxConfig.Text = "Config Name:"

    #ComboBoxConfig
    $comboBoxConfig.DataBindings.DefaultDataSourceUpdateMode = 0
    $comboBoxConfig.FormattingEnabled = $True
    $comboBoxConfig.Location = New-Object System.Drawing.Point(225,285)
    $ComboboxConfig.Size = New-Object System.Drawing.Size(180,35)
    $comboBoxConfig.Name = "comboBoxConfig"
    $comboBoxConfig.Items.Add("")|Out-Null
    $comboBoxConfig.Items.Add("Aggregated.OwaUserConfiguration")|Out-Null
    $comboBoxConfig.Items.Add("UserConfigurationProperties.All")|Out-Null
    $comboBoxConfig.Items.Add("OWA.AttachmentDataProvider")|Out-Null
    $comboBoxConfig.Items.Add("OWA.AutocompleteCache")|Out-Null
    $comboBoxConfig.Items.Add("OWA.SessionInformation")|Out-Null
    $comboBoxConfig.Items.Add("OWA.UserOptions")|Out-Null
    $comboBoxConfig.Items.Add("OWA.ViewStateConfiguration")|Out-Null
    $comboBoxConfig.Items.Add("Suite.Storage")|Out-Null
    $comboBoxConfig.Items.Add("UM.E14.PersonalAutoAttendants")|Out-Null
    $comboBoxConfig.Items.Add("CleanFinders")|Out-Null
    $comboBoxConfig.add_SelectedIndexChanged($handler_comboBoxConfig_SelectedIndexChanged)

    if($radiobutton4.Checked){
        $PremiseForm.Controls.Add($labFolderID)
        $PremiseForm.Controls.Add($txtBoxFolderID)
        }
    elseif($radiobutton7.Checked){
        $PremiseForm.Controls.Add($labFolderID)
        $PremiseForm.Controls.Add($txtBoxFolderID)
        $PremiseForm.Controls.Add($labFromDate)
        $PremiseForm.Controls.Add($FromDatePicker)
        $PremiseForm.Controls.Add($labToDate)
        $PremiseForm.Controls.Add($ToDatePicker)
        $PremiseForm.Controls.Add($labSubject)
        $PremiseForm.Controls.Add($txtBoxSubject)
    }
    elseif($radiobutton8.Checked){
        $labFolderID.Size = New-Object System.Drawing.Size(95,20)
        $labFolderID.Text = "Folder Name:"
        $PremiseForm.Controls.Add($labFolderID)
        $PremiseForm.Controls.Add($txtBoxFolderID)
    }
    elseif($radiobutton9.Checked){
        $comboBoxMenu.Items.Add("")|Out-Null
        $comboBoxMenu.Items.Add("HardDelete")|Out-Null
        $comboBoxMenu.Items.Add("MoveToDeletedItems")|Out-Null
        $comboBoxMenu.SelectedItem = "MoveToDeletedItems"
        $PremiseForm.Controls.Add($labFolderID)
        $PremiseForm.Controls.Add($txtBoxFolderID)
        $PremiseForm.Controls.Add($labelCombobox)
        $PremiseForm.Controls.Add($comboBoxMenu)
    }
    elseif($radiobutton12.Checked){
        $PremiseForm.Controls.Add($labFromDate)
        $PremiseForm.Controls.Add($FromDatePicker)
        $PremiseForm.Controls.Add($labToDate)
        $PremiseForm.Controls.Add($ToDatePicker)
        $PremiseForm.Controls.Add($labSubject)
        $PremiseForm.Controls.Add($txtBoxSubject)
        $PremiseForm.Controls.Add($labFolderID)
        $PremiseForm.Controls.Add($txtBoxFolderID)
        $PremiseForm.Controls.Add($labTargetFolderID)
        $PremiseForm.Controls.Add($txtBoxTargetFolderID)
    }
    elseif($radiobutton13.Checked){
        $comboBoxMenu.Items.Add("")|Out-Null
        $comboBoxMenu.Items.Add("SoftDelete")|Out-Null
        $comboBoxMenu.Items.Add("HardDelete")|Out-Null
        $comboBoxMenu.Items.Add("MoveToDeletedItems")|Out-Null
        $comboBoxMenu.SelectedItem = "MoveToDeletedItems"
        $PremiseForm.Controls.Add($labFromDate)
        $PremiseForm.Controls.Add($FromDatePicker)
        $PremiseForm.Controls.Add($labToDate)
        $PremiseForm.Controls.Add($ToDatePicker)
        $PremiseForm.Controls.Add($labSubject)
        $PremiseForm.Controls.Add($txtBoxSubject)
        $PremiseForm.Controls.Add($labFolderID)
        $PremiseForm.Controls.Add($txtBoxFolderID)
        $PremiseForm.Controls.Add($labelCombobox)
        $PremiseForm.Controls.Add($comboBoxMenu)
    }
    elseif($radiobutton15.Checked){
        $comboBoxMenu.Items.Add("")|Out-Null
        $comboBoxMenu.Items.Add("Normal")|Out-Null
        $comboBoxMenu.Items.Add("Personal")|Out-Null
        $comboBoxMenu.Items.Add("Private")|Out-Null
        $comboBoxMenu.Items.Add("Confidential")|Out-Null
        $comboBoxMenu.SelectedItem = "Normal"
        $PremiseForm.Controls.Add($labFromDate)
        $PremiseForm.Controls.Add($FromDatePicker)
        $PremiseForm.Controls.Add($labToDate)
        $PremiseForm.Controls.Add($ToDatePicker)
        $PremiseForm.Controls.Add($labSubject)
        $PremiseForm.Controls.Add($txtBoxSubject)
        $PremiseForm.Controls.Add($labFolderID)
        $PremiseForm.Controls.Add($txtBoxFolderID)
        $PremiseForm.Controls.Add($labelCombobox)
        $PremiseForm.Controls.Add($comboBoxMenu)
    }
    elseif($radiobutton16.Checked){
        $PremiseForm.Controls.Add($labelComboboxFolder)
        $PremiseForm.Controls.Add($comboBoxFolder)
        $PremiseForm.Controls.Add($labelComboboxConfig)
        $PremiseForm.Controls.Add($comboBoxConfig)
    }
    elseif($radiobutton17.Checked){
        $PremiseForm.Controls.Add($labFolderID)
        $PremiseForm.Controls.Add($txtBoxFolderID)
    }
    $PremiseForm.refresh()
    }

    $handler_comboBoxMenu_SelectedIndexChanged= {
    # Get the Event ID when item is selected
        $Global:ComboOption = $comboBoxMenu.selectedItem.ToString()
    }

    $handler_comboBoxFolder_SelectedIndexChanged= {
    # Get the Event ID when item is selected
        $Global:ComboOption1 = $comboBoxFolder.selectedItem.ToString()
    }

    $handler_comboBoxConfig_SelectedIndexChanged= {
        # Get the Event ID when item is selected
            $Global:ComboOption2 = $comboBoxConfig.selectedItem.ToString()
    }

    $handler_labImpersonationHelp_Click={
        [Microsoft.VisualBasic.Interaction]::MsgBox("In order to use Impersonation, we must first assign proper ManagementRole to the 'administrative' account that run the different options.
    New-ManagementRoleAssignment –Name:impersonationAssignmentName –Role:ApplicationImpersonation –User:<Account>
 
    More info at: https://msdn.microsoft.com/en-us/library/bb204095(exchg.140).aspx
 
    Press CTRL + C to copy this message to clipboard."
,[Microsoft.VisualBasic.MsgBoxStyle]::Okonly,"Information Message")
    }

    $OnLoadMainWindow_StateCorrection={#Correct the initial state of the form to prevent the .Net maximized form issue
        $PremiseForm.WindowState = $InitialFormWindowState
    }

    #----------------------------------------------
    #region Generated Form Code

    $PremiseForm.Controls.Add($radiobutton1)
    $PremiseForm.Controls.Add($radiobutton2)
    $PremiseForm.Controls.Add($radiobutton3)
    $PremiseForm.Controls.Add($radiobutton4)
    $PremiseForm.Controls.Add($radiobutton5)
    $PremiseForm.Controls.Add($radiobutton6)
    $PremiseForm.Controls.Add($radiobutton7)
    $PremiseForm.Controls.Add($radiobutton8)
    $PremiseForm.Controls.Add($radiobutton9)
    $PremiseForm.Controls.Add($radiobutton10)
    $PremiseForm.Controls.Add($radiobutton11)
    $PremiseForm.Controls.Add($radiobutton12)
    $PremiseForm.Controls.Add($radiobutton13)
    $PremiseForm.Controls.Add($radiobutton14)
    $PremiseForm.Controls.Add($radiobutton15)
    $PremiseForm.Controls.Add($radiobutton16)
    $PremiseForm.Controls.Add($radiobutton17)
    $statusBar = New-Object System.Windows.Forms.StatusStrip
    $statusBar.Name = "statusBar"
    $statusBarLabel = New-Object System.Windows.Forms.ToolStripStatusLabel
    $null = $statusBar.Items.Add($statusBarLabel)
    $statusBarLabel.Text = "Ready..."
    $PremiseForm.Controls.Add($statusBar)
    $PremiseForm.ClientSize = New-Object System.Drawing.Size(800,720)
    $PremiseForm.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $PremiseForm.Name = "form1"
    $PremiseForm.Text = "Managing user: " + $email + ". Choose your Option"
    $PremiseForm.StartPosition = "CenterScreen"
    $PremiseForm.KeyPreview = $True
    $PremiseForm.Add_KeyDown({if ($_.KeyCode -eq "Escape"){$PremiseForm.Close()} })
    #
    # radiobutton1
    #
    $radiobutton1.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton1.Location = New-Object System.Drawing.Point(20,20)
    $radiobutton1.Size = New-Object System.Drawing.Size(300,15)
    $radiobutton1.TabIndex = 1
    $radiobutton1.Text = "1 - List Folders in Root"
    $radioButton1.Checked = $true
    $radiobutton1.UseVisualStyleBackColor = $True
    $radiobutton1.Add_Click({& $ExpandFilters})
    #
    # radiobutton2
    #
    $radiobutton2.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton2.Location = New-Object System.Drawing.Point(20,50)
    $radiobutton2.Size = New-Object System.Drawing.Size(300,15)
    $radiobutton2.TabIndex = 2
    $radiobutton2.Text = "2 - List Folders in Archive Root"
    $radioButton2.Checked = $false
    $radiobutton2.UseVisualStyleBackColor = $True
    $radiobutton2.Add_Click({& $ExpandFilters})
    #
    # radiobutton3
    #
    $radiobutton3.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton3.Location = New-Object System.Drawing.Point(20,80)
    $radiobutton3.Size = New-Object System.Drawing.Size(300,15)
    $radiobutton3.TabIndex = 3
    $radiobutton3.Text = "3 - List Folders in Public Folder Root"
    $radiobutton3.Checked = $false
    $radiobutton3.UseVisualStyleBackColor = $True
    $radiobutton3.Add_Click({& $ExpandFilters})
    #
    # radiobutton4
    #
    $radiobutton4.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton4.Location = New-Object System.Drawing.Point(20,110)
    $radiobutton4.Size = New-Object System.Drawing.Size(300,15)
    $radiobutton4.TabIndex = 4
    $radiobutton4.Text = "4 - List subFolders from a desired Parent Folder"
    $radiobutton4.Checked = $false
    $radiobutton4.UseVisualStyleBackColor = $True
    $radiobutton4.Add_Click({& $ExpandFilters})
    #
    # radiobutton5
    #
    $radiobutton5.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton5.Location = New-Object System.Drawing.Point(20,140)
    $radiobutton5.Size = New-Object System.Drawing.Size(300,15)
    $radiobutton5.Tabindex = 5
    $radiobutton5.Text = "5 - List folders in Recoverable Items Root folder"
    $radiobutton5.Checked = $false
    $radiobutton5.UseVisualStyleBackColor = $True
    $radiobutton5.Add_Click({& $ExpandFilters})
    #
    # radiobutton6
    #
    $radiobutton6.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton6.Location = New-Object System.Drawing.Point(20,170)
    $radiobutton6.Size = New-Object System.Drawing.Size(300,15)
    $radiobutton6.TabIndex = 6
    $radiobutton6.Text = "6 - List folders in Recoverable Items folder in Archive"
    $radiobutton6.Checked = $false
    $radiobutton6.UseVisualStyleBackColor = $True
    $radiobutton6.Add_Click({& $ExpandFilters})
    #
    # radiobutton7
    #
    $radiobutton7.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton7.Location = New-Object System.Drawing.Point(20,200)
    $radiobutton7.Name = "radiobutton7"
    $radiobutton7.Size = New-Object System.Drawing.Size(300,15)
    $radiobutton7.TabIndex = 7
    $radiobutton7.Text = "7 - List Items in a desired Folder"
    $radiobutton7.Checked = $false
    $radiobutton7.UseVisualStyleBackColor = $True
    $radiobutton7.Add_Click({& $ExpandFilters})
    #
    # radiobutton8
    #
    $radiobutton8.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton8.Location = New-Object System.Drawing.Point(20,230)
    $radiobutton8.Size = New-Object System.Drawing.Size(300,15)
    $radiobutton8.TabIndex = 8
    $radiobutton8.Text = "8 - Create a custom Folder in Root"
    $radiobutton8.Checked = $false
    $radiobutton8.UseVisualStyleBackColor = $True
    $radiobutton8.Add_Click({& $ExpandFilters})
    #
    # radiobutton9
    #
    $radiobutton9.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton9.Location = New-Object System.Drawing.Point(20,260)
    $radiobutton9.Size = New-Object System.Drawing.Size(300,15)
    $radiobutton9.TabIndex = 9
    $radiobutton9.Text = "9 - Delete a Folder"
    $radiobutton9.Checked = $false
    $radiobutton9.UseVisualStyleBackColor = $True
    $radiobutton9.Add_Click({& $ExpandFilters})
    #
    # radiobutton10
    #
    $radiobutton10.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton10.Location = New-Object System.Drawing.Point(400,20)
    $radiobutton10.Size = New-Object System.Drawing.Size(300,15)
    $radiobutton10.TabIndex = 10
    $radiobutton10.Text = "10 - Get user's Inbox Rules"
    $radiobutton10.Checked = $false
    $radiobutton10.UseVisualStyleBackColor = $True
    $radiobutton10.Add_Click({& $ExpandFilters})
    #
    # radiobutton11
    #
    $radiobutton11.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton11.Location = New-Object System.Drawing.Point(400,50)
    $radiobutton11.Size = New-Object System.Drawing.Size(300,15)
    $radiobutton11.TabIndex = 11
    $radiobutton11.Text = "11 - Get user's OOF Settings"
    $radiobutton11.Checked = $false
    $radiobutton11.UseVisualStyleBackColor = $True
    $radiobutton11.Add_Click({& $ExpandFilters})
    #
    # radiobutton12
    #
    $radiobutton12.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton12.Location = New-Object System.Drawing.Point(400,80)
    $radiobutton12.Size = New-Object System.Drawing.Size(300,15)
    $radiobutton12.TabIndex = 12
    $radiobutton12.Text = "12 - Move items between folders"
    $radiobutton12.Checked = $false
    $radiobutton12.UseVisualStyleBackColor = $True
    $radiobutton12.Add_Click({& $ExpandFilters})
    #
    # radiobutton13
    #
    $radiobutton13.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton13.Location = New-Object System.Drawing.Point(400,110)
    $radiobutton13.Size = New-Object System.Drawing.Size(300,15)
    $radiobutton13.TabIndex = 13
    $radiobutton13.Text = "13 - Delete a subset of items in a folder"
    $radiobutton13.Checked = $false
    $radiobutton13.UseVisualStyleBackColor = $True
    $radiobutton13.Add_Click({& $ExpandFilters})
    #
    # radiobutton14
    #
    $radiobutton14.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton14.Location = New-Object System.Drawing.Point(400,140)
    $radiobutton14.Size = New-Object System.Drawing.Size(300,15)
    $radiobutton14.TabIndex = 14
    $radiobutton14.Text = "14 - Get user's Delegate information"
    $radiobutton14.Checked = $false
    $radiobutton14.UseVisualStyleBackColor = $True
    $radiobutton14.Add_Click({& $ExpandFilters})
    #
    # radiobutton15
    #
    $radiobutton15.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton15.Location = New-Object System.Drawing.Point(400,170)
    $radiobutton15.Size = New-Object System.Drawing.Size(300,15)
    $radiobutton15.TabIndex = 15
    $radiobutton15.Text = "15 - Change sensitivity to items in a folder"
    $radiobutton15.Checked = $false
    $radiobutton15.UseVisualStyleBackColor = $True
    $radiobutton15.Add_Click({& $ExpandFilters})
    #
    # radiobutton16
    #
    $radiobutton16.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton16.Location = New-Object System.Drawing.Point(400,200)
    $radiobutton16.Size = New-Object System.Drawing.Size(300,15)
    $radiobutton16.TabIndex = 16
    $radiobutton16.Text = "16 - Remove OWA configurations"
    $radiobutton16.Checked = $false
    $radiobutton16.UseVisualStyleBackColor = $True
    $radiobutton16.Add_Click({& $ExpandFilters})
    #
    # radiobutton17
    #
    $radiobutton17.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation
    $radiobutton17.Location = New-Object System.Drawing.Point(400,230)
    $radiobutton17.Size = New-Object System.Drawing.Size(175,15)
    $radiobutton17.TabIndex = 17
    $radiobutton17.Text = "17 - Switch to another Mailbox"
    $radiobutton17.Checked = $false
    $radiobutton17.UseVisualStyleBackColor = $True
    $radiobutton17.Add_Click({& $ExpandFilters})
    #
    # Label Impersonation Help
    #
    $labImpersonationHelp.Location = New-Object System.Drawing.Point(380,231)
    $labImpersonationHelp.Size = New-Object System.Drawing.Size(10,20)
    $labImpersonationHelp.Name = "labImpersonation"
    $labImpersonationHelp.ForeColor = "Blue"
    $labImpersonationHelp.Text = "?"
    $labImpersonationHelp.add_Click($handler_labImpersonationHelp_Click)
    $PremiseForm.Controls.Add($labImpersonationHelp)

    #"Go" button
    $Global:buttonGo.Dispose()

    $Global:buttonGo2 = New-Object System.Windows.Forms.Button
    $buttonGo2.DataBindings.DefaultDataSourceUpdateMode = 0
    $buttonGo2.ForeColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
    $buttonGo2.Location = New-Object System.Drawing.Point(700,20)
    $buttonGo2.Size = New-Object System.Drawing.Size(50,25)
    $buttonGo2.TabIndex = 17
    $buttonGo2.Name = "Go"
    $buttonGo2.Text = "Go"
    $buttonGo2.UseVisualStyleBackColor = $True
    $buttonGo2.add_Click({
            if($radiobutton1.Checked){Method1to6}
            elseif($radiobutton2.Checked){Method1to6}
            elseif($radiobutton3.Checked){Method1to6}
            elseif($radiobutton4.Checked){Method1to6}
            elseif($radiobutton5.Checked){Method1to6}
            elseif($radiobutton6.Checked){Method1to6}
            elseif($radiobutton7.Checked){Method7}
            elseif($radiobutton8.Checked){Method8}
            elseif($radiobutton9.Checked){Method9}
            elseif($radiobutton10.Checked){Method10}
            elseif($radiobutton11.Checked){Method11}
            elseif($radiobutton12.Checked){Method12}
            elseif($radiobutton13.Checked){Method13}
            elseif($radiobutton14.Checked){Method14}
            elseif($radiobutton15.Checked){Method15}
            elseif($radiobutton16.Checked){Method16}
            elseif($radiobutton17.Checked){Method17}
    })
    $PremiseForm.Controls.Add($buttonGo2)

    #"Exit" button
    $buttonExit.DataBindings.DefaultDataSourceUpdateMode = 0
    $buttonExit.ForeColor = [System.Drawing.Color]::FromArgb(255,0,0,0)
    $buttonExit.Location = New-Object System.Drawing.Point(700,50)
    $buttonExit.Size = New-Object System.Drawing.Size(50,25)
    $buttonExit.TabIndex = 17
    $buttonExit.Name = "Exit"
    $buttonExit.Text = "Exit"
    $buttonExit.UseVisualStyleBackColor = $True
    $PremiseForm.Controls.Add($buttonExit)

    #TextBox results
    $txtBoxResults.DataBindings.DefaultDataSourceUpdateMode = 0
    $txtBoxResults.Location = New-Object System.Drawing.Point(5,460)
    $txtBoxResults.Size = New-Object System.Drawing.Size(790,240)
    $txtBoxResults.Name = "TextResults"
    $txtBoxResults.BackColor = [System.Drawing.Color]::White
    $txtBoxResults.BorderStyle = [System.Windows.Forms.BorderStyle]::Fixed3D
    $Font = New-Object System.Drawing.Font("Consolas",8)
    $txtBoxResults.Font = $Font
    $PremiseForm.Controls.Add($txtBoxResults)

    #dataGrid

    $dgResults.Anchor = 15
    $dgResults.DataBindings.DefaultDataSourceUpdateMode = 0
    $dgResults.DataMember = ""
    $dgResults.Location = New-Object System.Drawing.Point(5,460)
    $dgResults.Size = New-Object System.Drawing.Size(790,240)
    $dgResults.Name = "dgResults"
    $dgResults.ReadOnly = $True
    $dgResults.RowHeadersVisible = $False
    $dgResults.Visible = $False
    $dgResults.AllowUserToOrderColumns = $True
    $dgResults.AllowUserToResizeColumns = $True
    $PremiseForm.Controls.Add($dgResults)

    #endregion Generated Form Code

    # Show Form
    #Save the initial state of the form
    $InitialFormWindowState = $PremiseForm.WindowState
    #Init the OnLoad event to correct the initial state of the form
    $PremiseForm.add_Load($OnLoadMainWindow_StateCorrection)
    $PremiseForm.Add_Shown({$PremiseForm.Activate()})
    $PremiseForm.ShowDialog()| Out-Null
    #exit if 'Exit' button is pushed
    if($buttonExit.IsDisposed){return}

    } #End Function

    #Call the Function
    try {
        GenerateForm
    }
    finally {
        Stop-ModuleUpdate -RunspaceData $runspaceData
    }
}

<#
This is an example configuration file
 
By default, it is enough to have a single one of them,
however if you have enough configuration settings to justify having multiple copies of it,
feel totally free to split them into multiple files.
#>


<#
# Example Configuration
Set-PSFConfig -Module 'EWSGui' -Name 'Example.Setting' -Value 10 -Initialize -Validation 'integer' -Handler { } -Description "Example configuration setting. Your module can then use the setting using 'Get-PSFConfigValue'"
#>


Set-PSFConfig -Module 'EWSGui' -Name 'Import.DoDotSource' -Value $false -Initialize -Validation 'bool' -Description "Whether the module files should be dotsourced on import. By default, the files of this module are read as string value and invoked, which is faster but worse on debugging."
Set-PSFConfig -Module 'EWSGui' -Name 'Import.IndividualFiles' -Value $false -Initialize -Validation 'bool' -Description "Whether the module files should be imported individually. During the module build, all module code is compiled into few files, which are imported instead by default. Loading the compiled versions is faster, using the individual files is easier for debugging and testing out adjustments."

<#
Stored scriptblocks are available in [PsfValidateScript()] attributes.
This makes it easier to centrally provide the same scriptblock multiple times,
without having to maintain it in separate locations.
 
It also prevents lengthy validation scriptblocks from making your parameter block
hard to read.
 
Set-PSFScriptblock -Name 'EWSGui.ScriptBlockName' -Scriptblock {
     
}
#>


<#
# Example:
Register-PSFTeppScriptblock -Name "EWSGui.alcohol" -ScriptBlock { 'Beer','Mead','Whiskey','Wine','Vodka','Rum (3y)', 'Rum (5y)', 'Rum (7y)' }
#>


<#
# Example:
Register-PSFTeppArgumentCompleter -Command Get-Alcohol -Parameter Type -Name EWSGui.alcohol
#>


New-PSFLicense -Product 'EWSGui' -Manufacturer 'agallego' -ProductVersion $script:ModuleVersion -ProductType Module -Name MIT -Version "1.0.0.0" -Date (Get-Date "2021-11-29") -Text @"
Copyright (c) 2021 agallego
 
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
 
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
 
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
"@

#endregion Load compiled code