public/New-UcmSFBOConnection.ps1

#PerformScriptSigning
Function New-UcmSFBOConnection
{
    <#
            .SYNOPSIS
            Grabs stored creds and creates a new SFBO session
 
            .DESCRIPTION
            This function is designed to auto reconnect to Skype for Business online during batch migrations and the like.
            At present, it does not support modern auth. (The New-CsOnlineSession cmdlet doesnt support certificates yet)
 
            When called, the function looks for a cred.xml file in the current folder and attempts to connect to Skype for Business online using Basic Auth
 
            If there is no cred.xml in the current folder it will prompt for credentials, encrypt them and store them in a cred.xml file.
            The encrypted credentials can only be read by the windows user that created them so other users on the same system cant steal your credentials.
 
            .EXAMPLE
            PS> New-UcmSFBOConnection
 
            .INPUTS
            This function does not accept any input
 
            .OUTPUT
            This Cmdet returns a PSCustomObject with multiple Keys to indicate status
            $Return.Status
            $Return.Message
 
            Return.Status can return one of three values
            "OK" : Connected to Skype for Business Online
            "Error" : Unable to connect to Skype for Business Online
            "Unknown" : Cmdlet reached the end of the function without returning anything, this shouldnt happen, if it does please log an issue on Github
 
            Return.Message returns descriptive text showing the connected tenant, mainly for logging or reporting
 
            .NOTES
            Version: 1.2
            Date: 15/05/2021
 
            .VERSION HISTORY
            1.2: Fixed required module references (incorrectly referenced the Exchange Module)
 
            1.1: Updated to "Ucm" naming convention
            Better inline documentation
 
            1.0: Initial Public Release
 
            .REQUIRED FUNCTIONS/MODULES
            Modules
            Microsoft Teams (Install-Module MicrosoftTeams)
            UcmPSTools (Install-Module UcmPsTools) Includes Cmdlets below.
 
            Cmdlets
            Write-UcmLog: https://github.com/Atreidae/UcmPsTools/blob/main/public/Write-UcmLog.ps1
            Write-HTMLReport: https://github.com/Atreidae/UcmPsTools/blob/main/public/Write-HTMLReport.ps1 (optional)
 
 
            .REQUIRED PERMISIONS
            'Exchange Read Only Administrator' or better
 
            .LINK
            http://www.UcMadScientist.com
            https://github.com/Atreidae/UcmPsTools
 
            .ACKNOWLEDGEMENTS
            Greig Sheridan: Stop connect cmdlets deleting password variable https://github.com/Atreidae/BounShell/issues/7
    #>

    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidGlobalVars', '', Scope='Function')] #Required for intergration with BounShell
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidUsingConvertToSecureStringWithPlainText', '', Scope='Function')] #Todo https://github.com/Atreidae/UcmPSTools/issues/24
    [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '', Scope='Function')] #Todo https://github.com/Atreidae/UcmPSTools/issues/27

    Param #No parameters
    (

    )

    #region FunctionSetup, Set Default Variables for HTML Reporting and Write Log
    $function = 'New-UcmSFBOConnection'
    [hashtable]$Return = @{}
    $return.Function = $function
    $return.Status = "Unknown"
    $return.Message = "Function did not return a status message"

    # Log why we were called
    Write-UcmLog -Message "$($MyInvocation.InvocationName) called with $($MyInvocation.Line)" -Severity 1 -Component $function
    Write-UcmLog -Message "Parameters" -Severity 1 -Component $function -LogOnly
    Write-UcmLog -Message "$($PsBoundParameters.Keys)" -Severity 1 -Component $function -LogOnly
    Write-UcmLog -Message "Parameters Values" -Severity 1 -Component $function -LogOnly
    Write-UcmLog -Message "$($PsBoundParameters.Values)" -Severity 1 -Component $function -LogOnly
    Write-UcmLog -Message "Optional Arguments" -Severity 1 -Component $function -LogOnly
    Write-UcmLog -Message "$Args" -Severity 1 -Component $function -LogOnly

    #endregion FunctionSetup

    #region FunctionWork

    #Check we have creds, if not, get and store them
    If ($null -eq $Global:Config.SignInAddress)
    {
        Write-UcmLog -Message "No Credentials stored in Memory, checking for Creds file" -Severity 2 -Component $function
        If(!(Test-Path cred.xml))
        {
            Write-UcmLog -component $function -Message 'Could not locate creds file' -severity 2

            #Create a new creds variable
            $null = (Remove-Variable -Name Config -Scope Global -ErrorAction SilentlyContinue)
            $global:Config = @{}

            #Prompt user for creds
            $Global:Config.SignInAddress = (Read-Host -Prompt "Username")
            $Global:Config.Password = (Read-Host -Prompt "Password")
            $Global:Config.Override = (Read-Host -Prompt "OverrideDomain (Blank for none)")

            #Encrypt the creds
            $global:Config.Credential = ($Global:Config.Password | ConvertTo-SecureString -AsPlainText -Force)
            Remove-Variable -Name "Config.Password" -Scope "Global" -ErrorAction SilentlyContinue

            #write a secure creds file
            $Global:Config | Export-Clixml -Path ".\cred.xml"
        }
        Else #Cred XML Exists, load it
        {
            Write-UcmLog -component $function -Message 'Importing Credentials File' -severity 2
            $global:Config = @{}
            $global:Config = (Import-Clixml -Path ".\cred.xml")
            Write-UcmLog -component $function -Message 'Creds Loaded' -severity 2
        }
    }

    #Get the creds ready for the module

    $global:StoredPsCred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList ($global:Config.SignInAddress, $global:Config.Credential)
    ($global:StoredPsCred).Password.MakeReadOnly() #Stop modules deleteing the variable.

    #Connect to SFBO
    $pscred = $global:StoredPsCred
    Write-UcmLog -Message 'Connecting to Skype4B Online' -Severity 2 -Component $function
    Try
    {
        #Handle Domain Override
        If ($Global:Config.override -eq "")
        {
            $S4BOSession = (New-CsOnlineSession -Credential $pscred)
        }
        Else
        {
            $S4BOSession = (New-CsOnlineSession -Credential $pscred -OverrideAdminDomain $Global:Config.Override)
        }

        #Import the connected session
        Import-Module (Import-PSSession -Session $S4BOSession -AllowClobber -DisableNameChecking) -Global -DisableNameChecking

        #We haven't errored so return sucsessful
        $Return.Status = "OK"
        $Return.Message  = "Connected"
        Return $Return
    }
    Catch
    {
        #Something went wrong during the try block, return error
        $Return.Status = "Error"
        $Return.Message  = "Failed to connect to Skype for Business Online: $error[0]"
        Return $Return
    }
    #endregion FunctionWork

    #region FunctionReturn

    #Default Return Variable for my HTML Reporting Fucntion
    Write-UcmLog -Message "Reached end of $function without a Return Statement" -Severity 3 -Component $function
    $return.Status = "Unknown"
    $return.Message = "Function did not encounter return statement"
    Return $Return
    #endregion FunctionReturn
}
# SIG # Begin signature block
# MIIRwgYJKoZIhvcNAQcCoIIRszCCEa8CAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB
# gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUunimWosXtNtxypR/KP2ZvEo2
# liuggg4OMIIGsDCCBJigAwIBAgIQCK1AsmDSnEyfXs2pvZOu2TANBgkqhkiG9w0B
# AQwFADBiMQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYD
# VQQLExB3d3cuZGlnaWNlcnQuY29tMSEwHwYDVQQDExhEaWdpQ2VydCBUcnVzdGVk
# IFJvb3QgRzQwHhcNMjEwNDI5MDAwMDAwWhcNMzYwNDI4MjM1OTU5WjBpMQswCQYD
# VQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lD
# ZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEg
# Q0ExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEA1bQvQtAorXi3XdU5
# WRuxiEL1M4zrPYGXcMW7xIUmMJ+kjmjYXPXrNCQH4UtP03hD9BfXHtr50tVnGlJP
# DqFX/IiZwZHMgQM+TXAkZLON4gh9NH1MgFcSa0OamfLFOx/y78tHWhOmTLMBICXz
# ENOLsvsI8IrgnQnAZaf6mIBJNYc9URnokCF4RS6hnyzhGMIazMXuk0lwQjKP+8bq
# HPNlaJGiTUyCEUhSaN4QvRRXXegYE2XFf7JPhSxIpFaENdb5LpyqABXRN/4aBpTC
# fMjqGzLmysL0p6MDDnSlrzm2q2AS4+jWufcx4dyt5Big2MEjR0ezoQ9uo6ttmAaD
# G7dqZy3SvUQakhCBj7A7CdfHmzJawv9qYFSLScGT7eG0XOBv6yb5jNWy+TgQ5urO
# kfW+0/tvk2E0XLyTRSiDNipmKF+wc86LJiUGsoPUXPYVGUztYuBeM/Lo6OwKp7AD
# K5GyNnm+960IHnWmZcy740hQ83eRGv7bUKJGyGFYmPV8AhY8gyitOYbs1LcNU9D4
# R+Z1MI3sMJN2FKZbS110YU0/EpF23r9Yy3IQKUHw1cVtJnZoEUETWJrcJisB9IlN
# Wdt4z4FKPkBHX8mBUHOFECMhWWCKZFTBzCEa6DgZfGYczXg4RTCZT/9jT0y7qg0I
# U0F8WD1Hs/q27IwyCQLMbDwMVhECAwEAAaOCAVkwggFVMBIGA1UdEwEB/wQIMAYB
# Af8CAQAwHQYDVR0OBBYEFGg34Ou2O/hfEYb7/mF7CIhl9E5CMB8GA1UdIwQYMBaA
# FOzX44LScV1kTN8uZz/nupiuHA9PMA4GA1UdDwEB/wQEAwIBhjATBgNVHSUEDDAK
# BggrBgEFBQcDAzB3BggrBgEFBQcBAQRrMGkwJAYIKwYBBQUHMAGGGGh0dHA6Ly9v
# Y3NwLmRpZ2ljZXJ0LmNvbTBBBggrBgEFBQcwAoY1aHR0cDovL2NhY2VydHMuZGln
# aWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJvb3RHNC5jcnQwQwYDVR0fBDwwOjA4
# oDagNIYyaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZFJv
# b3RHNC5jcmwwHAYDVR0gBBUwEzAHBgVngQwBAzAIBgZngQwBBAEwDQYJKoZIhvcN
# AQEMBQADggIBADojRD2NCHbuj7w6mdNW4AIapfhINPMstuZ0ZveUcrEAyq9sMCcT
# Ep6QRJ9L/Z6jfCbVN7w6XUhtldU/SfQnuxaBRVD9nL22heB2fjdxyyL3WqqQz/WT
# auPrINHVUHmImoqKwba9oUgYftzYgBoRGRjNYZmBVvbJ43bnxOQbX0P4PpT/djk9
# ntSZz0rdKOtfJqGVWEjVGv7XJz/9kNF2ht0csGBc8w2o7uCJob054ThO2m67Np37
# 5SFTWsPK6Wrxoj7bQ7gzyE84FJKZ9d3OVG3ZXQIUH0AzfAPilbLCIXVzUstG2MQ0
# HKKlS43Nb3Y3LIU/Gs4m6Ri+kAewQ3+ViCCCcPDMyu/9KTVcH4k4Vfc3iosJocsL
# 6TEa/y4ZXDlx4b6cpwoG1iZnt5LmTl/eeqxJzy6kdJKt2zyknIYf48FWGysj/4+1
# 6oh7cGvmoLr9Oj9FpsToFpFSi0HASIRLlk2rREDjjfAVKM7t8RhWByovEMQMCGQ8
# M4+uKIw8y4+ICw2/O/TOHnuO77Xry7fwdxPm5yg/rBKupS8ibEH5glwVZsxsDsrF
# hsP2JjMMB0ug0wcCampAMEhLNKhRILutG4UI4lkNbcoFUCvqShyepf2gpx8GdOfy
# 1lKQ/a+FSCH5Vzu0nAPthkX0tGFuv2jiJmCG6sivqf6UHedjGzqGVnhOMIIHVjCC
# BT6gAwIBAgIQDyLHeeRvkUFg5QtSFTT8FjANBgkqhkiG9w0BAQsFADBpMQswCQYD
# VQQGEwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lD
# ZXJ0IFRydXN0ZWQgRzQgQ29kZSBTaWduaW5nIFJTQTQwOTYgU0hBMzg0IDIwMjEg
# Q0ExMB4XDTIzMDIyMzAwMDAwMFoXDTI2MDIyMzIzNTk1OVowXjELMAkGA1UEBhMC
# QVUxETAPBgNVBAgTCFZpY3RvcmlhMRAwDgYDVQQHEwdCZXJ3aWNrMRQwEgYDVQQK
# EwtKYW1lcyBBcmJlcjEUMBIGA1UEAxMLSmFtZXMgQXJiZXIwggIiMA0GCSqGSIb3
# DQEBAQUAA4ICDwAwggIKAoICAQC47oExh25TrxvApIYdMRYvjOdZCb8WwgeTemm3
# ZY7BElIWu6+gzRGqQe8RFsN7oIgin5pvjTYIToxt1CCag2A5o8L0NtULmxJEegc+
# VaF24DZQqI4qGQGH/Qnglqys6+yPkwLnfeSxpeWe4u49HUUGDFIxHCh42MlCLp/f
# fHT49QhhpO+LyeLnDoUs6DmahyIb6NeE2cW5AYRXEesW7GRNfXzygBSlVWJOgvcy
# V5Y4IvAZVx2hKKMTjYFIz4/RYMg7fwYZEJ2LRJ/GnVazobKAvh6ZBet5KwVNI9EI
# 29DtWQyK/RoPOguTRcB5VuiZVlv0xjBYM7iJuH2Soa3StQYVxL/5gjZCC9WOs4NR
# EIGU3XmHoogFDvoT1vf1izMPFQzdZfgPvy/XXsbgTVo5ncesJ6WtZwqwCXG1K0XW
# IPZqTHolc1MyU6K1bEHO+7YWLpKgM9THl644G7PEhcKpNDsHlfvLVQdYhI55UJtc
# iyMrTw11CNECvk3GK1mrluvKsrxdaH6G3Sp9VVHRtef6OZ5SlzkM5ID4egB2bXRb
# R/69bEuZr5hhm+v2lBSWIbZj/Mva6i/a/TAvy4vvPLo3DRcASkYZDC4T8gDMzmpG
# Xs4jAc9sfTL9z+o5u1PLJHFGRjJ+Wa2CgSftCdbKLjn+AY9m8ipc8jmOBKNY9yGI
# pQWapQIDAQABo4ICAzCCAf8wHwYDVR0jBBgwFoAUaDfg67Y7+F8Rhvv+YXsIiGX0
# TkIwHQYDVR0OBBYEFOBsg1xudlbXVSql8pWbiHoTyZS/MA4GA1UdDwEB/wQEAwIH
# gDATBgNVHSUEDDAKBggrBgEFBQcDAzCBtQYDVR0fBIGtMIGqMFOgUaBPhk1odHRw
# Oi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRDb2RlU2lnbmlu
# Z1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNybDBToFGgT4ZNaHR0cDovL2NybDQuZGln
# aWNlcnQuY29tL0RpZ2lDZXJ0VHJ1c3RlZEc0Q29kZVNpZ25pbmdSU0E0MDk2U0hB
# Mzg0MjAyMUNBMS5jcmwwPgYDVR0gBDcwNTAzBgZngQwBBAEwKTAnBggrBgEFBQcC
# ARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMIGUBggrBgEFBQcBAQSBhzCB
# hDAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMFwGCCsGAQUF
# BzAChlBodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVk
# RzRDb2RlU2lnbmluZ1JTQTQwOTZTSEEzODQyMDIxQ0ExLmNydDAJBgNVHRMEAjAA
# MA0GCSqGSIb3DQEBCwUAA4ICAQBOh5vRXqTCQzv0T1F2EgDkq5VnljlHsa7Ov/d/
# lpOvr8NebBiatxbhfhPCnToY7BD2f7YVsUuQ+VDdcIYsskcU5spBHcFYidg2jGu4
# 59FGMaS765XStDwGGTN/360gEsNYSnKWYL4+8jYWHlzRO0jHloyWz+gF5dYWzdDJ
# u1dudLIJ0RgrEVJeLSgIBWygLL5EyIzOPlrxztsILMSbdPTQLeBIm7ipOk4EACx1
# hhBVUsUoCAlASH+yCKDU4v2HFd7SzrkRUrf7XJ2Na2YsiHjiTGqHIE86KyvxGDhT
# 3n2/jX23Nh/bkWHurHwTfaTCOQ44ZlAbnZQjBlmrFn5hPMXRpciiQFmrKTPD/nuo
# 9MVnCciHEpHJ63/JZNF/eno1122/wVkL7MuRlCVHN7L/wuNQxQk3ARdIju6OD/Gi
# Mwg0Qih6HVWJtkHK3ExoUKKKUZCOvIeHxzp+K6FWUupPZKUgWzn4AHMxm6zr+Sde
# laIAACqAkxYsDYKbM7WlNi3uIH2HeXqU9uSDt5tgPpImrog/ab4HrhpDfITRgT1c
# cxaWQezpJEPC+kqVD41T3wlEie1Qm4vYWg+oBVEMBxVLh6CYbeppCRTEXRGnAiCH
# /Ma1uwyWnNCWxrhd1uSi6sj4ISzgnFyGCvsI0gavKpS5AQhapJgk6/fULTFeS+Ee
# kRH9FDGCAx4wggMaAgEBMH0waTELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lD
# ZXJ0LCBJbmMuMUEwPwYDVQQDEzhEaWdpQ2VydCBUcnVzdGVkIEc0IENvZGUgU2ln
# bmluZyBSU0E0MDk2IFNIQTM4NCAyMDIxIENBMQIQDyLHeeRvkUFg5QtSFTT8FjAJ
# BgUrDgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkqhkiG9w0B
# CQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAj
# BgkqhkiG9w0BCQQxFgQUczY4W95Yk7vZtvgkeFpaUQZYaC8wDQYJKoZIhvcNAQEB
# BQAEggIAGTPr8GJWjMrYgFwXCntR4KSZezIfZPzGyUBDFINYWh49VDS5QASzrmEH
# nnxyICQr+edQIKHtFVAi5Mta3bChMoq9cnm4qjl+YBkeoJipex0ClX5wyoHF+uyh
# RRzCl5uvlAQYOVthsmUDbVaaBIBT4Ef//2KMyi0Lci/Q9KtujlIKeIO+oBDAbhKD
# skqJWIS913Hae6hPIvz3dymhMZCxWAnb4N9T4tcf3laf4aDHkfvtoUFpRmp7gwZ7
# HSV0u+Da9YvhSb74vAdA3HoZV9yu1kIyjx4cwc3NWGIdPGhc0KPvFhvenoCWko27
# QLJNDFkvhTHU5Ncep97wR2Rr8BYMBDutaxLWdMY9Nui/9hThqU6vJ4XQUDQT4i7e
# LFhNwXzd90dzJ2Xv9PNk70ZT+ZC3UtA6zaYle9ZPFGGsSgLeitXeskY5w2jjs8p6
# pUEIjE4aWQVoa10kSkZwmTuw3ZTzIM9HSjN4M9ZaLrGW6VOBi0msjKqJX+7Ruv8z
# 90ZYbYwb6A+QxMMAC367+VG3c2/ZFuttgryi+K5zmzA14MuYn2LOLuXExVJ8mqkp
# aSzzXyiTaYGgm/XRnNyDGZvkwGFqCKINpvVPaeH5NOghBrivGfSrhevCKtcb67aK
# BI2R9qMFccyfRbvVbjWMJXVD7NM2i3NplsYSVrwv3KVkPCownl8=
# SIG # End signature block