Private/GetWorkingCredentials.ps1
function GetWorkingCredentials { [CmdletBinding(DefaultParameterSetName='PSCredential')] Param( [Parameter(Mandatory=$False)] [string]$RemoteHostNameOrIP, [Parameter( Mandatory=$False, ParameterSetName='PSCredential' )] [System.Management.Automation.PSCredential]$AltCredentials, [Parameter( Mandatory=$False, ParameterSetName='NoCredentialObject' )] [string]$UserName, [Parameter( Mandatory=$False, ParameterSetName='NoCredentialObject' )] [System.Security.SecureString]$Password ) #region >> Helper Functions function Check-CredsAndLockStatus { [CmdletBinding()] Param( [Parameter(Mandatory=$True)] $RemoteHostNetworkInfo, [Parameter( Mandatory=$True, ParameterSetName='PSCredential' )] [System.Management.Automation.PSCredential]$AltCredentials ) $CurrentlyLoadedAssemblies = [System.AppDomain]::CurrentDomain.GetAssemblies() if (![bool]$($CurrentlyLoadedAssemblies -match "System.DirectoryServices.AccountManagement")) { Add-Type -AssemblyName System.DirectoryServices.AccountManagement } $SimpleDomain = $RemoteHostNetworkInfo.Domain $SimpleDomainWLDAPPort = $SimpleDomain + ":3268" $DomainLDAPContainers = "DC=" + $($SimpleDomain -split "\.")[0] + "," + "DC=" + $($SimpleDomain -split "\.")[1] try { $SimpleUserName = $($AltCredentials.UserName -split "\\")[1] $PrincipleContext = [System.DirectoryServices.AccountManagement.PrincipalContext]::new( [System.DirectoryServices.AccountManagement.ContextType]::Domain, "$SimpleDomainWLDAPPort", "$DomainLDAPContainers", [System.DirectoryServices.AccountManagement.ContextOptions]::SimpleBind, "$($AltCredentials.UserName)", "$([Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($AltCredentials.Password)))" ) try { $UserPrincipal = [System.DirectoryServices.AccountManagement.UserPrincipal]::FindByIdentity($PrincipleContext, [System.DirectoryServices.AccountManagement.IdentityType]::SamAccountName, "$SimpleUserName") $AltCredentialsAreValid = $True } catch { $AltCredentialsAreValid = $False } if ($AltCredentialsAreValid) { # Determine if the User Account is locked $AccountLocked = $UserPrincipal.IsAccountLockedOut() if ($AccountLocked -eq $True) { Write-Error "The provided UserName $($AltCredentials.Username) is locked! Please unlock it before additional attempts at getting working credentials!" $global:FunctionResult = "1" return } } } catch { Write-Error $_ $global:FunctionResult = "1" return } $Output = [ordered]@{ AltCredentialsAreValid = $AltCredentialsAreValid } if ($AccountLocked) { $Output.Add("AccountLocked",$AccountLocked) } [pscustomobject]$Output } #endregion >> Helper Functions #region >> Variable/Parameter Transforms and PreRun Prep $CurrentlyLoadedAssemblies = [System.AppDomain]::CurrentDomain.GetAssemblies() $ResolveHostSplatParams = @{ ErrorAction = "Stop" } if ($RemoteHostNameOrIP) { $ResolveHostSplatParams.Add("HostNameOrIP",$RemoteHostNameOrIP) } else { $ResolveHostSplatParams.Add("HostNameOrIP",$env:ComputerName) } try { $RemoteHostNetworkInfo = ResolveHost @ResolveHostSplatParams } catch { if ($env:ComputerName -eq $($RemoteHostNameOrIP -split "\.")[0]) { $ResolveHostSplatParams = @{ ErrorAction = "Stop" } $ResolveHostSplatParams.Add("HostNameOrIP",$env:ComputerName) try { $RemoteHostNetworkInfo = ResolveHost @ResolveHostSplatParams } catch { Write-Error $_ Write-Error "Unable to resolve $RemoteHostNameOrIP! Halting!" $global:FunctionResult = "1" return } } else { Write-Error $_ Write-Error "Unable to resolve $RemoteHostNameOrIP! Halting!" $global:FunctionResult = "1" return } } [System.Collections.ArrayList]$WinRMEntriesToAdd = @() $null = $WinRMEntriesToAdd.Add($RemoteHostNetworkInfo.HostName) $null = $WinRMEntriesToAdd.Add($RemoteHostNetworkInfo.FQDN) $RemoteHostNetworkInfo.IPAddressList | foreach {$null = $WinRMEntriesToAdd.Add($_)} AddWinRMTrustedHost -NewRemoteHost $WinRMEntriesToAdd if (!$Username -and !$AltCredentials -and $RemoteHostNetworkInfo.HostName -eq $env:ComputerName) { #Write-Warning "The Remote Host is actually the Local Host (i.e. $env:ComputerName)!" $Output = [ordered]@{ LogonType = "LocalAccount" DeterminedCredsThatWorkedOnRemoteHost = $True WorkingCredsAreValidOnDomain = $False WorkingCredentials = "$(whoami)" RemoteHostWorkingLocation = $RemoteHostNetworkInfo.FQDN CurrentLoggedInUserCredsWorked = $True } [pscustomobject]$Output return } $EnvironmentInfo = Get-ItemProperty 'Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Volatile Environment\' $CurrentUserLogonServer = $EnvironmentInfo.LogonServer -replace '\\\\','' if ($CurrentUserLogonServer -eq $env:ComputerName) { $LogonServerIsDomainController = $False $LoggedInAsLocalUser = $True } else { $LogonServerIsDomainController = $True $LoggedInAsLocalUser = $False } if ($UserName) { while ($UserName -notmatch "\\") { $UserName = Read-Host -Prompt "The provided UserName is NOT in the correct format! Please enter a UserName with access to $($RemoteHostNetworkInfo.FQDN) using format <DomainPrefix_Or_$($RemoteHostNetworkInfo.HostName)>\<UserName>" } if (!$Password) { $Password = Read-Host -Prompt "Please enter the password for $UserName" -AsSecureString } $AltCredentials = [System.Management.Automation.PSCredential]::new($UserName,$Password) } #endregion >> Variable/Parameter Transforms and PreRun Prep #region >> Main Body if ($AltCredentials) { while ($AltCredentials.UserName -notmatch "\\") { $AltUserName = Read-Host -Prompt "The provided UserName is NOT in the correct format! Please enter a UserName with access to $($RemoteHostNetworkInfo.FQDN) using format <DomainPrefix_Or_$($RemoteHostNetworkInfo.HostName)>\<UserName>" $AltPassword = Read-Host -Prompt "Please enter the password for $AltUserName" -AsSecureString $AltCredentials = [System.Management.Automation.PSCredential]::new($AltUserName,$AltPassword) } if ($($AltCredentials.UserName -split "\\")[0] -ne $RemoteHostNetworkInfo.HostName -and $($AltCredentials.UserName -split "\\")[0] -ne $($RemoteHostNetworkInfo.Domain -split "\.")[0] ) { $ErrMsg = "Using the credentials provided we will not be able to find a Logon Server. The credentials do not " + "indicate a Local Logon (i.e. $($RemoteHostNetworkInfo.HostName)\$($($AltCredentials.UserName -split "\\")[1]) " + "or a Domain Logon (i.e. $($($($RemoteHostNetworkInfo.Domain) -split "\.")[0])\$($($AltCredentials.UserName -split "\\")[1])! " + "Halting!" Write-Error $ErrMsg $global:FunctionResult = "1" return } if ($LoggedInAsLocalUser) { # If we ARE trying a Local Account on the Remote Host if ($($AltCredentials.Username -split "\\")[0] -eq $RemoteHostNetworkInfo.HostName) { $LogonType = "LocalAccount" $AltCredentialsUncertain = $True $CurrentUserCredentialsMightWork = $False } # If we ARE NOT trying a Local Account on the Remote Host, we are necessarily trying Domain Credentials if ($($AltCredentials.Username -split "\\")[0] -ne $RemoteHostNetworkInfo.HostName) { $LogonType = "DomainAccount" $CurrentUserCredentialsMightWork = $False $CredsAndLockStatus = Check-CredsAndLockStatus -RemoteHostNetworkInfo $RemoteHostNetworkInfo -AltCredentials $AltCredentials $AltCredentialsAreValid = $CredsAndLockStatus.AltCredentialsAreValid if ($AltCredentialsAreValid) { $AccountLocked = $CredsAndLockStatus.AccountLocked } } } if (!$LoggedInAsLocalUser) { if ($AltCredentials.Username -eq $(whoami)) { # If we ARE trying a Local Account on the Remote Host if ($($AltCredentials.Username -split "\\")[0] -eq $RemoteHostNetworkInfo.HostName) { $LogonType = "LocalAccount" $AltCredentialsUncertain = $True $CurrentUserCredentialsMightWork = $False } # If we ARE NOT trying a Local Account on the Remote Host, we are necessarily trying Domain Credentials if ($($AltCredentials.Username -split "\\")[0] -ne $RemoteHostNetworkInfo.HostName) { $LogonType = "DomainAccount" # We know we're staying within the same Domain... $CurrentUserCredentialsMightWork = $True } } if ($AltCredentials.Username -ne $(whoami)) { # If we ARE trying a Local Account on the Remote Host if ($($AltCredentials.Username -split "\\")[0] -eq $RemoteHostNetworkInfo.HostName) { $LogonType = "LocalAccount" $AltCredentialsUncertain = $True $CurrentUserCredentialsMightWork = $False } # If we ARE NOT trying a Local Account on the Remote Host, we are necessarily trying Domain Credentials if ($($AltCredentials.Username -split "\\")[0] -ne $RemoteHostNetworkInfo.HostName) { $LogonType = "DomainAccount" # If we're staying in the same Domain... if ($EnvironmentInfo.UserDNSDomain -eq $RemoteHostNetworkInfo.Domain) { $CurrentUserCredentialsMightWork = $True } # If we're trying a machine on a different Domain... if ($EnvironmentInfo.UserDNSDomain -ne $RemoteHostNetworkInfo.Domain) { $CredsAndLockStatus = Check-CredsAndLockStatus -RemoteHostNetworkInfo $RemoteHostNetworkInfo -AltCredentials $AltCredentials $AltCredentialsAreValid = $CredsAndLockStatus.AltCredentialsAreValid if ($AltCredentialsAreValid) { $AccountLocked = $CredsAndLockStatus.AccountLocked } } # end Different Domain 'if' block } # end Domain Creds 'if' block } # end $AltCredentials.Username -ne $(whoami) 'if block' } # end !$LoggedInAsLocalUser 'if' block } # end $AltCredentials 'if' block if (!$AltCredentials) { # $AltCredentialsAreValid -eq $False because they are not provided... $AltCredentialsAreValid = $False if ($LoggedInAsLocalUser) { $CurrentUserCredentialsMightWork = $False } else { if ($RemoteHostNetworkInfo.Domain -eq $EnvironmentInfo.UserDNSDomain) { $LogonType = "DomainAccount" $CurrentUserCredentialsMightWork = $True } else { $CurrentUserCredentialsMightWork = $False } } } if ($AltCredentialsAreValid -or $AltCredentialsUncertain -or $AltCredentials) { # NOTE: For some reason, there are situations where FQDN works over HostName or visa versa. So we use # logic to try FQDN, and if that fails, try HostName try { $InvokeCommandOutput = Invoke-Command -ComputerName $RemoteHostNetworkInfo.FQDN -Credential $AltCredentials -ScriptBlock {"Success"} -ErrorAction Stop $TargetHostLocation = $RemoteHostNetworkInfo.FQDN $CredentialsWorked = $True $ProvidedCredsWorked = $True } catch { try { $InvokeCommandOutput = Invoke-Command -ComputerName $RemoteHostNetworkInfo.HostName -Credential $AltCredentials -ScriptBlock {"Success"} -ErrorAction Stop $TargetHostLocation = $RemoteHostNetworkInfo.HostName $CredentialsWorked = $True $ProvidedCredsWorked = $True } catch { if ($CurrentUserCredentialsMightWork) { $TryCurrentUserCreds = $True } else { Write-Warning "Unable to determine working credentials for $RemoteHostNameOrIP!" } } } } if ($($AltCredentialsAreValid -and $TryCurrentUserCreds) -or $(!$AltCredentials -and $CurrentUserCredentialsMightWork) -or $(!$LoggedInAsLocalUser -and $AltCredentials.Username -eq $(whoami)) ) { try { $InvokeCommandOutput = Invoke-Command -ComputerName $RemoteHostNetworkInfo.FQDN -ScriptBlock {"Success"} -ErrorAction Stop $TargetHostLocation = $RemoteHostNetworkInfo.FQDN $CredentialsWorked = $True $TriedCurrentlyLoggedInUser = $True } catch { try { $InvokeCommandOutput = Invoke-Command -ComputerName $RemoteHostNetworkInfo.HostName -ScriptBlock {"Success"} -ErrorAction Stop $TargetHostLocation = $RemoteHostNetworkInfo.HostName $CredentialsWorked = $True $TriedCurrentlyLoggedInUser = $True } catch { Write-Warning "Unable to determine working credentials for $RemoteHostNameOrIP!" } } } # Create Output $Output = [ordered]@{ LogonType = $LogonType } $CredentialsWorked = if ($CredentialsWorked) {$True} else {$False} $Output.Add("DeterminedCredsThatWorkedOnRemoteHost",$CredentialsWorked) if ($CredentialsWorked) { if ($LogonType -eq "LocalAccount") { $Output.Add("WorkingCredsAreValidOnDomain",$False) } else { $Output.Add("WorkingCredsAreValidOnDomain",$True) } if ($AltCredentials -and $ProvidedCredsWorked) { $WorkingCredentials = $AltCredentials } else { $WorkingCredentials = "$(whoami)" } $Output.Add("WorkingCredentials",$WorkingCredentials) $Output.Add("RemoteHostWorkingLocation",$TargetHostLocation) } if ($WorkingCredentials.UserName -eq "$(whoami)" -or $WorkingCredentials -eq "$(whoami)") { $Output.Add("CurrentLoggedInUserCredsWorked",$True) } else { if (!$TriedCurrentlyLoggedInUser) { $Output.Add("CurrentLoggedInUserCredsWorked","NotTested") } elseif ($TriedCurrentlyLoggedInUser -and $CredentialsWorked) { $Output.Add("CurrentLoggedInUserCredsWorked",$True) } elseif ($TriedCurrentlyLoggedInUser -and !$CredentialsWorked) { $Output.Add("CurrentLoggedInUserCredsWorked",$False) } } if ($AltCredentials) { if ($LogonType -eq "LocalAccount" -or $AltCredentialsAreValid -eq $False) { $Output.Add("ProvidedCredsAreValidOnDomain",$False) } elseif ($AltCredentialsAreValid -eq $True -or $ProvidedCredsWorked) { $Output.Add("ProvidedCredsAreValidOnDomain",$True) } elseif ($ProvidedCredsWorked -eq $null) { $Output.Add("ProvidedCredsAreValidOnDomain","NotTested") } elseif ($ProvidedCredsWorked -eq $False) { $Output.Add("ProvidedCredsAreValidOnDomain",$False) } else { $Output.Add("ProvidedCredsAreValidOnDomain",$AltCredentialsAreValid) } } if ($AltCredentialsAreValid -and !$CredentialsWorked) { $FinalWarnMsg = "Either $($RemoteHostNetworkInfo.FQDN) and/or $($RemoteHostNetworkInfo.HostName) " + "and/or $($RemoteHostNetworkInfo.IPAddressList[0]) is not part of the WinRM Trusted Hosts list " + "(see '`$(Get-ChildItem WSMan:\localhost\Client\TrustedHosts).Value'), or the WinRM Service on " + "$($RemoteHostNetworkInfo.FQDN) is not running, or $($AltCredentials.UserName) specifically " + "does not have access to $($RemoteHostNetworkInfo.FQDN)! If $($RemoteHostNetworkInfo.FQDN) is " + "not part of a Domain, then you may also need to add this regsitry setting on $($RemoteHostNetworkInfo.FQDN):`n" + " reg add HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System /v LocalAccountTokenFilterPolicy /t REG_DWORD /d 1 /f" + "Lastly, use the 'Get-NetConnectionProfile' cmdlet on $($RemoteHostNetworkInfo.FQDN) to determine if any " + "network adapters have a 'NetworkCategory' of 'Public'. If so you must change them to 'Private' via:`n" + " Get-NetConnectionProfile | Where-Object {`$_.NetworkCategory -eq 'Public'} | Set-NetConnectionProfile -NetworkCategory 'Private'" Write-Warning $FinalWarnMsg } [pscustomobject]$Output #endregion >> Main Body } # SIG # Begin signature block # MIIM3gYJKoZIhvcNAQcCoIIMzzCCDMsCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUuCHPXt5vBKaGkqe7ES8/B/sq # lqagggpPMIIEKTCCAxGgAwIBAgITRAAAAALGGh0rrvpIiwAAAAAAAjANBgkqhkiG # 9w0BAQsFADBAMRMwEQYKCZImiZPyLGQBGRYDbGFiMRUwEwYKCZImiZPyLGQBGRYF # YWxwaGExEjAQBgNVBAMTCUFscGhhREMwMTAeFw0xODExMDYxNTQ2MjhaFw0yMDEx # MDYxNTU2MjhaMEExEzARBgoJkiaJk/IsZAEZFgNsYWIxFTATBgoJkiaJk/IsZAEZ # FgVhbHBoYTETMBEGA1UEAxMKQWxwaGFTdWJDQTCCASIwDQYJKoZIhvcNAQEBBQAD # ggEPADCCAQoCggEBAJ0yJxQZZ7jXPnBuOefihL0ehpBF1zoZpcM30pWneQA/kk9w # ByX9ISyKWTABstiIu8b2g6lKUjZBM8AOcLPSjl1ZMQkh+qaSQbJFVNeNYllGpjd1 # oOYvSPtr9iPpghVkAFWw9IdOgnd/4XDd4NqlddyR4Qb0g7v3+AMYrqhQCk2VzELp # 215LEO9sy1EMy7+B29B6P43Rp7ljA9Wc4Hnl+onviFWcIxmIhd0yGdobSxOSDgv5 # SUBfwk+DW03Y9pmJJHCU9hXFFVsPnrfBEvicGrkYx0vA+/O+jh5otex4eR+Tt7eB # 5VhrfdHKbEkZnBwrJOVz3rURZIu3BsDFSfwNd70CAwEAAaOCARkwggEVMBAGCSsG # AQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRWBfwwFO+72Ebloy7rHmHnxX3k5DAZBgkr # BgEEAYI3FAIEDB4KAFMAdQBiAEMAQTAOBgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/ # BAUwAwEB/zAfBgNVHSMEGDAWgBTq79v4G/Vf91c0y+vSJBWEI/vmDTA8BgNVHR8E # NTAzMDGgL6AthitodHRwOi8vcGtpLmFscGhhLmxhYi9jZXJ0ZGF0YS9BbHBoYURD # MDEuY3JsMEcGCCsGAQUFBwEBBDswOTA3BggrBgEFBQcwAoYraHR0cDovL3BraS5h # bHBoYS5sYWIvY2VydGRhdGEvQWxwaGFEQzAxLmNydDANBgkqhkiG9w0BAQsFAAOC # AQEAoE9hHZ0Y5M5tC15cnxVNJa/ILfwRmwCxzPyOAUrdBu4jbSHF2vRsKIJAXFs4 # +mwXqXpLYSUbXF5tfB86OKs2f9L7soln3BXJHj3eEs27htf7RJK1JjPtO8rs3pdn # h7TbDO3nyjkTcywJioScFZUTdIsQj7TBm3HIQ+/ZSdIWMHlQnYV2kW13XqUZnLhv # PRjy1NMBG1BAxUrc4bMi1X+mVxoYb/tiB59jakd95wi7ICi2H/07dXoDpi+kAQA1 # ki1/U+cuDhuH7Q8hegt64MlmKD01rO5HODVujuIG1+M5ZkGDeLNKksPHcSJ/DBSn # KjZca16Sn9No2kLq1q9gD8X/wzCCBh4wggUGoAMCAQICE3AAAAAHhXSIXehTWisA # AAAAAAcwDQYJKoZIhvcNAQELBQAwQTETMBEGCgmSJomT8ixkARkWA2xhYjEVMBMG # CgmSJomT8ixkARkWBWFscGhhMRMwEQYDVQQDEwpBbHBoYVN1YkNBMB4XDTE4MTEw # NzAzMTQyMFoXDTE5MTEwNzAzMTQyMFowTzETMBEGCgmSJomT8ixkARkWA2xhYjEV # MBMGCgmSJomT8ixkARkWBWFscGhhMQ4wDAYDVQQDEwVVc2VyczERMA8GA1UEAxMI # YWxwaGFkZXYwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCMUGwGv3p0 # prkDmSUQphU6UvIFQ57NxJFUOSmMZ7SY/nYNDy0iTN26eD0S5J8AQE8B/IGLHUno # tKFl2AUcQ31hpaSLE1YkThR3WZ4SFUaBMUgKKLc/RQKqE0iNbAfh53N/nnGs6jyu # 47kyuFRwWE2tZee6b5hh0dbT7YZnahLO7cLWErU4ikWWjEA98TcMK1gaNa5ThBn1 # +4bo9wuxjRKIGpkUJBP/1gq8qeSJnfNelZ34lD0EEirj7/YTzL5YkHMSXTuFMozw # Av4lXUW/qZ1pAT9rKBalQETxBv9SuC31hU/2EiB4EYYqVFLHglFRogLd7nFZhqa/ # 2O+WdW2LsW9lAgMBAAGjggL/MIIC+zAOBgNVHQ8BAf8EBAMCB4AwHQYDVR0OBBYE # FMy71rz8tJOXdsGvBt6SIVSKUlrkMB8GA1UdIwQYMBaAFFYF/DAU77vYRuWjLuse # YefFfeTkMIH3BgNVHR8Ege8wgewwgemggeaggeOGgbJsZGFwOi8vL0NOPUFscGhh # U3ViQ0EsQ049QWxwaGFTdWJDQSxDTj1DRFAsQ049UHVibGljJTIwS2V5JTIwU2Vy # dmljZXMsQ049U2VydmljZXMsQ049Q29uZmlndXJhdGlvbixEQz1hbHBoYSxEQz1s # YWI/Y2VydGlmaWNhdGVSZXZvY2F0aW9uTGlzdD9iYXNlP29iamVjdENsYXNzPWNS # TERpc3RyaWJ1dGlvblBvaW50hixodHRwOi8vcGtpLmFscGhhLmxhYi9jZXJ0ZGF0 # YS9BbHBoYVN1YkNBLmNybDCB9AYIKwYBBQUHAQEEgecwgeQwgacGCCsGAQUFBzAC # hoGabGRhcDovLy9DTj1BbHBoYVN1YkNBLENOPUFJQSxDTj1QdWJsaWMlMjBLZXkl # MjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25maWd1cmF0aW9uLERDPWFscGhh # LERDPWxhYj9jQUNlcnRpZmljYXRlP2Jhc2U/b2JqZWN0Q2xhc3M9Y2VydGlmaWNh # dGlvbkF1dGhvcml0eTA4BggrBgEFBQcwAoYsaHR0cDovL3BraS5hbHBoYS5sYWIv # Y2VydGRhdGEvQWxwaGFTdWJDQS5jcnQwPQYJKwYBBAGCNxUHBDAwLgYmKwYBBAGC # NxUIhLycPIHG3hyBiYk0hLvpfobokGRgg9+kPoHDslgCAWQCAQIwHwYDVR0lBBgw # FgYKKwYBBAGCNwoDDAYIKwYBBQUHAwMwKQYJKwYBBAGCNxUKBBwwGjAMBgorBgEE # AYI3CgMMMAoGCCsGAQUFBwMDMC0GA1UdEQQmMCSgIgYKKwYBBAGCNxQCA6AUDBJh # bHBoYWRldkBhbHBoYS5sYWIwDQYJKoZIhvcNAQELBQADggEBAIhV0GPEvq5KwIs+ # DTqLsqHcojMyJhJwrZkEim2XAJfNQFkiDrZzism7lOyXYJol6Bjz1txhos7P194+ # VyBdEZ/Q+r94hrq6SFgC2gCAReDZiy50Au/hTv958QNX/O0OFdIGBxavLqBrWbwu # yH+RtE9E4LICSPPd0dM/5XE0xtqDMjZcl3pVkqgHpv3O3zgtsTW+FWr4b9lq3rCO # HxsBGU1w7Eh0LLK8MLqioecr/4B1rPTJkcASXWMU5bllQgQvUmlKW0GIfhC9aM4J # 04MeJOU1mHLjDcxwWpDD670AFmGRg/mMPxMywvY0HLUszWikcXNYxF1ph+LhlLI9 # f9R1qqkxggH5MIIB9QIBATBYMEExEzARBgoJkiaJk/IsZAEZFgNsYWIxFTATBgoJ # kiaJk/IsZAEZFgVhbHBoYTETMBEGA1UEAxMKQWxwaGFTdWJDQQITcAAAAAeFdIhd # 6FNaKwAAAAAABzAJBgUrDgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEKMAigAoAAoQKA # ADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYK # KwYBBAGCNwIBFTAjBgkqhkiG9w0BCQQxFgQU5csiMxggoObZY9WkH+eS/uD7jXMw # DQYJKoZIhvcNAQEBBQAEggEAe8cC0/5Jik53jFdPab/oi6q4/1VPcoWQkmPHDWLY # KsjwqD3izOLDVLXhdmK/uW2F4kTumkj39V4Dlkmww3if0aYiWGcAr4JJnEhSdiJc # obCpeWiZmx1+JQRJC+1wT02+NDVtnla6FnwoXsXkH9lDO7QwIZP+ar6d55eCm6+8 # z5D4x5G3oAFlUw2bGvIxmj0NKuAbnDs+HaWt6jIRQbOxPfhebVTnAy4tSeXNrjy4 # 2wcLqYrOM0f0Id3nJKkkI6fau21mmorgYu2uf6Lw0zW+w/msACvWq1oBjx2WcNj8 # 5wVX5ZvDug2+XkEytGx4r99TSjiuKles38FvP93Krr0m5A== # SIG # End signature block |