HPEVCCmdlets.psm1
<# � Copyright 2013-2017 Hewlett Packard Enterprise Development, L.P. All rights reserved. #> #The renci .dll used is version: 2014.4.6-beta1 #This version includes a few fixes that were important in some cases. #It can be downloaded at http://sshnet.codeplex.com/ try { #load the .dll - assumed to be in the current directory where the script is located $currModule = $MyInvocation.MyCommand.Definition $currPath = Split-Path -Path $currModule $dll = $currPath + "\Renci.Sshnet.dll" [void][reflection.assembly]::LoadFrom((Resolve-Path $dll)) } catch { Write-Error "Unable to load Renci.Sshnet.dll`n" } class HPEVCConnection { [string] $IP [string] $STATUS_TYPE [string] $STATUS_MESSAGE hidden [Object] $SSH hidden [Object] $Writer hidden [Object] $Stream # Constructor HPEVCConnection () { $this.IP = "" $this.STATUS_TYPE = "NA" $this.STATUS_MESSAGE = "NONE" } } function ReadStream($stream) { $op = "" $nullReadCount = 0 while($true) { $readOutput = $stream.Read() #Write-Host $readOutput -ForegroundColor Yellow $op = $op + $readOutput if($op.trim().EndsWith("hpiLO->")) { break } else { Start-Sleep -Milliseconds 100 Write-Host "." -NoNewline #uncomment this if you don't want to see a . for each read attempt if($readOutput -eq "") { if($nullReadCount -lt 50) #50 is the number of times to try reading - can be increased if output is missing { $nullReadCount = $nullReadCount + 1 } else { break } } } } Write-Host "`n" return $op } <# .Synopsis Connect-HPEVC Cmdlets creates connection to VC target .DESCRIPTION Connect-HPEVC Cmdlet creats a session to VC hardware represnted by its VC IP, Username and Password information from input parameters. This cmdlets creates a SSH connection to the VC hardware and returns a HPEVCConnection object. .EXAMPLE PS C:\Windows\system32> $con = Connect-HPEVC -VC 192.168.10.210 -Username Administrator -Password admin123 -Verbose VERBOSE: Last login: Wed Mar 15 15:34:02 2017 from 192.168.1.128 ------------------------------------------------------------------------------- HP Virtual Connect Management CLI v4.10 Build: 4.10-244 (r232253) Aug 27 2013 17:35:29 (C) Copyright 2006-2013 Hewlett-Packard Development Company, L.P. All Rights Reserved ------------------------------------------------------------------------------- GETTING STARTED: help : Displays a list of available subcommands exit : Quits the command shell <subcommand> ? : Displays a list of managed elements for a subcommand <subcommand> <managed element> ? : Displays detailed help for a command -> PS C:\Windows\system32> $con | fl IP : 192.168.10.210 STATUS_TYPE : OK STATUS_MESSAGE : #> function Connect-HPEVC { [CmdletBinding()] [Alias("convc")] [OutputType([HPEVCConnection])] Param ( # VC hardware IP address [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [string] $VC, # VC hardware Username [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=1)] [string] $Username, # VC hardware Password [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=2)] [string] $Password, # VC hardware Port with 22 as default value [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=3)] [int] $Port = 22 ) Process { try { # connecting to OA or iLO depending on $server type $ssh = new-object Renci.SshNet.SshClient($vc, $port, $Username, $Password) $ssh.Connect() $stream = $ssh.CreateShellStream("", 100,100,100,100,9999) #$reader = new-object System.IO.StreamReader($stream) $writer = new-object System.IO.StreamWriter($stream) $writer.AutoFlush = $true #display initial prompt start-sleep -milliseconds 1000 $line = $stream.Read(); Write-Verbose $line $conObj = New-Object HPEVCConnection $conObj.IP = $VC $conObj.STATUS_TYPE = "OK" $conObj.STATUS_MESSAGE = "" $conObj.SSH = $ssh $conObj.Writer = $writer $conObj.Stream = $stream } catch { $errStr = $_.ToString() $conObj = New-Object HPEVCConnection $conObj.IP = $VC $conObj.STATUS_TYPE = "ERROR" $conObj.STATUS_MESSAGE = $errStr } return $conObj } } <# .Synopsis Disconnects the session object. .DESCRIPTION Disconnect-HPEVC cmdlet disconnects the parameter connection object and clears the IP address and other members of the object. .EXAMPLE $con | Disconnect-HPEVC $con is a object created out of connect-HPEVC and after the execution $con will not hold any connection information. #> function Disconnect-HPEVC { [CmdletBinding()] [Alias("dishpevc")] [OutputType()] Param ( # Connection parameter object [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)] [HPEVCConnection] $Connection ) Process { try { if ( $Connection -ne $null -and $Connection.Stream -and $Connection.SSH ) { #clean up and disconnect $Connection.Stream.Dispose() if ( $con.SSH.IsConnected) { $Connection.SSH.Disconnect() $Connection.SSH.Dispose() } $Connection.IP = "" $Connection.STATUS_TYPE = "" $Connection = $null } } catch { $errStr = $_.ToString() Write-Error $errStr } } } <# .Synopsis Get-HPEVCModuleVersion returns self-module information. .DESCRIPTION This cmdlet displays all module related information from the manifest (.psd1) file into an object. .EXAMPLE PS C:\Windows\system32> $mod = Get-HPEVCModuleVersion PS C:\Windows\system32> $mod Name : hpevccmdlets Path : C:\Program Files\Hewlett-Packard\PowerShell\Modules\hpevccmdlets\HPEVCCmdlets.psm1 Description : Scripting Tools for Windows PowerShell : Virtual Connect (VC) Cmdlets use the VC CLI interface to communicate to VC. These cmdlets can be used to configure and manage VC hardware. NOTE: Only limited cmdlets are developed in this module. GUID : d53e17c5-e9cb-47ed-80a3-cb89132e8f16 Version : 1.0.0.0 CurrentUICultureName : en-US #> function Get-HPEVCModuleVersion{ [CmdletBinding()] [Alias("hpevcmodver")] [OutputType([PSObject])] param() # no parameters $mod = Get-Module | Where-Object {$_.Name -eq "HPEVCCmdlets"} $cul = Get-UICulture $versionObject = New-Object PSObject $versionObject | Add-member "Name" $mod.Name $versionObject | Add-member "Path" $mod.Path $versionObject | Add-member "Description" $mod.Description $versionObject | Add-member "GUID" $mod.GUID $versionObject | Add-member "Version" $mod.Version $versionObject | Add-member "CurrentUICultureName" $cul.Name return $versionObject } <# .Synopsis Start-HPEVCCertificateSigningRequest generate and transfer an SSL certificate signing request to a remote FTP or SFTP server.. .DESCRIPTION Generate and transfer an SSL certificate signing request to a remote FTP or SFTP server. If the private key size is 1024 bits, then this command upgrades the size to 2048 bits and restarts the VC web server. NOTE: Be sure to add brackets when using an IPv6 address in Address parameter. .EXAMPLE PS C:\Windows\system32> $con | Start-HPEVCCertificateSigningRequest -Address ftp://username:password@192.168.1.133 -CertificateFileName vc210.csr -Country US -State TX -Locality Houston -Organization HPE -CommonName powershvpn.com -Verbose ..................................................... VERBOSE: save ssl-csr address='ftp://192.168.1.133' filename='vc210.csr' CN='powershvpn.com' O='HPE' C='US' ST='TX' L='Houston' SUCCESS: SSL Certificate Signing Request (CSR) generated and transferred -> IP STATUS_TYPE STATUS_MESSAGE CERTIFICATE_LOCATION -- ----------- -------------- -------------------- 192.168.10.210 OK ftp://192.168.1.133/vc210.csr #> function Start-HPEVCCertificateSigningRequest { [CmdletBinding()] [Alias("hpevcgen")] [OutputType([PSObject])] Param ( # Connection Object as parameter [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true,Position=0)] [HPEVCConnection] $Connection, # The Address or host name of the FTP or SFTP server, with user name, password, and remote file containing the SSH keys to transfer. [parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=1)] [string] $Address, # Country information [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=2)] [string] $Country, # State information [parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=3)] [string] $State, # Locality information [parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=4)] [string] $Locality, # Organization information [parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=5)] [string] $Organization, # Common Name information [parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=6)] [string] $CommonName, [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=7)] [string] $CertificateFileName, [parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=8)] [string] $ContactPerson, [parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=9)] [string] $Email, [parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=10)] [string] $OrganizationalUnit, [parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=11)] [string] $Surname, [parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=12)] [string] $GivenName, [parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=13)] [string] $Initials, [parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=14)] [string] $DNQualifier, [parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=15)] [string] $AlternativeName, [parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=16)] [string] $ChallengePassword, [parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=17)] [string] $ConfirmPassword, [parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=18)] [string] $UnstructuredName ) Process { try { #$VCCmd = "save ssl-csr address=ftp://192.168.1.133 filename=vc-ssl-1.csr CN=powershvpn.com O='Hewlett-Packard' C=US ST=CA L=Cupertino OU=HPE Contact=HPE AlternativeName=HPE Email=HPE Surname=HPE GivenName=HPE Initials=HPE" #go to command menu to update server or enclosure UID $VCCmd = "save ssl-csr " if ( $Connection -ne $null ) { if($Address) { $VCCmd += "address='" + $Address + "' " } if($CertificateFileName) { $VCCmd += "filename='" + $CertificateFileName + "' " } if($CommonName) { $VCCmd += "CN='" + $CommonName + "' " } if($Organization) { $VCCmd += "O='" + $Organization + "' " } if($Country) { $VCCmd += "C='" + $Country + "' " } if($State) { $VCCmd += "ST='" + $State + "' " } if($Locality) { $VCCmd += "L='" + $Locality + "' " } if($OrganizationalUnit) { $VCCmd += "OU='" + $OrganizationalUnit + "' " } if($ContactPerson) { $VCCmd += "Contact='" + $ContactPerson + "' " } if($AlternativeName) { $VCCmd += "AlternativeName='" + $AlternativeName + "' " } if($Email) { $VCCmd += "Email='" + $Email + "' " } if($Surname) { $VCCmd += "Surname='" + $Surname + "' " } if($GivenName) { $VCCmd += "GivenName='" + $GivenName + "' " } if($Initials) { $VCCmd += "Initials='" + $Initials + "' " } if($UnstructuredName) { $VCCmd += "UnstructuredName='" + $UnstructuredName + "' " } if($DNQualifier) { $VCCmd += "DNQualifier='" + $DNQualifier + "' " } if($PSCmdlet.MyInvocation.BoundParameters.Keys.Contains("ChallengePassword")) { if($ChallengePassword -eq "") { $ChallengePassword = Read-Host "Enter Challenge Password" } $VCCmd += "ChallengePW='" + $ChallengePassword + "' " } if($PSCmdlet.MyInvocation.BoundParameters.Keys.Contains("ConfirmPassword")) { if($ConfirmPassword -eq "") { $ConfirmPassword = Read-Host "Enter Confirm Password" } $VCCmd += "ConfirmPW='" + $ConfirmPassword + "' " } } $Connection.Writer.Write($VCCmd+"`n") start-sleep -milliseconds 1000 $output = ReadStream $Connection.Stream Write-Verbose $output if($CertificateFileName) { $certifiateloc = $Address + '/' + $CertificateFileName } else { $certifiateloc = $Address + '/' + "vc-ssl.csr" } $Obj = New-Object PSObject $Obj | Add-Member NoteProperty IP $Connection.IP $Obj | Add-Member NoteProperty STATUS_TYPE "OK" $Obj | Add-Member NoteProperty STATUS_MESSAGE "" $Obj | Add-Member NoteProperty CERTIFICATE_LOCATION $certifiateloc #Extracting string message after ERROR: text in $output if($output -imatch "ERROR:") { $ret = $output -match "ERROR: (?<content>.*)" if($ret) { $Message = $Matches['content'] } $Obj.STATUS_TYPE = "ERROR" $Obj.STATUS_MESSAGE = $Message $Obj.CERTIFICATE_LOCATION = "" } } catch { $errStr = $_.ToString() #Write-Error $errStr $Obj = New-Object PSObject $Obj | Add-Member NoteProperty IP $Connection.IP $Obj | Add-Member NoteProperty STATUS_TYPE "ERROR" $Obj | Add-Member NoteProperty STATUS_MESSAGE $errStr } return $Obj } } <# .Synopsis Import-HPEVCCertificate cmdlet uploads the SSL certificate from a remote FTP server to VC. .DESCRIPTION Transfer an SSL certificate from a remote FTP or SFTP server and apply it to the VCM web server. When renewing certificates, the upload removes any previous Signed Certificate from VCM. NOTE: (1) After a new SSL certificate is applied, the web server resets. (2) Be sure to add brackets when using an IPv6 address in Address parameter (3) If Successful this cmdlet does not return output but in case of ERROR it returns PSObject. .EXAMPLE PS C:\Windows\system32> $con | Import-HPEVCCertificate -Address ftp://username:password@192.168.1.133 -Verbose -Filename certnew.cer .................................................... VERBOSE: load ssl-certificate Address='ftp://192.168.1.133' Filename='certnew.cer' SUCCESS: SSL certificate transferred and applied .EXAMPLE PS C:\Windows\system32> Import-HPEVCCertificate $con ftp://192.168.1.133 RootCA.cer -LDAPCertificate -Verbose .................................................... VERBOSE: load ldap-certificate Address='ftp://192.168.1.133' Filename='/RootCA.cer' SUCCESS: LDAP certificate transferred and applied -> #> function Import-HPEVCCertificate { [CmdletBinding()] [Alias("hpevccert")] [OutputType([PSObject])] Param ( # Connection object as parameter [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true, Position=0)] [HPEVCConnection] $Connection, # The Address or host name of the FTP or SFTP server, with user name, password, and remote file containing the SSH keys to transfer. [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, Position=1)] [string] $Address, # Filename of the uploading certificate [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=2)] [string] $Filename, # Switch parameter if user wants to use LDAP certificate [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName=$true, Position=3)] [switch] $LDAPCertificate ) Process { try { if ( $LDAPCertificate -eq $false ) { #$VCCmd = "load ssl-certificate Address=ftp://user:password@192.168.10.12 Filename=my-new-ssl.crt" $VCCmd = "load ssl-certificate " if($Address) { $VCCmd += "Address='" + $Address + "' " } if($Filename) { $VCCmd += "Filename='" + $Filename + "' " } } else { #$VCCmd = "load ldap-certificate Address=ftp://user:password@192.168.10.12 filename=/new-ldap.crt" $VCCmd = "load ldap-certificate " if($Address) { $VCCmd += "Address='" + $Address + "' " } if($Filename) { $VCCmd += "Filename='/" + $Filename + "' " } } #Write-Verbose "SSL cmd sent to VC:`n $VCCmd" $Connection.Writer.Write($VCCmd+"`n") start-sleep -milliseconds 1000 $output = ReadStream $Connection.Stream Write-Verbose $output #Extracting string message after ERROR: text in $output if($output -imatch "ERROR:") { $ret = $output -match "ERROR: (?<content>.*)" if($ret) { $Message = $Matches['content'] } $Obj = New-Object PSObject $Obj | Add-Member NoteProperty IP $Connection.IP $Obj | Add-Member NoteProperty STATUS_TYPE "ERROR" $Obj | Add-Member NoteProperty STATUS_MESSAGE $Message return $Obj } #No return object on SUCCESS case } catch { $errStr = $_.ToString() $Obj = New-Object PSObject $Obj | Add-Member NoteProperty IP $Connection.IP $Obj | Add-Member NoteProperty STATUS_TYPE "ERROR" $Obj | Add-Member NoteProperty STATUS_MESSAGE $errStr return $Obj } } } Export-ModuleMember -Function Connect-HPEVC, Disconnect-HPEVC, Start-HPEVCCertificateSigningRequest, Get-HPEVCModuleVersion, Import-HPEVCCertificate # SIG # Begin signature block # MIIkYQYJKoZIhvcNAQcCoIIkUjCCJE4CAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCDr8at8/xXO/Yq # 7fqftwapmBYHfOodL0biTtFKZsiUBKCCHtUwggQUMIIC/KADAgECAgsEAAAAAAEv # TuFS1zANBgkqhkiG9w0BAQUFADBXMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xv # YmFsU2lnbiBudi1zYTEQMA4GA1UECxMHUm9vdCBDQTEbMBkGA1UEAxMSR2xvYmFs # U2lnbiBSb290IENBMB4XDTExMDQxMzEwMDAwMFoXDTI4MDEyODEyMDAwMFowUjEL # MAkGA1UEBhMCQkUxGTAXBgNVBAoTEEdsb2JhbFNpZ24gbnYtc2ExKDAmBgNVBAMT # H0dsb2JhbFNpZ24gVGltZXN0YW1waW5nIENBIC0gRzIwggEiMA0GCSqGSIb3DQEB # AQUAA4IBDwAwggEKAoIBAQCU72X4tVefoFMNNAbrCR+3Rxhqy/Bb5P8npTTR94ka # v56xzRJBbmbUgaCFi2RaRi+ZoI13seK8XN0i12pn0LvoynTei08NsFLlkFvrRw7x # 55+cC5BlPheWMEVybTmhFzbKuaCMG08IGfaBMa1hFqRi5rRAnsP8+5X2+7UulYGY # 4O/F69gCWXh396rjUmtQkSnF/PfNk2XSYGEi8gb7Mt0WUfoO/Yow8BcJp7vzBK6r # kOds33qp9O/EYidfb5ltOHSqEYva38cUTOmFsuzCfUomj+dWuqbgz5JTgHT0A+xo # smC8hCAAgxuh7rR0BcEpjmLQR7H68FPMGPkuO/lwfrQlAgMBAAGjgeUwgeIwDgYD # VR0PAQH/BAQDAgEGMBIGA1UdEwEB/wQIMAYBAf8CAQAwHQYDVR0OBBYEFEbYPv/c # 477/g+b0hZuw3WrWFKnBMEcGA1UdIARAMD4wPAYEVR0gADA0MDIGCCsGAQUFBwIB # FiZodHRwczovL3d3dy5nbG9iYWxzaWduLmNvbS9yZXBvc2l0b3J5LzAzBgNVHR8E # LDAqMCigJqAkhiJodHRwOi8vY3JsLmdsb2JhbHNpZ24ubmV0L3Jvb3QuY3JsMB8G # A1UdIwQYMBaAFGB7ZhpFDZfKiVAvfQTNNKj//P1LMA0GCSqGSIb3DQEBBQUAA4IB # AQBOXlaQHka02Ukx87sXOSgbwhbd/UHcCQUEm2+yoprWmS5AmQBVteo/pSB204Y0 # 1BfMVTrHgu7vqLq82AafFVDfzRZ7UjoC1xka/a/weFzgS8UY3zokHtqsuKlYBAIH # MNuwEl7+Mb7wBEj08HD4Ol5Wg889+w289MXtl5251NulJ4TjOJuLpzWGRCCkO22k # aguhg/0o69rvKPbMiF37CjsAq+Ah6+IvNWwPjjRFl+ui95kzNX7Lmoq7RU3nP5/C # 2Yr6ZbJux35l/+iS4SwxovewJzZIjyZvO+5Ndh95w+V/ljW8LQ7MAbCOf/9RgICn # ktSzREZkjIdPFmMHMUtjsN/zMIIEnzCCA4egAwIBAgISESHWmadklz7x+EJ+6RnM # U0EUMA0GCSqGSIb3DQEBBQUAMFIxCzAJBgNVBAYTAkJFMRkwFwYDVQQKExBHbG9i # YWxTaWduIG52LXNhMSgwJgYDVQQDEx9HbG9iYWxTaWduIFRpbWVzdGFtcGluZyBD # QSAtIEcyMB4XDTE2MDUyNDAwMDAwMFoXDTI3MDYyNDAwMDAwMFowYDELMAkGA1UE # BhMCU0cxHzAdBgNVBAoTFkdNTyBHbG9iYWxTaWduIFB0ZSBMdGQxMDAuBgNVBAMT # J0dsb2JhbFNpZ24gVFNBIGZvciBNUyBBdXRoZW50aWNvZGUgLSBHMjCCASIwDQYJ # KoZIhvcNAQEBBQADggEPADCCAQoCggEBALAXrqLTtgQwVh5YD7HtVaTWVMvY9nM6 # 7F1eqyX9NqX6hMNhQMVGtVlSO0KiLl8TYhCpW+Zz1pIlsX0j4wazhzoOQ/DXAIlT # ohExUihuXUByPPIJd6dJkpfUbJCgdqf9uNyznfIHYCxPWJgAa9MVVOD63f+ALF8Y # ppj/1KvsoUVZsi5vYl3g2Rmsi1ecqCYr2RelENJHCBpwLDOLf2iAKrWhXWvdjQIC # KQOqfDe7uylOPVOTs6b6j9JYkxVMuS2rgKOjJfuv9whksHpED1wQ119hN6pOa9PS # UyWdgnP6LPlysKkZOSpQ+qnQPDrK6Fvv9V9R9PkK2Zc13mqF5iMEQq8CAwEAAaOC # AV8wggFbMA4GA1UdDwEB/wQEAwIHgDBMBgNVHSAERTBDMEEGCSsGAQQBoDIBHjA0 # MDIGCCsGAQUFBwIBFiZodHRwczovL3d3dy5nbG9iYWxzaWduLmNvbS9yZXBvc2l0 # b3J5LzAJBgNVHRMEAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUFBwMIMEIGA1UdHwQ7 # MDkwN6A1oDOGMWh0dHA6Ly9jcmwuZ2xvYmFsc2lnbi5jb20vZ3MvZ3N0aW1lc3Rh # bXBpbmdnMi5jcmwwVAYIKwYBBQUHAQEESDBGMEQGCCsGAQUFBzAChjhodHRwOi8v # c2VjdXJlLmdsb2JhbHNpZ24uY29tL2NhY2VydC9nc3RpbWVzdGFtcGluZ2cyLmNy # dDAdBgNVHQ4EFgQU1KKESjhaGH+6TzBQvZ3VeofWCfcwHwYDVR0jBBgwFoAURtg+ # /9zjvv+D5vSFm7DdatYUqcEwDQYJKoZIhvcNAQEFBQADggEBAI+pGpFtBKY3IA6D # lt4j02tuH27dZD1oISK1+Ec2aY7hpUXHJKIitykJzFRarsa8zWOOsz1QSOW0zK7N # ko2eKIsTShGqvaPv07I2/LShcr9tl2N5jES8cC9+87zdglOrGvbr+hyXvLY3nKQc # MLyrvC1HNt+SIAPoccZY9nUFmjTwC1lagkQ0qoDkL4T2R12WybbKyp23prrkUNPU # N7i6IA7Q05IqW8RZu6Ft2zzORJ3BOCqt4429zQl3GhC+ZwoCNmSIubMbJu7nnmDE # Rqi8YTNsz065nLlq8J83/rU9T5rTTf/eII5Ol6b9nwm8TcoYdsmwTYVQ8oDSHQb1 # WAQHsRgwggVMMIIDNKADAgECAhMzAAAANdjVWVsGcUErAAAAAAA1MA0GCSqGSIb3 # DQEBBQUAMH8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYD # VQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xKTAn # BgNVBAMTIE1pY3Jvc29mdCBDb2RlIFZlcmlmaWNhdGlvbiBSb290MB4XDTEzMDgx # NTIwMjYzMFoXDTIzMDgxNTIwMzYzMFowbzELMAkGA1UEBhMCU0UxFDASBgNVBAoT # C0FkZFRydXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5hbCBUVFAgTmV0 # d29yazEiMCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9vdDCCASIwDQYJ # KoZIhvcNAQEBBQADggEPADCCAQoCggEBALf3GjPm8gAELTngTlvtH7xsD821+iO2 # zt6bETOXpClMfZOfvUq8k+0DGuOPz+VtUFrWlymUWoCwSXrbLpX9uMq/NzgtHj6R # Qa1wVsfwTz/oMp50ysiQVOnGXw94nZpAPA6sYapeFI+eh6FqUNzXmk6vBbOmcZSc # cbNQYArHE504B4YCqOmoaSYYkKtMsE8jqzpPhNjfzp/haW+710LXa0Tkx63ubUFf # clpxCDezeWWkWaCUN/cALw3CknLa0Dhy2xSoRcRdKn23tNbE7qzNE0S3ySvdQwAl # +mG5aWpYIxG3pzOPVnVZ9c0p10a3CitlttNCbxWyuHv77+ldU9U0WicCAwEAAaOB # 0DCBzTATBgNVHSUEDDAKBggrBgEFBQcDAzASBgNVHRMBAf8ECDAGAQH/AgECMB0G # A1UdDgQWBBStvZh6NLQm9/rEJlTvA73gJMtUGjALBgNVHQ8EBAMCAYYwHwYDVR0j # BBgwFoAUYvsKIVt/Q24R2glUUGv10pZx8Z4wVQYDVR0fBE4wTDBKoEigRoZEaHR0 # cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljcm9zb2Z0 # Q29kZVZlcmlmUm9vdC5jcmwwDQYJKoZIhvcNAQEFBQADggIBADYrovLhMx/kk/fy # aYXGZA7Jm2Mv5HA3mP2U7HvP+KFCRvntak6NNGk2BVV6HrutjJlClgbpJagmhL7B # vxapfKpbBLf90cD0Ar4o7fV3x5v+OvbowXvTgqv6FE7PK8/l1bVIQLGjj4OLrSsl # U6umNM7yQ/dPLOndHk5atrroOxCZJAC8UP149uUjqImUk/e3QTA3Sle35kTZyd+Z # BapE/HSvgmTMB8sBtgnDLuPoMqe0n0F4x6GENlRi8uwVCsjq0IT48eBr9FYSX5Xg # /N23dpP+KUol6QQA8bQRDsmEntsXffUepY42KRk6bWxGS9ercCQojQWj2dUk8vig # 0TyCOdSogg5pOoEJ/Abwx1kzhDaTBkGRIywipacBK1C0KK7bRrBZG4azm4foSU45 # C20U30wDMB4fX3Su9VtZA1PsmBbg0GI1dRtIuH0T5XpIuHdSpAeYJTsGm3pOam9E # hk8UTyd5Jz1Qc0FMnEE+3SkMc7HH+x92DBdlBOvSUBCSQUns5AZ9NhVEb4m/aX35 # TUDBOpi2oH4x0rWuyvtT1T9Qhs1ekzttXXyaPz/3qSVYhN0RSQCix8ieN913jm1x # i+BbgTRdVLrM9ZNHiG3n71viKOSAG0DkDyrRfyMVZVqsmZRDP0ZVJtbE+oiV4pGa # oy0Lhd6sjOD5Z3CfcXkCMfdhoinEMIIFajCCBFKgAwIBAgIRANVLBedLvu60+SoC # Sc7WTm0wDQYJKoZIhvcNAQELBQAwfTELMAkGA1UEBhMCR0IxGzAZBgNVBAgTEkdy # ZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UEChMRQ09N # T0RPIENBIExpbWl0ZWQxIzAhBgNVBAMTGkNPTU9ETyBSU0EgQ29kZSBTaWduaW5n # IENBMB4XDTE2MDQxNDAwMDAwMFoXDTE3MDQxNDIzNTk1OVowgdIxCzAJBgNVBAYT # AlVTMQ4wDAYDVQQRDAU5NDMwNDELMAkGA1UECAwCQ0ExEjAQBgNVBAcMCVBhbG8g # QWx0bzEcMBoGA1UECQwTMzAwMCBIYW5vdmVyIFN0cmVldDErMCkGA1UECgwiSGV3 # bGV0dCBQYWNrYXJkIEVudGVycHJpc2UgQ29tcGFueTEaMBgGA1UECwwRSFAgQ3li # ZXIgU2VjdXJpdHkxKzApBgNVBAMMIkhld2xldHQgUGFja2FyZCBFbnRlcnByaXNl # IENvbXBhbnkwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCunerYOuFO # GYrBGLEga/002xkFcuIDhZq21GlLbyBoHN05Q475vk6Bj8NTc9vli2dUEwBTPTGb # /tQYxU6NOx3DJbXBFqR5Z20nnyQpsXp/qzJ+VAOyT1PqXzYtn5F4sqzXBBywoMQH # LuHqaQDS2QaKHR9c19LLyWQnM/LKrVx7ZIAcsvUTwqCFwNy7mUUGHviBt89Vh1EU # tBDjaRj9qFbb0+NQXXNonej4D56OLghczihz2WRWI5Fc6Y0zbrbT/D0dqj0myk+x # D/5QdTjT9w8uAAQX7mqdOGSrcMcASWi1S4J1u2zcK8NWJReZ9CJ8IKXbrxu1Xl0B # EhgycjnrI027AgMBAAGjggGNMIIBiTAfBgNVHSMEGDAWgBQpkWD/ik366/mmarjP # +eZLvUnOEjAdBgNVHQ4EFgQUZPsWkF11GCq0kSpLgIWjf0xtry8wDgYDVR0PAQH/ # BAQDAgeAMAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEQYJYIZI # AYb4QgEBBAQDAgQQMEYGA1UdIAQ/MD0wOwYMKwYBBAGyMQECAQMCMCswKQYIKwYB # BQUHAgEWHWh0dHBzOi8vc2VjdXJlLmNvbW9kby5uZXQvQ1BTMEMGA1UdHwQ8MDow # OKA2oDSGMmh0dHA6Ly9jcmwuY29tb2RvY2EuY29tL0NPTU9ET1JTQUNvZGVTaWdu # aW5nQ0EuY3JsMHQGCCsGAQUFBwEBBGgwZjA+BggrBgEFBQcwAoYyaHR0cDovL2Ny # dC5jb21vZG9jYS5jb20vQ09NT0RPUlNBQ29kZVNpZ25pbmdDQS5jcnQwJAYIKwYB # BQUHMAGGGGh0dHA6Ly9vY3NwLmNvbW9kb2NhLmNvbTANBgkqhkiG9w0BAQsFAAOC # AQEATO9K8RCpFYjZXn493q1DeW0i+01uNLnZ40k+xCqPP1uojqmqd/58DBDuvoFP # p5ip9SYNVrf6KSGt8QEpi11RcN+ykRLewi/L0Cv9CcYkOg3AtEbd3AL6CiRT6yIq # igwd4zOezhS/tPnDWbaPLo79EoStC7xBItP44b+IJ+N/LdZpPPfepMKZlpizFYdB # RtfPoNJtTLhrHXclj8QS8CBmjKMgPkTKcJIVXaJ7hf0SVQm02WyXm/X16VO0obvF # T7j6FVeK4Kv0+jI7fEtT7L06nTV7pJSXuGrqgfPlLA3fwZkufFC1YC06IJ3u+lwZ # rdSYAngEhK4RCWKdS5iVT0ml6zCCBXQwggRcoAMCAQICECdm7lbrSfOOq9dwovyE # 3iIwDQYJKoZIhvcNAQEMBQAwbzELMAkGA1UEBhMCU0UxFDASBgNVBAoTC0FkZFRy # dXN0IEFCMSYwJAYDVQQLEx1BZGRUcnVzdCBFeHRlcm5hbCBUVFAgTmV0d29yazEi # MCAGA1UEAxMZQWRkVHJ1c3QgRXh0ZXJuYWwgQ0EgUm9vdDAeFw0wMDA1MzAxMDQ4 # MzhaFw0yMDA1MzAxMDQ4MzhaMIGFMQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3Jl # YXRlciBNYW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01P # RE8gQ0EgTGltaXRlZDErMCkGA1UEAxMiQ09NT0RPIFJTQSBDZXJ0aWZpY2F0aW9u # IEF1dGhvcml0eTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJHoVJLS # ClaxrA0k3cXPRGd0mSs3o30jcABxvFPfxPoqEo9LfxBWvZ9wcrdhf8lLDxenPeOw # BGHu/xGXx/SGPgr6Plz5k+Y0etkUa+ecs4Wggnp2r3GQ1+z9DfqcbPrfsIL0FH75 # vsSmL09/mX+1/GdDcr0MANaJ62ss0+2PmBwUq37l42782KjkkiTaQ2tiuFX96sG8 # bLaL8w6NmuSbbGmZ+HhIMEXVreENPEVg/DKWUSe8Z8PKLrZr6kbHxyCgsR9l3kgI # uqROqfKDRjeE6+jMgUhDZ05yKptcvUwbKIpcInu0q5jZ7uBRg8MJRk5tPpn6lRfa # fDNXQTyNUe0LtlyvLGMa31fIP7zpXcSbr0WZ4qNaJLS6qVY9z2+q/0lYvvCo//S4 # rek3+7q49As6+ehDQh6J2ITLE/HZu+GJYLiMKFasFB2cCudx688O3T2plqFIvTz3 # r7UNIkzAEYHsVjv206LiW7eyBCJSlYCTaeiOTGXxkQMtcHQC6otnFSlpUgK7199Q # alVGv6CjKGF/cNDDoqosIapHziicBkV2v4IYJ7TVrrTLUOZr9EyGcTDppt8WhuDY # /0Dd+9BCiH+jMzouXB5BEYFjzhhxayvspoq3MVw6akfgw3lZ1iAar/JqmKpyvFdK # 0kuduxD8sExB5e0dPV4onZzMv7NR2qdH5YRTAgMBAAGjgfQwgfEwHwYDVR0jBBgw # FoAUrb2YejS0Jvf6xCZU7wO94CTLVBowHQYDVR0OBBYEFLuvfgI9+qbxPISOre44 # mOzZMjLUMA4GA1UdDwEB/wQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MBEGA1UdIAQK # MAgwBgYEVR0gADBEBgNVHR8EPTA7MDmgN6A1hjNodHRwOi8vY3JsLnVzZXJ0cnVz # dC5jb20vQWRkVHJ1c3RFeHRlcm5hbENBUm9vdC5jcmwwNQYIKwYBBQUHAQEEKTAn # MCUGCCsGAQUFBzABhhlodHRwOi8vb2NzcC51c2VydHJ1c3QuY29tMA0GCSqGSIb3 # DQEBDAUAA4IBAQBkv4PxX5qF0M24oSlXDeha99HpPvJ2BG7xUnC7Hjz/TQ10asyB # giXTw6AqXUz1uouhbcRUCXXH4ycOXYR5N0ATd/W0rBzQO6sXEtbvNBh+K+l506tX # RQyvKPrQ2+VQlYi734VXaX2S2FLKc4G/HPPmuG5mEQWzHpQtf5GVklnxTM6jkXFM # fEcMOwsZ9qGxbIY+XKrELoLL+QeWukhNkPKUyKlzousGeyOd3qLzTVWfemFFmBho # x15AayP1eXrvjLVri7dvRvR78T1LBNiTgFla4EEkHbKPFWBYR9vvbkb9FfXZX5qz # 29i45ECzzZc5roW7HY683Ieb0abv8TtvEDhvMIIF4DCCA8igAwIBAgIQLnyHzA6T # SlL+lP0ct800rzANBgkqhkiG9w0BAQwFADCBhTELMAkGA1UEBhMCR0IxGzAZBgNV # BAgTEkdyZWF0ZXIgTWFuY2hlc3RlcjEQMA4GA1UEBxMHU2FsZm9yZDEaMBgGA1UE # ChMRQ09NT0RPIENBIExpbWl0ZWQxKzApBgNVBAMTIkNPTU9ETyBSU0EgQ2VydGlm # aWNhdGlvbiBBdXRob3JpdHkwHhcNMTMwNTA5MDAwMDAwWhcNMjgwNTA4MjM1OTU5 # WjB9MQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBNYW5jaGVzdGVyMRAw # DgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0EgTGltaXRlZDEjMCEG # A1UEAxMaQ09NT0RPIFJTQSBDb2RlIFNpZ25pbmcgQ0EwggEiMA0GCSqGSIb3DQEB # AQUAA4IBDwAwggEKAoIBAQCmmJBjd5E0f4rR3elnMRHrzB79MR2zuWJXP5O8W+Of # HiQyESdrvFGRp8+eniWzX4GoGA8dHiAwDvthe4YJs+P9omidHCydv3Lj5HWg5TUj # jsmK7hoMZMfYQqF7tVIDSzqwjiNLS2PgIpQ3e9V5kAoUGFEs5v7BEvAcP2FhCoyi # 3PbDMKrNKBh1SMF5WgjNu4xVjPfUdpA6M0ZQc5hc9IVKaw+A3V7Wvf2pL8Al9fl4 # 141fEMJEVTyQPDFGy3CuB6kK46/BAW+QGiPiXzjbxghdR7ODQfAuADcUuRKqeZJS # zYcPe9hiKaR+ML0btYxytEjy4+gh+V5MYnmLAgaff9ULAgMBAAGjggFRMIIBTTAf # BgNVHSMEGDAWgBS7r34CPfqm8TyEjq3uOJjs2TIy1DAdBgNVHQ4EFgQUKZFg/4pN # +uv5pmq4z/nmS71JzhIwDgYDVR0PAQH/BAQDAgGGMBIGA1UdEwEB/wQIMAYBAf8C # AQAwEwYDVR0lBAwwCgYIKwYBBQUHAwMwEQYDVR0gBAowCDAGBgRVHSAAMEwGA1Ud # HwRFMEMwQaA/oD2GO2h0dHA6Ly9jcmwuY29tb2RvY2EuY29tL0NPTU9ET1JTQUNl # cnRpZmljYXRpb25BdXRob3JpdHkuY3JsMHEGCCsGAQUFBwEBBGUwYzA7BggrBgEF # BQcwAoYvaHR0cDovL2NydC5jb21vZG9jYS5jb20vQ09NT0RPUlNBQWRkVHJ1c3RD # QS5jcnQwJAYIKwYBBQUHMAGGGGh0dHA6Ly9vY3NwLmNvbW9kb2NhLmNvbTANBgkq # hkiG9w0BAQwFAAOCAgEAAj8COcPu+Mo7id4MbU2x8U6ST6/COCwEzMVjEasJY6+r # otcCP8xvGcM91hoIlP8l2KmIpysQGuCbsQciGlEcOtTh6Qm/5iR0rx57FjFuI+9U # US1SAuJ1CAVM8bdR4VEAxof2bO4QRHZXavHfWGshqknUfDdOvf+2dVRAGDZXZxHN # TwLk/vPa/HUX2+y392UJI0kfQ1eD6n4gd2HITfK7ZU2o94VFB696aSdlkClAi997 # OlE5jKgfcHmtbUIgos8MbAOMTM1zB5TnWo46BLqioXwfy2M6FafUFRunUkcyqfS/ # ZEfRqh9TTjIwc8Jvt3iCnVz/RrtrIh2IC/gbqjSm/Iz13X9ljIwxVzHQNuxHoc/L # i6jvHBhYxQZ3ykubUa9MCEp6j+KjUuKOjswm5LLY5TjCqO3GgZw1a6lYYUoKl7RL # QrZVnb6Z53BtWfhtKgx/GWBfDJqIbDCsUgmQFhv/K53b0CDKieoofjKOGd97SDMe # 12X4rsn4gxSTdn1k0I7OvjV9/3IxTZ+evR5sL6iPDAZQ+4wns3bJ9ObXwzTijIch # hmH+v1V04SF3AwpobLvkyanmz1kl63zsRQ55ZmjoIs2475iFTZYRPAmK0H+8KCgT # +2rKVI2SXM3CZZgGns5IW9S1N5NGQXwH3c/6Q++6Z2H/fUnguzB9XIDj5hY5S6cx # ggTiMIIE3gIBATCBkjB9MQswCQYDVQQGEwJHQjEbMBkGA1UECBMSR3JlYXRlciBN # YW5jaGVzdGVyMRAwDgYDVQQHEwdTYWxmb3JkMRowGAYDVQQKExFDT01PRE8gQ0Eg # TGltaXRlZDEjMCEGA1UEAxMaQ09NT0RPIFJTQSBDb2RlIFNpZ25pbmcgQ0ECEQDV # SwXnS77utPkqAknO1k5tMA0GCWCGSAFlAwQCAQUAoHwwEAYKKwYBBAGCNwIBDDEC # MAAwGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEOMAwG # CisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIGe1xayyKozN5pSSvWTnQXrThJIJ # QhZFlKK0O2z7XHLaMA0GCSqGSIb3DQEBAQUABIIBAD3uWsycr76eDGZXw+ns74ra # JJ3E3+4ekUEBU0eMFYNw75nfA6AU4xIGTvefoQhsnraKnkphc4K9MsUasSNMEOxo # 4pOq+4NmbvwZGCjdGAKR8N7FUyHqqxpM2oqrJTvxsXJ09lPSMN+ykTdiPbjTQRnM # N5DDTidLJhE0ZQ1jHZYO5oZyOEi00GW/mztXbdf/zcyN/mHTjIUT7LnWQEXMeLQE # j1DgbIPup35Dnsu3Km1ApI49yoAuN+kBeG5b5+cbWPWsqglY48ZCvfDB9AXpSJr2 # sCpZqkFVMgIE4eFGhlFExXG76PYcSnGW/oYlvULWEoiCcgwfFKD9qaBHKJ5vj3Ch # ggKiMIICngYJKoZIhvcNAQkGMYICjzCCAosCAQEwaDBSMQswCQYDVQQGEwJCRTEZ # MBcGA1UEChMQR2xvYmFsU2lnbiBudi1zYTEoMCYGA1UEAxMfR2xvYmFsU2lnbiBU # aW1lc3RhbXBpbmcgQ0EgLSBHMgISESHWmadklz7x+EJ+6RnMU0EUMAkGBSsOAwIa # BQCggf0wGAYJKoZIhvcNAQkDMQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcN # MTcwMzI4MDcxNTI0WjAjBgkqhkiG9w0BCQQxFgQUoU59somyawwy6jOmNnGAK0XO # zO0wgZ0GCyqGSIb3DQEJEAIMMYGNMIGKMIGHMIGEBBRjuC+rYfWDkJaVBQsAJJxQ # KTPseTBsMFakVDBSMQswCQYDVQQGEwJCRTEZMBcGA1UEChMQR2xvYmFsU2lnbiBu # di1zYTEoMCYGA1UEAxMfR2xvYmFsU2lnbiBUaW1lc3RhbXBpbmcgQ0EgLSBHMgIS # ESHWmadklz7x+EJ+6RnMU0EUMA0GCSqGSIb3DQEBAQUABIIBAAun8qrhZThc7IsC # YrB9y/1NwPmtlgTDyXa3KsvB2k15RGVXWshzlznqVgE7I7BS42KgFGzXHWgL4fip # nO4F0MnvvIugUhXpymiBl8lcm96LryhITGb2lgXPrc0VOh/vGfz/gDa7CrUkgMU3 # 8wzWEXTVHPyg1iNa8tWYMKjrf2c+QISLJTthAxwwTRgh2QEcvbE98BXeQRAzgn7J # 5KZrI8e1OFVS82OW+f+UoHrvsmv50269u5VRSciApV5/FbYVxHTHATPkFP0AMxih # IrIxbDLE0QsXMmzo/5xjoN+XbLUJVBKcrAWv0QJ/HNEJdBZZGCEc/KzlPJtPN80t # rFKiRmU= # SIG # End signature block |