public/New-UcmEXHOConnection.ps1
#PerformScriptSigning Function New-UcmEXHOConnection { <# .SYNOPSIS Grabs stored creds and creates a new Exchange Online session This function is designed to auto reconnect to Exchange Online during batch migrations and the like. At present, it does not support modern auth. (I havent intergrated it yet) When called, the function looks for a cred.xml file in the current folder and attempts to connect to Exchange 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-UcmEXHOConnection .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" : Not connected 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: 18/11/2021 .VERSION HISTORY 1.2: Fixed function returning "OK" on connection failure ( https://github.com/Atreidae/UcmPSTools/issues/6 ) 1.1: Updated to "Ucm" naming convention Better inline documentation 1.0: Initial Public Release .REQUIRED FUNCTIONS/MODULES Modules MicrosoftTeams (Install-Module MicrosoftTeams) 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 connect to Exchange Online PowerShell Typicaly 'Exchange Read Only Admin' or better .LINK http://www.UcMadScientist.com https://github.com/Atreidae/UcmPsTools #> [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-UcmEXHOConnection' [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 file $null = (Remove-Variable -Name Config -Scope Global -ErrorAction SilentlyContinue) $global:Config = @{} $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. $pscred = $global:StoredPsCred #Exchange connection try block Try { Write-UcmLog -Message 'Connecting to Exchange Online' -Severity 2 -Component $function #Handle domain override if ($null -eq $Global:Config.override){ $EXCHOSession = (New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $pscred -Authentication Basic -AllowRedirection)} Else {$EXCHOSession = (New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://outlook.office365.com/powershell-liveid/ -Credential $pscred -Authentication Basic -AllowRedirection) } #Import the connected session Import-Module (Import-PSSession -Session $EXCHOSession -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 Exchange 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 # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUep1vN8324YIi1Jaak4wBkHjW # da+ggg4OMIIGsDCCBJigAwIBAgIQCK1AsmDSnEyfXs2pvZOu2TANBgkqhkiG9w0B # 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 # BgkqhkiG9w0BCQQxFgQUHxhv5dqmgB5xDoS2ywVG5oAzHOIwDQYJKoZIhvcNAQEB # BQAEggIAb9npSonGLTgNh20t4QHw85ndzGK+2p98yvlheteGLO/zzdT4CPFWn2Js # nsj/sQa90XEl1iaITglzzSINBCd4dICgJ0Nn07Eq0ad3qA/UL1IexHXC/c/EgmHN # 6ZgByGhcoPpWEMPGJ1DtFqLtJsenyIvZkwdeMzNVCSru9pfcoUChNVaRiGcVohL5 # Rq+tz9SQl0cKmvkP5GXz2k+vfHXUSmzUmAX+ByQV7dTP5hB0a0W3XknAEFPjQh7f # uVeIL7KlEaahd+d6AoLB6pELjal6LxyH8zLM9Bk0kkB74cqH+eP8s9mcCMpZZ+60 # vtB4oXBZ2ileTYQeAYcWe3YkjXZhp3xyfdxpDNig+83rVJD8N3CxiR4TlvGWbRU2 # 4h7dIpkPvj5F8YgzUyY9IcnBeSnXTrPGhMcELQ4ftJ2A7Z9smpSmp5gQKF+ZU9lD # aFBetoj4V6Liv2eQycZozFoShaFuKkXsVu7JRgdSJl2R9+BZ3Dtr9OL/0GgLoSll # G0k4PFtcrZ16kqkcYoF9qNVk4U6oJWthTAybY4w8htrPl61KOWTSUTVlbgAExc9C # pYGIuFSslpdtSdAQ0bUILpanMEarOj9IN0OqrBIvBmjqzTcyGDe8jX9ACMm9gcqs # Zi8UJPmwmvYASNqke0xWtneC4Gl2H5ftS+HFlrb+UNcEDUbgG7Y= # SIG # End signature block |