O365Essentials.psm1

function Connect-O365Admin {
    [cmdletbinding()]
    param(
        [parameter(Mandatory, ParameterSetName = 'Credential')][PSCredential] $Credential,
        [int] $ExpiresIn = 3600,
        [int] $ExpiresTimeout = 30,
        [switch] $ForceRefresh
    )

    if (-not $Script:AuthorizationO365Cache) {
        $Script:AuthorizationO365Cache = [ordered] @{}
    }

    $UserName = $Credential.UserName

    if ($Script:AuthorizationO365Cache[$UserName] -and -not $ForceRefesh) {
        if ($Script:AuthorizationO365Cache[$UserName].ExpiresOnUTC -gt [datetime]::UtcNow) {
            Write-Verbose "Connect-O365Admin - Using cache for $UserName"
            return $Script:AuthorizationO365Cache[$UserName]
        }
    }

    $Script:AuthorizationO365Cache['CurrentUsername'] = $UserName

    $AzConnect =(Connect-AzAccount-Credential$Credential -ErrorAction Stop)

    $Context = $AzConnect.Context
    $Authentication = [Microsoft.Azure.Commands.Common.Authentication.AzureSession]::Instance.AuthenticationFactory.Authenticate(
        $Context.Account,
        $Context.Environment,
        $Context.Tenant.Id.ToString(),
        $null,
        [Microsoft.Azure.Commands.Common.Authentication.ShowDialog]::Never,
        $null,
        "https://admin.microsoft.com"
    )

    $null=Disconnect-AzAccount-AzureContext$Context

    $Script:AuthorizationO365Cache[$UserName] = [ordered] @{
        'Credential'     = $Credential
        'UserName'       = $Context.Account
        'Environment'    = $Context.Environment
        'Tenant'         = $Context.Tenant.Id
        'Authentication' = $Authentication
        'AccessToken'    = $Authentication.AccessToken
        'ExpiresOnUTC'   = ([datetime]::UtcNow).AddSeconds($ExpiresIn - $ExpiresTimeout)
        'Headers'        = [ordered] @{"Content-Type" ="application/json; charset=UTF-8";"Authorization"="Bearer $($Authentication.AccessToken)"}

    }
    $Script:AuthorizationO365Cache[$UserName]
}
function Get-O365AzureSpeechServices {
    [cmdletbinding()]
    param(
        [parameter()][alias('Authorization')][System.Collections.IDictionary] $Headers
    )

    if (-not $Headers -and $Script:AuthorizationO365Cache) {
        $Headers = $Script:AuthorizationO365Cache
    }

    $Uri ="https://admin.microsoft.com/admin/api/services/apps/azurespeechservices"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers

    [PSCustomobject] @{
        AllowTheOrganizationWideLanguageModel = $Output.IsTenantEnabled
    }
}
function Get-O365Bookings {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )

    $Uri ="https://admin.microsoft.com/admin/api/settings/apps/bookings"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365BriefingEmail {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )

    $Uri ="https://admin.microsoft.com/admin/api/services/apps/briefingemail"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365CalendarSharing {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri = 'https://admin.microsoft.com/admin/api/settings/apps/calendarsharing'

    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365CommunicationToUsers {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri = 'https://admin.microsoft.com/admin/api/settings/apps/EndUserCommunications'

    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365CompanyInformation {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri ="https://admin.microsoft.com/admin/api/Settings/company/profile"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365Cortana {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri = 'https://admin.microsoft.com/admin/api/services/apps/cortana'

    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365Dynamics365CustomerVoice {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri = 'https://admin.microsoft.com/admin/api/settings/apps/officeformspro'

    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365Dynamics365SalesInsights {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri = 'https://admin.microsoft.com/admin/api/settings/apps/dci'

    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365Forms {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri = 'https://admin.microsoft.com/admin/api/settings/apps/officeforms/'

    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365GraphDataConnect {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )

    $Uri ="https://admin.microsoft.com/admin/api/settings/apps/o365dataplan"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365Groups {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri ="https://admin.microsoft.com/admin/api/settings/security/guestUserPolicy"
    $Output1 = Invoke-O365Admin -Uri $Uri -Headers $Headers


    $Uri ="https://admin.microsoft.com/admin/api/settings/security/o365guestuser"
    $Output2 = Invoke-O365Admin -Uri $Uri -Headers $Headers

    <# same/similar properties on both objects
    $Object = [ordered] @{}
    foreach ($O in $Output1, $Output2) {
        foreach ($Key in $O.PSObject.Properties.Name) {
            $Object[$Key] = $O.$Key
        }
    }
     [PSCustomObject] $Object
    #>


    [PSCustomObject] @{
        AllowGuestAccess      = $Output1.AllowGuestAccess
        AllowGuestInvitations = $Output1.AllowGuestInvitations
        SitesSharingEnabled   = $Output1.SitesSharingEnabled
        AllowGuestsAsMembers  = $Output2.AllowGuestsAsMembers
        AllowGuestAccessO365  = $Output2.AllowGuestAccess
    }
}
function Get-O365InstallationOptions {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )

    $Uri ="https://admin.microsoft.com/admin/api/settings/apps/usersoftware"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output.UserSoftwareSettings

    # Fix me
    <#
    $Uri = "https://admin.microsoft.com/fd/oacms/api/ReleaseManagement/admin?tenantId=29c50a66"
    $Output1 = Invoke-O365Admin -Uri $Uri -Headers $Headers
 
    $Uri = "https://admin.microsoft.com/fd/oacms/api/MroDeviceManagement/TenantInfo?tenantId=29c50a66 "
    $Output2 = Invoke-O365Admin -Uri $Uri -Headers $Headers
    #>

    <#
    $Uri = "https://admin.microsoft.com/fd/oacms/api/mrodevicemanagement/?ffn=55336b82-a18d-4dd6-b5f6-9e5095c314a6"
    $Output3 = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output3
    #>


    #‎Office‎ installation options
    # /fd/oacms/api/ReleaseManagement/admin?tenantId=ceb371f6
    # /fd/oacms/api/MroDeviceManagement/TenantInfo?tenantId=ceb371f6-
    # /fd/oacms/api/mrodevicemanagement/?ffn=55336b82-a18d-4dd6-b5f6-9e5095c314a6

}
function Get-O365MicrosoftSearch {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri ="https://admin.microsoft.com/admin/api/searchadminapi/configurations"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365MicrosoftTeams {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri ="https://admin.microsoft.com/admin/api/settings/apps/skypeteams"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
    <#
    IsSkypeTeamsLicensed : True
    TenantCategorySettings : {@{TenantSkuCategory=BusinessEnterprise; IsSkypeTeamsEnabled=; Meetups=; FunControl=; Messaging=}, @{TenantSkuCategory=Guest; IsSkypeTeamsEnabled=; Meetups=; FunControl=; Messaging=}}
    Bots : @{IsBotsEnabled=; IsSideLoadedBotsEnabled=; BotSettings=System.Object[]; IsExternalAppsEnabledByDefault=}
    Miscellaneous : @{IsOrganizationTabEnabled=; IsSkypeBusinessInteropEnabled=; IsTBotProactiveMessagingEnabled=}
    Email : @{IsEmailIntoChannelsEnabled=; RestrictedSenderList=System.Object[]}
    CloudStorage : @{Box=; Dropbox=; GoogleDrive=; ShareFile=}
    TeamsOwnedApps : @{TeamsOwnedAppSettings=System.Object[]}
    TenantOwnedApps : @{TenantOwnedAppSettings=System.Object[]}
    MigrationStates : @{EnableAppsMigration=; EnableClientSettingsMigration=; EnableMeetupsMigration=; EnableMessagingMigration=}
    #>

}
function Get-O365ModernAuthentication {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri ="https://admin.microsoft.com/admin/api/services/apps/modernAuth"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365MyAnalytics {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri ="https://admin.microsoft.com/admin/api/services/apps/myanalytics"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365News {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )

    $Uri ="https://admin.microsoft.com/admin/api/searchadminapi/news"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output

    $Uri ="https://admin.microsoft.com/admin/api/searchadminapi/news/options"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output

    $Uri ="https://admin.microsoft.com/admin/api/searchadminapi/news/options/Bing"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output

    $Uri ="https://admin.microsoft.com/admin/api/searchadminapi/news/industry/Bing"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output

    $Uri ="https://admin.microsoft.com/admin/api/searchadminapi/news/msbenabled/Bing"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365OfficeOnTheWeb {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri ="https://admin.microsoft.com/admin/api/settings/apps/officeonline"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365OfficeProductivity {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri ="https://admin.microsoft.com/admin/api/reports/productivityScoreCustomerOption"
    $Output1 = Invoke-O365Admin -Uri $Uri -Headers $Headers

    $Uri ="https://admin.microsoft.com/admin/api/reports/productivityScoreConfig/GetProductivityScoreConfig"
    $Output2 = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output2Json = $Output2.Output | ConvertFrom-Json
    $Output1Json = $Output1.Output | ConvertFrom-Json
    $Output = [PSCustomObject] @{
        TenantId                  = $Output2Json.TenantId
        ProductivityScoreSignedup = $Output2Json.ProductivityScoreSignedup
        SignupUserPuid            = $Output2Json.SignupUserPuid
        SignupTime                = $Output2Json.SignupTime
        ReadyTime                 = $Output2Json.ReadyTime
        ProductivityScoreOptedIn  = $Output1Json.ProductivityScoreOptedIn
        OperationUserPuid         = $Output1Json.OperationUserPuid
        OperationTime             = $Output1Json.OperationTime
    }
    $Output
}
function Get-O365Planner {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )

    $Uri ="https://admin.microsoft.com/admin/api/services/apps/planner"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365Project {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )

    $Uri ="https://admin.microsoft.com/admin/api/settings/apps/projectonline"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365Reports {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri ="https://admin.microsoft.com/admin/api/reports/config/GetTenantConfiguration"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $OutputFromJson = $Output.Output | ConvertFrom-Json
    $OutputFromJson
}
function Get-O365Scripts {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri ="https://admin.microsoft.com/admin/api/settings/apps/officescripts"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365SharePoint {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri ="https://admin.microsoft.com/admin/api/settings/apps/sitessharing"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365Sway {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri ="https://admin.microsoft.com/admin/api/settings/apps/Sway"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365TenantID {
    <#
    .SYNOPSIS
    Short description
 
    .DESCRIPTION
    Long description
 
    .PARAMETER Domain
    Parameter description
 
    .EXAMPLE
    Get-O365TenantID -Domain 'evotec.pl'
 
    .NOTES
    General notes
    #>

    [cmdletbinding()]
    param(
        [parameter(Mandatory)][string] $Domain
    )
    (Invoke-RestMethod"https://login.windows.net/$Domain/.well-known/openid-configuration"-MethodGET).userinfo_endpoint.Split("/")[3]
}


function Get-O365ToDo {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri ="https://admin.microsoft.com/admin/api/services/apps/todo"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365UserConsentApps {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri ="https://admin.microsoft.com/admin/api/settings/apps/IntegratedApps"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Get-O365UserOwnedApps {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri ="https://admin.microsoft.com/admin/api/settings/apps/store"
    $Output1 = Invoke-O365Admin -Uri $Uri -Headers $Headers

    $Uri ="https://admin.microsoft.com/admin/api/storesettings/iwpurchaseallowed"
    $Output2 = Invoke-O365Admin -Uri $Uri -Headers $Headers

    $Uri = 'https://admin.microsoft.com/fd/m365licensing/v1/policies/autoclaim'
    $Output4 = Invoke-O365Admin -Uri $Uri -Headers $Headers

    [PSCustomObject] @{
        LetUsersAccessOfficeStore = $Output1
        LetUsersStartTrials       = $Output2
        LetUsersAutoClaimLicenses = $Output4.tenantPolicyValue
        <#
        {
        "policyId": "Autoclaim",
        "tenantPolicyValue": "Enabled",
        "tenantId": "ceb371f6-"
        }
        #>


    }
}
function Get-O365Whiteboard {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers
    )
    $Uri = 'https://admin.microsoft.com/admin/api/settings/apps/whiteboard'

    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers
    $Output
}
function Invoke-O365Admin {
    [cmdletBinding(SupportsShouldProcess)]
    param(
        [uri] $Uri,
        [alias('Authorization')][System.Collections.IDictionary] $Headers,
        [validateset('GET', 'DELETE', 'POST', 'PATCH')][string] $Method = 'GET',
        [string] $ContentType = "application/json; charset=UTF-8",
        [System.Collections.IDictionary] $Body
    )
    if (-not $Headers) {
        if ($Script:AuthorizationO365Cache -and $Script:AuthorizationO365Cache['CurrentUserName']) {
            $UserName = $Script:AuthorizationO365Cache['CurrentUsername']
            if ($Script:AuthorizationO365Cache[$UserName]) {
                $Headers = $Script:AuthorizationO365Cache[$UserName]
            }
        }
    }

    if (-not $Headers) {
        Write-Warning "Invoke-O365Admin - Not connected. Please connect using Connect-O365Admin."
        return
    }

    if ($Headers) {
        # This forces a reconnect of session in case it's about to time out. If it's not timeouting a cache value is used
        $Headers = Connect-O365Admin -Credential $Headers.Credential
    }


    if ($Headers.Error) {
        Write-Warning "Invoke-O365Admin - Authorization error. Skipping."
        return
    }
    $RestSplat = @{
        Headers     = $Headers.Headers
        Method      = $Method
        ContentType = $ContentType
    }
    if ($Body) {
        $RestSplat['Body'] = $Body | ConvertTo-Json -Depth 5
    }
    $RestSplat.Uri = $Uri
    try {
        Write-Verbose "Invoke-O365Admin - Querying [$Method] $($RestSplat.Uri)"
        if ($PSCmdlet.ShouldProcess($($RestSplat.Uri), "Querying [$Method]")) {
            $OutputQuery = Invoke-RestMethod @RestSplat -Verbose:$false
            if ($Method -in 'GET') {
                if ($null -ne $OutputQuery) {
                    $OutputQuery
                }
                if ($OutputQuery.'@odata.nextLink') {
                    $RestSplat.Uri = $OutputQuery.'@odata.nextLink'
                    $MoreData = Invoke-O365Admin @RestSplat -FullUri
                    if ($MoreData) {
                        $MoreData
                    }
                }
            } elseif ($Method -in 'POST') {
                $OutputQuery
            } else {
                return $true
            }
        }
    } catch {
        $RestError = $_.ErrorDetails.Message
        if ($RestError) {
            try {
                $ErrorMessage = ConvertFrom-Json -InputObject $RestError -ErrorAction Stop
                # Write-Warning -Message "Invoke-Graph - [$($ErrorMessage.error.code)] $($ErrorMessage.error.message), exception: $($_.Exception.Message)"
                Write-Warning -Message "Invoke-O365Admin - Error JSON: $($_.Exception.Message) $($ErrorMessage.error.message)"
            } catch {
                Write-Warning -Message "Invoke-O365Admin - Error: $($RestError.Trim())"
            }
        } else {
            Write-Warning -Message "Invoke-O365Admin - $($_.Exception.Message)"
        }
        if ($_.ErrorDetails.RecommendedAction) {
            Write-Warning -Message "Invoke-O365Admin - Recommended action: $RecommendedAction"
        }
        if ($Method -notin 'GET', 'POST') {
            return $false
        }
    }
}
function Set-O365AzureSpeechServices {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers,
        [bool] $AllowTheOrganizationWideLanguageModel
    )
    $Uri ="https://admin.microsoft.com/admin/api/services/apps/azurespeechservices"

    $Body = @{
        isTenantEnabled = $AllowTheOrganizationWideLanguageModel
    }
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body
    $Output
}
function Set-O365Forms {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers,
        [nullable[bool]] $BingImageSearchEnabled,
        [nullable[bool]] $ExternalCollaborationEnabled,
        [nullable[bool]] $ExternalSendFormEnabled,
        [nullable[bool]] $ExternalShareCollaborationEnabled,
        [nullable[bool]] $ExternalShareTemplateEnabled,
        [nullable[bool]] $ExternalShareResultEnabled,
        [nullable[bool]] $InOrgFormsPhishingScanEnabled,
        [nullable[bool]] $InOrgSurveyIncentiveEnabled,
        [nullable[bool]] $RecordIdentityByDefaultEnabled
    )
    # We need to get current settings because it always requires all parameters
    # If we would just provide one parameter it would reset everything else
    $CurrentSettings = Get-O365Forms -Headers $Headers
    $Body = [ordered] @{
        BingImageSearchEnabled            = $CurrentSettings.BingImageSearchEnabled
        ExternalCollaborationEnabled      = $CurrentSettings.ExternalCollaborationEnabled
        ExternalSendFormEnabled           = $CurrentSettings.ExternalSendFormEnabled
        ExternalShareCollaborationEnabled = $CurrentSettings.ExternalShareCollaborationEnabled
        ExternalShareTemplateEnabled      = $CurrentSettings.ExternalShareTemplateEnabled
        ExternalShareResultEnabled        = $CurrentSettings.ExternalShareResultEnabled
        InOrgFormsPhishingScanEnabled     = $CurrentSettings.InOrgFormsPhishingScanEnabled
        InOrgSurveyIncentiveEnabled       = $CurrentSettings.InOrgSurveyIncentiveEnabled
        RecordIdentityByDefaultEnabled    = $CurrentSettings.RecordIdentityByDefaultEnabled
    }
    if ($null -ne $BingImageSearchEnabled) {
        $Body.BingImageSearchEnabled = $BingImageSearchEnabled
    }
    if ($null -ne $ExternalCollaborationEnabled) {
        $Body.ExternalCollaborationEnabled = $ExternalCollaborationEnabled
    }
    if ($null -ne $ExternalSendFormEnabled) {
        $Body.ExternalSendFormEnabled = $ExternalSendFormEnabled
    }
    if ($null -ne $ExternalShareCollaborationEnabled) {
        $Body.ExternalShareCollaborationEnabled = $ExternalShareCollaborationEnabled
    }
    if ($null -ne $ExternalShareTemplateEnabled) {
        $Body.ExternalShareTemplateEnabled = $ExternalShareTemplateEnabled
    }
    if ($null -ne $ExternalShareResultEnabled) {
        $Body.ExternalShareResultEnabled = $ExternalShareResultEnabled
    }
    if ($null -ne $InOrgFormsPhishingScanEnabled) {
        $Body.InOrgFormsPhishingScanEnabled = $InOrgFormsPhishingScanEnabled
    }
    if ($null -ne $InOrgSurveyIncentiveEnabled) {
        $Body.InOrgSurveyIncentiveEnabled = $InOrgSurveyIncentiveEnabled
    }
    if ($null -ne $RecordIdentityByDefaultEnabled) {
        $Body.RecordIdentityByDefaultEnabled = $RecordIdentityByDefaultEnabled
    }

    $Uri ="https://admin.microsoft.com/admin/api/settings/apps/officeforms"
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body
    $Output
}
function Set-O365Planner {
    [cmdletbinding()]
    param(
        [alias('Authorization')][System.Collections.IDictionary] $Headers,
        [bool] $AllowCalendarSharing
    )
    $Uri ="https://admin.microsoft.com/admin/api/services/apps/planner"

    $Body = @{
        allowCalendarSharing = $AllowCalendarSharing
        id                   = "1"
        isPlannerAllowed     = $true
    }
    $Output = Invoke-O365Admin -Uri $Uri -Headers $Headers -Method POST -Body $Body
    $Output
}



# Export functions and aliases as required
Export-ModuleMember -Function @('Connect-O365Admin', 'Get-O365AzureSpeechServices', 'Get-O365Bookings', 'Get-O365BriefingEmail', 'Get-O365CalendarSharing', 'Get-O365CommunicationToUsers', 'Get-O365CompanyInformation', 'Get-O365Cortana', 'Get-O365Dynamics365CustomerVoice', 'Get-O365Dynamics365SalesInsights', 'Get-O365Forms', 'Get-O365GraphDataConnect', 'Get-O365Groups', 'Get-O365InstallationOptions', 'Get-O365MicrosoftSearch', 'Get-O365MicrosoftTeams', 'Get-O365ModernAuthentication', 'Get-O365MyAnalytics', 'Get-O365News', 'Get-O365OfficeOnTheWeb', 'Get-O365OfficeProductivity', 'Get-O365Planner', 'Get-O365Project', 'Get-O365Reports', 'Get-O365Scripts', 'Get-O365SharePoint', 'Get-O365Sway', 'Get-O365TenantID', 'Get-O365ToDo', 'Get-O365UserConsentApps', 'Get-O365UserOwnedApps', 'Get-O365Whiteboard', 'Invoke-O365Admin', 'Set-O365AzureSpeechServices', 'Set-O365Forms', 'Set-O365Planner') -Alias @()
# SIG # Begin signature block
# MIIdWQYJKoZIhvcNAQcCoIIdSjCCHUYCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUCKKKtrf5hv7tsGeaQCN0oGm7
# D1qgghhnMIIDtzCCAp+gAwIBAgIQDOfg5RfYRv6P5WD8G/AwOTANBgkqhkiG9w0B
# AQUFADBlMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
# VQQLExB3d3cuZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVk
# IElEIFJvb3QgQ0EwHhcNMDYxMTEwMDAwMDAwWhcNMzExMTEwMDAwMDAwWjBlMQsw
# CQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3d3cu
# ZGlnaWNlcnQuY29tMSQwIgYDVQQDExtEaWdpQ2VydCBBc3N1cmVkIElEIFJvb3Qg
# Q0EwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCtDhXO5EOAXLGH87dg
# +XESpa7cJpSIqvTO9SA5KFhgDPiA2qkVlTJhPLWxKISKityfCgyDF3qPkKyK53lT
# XDGEKvYPmDI2dsze3Tyoou9q+yHyUmHfnyDXH+Kx2f4YZNISW1/5WBg1vEfNoTb5
# a3/UsDg+wRvDjDPZ2C8Y/igPs6eD1sNuRMBhNZYW/lmci3Zt1/GiSw0r/wty2p5g
# 0I6QNcZ4VYcgoc/lbQrISXwxmDNsIumH0DJaoroTghHtORedmTpyoeb6pNnVFzF1
# roV9Iq4/AUaG9ih5yLHa5FcXxH4cDrC0kqZWs72yl+2qp/C3xag/lRbQ/6GW6whf
# GHdPAgMBAAGjYzBhMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB0G
# A1UdDgQWBBRF66Kv9JLLgjEtUYunpyGd823IDzAfBgNVHSMEGDAWgBRF66Kv9JLL
# gjEtUYunpyGd823IDzANBgkqhkiG9w0BAQUFAAOCAQEAog683+Lt8ONyc3pklL/3
# cmbYMuRCdWKuh+vy1dneVrOfzM4UKLkNl2BcEkxY5NM9g0lFWJc1aRqoR+pWxnmr
# EthngYTffwk8lOa4JiwgvT2zKIn3X/8i4peEH+ll74fg38FnSbNd67IJKusm7Xi+
# fT8r87cmNW1fiQG2SVufAQWbqz0lwcy2f8Lxb4bG+mRo64EtlOtCt/qMHt1i8b5Q
# Z7dsvfPxH2sMNgcWfzd8qVttevESRmCD1ycEvkvOl77DZypoEd+A5wwzZr8TDRRu
# 838fYxAe+o0bJW1sj6W3YQGx0qMmoRBxna3iw/nDmVG3KwcIzi7mULKn+gpFL6Lw
# 8jCCBP4wggPmoAMCAQICEA1CSuC+Ooj/YEAhzhQA8N0wDQYJKoZIhvcNAQELBQAw
# cjELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ
# d3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVk
# IElEIFRpbWVzdGFtcGluZyBDQTAeFw0yMTAxMDEwMDAwMDBaFw0zMTAxMDYwMDAw
# MDBaMEgxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwgSW5jLjEgMB4G
# A1UEAxMXRGlnaUNlcnQgVGltZXN0YW1wIDIwMjEwggEiMA0GCSqGSIb3DQEBAQUA
# A4IBDwAwggEKAoIBAQDC5mGEZ8WK9Q0IpEXKY2tR1zoRQr0KdXVNlLQMULUmEP4d
# yG+RawyW5xpcSO9E5b+bYc0VkWJauP9nC5xj/TZqgfop+N0rcIXeAhjzeG28ffnH
# bQk9vmp2h+mKvfiEXR52yeTGdnY6U9HR01o2j8aj4S8bOrdh1nPsTm0zinxdRS1L
# sVDmQTo3VobckyON91Al6GTm3dOPL1e1hyDrDo4s1SPa9E14RuMDgzEpSlwMMYpK
# jIjF9zBa+RSvFV9sQ0kJ/SYjU/aNY+gaq1uxHTDCm2mCtNv8VlS8H6GHq756Wwog
# L0sJyZWnjbL61mOLTqVyHO6fegFz+BnW/g1JhL0BAgMBAAGjggG4MIIBtDAOBgNV
# HQ8BAf8EBAMCB4AwDAYDVR0TAQH/BAIwADAWBgNVHSUBAf8EDDAKBggrBgEFBQcD
# CDBBBgNVHSAEOjA4MDYGCWCGSAGG/WwHATApMCcGCCsGAQUFBwIBFhtodHRwOi8v
# d3d3LmRpZ2ljZXJ0LmNvbS9DUFMwHwYDVR0jBBgwFoAU9LbhIB3+Ka7S5GGlsqIl
# ssgXNW4wHQYDVR0OBBYEFDZEho6kurBmvrwoLR1ENt3janq8MHEGA1UdHwRqMGgw
# MqAwoC6GLGh0dHA6Ly9jcmwzLmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtdHMu
# Y3JsMDKgMKAuhixodHRwOi8vY3JsNC5kaWdpY2VydC5jb20vc2hhMi1hc3N1cmVk
# LXRzLmNybDCBhQYIKwYBBQUHAQEEeTB3MCQGCCsGAQUFBzABhhhodHRwOi8vb2Nz
# cC5kaWdpY2VydC5jb20wTwYIKwYBBQUHMAKGQ2h0dHA6Ly9jYWNlcnRzLmRpZ2lj
# ZXJ0LmNvbS9EaWdpQ2VydFNIQTJBc3N1cmVkSURUaW1lc3RhbXBpbmdDQS5jcnQw
# DQYJKoZIhvcNAQELBQADggEBAEgc3LXpmiO85xrnIA6OZ0b9QnJRdAojR6OrktIl
# xHBZvhSg5SeBpU0UFRkHefDRBMOG2Tu9/kQCZk3taaQP9rhwz2Lo9VFKeHk2eie3
# 8+dSn5On7UOee+e03UEiifuHokYDTvz0/rdkd2NfI1Jpg4L6GlPtkMyNoRdzDfTz
# ZTlwS/Oc1np72gy8PTLQG8v1Yfx1CAB2vIEO+MDhXM/EEXLnG2RJ2CKadRVC9S0y
# OIHa9GCiurRS+1zgYSQlT7LfySmoc0NR2r1j1h9bm/cuG08THfdKDXF+l7f0P4Tr
# weOjSaH6zqe/Vs+6WXZhiV9+p7SOZ3j5NpjhyyjaW4emii8wggUwMIIEGKADAgEC
# AhAECRgbX9W7ZnVTQ7VvlVAIMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVT
# MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j
# b20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0xMzEw
# MjIxMjAwMDBaFw0yODEwMjIxMjAwMDBaMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK
# EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNV
# BAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EwggEi
# MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQD407Mcfw4Rr2d3B9MLMUkZz9D7
# RZmxOttE9X/lqJ3bMtdx6nadBS63j/qSQ8Cl+YnUNxnXtqrwnIal2CWsDnkoOn7p
# 0WfTxvspJ8fTeyOU5JEjlpB3gvmhhCNmElQzUHSxKCa7JGnCwlLyFGeKiUXULaGj
# 6YgsIJWuHEqHCN8M9eJNYBi+qsSyrnAxZjNxPqxwoqvOf+l8y5Kh5TsxHM/q8grk
# V7tKtel05iv+bMt+dDk2DZDv5LVOpKnqagqrhPOsZ061xPeM0SAlI+sIZD5SlsHy
# DxL0xY4PwaLoLFH3c7y9hbFig3NBggfkOItqcyDQD2RzPJ6fpjOp/RnfJZPRAgMB
# AAGjggHNMIIByTASBgNVHRMBAf8ECDAGAQH/AgEAMA4GA1UdDwEB/wQEAwIBhjAT
# BgNVHSUEDDAKBggrBgEFBQcDAzB5BggrBgEFBQcBAQRtMGswJAYIKwYBBQUHMAGG
# GGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBDBggrBgEFBQcwAoY3aHR0cDovL2Nh
# Y2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNydDCB
# gQYDVR0fBHoweDA6oDigNoY0aHR0cDovL2NybDQuZGlnaWNlcnQuY29tL0RpZ2lD
# ZXJ0QXNzdXJlZElEUm9vdENBLmNybDA6oDigNoY0aHR0cDovL2NybDMuZGlnaWNl
# cnQuY29tL0RpZ2lDZXJ0QXNzdXJlZElEUm9vdENBLmNybDBPBgNVHSAESDBGMDgG
# CmCGSAGG/WwAAgQwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNlcnQu
# Y29tL0NQUzAKBghghkgBhv1sAzAdBgNVHQ4EFgQUWsS5eyoKo6XqcQPAYPkt9mV1
# DlgwHwYDVR0jBBgwFoAUReuir/SSy4IxLVGLp6chnfNtyA8wDQYJKoZIhvcNAQEL
# BQADggEBAD7sDVoks/Mi0RXILHwlKXaoHV0cLToaxO8wYdd+C2D9wz0PxK+L/e8q
# 3yBVN7Dh9tGSdQ9RtG6ljlriXiSBThCk7j9xjmMOE0ut119EefM2FAaK95xGTlz/
# kLEbBw6RFfu6r7VRwo0kriTGxycqoSkoGjpxKAI8LpGjwCUR4pwUR6F6aGivm6dc
# IFzZcbEMj7uo+MUSaJ/PQMtARKUT8OZkDCUIQjKyNookAv4vcn4c10lFluhZHen6
# dGRrsutmQ9qzsIzV6Q3d9gEgzpkxYz0IGhizgZtPxpMQBvwHgfqL2vmCSfdibqFT
# +hKUGIUukpHqaGxEMrJmoecYpJpkUe8wggUxMIIEGaADAgECAhAKoSXW1jIbfkHk
# Bdo2l8IVMA0GCSqGSIb3DQEBCwUAMGUxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxE
# aWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xJDAiBgNVBAMT
# G0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAeFw0xNjAxMDcxMjAwMDBaFw0z
# MTAxMDcxMjAwMDBaMHIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJ
# bmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAvBgNVBAMTKERpZ2lDZXJ0
# IFNIQTIgQXNzdXJlZCBJRCBUaW1lc3RhbXBpbmcgQ0EwggEiMA0GCSqGSIb3DQEB
# AQUAA4IBDwAwggEKAoIBAQC90DLuS82Pf92puoKZxTlUKFe2I0rEDgdFM1EQfdD5
# fU1ofue2oPSNs4jkl79jIZCYvxO8V9PD4X4I1moUADj3Lh477sym9jJZ/l9lP+Cb
# 6+NGRwYaVX4LJ37AovWg4N4iPw7/fpX786O6Ij4YrBHk8JkDbTuFfAnT7l3ImgtU
# 46gJcWvgzyIQD3XPcXJOCq3fQDpct1HhoXkUxk0kIzBdvOw8YGqsLwfM/fDqR9mI
# UF79Zm5WYScpiYRR5oLnRlD9lCosp+R1PrqYD4R/nzEU1q3V8mTLex4F0IQZchfx
# FwbvPc3WTe8GQv2iUypPhR3EHTyvz9qsEPXdrKzpVv+TAgMBAAGjggHOMIIByjAd
# BgNVHQ4EFgQU9LbhIB3+Ka7S5GGlsqIlssgXNW4wHwYDVR0jBBgwFoAUReuir/SS
# y4IxLVGLp6chnfNtyA8wEgYDVR0TAQH/BAgwBgEB/wIBADAOBgNVHQ8BAf8EBAMC
# AYYwEwYDVR0lBAwwCgYIKwYBBQUHAwgweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUF
# BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6
# Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5j
# cnQwgYEGA1UdHwR6MHgwOqA4oDaGNGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9E
# aWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwOqA4oDaGNGh0dHA6Ly9jcmwzLmRp
# Z2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwUAYDVR0gBEkw
# RzA4BgpghkgBhv1sAAIEMCowKAYIKwYBBQUHAgEWHGh0dHBzOi8vd3d3LmRpZ2lj
# ZXJ0LmNvbS9DUFMwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4IBAQBxlRLp
# UYdWac3v3dp8qmN6s3jPBjdAhO9LhL/KzwMC/cWnww4gQiyvd/MrHwwhWiq3BTQd
# aq6Z+CeiZr8JqmDfdqQ6kw/4stHYfBli6F6CJR7Euhx7LCHi1lssFDVDBGiy23UC
# 4HLHmNY8ZOUfSBAYX4k4YU1iRiSHY4yRUiyvKYnleB/WCxSlgNcSR3CzddWThZN+
# tpJn+1Nhiaj1a5bA9FhpDXzIAbG5KHW3mWOFIoxhynmUfln8jA/jb7UBJrZspe6H
# USHkWGCbugwtK22ixH67xCUrRwIIfEmuE7bhfEJCKMYYVs9BNLZmXbZ0e/VWMyIv
# IjayS6JKldj1po5SMIIFPTCCBCWgAwIBAgIQBNXcH0jqydhSALrNmpsqpzANBgkq
# hkiG9w0BAQsFADByMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5j
# MRkwFwYDVQQLExB3d3cuZGlnaWNlcnQuY29tMTEwLwYDVQQDEyhEaWdpQ2VydCBT
# SEEyIEFzc3VyZWQgSUQgQ29kZSBTaWduaW5nIENBMB4XDTIwMDYyNjAwMDAwMFoX
# DTIzMDcwNzEyMDAwMFowejELMAkGA1UEBhMCUEwxEjAQBgNVBAgMCcWabMSFc2tp
# ZTERMA8GA1UEBxMIS2F0b3dpY2UxITAfBgNVBAoMGFByemVteXPFgmF3IEvFgnlz
# IEVWT1RFQzEhMB8GA1UEAwwYUHJ6ZW15c8WCYXcgS8WCeXMgRVZPVEVDMIIBIjAN
# BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAv7KB3iyBrhkLUbbFe9qxhKKPBYqD
# Bqlnr3AtpZplkiVjpi9dMZCchSeT5ODsShPuZCIxJp5I86uf8ibo3vi2S9F9AlfF
# jVye3dTz/9TmCuGH8JQt13ozf9niHecwKrstDVhVprgxi5v0XxY51c7zgMA2g1Ub
# +3tii0vi/OpmKXdL2keNqJ2neQ5cYly/GsI8CREUEq9SZijbdA8VrRF3SoDdsWGf
# 3tZZzO6nWn3TLYKQ5/bw5U445u/V80QSoykszHRivTj+H4s8ABiforhi0i76beA6
# Ea41zcH4zJuAp48B4UhjgRDNuq8IzLWK4dlvqrqCBHKqsnrF6BmBrv+BXQIDAQAB
# o4IBxTCCAcEwHwYDVR0jBBgwFoAUWsS5eyoKo6XqcQPAYPkt9mV1DlgwHQYDVR0O
# BBYEFBixNSfoHFAgJk4JkDQLFLRNlJRmMA4GA1UdDwEB/wQEAwIHgDATBgNVHSUE
# DDAKBggrBgEFBQcDAzB3BgNVHR8EcDBuMDWgM6Axhi9odHRwOi8vY3JsMy5kaWdp
# Y2VydC5jb20vc2hhMi1hc3N1cmVkLWNzLWcxLmNybDA1oDOgMYYvaHR0cDovL2Ny
# bDQuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwTAYDVR0gBEUw
# QzA3BglghkgBhv1sAwEwKjAoBggrBgEFBQcCARYcaHR0cHM6Ly93d3cuZGlnaWNl
# cnQuY29tL0NQUzAIBgZngQwBBAEwgYQGCCsGAQUFBwEBBHgwdjAkBggrBgEFBQcw
# AYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tME4GCCsGAQUFBzAChkJodHRwOi8v
# Y2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRTSEEyQXNzdXJlZElEQ29kZVNp
# Z25pbmdDQS5jcnQwDAYDVR0TAQH/BAIwADANBgkqhkiG9w0BAQsFAAOCAQEAmr1s
# z4lsLARi4wG1eg0B8fVJFowtect7SnJUrp6XRnUG0/GI1wXiLIeow1UPiI6uDMsR
# XPHUF/+xjJw8SfIbwava2eXu7UoZKNh6dfgshcJmo0QNAJ5PIyy02/3fXjbUREHI
# NrTCvPVbPmV6kx4Kpd7KJrCo7ED18H/XTqWJHXa8va3MYLrbJetXpaEPpb6zk+l8
# Rj9yG4jBVRhenUBUUj3CLaWDSBpOA/+sx8/XB9W9opYfYGb+1TmbCkhUg7TB3gD6
# o6ESJre+fcnZnPVAPESmstwsT17caZ0bn7zETKlNHbc1q+Em9kyBjaQRcEQoQQNp
# ezQug9ufqExx6lHYDjGCBFwwggRYAgEBMIGGMHIxCzAJBgNVBAYTAlVTMRUwEwYD
# VQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xMTAv
# BgNVBAMTKERpZ2lDZXJ0IFNIQTIgQXNzdXJlZCBJRCBDb2RlIFNpZ25pbmcgQ0EC
# EATV3B9I6snYUgC6zZqbKqcwCQYFKw4DAhoFAKB4MBgGCisGAQQBgjcCAQwxCjAI
# oAKAAKECgAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIB
# CzEOMAwGCisGAQQBgjcCARUwIwYJKoZIhvcNAQkEMRYEFE5OZGrRsQjsA7T7vqcd
# 8HE6gTofMA0GCSqGSIb3DQEBAQUABIIBAEkwwgdbEYnUwBiYsE79ibj3LkfBYmnC
# 8eLfYTZuLxwYrExoFAOFLq8cG0GdLnuc6T15eCdAenV2StIc+q7frotHE6e2Lnr2
# wPfWx/mO8Rsg+f0SOP8nznr/jPSBTlRBCAUIz7rX1+bC3EaL4mxbHlltWgFfnfDS
# aUUdmJUV4/f38gOG+4y62VqNd1y6sUT8Hfmu4bFAuRikq3U4e5fBOfoZ5/8qWvPt
# BPLsxct9CnXvduICQiLnI5cT4VmytfbZeVXAqJawAH1v1UjCAE1ZKewqb+gOEeu2
# jLV3GIvjOC53h2rMcu6/XfKh2AZxmdMTApfHj0d9sQGAJScOoGP0C+2hggIwMIIC
# LAYJKoZIhvcNAQkGMYICHTCCAhkCAQEwgYYwcjELMAkGA1UEBhMCVVMxFTATBgNV
# BAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8G
# A1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIFRpbWVzdGFtcGluZyBDQQIQ
# DUJK4L46iP9gQCHOFADw3TANBglghkgBZQMEAgEFAKBpMBgGCSqGSIb3DQEJAzEL
# BgkqhkiG9w0BBwEwHAYJKoZIhvcNAQkFMQ8XDTIxMDgxOTA4NTE1OVowLwYJKoZI
# hvcNAQkEMSIEIABFzyXy2hregWo/xjFqTDOBjx2W+SjDwlMKJkKl2jNJMA0GCSqG
# SIb3DQEBAQUABIIBAFe2WnUJNTp86u+wGzE3zH+8Bn+evYL9dZoWW4nPs5Wnw5Li
# wmFzW0t/jVfBGZgjRnKv6Kyh6RyHwpmM5KVw0ImHtHOzCECCih0AmJTMizMN1zNB
# Jnshy2nQ0d8PQRNC6aIhtxQ+/dRIp58ewg+tPiDMFY7/4VLAqT03nCltLlx8NfAs
# ng0K0HfnFSk4YJ9h3Nl5iOCG5lREQQIeRHWVJadhHq6llAOOmkjsIthgXDuNuPcc
# 0WLy6gAg+adnTSr9BTkPmVbzQaW/IpIYYOc1tGhc42N8gnG8qOpsIN1v606gwguL
# FaBgw+UxXZB1WtNxlxS3pbXnbfCGTH7+jy/jpAE=
# SIG # End signature block