ConnectO365.psm1
<#
.SYNOPSIS module for connect-o365 .DESCRIPTION Authentication functions .NOTES General notes #> <# .Synopsis Retrieve credentials using the UI and store these in a file in the userprofile\creds folder the credentials are also returned. .EXAMPLE Set-myCreds -UserName Admin@contoso.com #> $script:MSG_Cred = 'Please enter the Tenant Admin or Service Admin password' $script:MSG_CredCancel = 'No password entered or user canceled' function Set-myCreds { Param ( # The Account or Username [Parameter()] [ValidateNotNullOrEmpty()] [Alias("Username")] # Backward compat with v1.6.7 and older [string]$Account ) $Credential = Get-Credential -Account $Account -Message $Script:MSG_Cred if ($Credential) { $Store = "$env:USERPROFILE\creds\$Account.txt" MkDir "$env:USERPROFILE\Creds" -ea 0 | Out-Null $Credential.Password | ConvertFrom-SecureString | Set-Content $store Write-Verbose "Saved credentials to $store" } else { write-warning $script:MSG_CredCancel } return $Credential } <# .Synopsis Test if credentials for a specific username are stored in the \creds folder .EXAMPLE if ( Test-MyCreds -UserName Admin@contoso.com ) { "credentials found" } #> function Test-myCreds { param( # The Account or Username [Parameter()] [ValidateNotNullOrEmpty()] [Alias("Username")] # Backward compat with v1.6.7 and older [string]$Account ) $Store = "$env:USERPROFILE\creds\$Account.txt" return (Test-Path $store) } <# .Synopsis retrieve credentials -Persist indicates that the credentials should be saved -Force indicates that the password should be re-entered by the user .EXAMPLE # retrieve the stored credentials, if not present just prompt for the password Get-MyCreds -UserName Admin@contoso.com .EXAMPLE # store the credentials for future re-use, overwrites any existing credentials Get-MyCreds -UserName Admin@contoso.com -persist #> <# .Synopsis Short description .DESCRIPTION Long description .EXAMPLE Example of how to use this cmdlet .EXAMPLE Another example of how to use this cmdlet #> function Get-myCreds { Param ( # The Account or Username [Parameter()] [ValidateNotNullOrEmpty()] [Alias("Username")] # Backward compat with v1.6.7 and older [string]$Account, # Persist username and password [switch] $Persist ) $Store = "$env:USERPROFILE\creds\$Account.txt" if ( (Test-Path $store) -AND $Persist -eq $false ) { #use a stored password if found , unless -persist/-force is used to ask for and store a new password Write-Verbose "Retrieved credentials from $store" $Password = Get-Content $store | ConvertTo-SecureString $Credential = New-Object System.Management.Automation.PsCredential($Account,$Password) return $Credential } else { if ($persist -and -not [string]::IsNullOrEmpty($Account)) { WRITE-VERBOSE 'Ask and store new credentials' $admincredentials = Set-myCreds $Account return $admincredentials } else { WRITE-VERBOSE 'Ask for credentials' return Get-Credential -Credential $Account } } } <# .Synopsis Retrieves credentials that are stored either in the \creds folder, or in the windows storedcredentials Windows stored credentials depend on an external module to be in installed (CredentialManager) .EXAMPLE RetrieveCredentials -account admin@contso.com .EXAMPLE RetrieveCredentials -account admin@contso.com -persist .EXAMPLE #retrieve a credentian using a alias from the credential manager RetrieveCredentials -account Production #> function RetrieveCredentials { Param ( # The Account or Username [Parameter()] [ValidateNotNullOrEmpty()] [string]$Account, [switch]$Persist ) $admincredentials = $null #if credentials are stored in the filestore if (test-myCreds $account) { write-verbose 'Find credentials from credential folder' $admincredentials = Get-myCreds $account -Persist:$Persist } else { #check if the credentialmanager module is installed $CM = get-module credentialmanager -ListAvailable | select -Last 1 if ($cm -ne $null -and $CM.Version -eq "2.0") { write-verbose 'Find credentials stored in the credential manager' #Find the credentials stored in the credential manager #check match on target name $stored = Get-StoredCredential -Type GENERIC -Target $account -AsCredentialObject| select -First 1 #otherwise check on username if ($stored -eq $null) { write-verbose 'Find credentials based on user name' $credentials = Get-StoredCredential -Type GENERIC -AsCredentialObject #work around pipeline constraints in get-stored $credentials = $credentials | where { $_.UserName -like '?*@?*' -and $_.Type -eq 'GENERIC'} | select -Property UserName, TargetName, Type, TargetAlias, Comment $stored = $credentials | where {$_.UserName-ieq $account} | select -First 1 } if ($persist) { write-verbose 'Asking for a new password' #if -Persist is specified we need to ask for a new password and update the stored password if ($stored) { $name= $stored.Username } else { $name=$account} $newCred = Get-Credential -UserName $name -Message $Script:MSG_Cred if ($newCred -eq $null) { write-warning $script:MSG_CredCancel } else { if ($stored) { write-verbose 'Update existing Stored Credential' $stored = New-StoredCredential -Comment "Connect-O365" -Password $newCred.GetNetworkCredential().Password -Persist ENTERPRISE -Target $stored.TargetName -Type GENERIC -UserName $newcred.UserName } else { write-verbose 'Create New Stored Credential' $stored = New-StoredCredential -Comment "Connect-O365" -Password $newCred.GetNetworkCredential().Password -Persist ENTERPRISE -Target $newcred.UserName -Type GENERIC -UserName $newcred.UserName } } } #If a stored cred was found if ($stored -ne $null) { write-verbose "Retrieving Target : $($stored.Targetname)" $admincredentials = Get-StoredCredential -Target $stored.Targetname -Type 'GENERIC' } else { #If not found, and if no -Persist then old fashioned write-verbose "Ask for credential" $admincredentials = Get-Credential -UserName $Account -Message $Script:MSG_Cred } } } #write-verbose "Cred : $($admincredentials.UserName)" -Verbose return $admincredentials } # SIG # Begin signature block # MIIgNAYJKoZIhvcNAQcCoIIgJTCCICECAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUAA9YiW6U4jwW5mL0CiLum1on # gQCgghtjMIIDtzCCAp+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 # 8jCCBTAwggQYoAMCAQICEAQJGBtf1btmdVNDtW+VUAgwDQYJKoZIhvcNAQELBQAw # ZTELMAkGA1UEBhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQ # d3d3LmRpZ2ljZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBS # b290IENBMB4XDTEzMTAyMjEyMDAwMFoXDTI4MTAyMjEyMDAwMFowcjELMAkGA1UE # BhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2lj # ZXJ0LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENvZGUg # U2lnbmluZyBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAPjTsxx/ # DhGvZ3cH0wsxSRnP0PtFmbE620T1f+Wondsy13Hqdp0FLreP+pJDwKX5idQ3Gde2 # qvCchqXYJawOeSg6funRZ9PG+yknx9N7I5TkkSOWkHeC+aGEI2YSVDNQdLEoJrsk # acLCUvIUZ4qJRdQtoaPpiCwgla4cSocI3wz14k1gGL6qxLKucDFmM3E+rHCiq85/ # 6XzLkqHlOzEcz+ryCuRXu0q16XTmK/5sy350OTYNkO/ktU6kqepqCquE86xnTrXE # 94zRICUj6whkPlKWwfIPEvTFjg/BougsUfdzvL2FsWKDc0GCB+Q4i2pzINAPZHM8 # np+mM6n9Gd8lk9ECAwEAAaOCAc0wggHJMBIGA1UdEwEB/wQIMAYBAf8CAQAwDgYD # VR0PAQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMDMHkGCCsGAQUFBwEBBG0w # azAkBggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEMGCCsGAQUF # BzAChjdodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVk # SURSb290Q0EuY3J0MIGBBgNVHR8EejB4MDqgOKA2hjRodHRwOi8vY3JsNC5kaWdp # Y2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3JsMDqgOKA2hjRodHRw # Oi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURSb290Q0EuY3Js # ME8GA1UdIARIMEYwOAYKYIZIAYb9bAACBDAqMCgGCCsGAQUFBwIBFhxodHRwczov # L3d3dy5kaWdpY2VydC5jb20vQ1BTMAoGCGCGSAGG/WwDMB0GA1UdDgQWBBRaxLl7 # KgqjpepxA8Bg+S32ZXUOWDAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823I # DzANBgkqhkiG9w0BAQsFAAOCAQEAPuwNWiSz8yLRFcgsfCUpdqgdXRwtOhrE7zBh # 134LYP3DPQ/Er4v97yrfIFU3sOH20ZJ1D1G0bqWOWuJeJIFOEKTuP3GOYw4TS63X # X0R58zYUBor3nEZOXP+QsRsHDpEV+7qvtVHCjSSuJMbHJyqhKSgaOnEoAjwukaPA # JRHinBRHoXpoaK+bp1wgXNlxsQyPu6j4xRJon89Ay0BEpRPw5mQMJQhCMrI2iiQC # /i9yfhzXSUWW6Fkd6fp0ZGuy62ZD2rOwjNXpDd32ASDOmTFjPQgaGLOBm0/GkxAG # /AeB+ova+YJJ92JuoVP6EpQYhS6SkepobEQysmah5xikmmRR7zCCBTEwggQZoAMC # AQICEAn8oNuSsuSr/+Oj5/k7HugwDQYJKoZIhvcNAQELBQAwcjELMAkGA1UEBhMC # VVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0 # LmNvbTExMC8GA1UEAxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENvZGUgU2ln # bmluZyBDQTAeFw0xNjA5MjQwMDAwMDBaFw0xNzA4MDExMjAwMDBaMG4xCzAJBgNV # BAYTAk5MMRUwEwYDVQQIEwxadWlkLUhvbGxhbmQxEjAQBgNVBAcTCVBpam5hY2tl # cjEZMBcGA1UEChMQQWRyaWFhbiBWZXJsaW5kZTEZMBcGA1UEAxMQQWRyaWFhbiBW # ZXJsaW5kZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBANaBtMwH6hc7 # qnfSqNmlEUnx+WuUlc/s9iGc15cGoXX3C1iis/Eib+kBFrxiAmO5fZR1rfhHQqPu # MWr5vLRzfSkPzU21SjeH1MWCV68UvxTEqG/GqMHZ0KfHiaG7BbL8+/j9a2PV8cBf # JXyTh7J6xSdeK7jDvkNOPI/VbWGT4tsZ8LghzeKIv7po9jSdf2fVrkSxc1Nrhzd7 # JxdPmVxnzlFXg6V/d/i2+MqBBLsgOsnYcPpujq+KFL0iWrnGBs6YcAmbWgCuzo/1 # CBA8AJARVroaKjY2ublzPiO5vnvvjalJ6WZbo9Oy7TGXmOpnajk4HsgErTrPnyEj # uqxRTLSZn0sCAwEAAaOCAcUwggHBMB8GA1UdIwQYMBaAFFrEuXsqCqOl6nEDwGD5 # LfZldQ5YMB0GA1UdDgQWBBS4iKChjKj7M8uDygqqUkPqQWbEajAOBgNVHQ8BAf8E # BAMCB4AwEwYDVR0lBAwwCgYIKwYBBQUHAwMwdwYDVR0fBHAwbjA1oDOgMYYvaHR0 # cDovL2NybDMuZGlnaWNlcnQuY29tL3NoYTItYXNzdXJlZC1jcy1nMS5jcmwwNaAz # oDGGL2h0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9zaGEyLWFzc3VyZWQtY3MtZzEu # Y3JsMEwGA1UdIARFMEMwNwYJYIZIAYb9bAMBMCowKAYIKwYBBQUHAgEWHGh0dHBz # Oi8vd3d3LmRpZ2ljZXJ0LmNvbS9DUFMwCAYGZ4EMAQQBMIGEBggrBgEFBQcBAQR4 # MHYwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmRpZ2ljZXJ0LmNvbTBOBggrBgEF # BQcwAoZCaHR0cDovL2NhY2VydHMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0U0hBMkFz # c3VyZWRJRENvZGVTaWduaW5nQ0EuY3J0MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcN # AQELBQADggEBAB0RlGTVco8OVFOTE1oybL5rjKQSljdOiRuJje8iK71RuTJ/7jsi # I2m8uMyY/6kjN7Hou3Ao/H0L4JVOGrYKOnLfDP64LowW9Kbsn3k+m6QLePPBk98M # v74fSzBdqdPJrCJkw5+nZFHmXZb9EhKyinEg2rua3XA0oUV51QxSJfrHHuA7CXUs # 7vGRCzIPewM+OxYu2MRvI6sOmLXk1jNOJnnkvx5cVoKTk2gmDKiTLLxLZCjXt9bf # H8AoGLhoyGV6NLZ/Yz/brGGJwNqzjuqOIDZjJ3ShxP8Tx9NjdssSKBMs8oG8pjY5 # VWqMyLKaK0r4JNQD3tZmCHUy+HfovC8UAD0wggZqMIIFUqADAgECAhADAZoCOv9Y # sWvW1ermF/BmMA0GCSqGSIb3DQEBBQUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV # BAMTGERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMTAeFw0xNDEwMjIwMDAwMDBaFw0y # NDEwMjIwMDAwMDBaMEcxCzAJBgNVBAYTAlVTMREwDwYDVQQKEwhEaWdpQ2VydDEl # MCMGA1UEAxMcRGlnaUNlcnQgVGltZXN0YW1wIFJlc3BvbmRlcjCCASIwDQYJKoZI # hvcNAQEBBQADggEPADCCAQoCggEBAKNkXfx8s+CCNeDg9sYq5kl1O8xu4FOpnx9k # WeZ8a39rjJ1V+JLjntVaY1sCSVDZg85vZu7dy4XpX6X51Id0iEQ7Gcnl9ZGfxhQ5 # rCTqqEsskYnMXij0ZLZQt/USs3OWCmejvmGfrvP9Enh1DqZbFP1FI46GRFV9GIYF # jFWHeUhG98oOjafeTl/iqLYtWQJhiGFyGGi5uHzu5uc0LzF3gTAfuzYBje8n4/ea # 8EwxZI3j6/oZh6h+z+yMDDZbesF6uHjHyQYuRhDIjegEYNu8c3T6Ttj+qkDxss5w # RoPp2kChWTrZFQlXmVYwk/PJYczQCMxr7GJCkawCwO+k8IkRj3cCAwEAAaOCAzUw # ggMxMA4GA1UdDwEB/wQEAwIHgDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoG # CCsGAQUFBwMIMIIBvwYDVR0gBIIBtjCCAbIwggGhBglghkgBhv1sBwEwggGSMCgG # CCsGAQUFBwIBFhxodHRwczovL3d3dy5kaWdpY2VydC5jb20vQ1BTMIIBZAYIKwYB # BQUHAgIwggFWHoIBUgBBAG4AeQAgAHUAcwBlACAAbwBmACAAdABoAGkAcwAgAEMA # ZQByAHQAaQBmAGkAYwBhAHQAZQAgAGMAbwBuAHMAdABpAHQAdQB0AGUAcwAgAGEA # YwBjAGUAcAB0AGEAbgBjAGUAIABvAGYAIAB0AGgAZQAgAEQAaQBnAGkAQwBlAHIA # dAAgAEMAUAAvAEMAUABTACAAYQBuAGQAIAB0AGgAZQAgAFIAZQBsAHkAaQBuAGcA # IABQAGEAcgB0AHkAIABBAGcAcgBlAGUAbQBlAG4AdAAgAHcAaABpAGMAaAAgAGwA # aQBtAGkAdAAgAGwAaQBhAGIAaQBsAGkAdAB5ACAAYQBuAGQAIABhAHIAZQAgAGkA # bgBjAG8AcgBwAG8AcgBhAHQAZQBkACAAaABlAHIAZQBpAG4AIABiAHkAIAByAGUA # ZgBlAHIAZQBuAGMAZQAuMAsGCWCGSAGG/WwDFTAfBgNVHSMEGDAWgBQVABIrE5iy # mQftHt+ivlcNK2cCzTAdBgNVHQ4EFgQUYVpNJLZJMp1KKnkag0v0HonByn0wfQYD # VR0fBHYwdDA4oDagNIYyaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0 # QXNzdXJlZElEQ0EtMS5jcmwwOKA2oDSGMmh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNv # bS9EaWdpQ2VydEFzc3VyZWRJRENBLTEuY3JsMHcGCCsGAQUFBwEBBGswaTAkBggr # BgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAChjVo # dHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRBc3N1cmVkSURDQS0x # LmNydDANBgkqhkiG9w0BAQUFAAOCAQEAnSV+GzNNsiaBXJuGziMgD4CH5Yj//7HU # aiwx7ToXGXEXzakbvFoWOQCd42yE5FpA+94GAYw3+puxnSR+/iCkV61bt5qwYCbq # aVchXTQvH3Gwg5QZBWs1kBCge5fH9j/n4hFBpr1i2fAnPTgdKG86Ugnw7HBi02JL # sOBzppLA044x2C/jbRcTBu7kA7YUq/OPQ6dxnSHdFMoVXZJB2vkPgdGZdA0mxA5/ # G7X1oPHGdwYoFenYk+VVFvC7Cqsc21xIJ2bIo4sKHOWV2q7ELlmgYd3a822iYemK # C23sEhi991VUQAOSK2vCUcIKSK+w1G7g9BQKOhvjjz3Kr2qNe9zYRDCCBs0wggW1 # oAMCAQICEAb9+QOWA63qAArrPye7uhswDQYJKoZIhvcNAQEFBQAwZTELMAkGA1UE # BhMCVVMxFTATBgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2lj # ZXJ0LmNvbTEkMCIGA1UEAxMbRGlnaUNlcnQgQXNzdXJlZCBJRCBSb290IENBMB4X # DTA2MTExMDAwMDAwMFoXDTIxMTExMDAwMDAwMFowYjELMAkGA1UEBhMCVVMxFTAT # BgNVBAoTDERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTEh # MB8GA1UEAxMYRGlnaUNlcnQgQXNzdXJlZCBJRCBDQS0xMIIBIjANBgkqhkiG9w0B # AQEFAAOCAQ8AMIIBCgKCAQEA6IItmfnKwkKVpYBzQHDSnlZUXKnE0kEGj8kz/E1F # kVyBn+0snPgWWd+etSQVwpi5tHdJ3InECtqvy15r7a2wcTHrzzpADEZNk+yLejYI # A6sMNP4YSYL+x8cxSIB8HqIPkg5QycaH6zY/2DDD/6b3+6LNb3Mj/qxWBZDwMiEW # icZwiPkFl32jx0PdAug7Pe2xQaPtP77blUjE7h6z8rwMK5nQxl0SQoHhg26Ccz8m # SxSQrllmCsSNvtLOBq6thG9IhJtPQLnxTPKvmPv2zkBdXPao8S+v7Iki8msYZbHB # c63X8djPHgp0XEK4aH631XcKJ1Z8D2KkPzIUYJX9BwSiCQIDAQABo4IDejCCA3Yw # DgYDVR0PAQH/BAQDAgGGMDsGA1UdJQQ0MDIGCCsGAQUFBwMBBggrBgEFBQcDAgYI # KwYBBQUHAwMGCCsGAQUFBwMEBggrBgEFBQcDCDCCAdIGA1UdIASCAckwggHFMIIB # tAYKYIZIAYb9bAABBDCCAaQwOgYIKwYBBQUHAgEWLmh0dHA6Ly93d3cuZGlnaWNl # cnQuY29tL3NzbC1jcHMtcmVwb3NpdG9yeS5odG0wggFkBggrBgEFBQcCAjCCAVYe # ggFSAEEAbgB5ACAAdQBzAGUAIABvAGYAIAB0AGgAaQBzACAAQwBlAHIAdABpAGYA # aQBjAGEAdABlACAAYwBvAG4AcwB0AGkAdAB1AHQAZQBzACAAYQBjAGMAZQBwAHQA # YQBuAGMAZQAgAG8AZgAgAHQAaABlACAARABpAGcAaQBDAGUAcgB0ACAAQwBQAC8A # QwBQAFMAIABhAG4AZAAgAHQAaABlACAAUgBlAGwAeQBpAG4AZwAgAFAAYQByAHQA # eQAgAEEAZwByAGUAZQBtAGUAbgB0ACAAdwBoAGkAYwBoACAAbABpAG0AaQB0ACAA # bABpAGEAYgBpAGwAaQB0AHkAIABhAG4AZAAgAGEAcgBlACAAaQBuAGMAbwByAHAA # bwByAGEAdABlAGQAIABoAGUAcgBlAGkAbgAgAGIAeQAgAHIAZQBmAGUAcgBlAG4A # YwBlAC4wCwYJYIZIAYb9bAMVMBIGA1UdEwEB/wQIMAYBAf8CAQAweQYIKwYBBQUH # AQEEbTBrMCQGCCsGAQUFBzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYI # KwYBBQUHMAKGN2h0dHA6Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFz # c3VyZWRJRFJvb3RDQS5jcnQwgYEGA1UdHwR6MHgwOqA4oDaGNGh0dHA6Ly9jcmwz # LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcmwwOqA4oDaG # NGh0dHA6Ly9jcmw0LmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RD # QS5jcmwwHQYDVR0OBBYEFBUAEisTmLKZB+0e36K+Vw0rZwLNMB8GA1UdIwQYMBaA # FEXroq/0ksuCMS1Ri6enIZ3zbcgPMA0GCSqGSIb3DQEBBQUAA4IBAQBGUD7Jtygk # pzgdtlspr1LPUukxR6tWXHvVDQtBs+/sdR90OPKyXGGinJXDUOSCuSPRujqGcq04 # eKx1XRcXNHJHhZRW0eu7NoR3zCSl8wQZVann4+erYs37iy2QwsDStZS9Xk+xBdIO # PRqpFFumhjFiqKgz5Js5p8T1zh14dpQlc+Qqq8+cdkvtX8JLFuRLcEwAiR78xXm8 # TBJX/l/hHrwCXaj++wc4Tw3GXZG5D2dFzdaD7eeSDY2xaYxP+1ngIw/Sqq4AfO6c # Qg7PkdcntxbuD8O9fAqg7iwIVYUiuOsYGk38KiGtSTGDR5V3cdyxG0tLHBCcdxTB # nU8vWpUIKRAmMYIEOzCCBDcCAQEwgYYwcjELMAkGA1UEBhMCVVMxFTATBgNVBAoT # DERpZ2lDZXJ0IEluYzEZMBcGA1UECxMQd3d3LmRpZ2ljZXJ0LmNvbTExMC8GA1UE # AxMoRGlnaUNlcnQgU0hBMiBBc3N1cmVkIElEIENvZGUgU2lnbmluZyBDQQIQCfyg # 25Ky5Kv/46Pn+Tse6DAJBgUrDgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEKMAigAoAA # oQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4w # DAYKKwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQUBNLCOMrdfJOB4C2IbrBLGHRF # 174wDQYJKoZIhvcNAQEBBQAEggEAYdzCk92E+bZzW87pj7kyvPn7Cx/QPztI0fRu # VfSYxBXLfpvhlnLJkQgLs1bDE4vrA51eyb/E7aHcHUUlYT1xbxO85nrANS9f9tX4 # 7EoTtQl12/795t7Yv59EiKMvkrUN8qsBiwp3vi2c/NkWCZ4PZLlwbP1XaWo0jPHP # 1hL6MIjHjamo5gMjz+UIkhk8UsX9MiyvhV7w79U6R2MV63SPjMvObQ0iHlATx3tY # oQcQljFFTdtLG8g15InnVRxDoZG/PEec2IiDEUcPGnG3vQchnjZZ3vvZlOpe9+Ao # 4fSFK9Qu6TCM370GIkL8IWhaPJsJfT59E++28SIGqULKULWowKGCAg8wggILBgkq # hkiG9w0BCQYxggH8MIIB+AIBATB2MGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxE # aWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNVBAMT # GERpZ2lDZXJ0IEFzc3VyZWQgSUQgQ0EtMQIQAwGaAjr/WLFr1tXq5hfwZjAJBgUr # DgMCGgUAoF0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUx # DxcNMTYxMDA4MjEwODA5WjAjBgkqhkiG9w0BCQQxFgQUfVdHW48+nnmBoArNWgrk # e2uTyWEwDQYJKoZIhvcNAQEBBQAEggEAo2KImwWOUNtOE1q2HhVSLtUGn7nbPe/H # E24WsFQ5yTuJgU3nx36UqoiTXfEj9jBSnUMD7SaT5a2x9JxmZ9UM2UJqQVwStSZM # JXiwCj6VWNHm7uHOonBWEldvUsAXusUDZQbmyNH/2R18Ewyrntzp8Vt9w1k2poDy # LkuI2MbdsAr4cQol7II/M6+SVSYg6fSdvMh4yXN8XKpxX6XQLTRv2rz52R7yFvrq # /59kvkTOp5KFNjMA3uZo24uCE3QvcvRPBovWn6f5IM9yzm/Bkc5e5vn9sUgyx9as # 5kj1FO3X8dUKL7gWn0e2lks/pNS1d8ULzRkpzAuRBBWVoRwAymZ95w== # SIG # End signature block |