public/New-UcmMSOLConnection.ps1

#PerformScriptSigning
Function New-UcmMSOLConnection
{
    <#
            .SYNOPSIS
            Grabs stored creds and creates a new MSOL session
 
            .DESCRIPTION
            This function is designed to auto reconnect to Azure AD (V1) during batch migrations and the like.
            At present, it does not support modern auth. (I havent implemented it yet)
 
            When called, the function looks for a cred.xml file in the current folder and attempts to connect to Office 365 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-MSOLConnection
 
            .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 Azure AD (V1)
            "Error" : Not connected to Azure AD (V1)
            "Unknown" : Cmdlet reached the end of the fucntion 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.1
            Date: 18/11/2021
 
            .VERSION HISTORY
            1.1: Updated to "Ucm" naming convention
            Better inline documentation
 
            1.0: Initial Public Release
 
            .REQUIRED FUNCTIONS/MODULES
            Modules
            AzureAD (Install-Module MSOnline)
            UcmPSTools (Install-Module UcmPsTools) Includes Cmdlets below.
 
            Cmdlets
            Write-UcmLog: https://github.com/Atreidae/UcmPsTools/blob/main/public/Write-UcmLog.ps1
 
            .REQUIRED PERMISSIONS
            Any privledge level that can run 'Connect-MsolService'
            Typically "Office 365 User 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-UcmMSOLConnection'
    [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 in memory, if not check for cred.xml, failing that prompt the user 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
        {
            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 MSOL
    $pscred = $global:StoredPsCred
    Write-UcmLog -Message 'Connecting to MSOnline (AzureAD V1)' -Severity 2 -Component $function
    Try
    {
        $MSOLSession = (Connect-MsolService -Credential $pscred)

        #Import the connected session
        Import-Module (Import-PSSession -Session $MSOLSession -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 Microsoft Online (AzureAD V1): $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
# AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUcYYCDMGla8Ngm9odS1gEsB2d
# n4aggg4OMIIGsDCCBJigAwIBAgIQCK1AsmDSnEyfXs2pvZOu2TANBgkqhkiG9w0B
# 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
# BgkqhkiG9w0BCQQxFgQUwY8UV7g326f1EN7YJ1V9sL+FwsYwDQYJKoZIhvcNAQEB
# BQAEggIAJNre3pZ5uuWu07rFYjx9koC8XKNpVFnf4+5wzgLa3snhu2bytZ0FYtJm
# LjudMhvd2xSFOHeu9kpAUH7aZRoBsJceDFEiEc64MREzbAg6Zu18CpGHay7ahm6T
# jq8zmi3/AWf65CvrcJT0emWu+5F7JJ1aEUggIYQ6Jmft/B3HjmuGvnPlLBv4q+Xo
# kX93ip65Q6t12F2aFj7mMT6IXd+MebCpZL7If9WPxs9eMq332gD2Lpi2RZKhMrnk
# Uj3vf8vDkTmhXPeRj1+VIGX6tc5bcahE5OB43RBTv1vRqobbS5mipSCszTpNT3wu
# pH+berju1I1CjMaMQrSGurtMUOoQM9b/vCfi/KPen98RqK8b927XLLqEagmLi+sc
# VVLjd+TqAK4oJoQYf9VKk6j+sM+/kaE6rsQQyrNweqRSumk+pK++sN1tyJFgL3z2
# j9BrGcCnOY8chb7S9JxATtkGW0Ym8Pz+LzFaCpwkGcGjlGZQi3L6BItZF0YQBX40
# 4su/yVHzESwGGVHiFY8ONFvQPuRVZHcgr8xaxNPidWJybbW2mNuYnFRbuKwJlbwj
# 0wuD2/CvHhGBqu0gWPXzJlnjNs7z++hq9ufpSo0D16X/TwIMaOXLlgMihJaI/23m
# lgePBOAXLdRSaw5H6q/EsvBu2qMaN81RruCDeBIr+GnOgUCnF0k=
# SIG # End signature block