Functions/Add-ADPrincipalCertificate.ps1
|
<#
.SYNOPSIS Add certificates to an Active Directory principal's userCertificate attribute. .DESCRIPTION This function adds certificates to the userCertificate attribute of AD principals (users, computers, service accounts, or other AD objects). Certificates can be provided as file paths via the -Certificate parameter, piped via the pipeline, or by piping a text file containing certificate file names using Get-Content. The function supports DER-encoded (.cer, .crt, .der) and PEM/Base64-encoded (.pem, .crt) certificate files. The script also accepts pipeline input from Get-ADUser, Get-ADComputer, Get-ADServiceAccount, or Get-ADObject cmdlets. .PARAMETER Identity One or more AD principal identities. This can be a Distinguished Name, SamAccountName, ObjectGUID, or SID. This parameter accepts pipeline input and multiple values when using the ByIdentity parameter set. .PARAMETER Certificate One or more paths to certificate files to add. Supported formats include DER-encoded (.cer, .crt, .der) and PEM/Base64-encoded (.pem, .crt) certificate files. This parameter accepts pipeline input when using the ByCertificatePipeline parameter set. .INPUTS Microsoft.ActiveDirectory.Management.ADUser, Microsoft.ActiveDirectory.Management.ADComputer, Microsoft.ActiveDirectory.Management.ADServiceAccount, Microsoft.ActiveDirectory.Management.ADObject, or String values. .OUTPUTS None. .EXAMPLE Add-ADPrincipalCertificate -Identity 'juser' -Certificate 'C:\Certs\user.cer' Adds a certificate from the specified file to user juser. .EXAMPLE Add-ADPrincipalCertificate -Identity 'juser' -Certificate 'cert1.cer', 'cert2.cer' Adds multiple certificates to user juser by specifying multiple file paths. .EXAMPLE Get-ADUser juser | Add-ADPrincipalCertificate -Certificate 'C:\Certs\user.cer' Pipes a user object and adds the specified certificate. .EXAMPLE Get-ADComputer 'app1' | Add-ADPrincipalCertificate -Certificate 'C:\Certs\computer.cer' Pipes a computer object and adds the specified certificate. .EXAMPLE Get-ADServiceAccount 'svc_app' | Add-ADPrincipalCertificate -Certificate 'C:\Certs\svc.cer' Pipes a service account object and adds the specified certificate. .EXAMPLE Get-ADUser -Filter {Department -eq 'Human Resources'} | Add-ADPrincipalCertificate -Certificate 'C:\Certs\hr.cer' Adds the same certificate to all users in the Human Resources department. .EXAMPLE 'cert1.cer', 'cert2.cer' | Add-ADPrincipalCertificate -Identity 'juser' Pipes certificate file paths to add multiple certificates to user juser. .EXAMPLE Get-Content -Path .\certs.txt | Add-ADPrincipalCertificate -Identity 'juser' Reads certificate file paths from a text file (one per line) and adds each certificate to user juser. .EXAMPLE Add-ADPrincipalCertificate -Identity 'app1' -Certificate 'C:\Certs\computer.cer' -WhatIf Shows what would happen if the certificate were added to computer app1 without actually adding it. .EXAMPLE Add-ADPrincipalCertificate -Identity 'juser', 'jdoe' -Certificate 'C:\Certs\shared.cer' Adds the same certificate to multiple principals juser and jdoe. .LINK https://github.com/richardhicks/adprincipalcertificate/blob/main/Functions/Add-ADPrincipalCertificate.ps1 .LINK https://www.richardhicks.com/ .NOTES Version: 1.0 Creation Date: February 9, 2026 Last Updated: February 9, 2026 Author: Richard Hicks Organization: Richard M. Hicks Consulting, Inc. Contact: rich@richardhicks.com Website: https://www.richardhicks.com/ #> Function Add-ADPrincipalCertificate { # Prerequisites #Requires -Module ActiveDirectory [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium', DefaultParameterSetName = 'ByIdentity')] [OutputType([System.Void])] Param ( [Parameter(ValueFromPipeline, ValueFromPipelineByPropertyName, Position = 0, Mandatory, ParameterSetName = 'ByIdentity', HelpMessage = 'Specify one or more AD principal identities')] [Parameter(Mandatory, Position = 0, ParameterSetName = 'ByCertificatePipeline', HelpMessage = 'Specify one or more AD principal identities')] [Alias('DistinguishedName', 'SamAccountName', 'ObjectGUID', 'SID', 'Name')] [ValidateNotNullOrEmpty()] $Identity, [Parameter(Mandatory, ParameterSetName = 'ByIdentity', HelpMessage = 'Specify one or more certificate file paths')] [Parameter(Mandatory, ValueFromPipeline, ParameterSetName = 'ByCertificatePipeline', HelpMessage = 'Specify one or more certificate file paths')] [ValidateNotNullOrEmpty()] [string[]]$Certificate ) Begin { Write-Verbose 'Begin certificate addition process...' # Define required properties once in Begin block for efficiency $RequiredProperties = @('userCertificate', 'SamAccountName', 'ObjectClass', 'DistinguishedName') # Initialize collection for certificate paths when piping certificates If ($PSCmdlet.ParameterSetName -eq 'ByCertificatePipeline') { $Script:CollectedCertificatePaths = [System.Collections.Generic.List[string]]::new() } # Helper function to load certificate bytes from a file Function Get-CertificateByte { [CmdletBinding()] [OutputType([byte[]])] Param ( [Parameter(Mandatory)] [string]$FilePath ) # Resolve to full path $ResolvedPath = $null Try { $ResolvedPath = (Resolve-Path -Path $FilePath -ErrorAction Stop).Path } Catch { Write-Warning "Certificate file not found: $FilePath" Return $null } Try { # Load certificate using X509Certificate2 which handles DER, PEM, and Base64 formats $Certificate = [System.Security.Cryptography.X509Certificates.X509Certificate2]::new($ResolvedPath) $RawData = $Certificate.RawData $Certificate.Dispose() Return $RawData } Catch { Write-Warning "Error loading certificate file '$FilePath': $_" Return $null } } # Helper function to resolve an AD principal Function Resolve-ADPrincipal { [CmdletBinding()] Param ( [Parameter(Mandatory)] $Id, [Parameter(Mandatory)] [string[]]$Properties ) $Principal = $null # Check if this is already an AD object If ($Id.PSObject.TypeNames -match 'Microsoft\.ActiveDirectory\.Management\.AD(User|Computer|ServiceAccount|Object)') { # Re-query to ensure we have the required properties Write-Verbose "Re-querying AD object for required properties: $($Id.DistinguishedName)" $IdentityValue = $Id.DistinguishedName $ObjectClass = $Id.ObjectClass } Else { Write-Verbose "Retrieving AD principal `"$Id`"..." $IdentityValue = $Id $ObjectClass = $null } Switch ($ObjectClass) { 'User' { $Principal = Get-ADUser -Identity $IdentityValue -Properties $Properties -ErrorAction Stop } 'Computer' { $Principal = Get-ADComputer -Identity $IdentityValue -Properties $Properties -ErrorAction Stop } { $_ -in 'msDS-ManagedServiceAccount', 'msDS-GroupManagedServiceAccount' } { $Principal = Get-ADServiceAccount -Identity $IdentityValue -Properties $Properties -ErrorAction Stop } Default { # Try to find the object using cascading approach Try { $Principal = Get-ADUser -Identity $IdentityValue -Properties $Properties -ErrorAction Stop Write-Verbose "Found user account `"$IdentityValue`"." } Catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { Try { $Principal = Get-ADComputer -Identity $IdentityValue -Properties $Properties -ErrorAction Stop Write-Verbose "Found computer account `"$IdentityValue`"." } Catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { Try { $Principal = Get-ADServiceAccount -Identity $IdentityValue -Properties $Properties -ErrorAction Stop Write-Verbose "Found service account `"$IdentityValue`"." } Catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { $Principal = Get-ADObject -Identity $IdentityValue -Properties $Properties -ErrorAction Stop Write-Verbose "Found AD object `"$IdentityValue`"." } } } } } Return $Principal } # Helper function to add certificates to a principal Function Add-CertificatesToPrincipal { [CmdletBinding(SupportsShouldProcess)] Param ( [Parameter(Mandatory)] $Principal, [Parameter(Mandatory)] [byte[][]]$CertificateBytes ) $AddCount = $CertificateBytes.Count $ConfirmMessage = "Add $AddCount certificate(s) to '$($Principal.SamAccountName)' ($($Principal.ObjectClass))?" $WhatIfMessage = "Adding $AddCount certificate(s) to '$($Principal.SamAccountName)' ($($Principal.ObjectClass))" If ($PSCmdlet.ShouldProcess($WhatIfMessage, $ConfirmMessage, 'Add AD Principal Certificate(s)')) { Try { Set-ADObject -Identity $Principal.DistinguishedName -Add @{ userCertificate = $CertificateBytes } -ErrorAction Stop Write-Verbose "Successfully added $AddCount certificate(s) to '$($Principal.SamAccountName)'." Write-Output "Added $AddCount certificate(s) to principal '$($Principal.SamAccountName)'." } Catch { Write-Error "Failed to add certificates to '$($Principal.SamAccountName)': $_" } } } } Process { If ($PSCmdlet.ParameterSetName -eq 'ByCertificatePipeline') { # Collect certificate paths from pipeline for processing in End block ForEach ($CertPath in $Certificate) { If (-not [string]::IsNullOrWhiteSpace($CertPath)) { $Script:CollectedCertificatePaths.Add($CertPath.Trim()) } } } Else { # ByIdentity parameter set - process each identity from pipeline or parameter $IdsToProcess = If ($Identity -is [array]) { $Identity } Else { , $Identity } ForEach ($Id in $IdsToProcess) { Try { # Resolve the AD principal $Principal = Resolve-ADPrincipal -Id $Id -Properties $RequiredProperties If (-not $Principal) { Write-Warning "Unable to resolve AD principal: $Id" Continue } # Load certificates from file paths $CertBytesCollection = [System.Collections.Generic.List[byte[]]]::new() ForEach ($CertPath in $Certificate) { $CertBytes = Get-CertificateByte -FilePath $CertPath If ($null -ne $CertBytes) { $CertBytesCollection.Add($CertBytes) } } If ($CertBytesCollection.Count -eq 0) { Write-Warning "No valid certificates to add for principal '$($Principal.SamAccountName)'. Verify the specified certificate file path(s)." Continue } # Add certificates to principal Add-CertificatesToPrincipal -Principal $Principal -CertificateBytes $CertBytesCollection.ToArray() } Catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { Write-Warning "AD principal not found: $Id" } Catch { Write-Warning "Error processing principal '$Id': $_" } } } } End { If ($PSCmdlet.ParameterSetName -eq 'ByCertificatePipeline') { If ($Script:CollectedCertificatePaths.Count -eq 0) { Write-Warning 'No certificate file paths were provided via the pipeline.' Return } Write-Verbose "Processing $($Script:CollectedCertificatePaths.Count) certificate file path(s) from pipeline..." # Resolve the AD principal(s) $IdsToProcess = If ($Identity -is [array]) { $Identity } Else { , $Identity } # Load all certificates from collected paths $CertBytesCollection = [System.Collections.Generic.List[byte[]]]::new() ForEach ($CertPath in $Script:CollectedCertificatePaths) { $CertBytes = Get-CertificateByte -FilePath $CertPath If ($null -ne $CertBytes) { $CertBytesCollection.Add($CertBytes) } } If ($CertBytesCollection.Count -eq 0) { Write-Warning 'No valid certificates found from the provided file paths. Verify the specified certificate file path(s).' Return } $CertBytesArray = $CertBytesCollection.ToArray() ForEach ($Id in $IdsToProcess) { Try { $Principal = Resolve-ADPrincipal -Id $Id -Properties $RequiredProperties If (-not $Principal) { Write-Warning "Unable to resolve AD principal: $Id" Continue } # Add certificates to principal Add-CertificatesToPrincipal -Principal $Principal -CertificateBytes $CertBytesArray } Catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException] { Write-Warning "AD principal not found: $Id" } Catch { Write-Warning "Error processing principal '$Id': $_" } } } Write-Verbose 'Certificate addition process completed.' } } # SIG # Begin signature block # MIIf2wYJKoZIhvcNAQcCoIIfzDCCH8gCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCCRKL9+vemuXNKG # orOLKs6fDBdu3hwZwCSVWAcTWquBJaCCGpkwggNZMIIC36ADAgECAhAPuKdAuRWN # A1FDvFnZ8EApMAoGCCqGSM49BAMDMGExCzAJBgNVBAYTAlVTMRUwEwYDVQQKEwxE # aWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xIDAeBgNVBAMT # F0RpZ2lDZXJ0IEdsb2JhbCBSb290IEczMB4XDTIxMDQyOTAwMDAwMFoXDTM2MDQy # ODIzNTk1OVowZDELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMu # MTwwOgYDVQQDEzNEaWdpQ2VydCBHbG9iYWwgRzMgQ29kZSBTaWduaW5nIEVDQyBT # SEEzODQgMjAyMSBDQTEwdjAQBgcqhkjOPQIBBgUrgQQAIgNiAAS7tKwnpUgNolNf # jy6BPi9TdrgIlKKaqoqLmLWx8PwqFbu5s6UiL/1qwL3iVWhga5c0wWZTcSP8GtXK # IA8CQKKjSlpGo5FTK5XyA+mrptOHdi/nZJ+eNVH8w2M1eHbk+HejggFXMIIBUzAS # BgNVHRMBAf8ECDAGAQH/AgEAMB0GA1UdDgQWBBSbX7A2up0GrhknvcCgIsCLizh3 # 7TAfBgNVHSMEGDAWgBSz20ik+aHF2K42QcwRY2liKbxLxjAOBgNVHQ8BAf8EBAMC # AYYwEwYDVR0lBAwwCgYIKwYBBQUHAwMwdgYIKwYBBQUHAQEEajBoMCQGCCsGAQUF # BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQAYIKwYBBQUHMAKGNGh0dHA6 # Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbFJvb3RHMy5jcnQw # QgYDVR0fBDswOTA3oDWgM4YxaHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lD # ZXJ0R2xvYmFsUm9vdEczLmNybDAcBgNVHSAEFTATMAcGBWeBDAEDMAgGBmeBDAEE # ATAKBggqhkjOPQQDAwNoADBlAjB4vUmVZXEB0EZXaGUOaKncNgjB7v3UjttAZT8N # /5Ovwq5jhqN+y7SRWnjsBwNnB3wCMQDnnx/xB1usNMY4vLWlUM7m6jh+PnmQ5KRb # qwIN6Af8VqZait2zULLd8vpmdJ7QFmMwggP+MIIDhKADAgECAhANSjTahpCPwBMs # vIE3k68kMAoGCCqGSM49BAMDMGQxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdp # Q2VydCwgSW5jLjE8MDoGA1UEAxMzRGlnaUNlcnQgR2xvYmFsIEczIENvZGUgU2ln # bmluZyBFQ0MgU0hBMzg0IDIwMjEgQ0ExMB4XDTI0MTIwNjAwMDAwMFoXDTI3MTIy # NDIzNTk1OVowgYYxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYw # FAYDVQQHEw1NaXNzaW9uIFZpZWpvMSQwIgYDVQQKExtSaWNoYXJkIE0uIEhpY2tz # IENvbnN1bHRpbmcxJDAiBgNVBAMTG1JpY2hhcmQgTS4gSGlja3MgQ29uc3VsdGlu # ZzBZMBMGByqGSM49AgEGCCqGSM49AwEHA0IABFCbtcqpc7vGGM4hVM79U+7f0tKz # o8BAGMJ/0E7JUwKJfyMJj9jsCNpp61+mBNdTwirEm/K0Vz02vak0Ftcb/3yjggHz # MIIB7zAfBgNVHSMEGDAWgBSbX7A2up0GrhknvcCgIsCLizh37TAdBgNVHQ4EFgQU # KIMkVkfISNUyQJ7bwvLm9sCIkxgwPgYDVR0gBDcwNTAzBgZngQwBBAEwKTAnBggr # BgEFBQcCARYbaHR0cDovL3d3dy5kaWdpY2VydC5jb20vQ1BTMA4GA1UdDwEB/wQE # AwIHgDATBgNVHSUEDDAKBggrBgEFBQcDAzCBqwYDVR0fBIGjMIGgME6gTKBKhkho # dHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRHbG9iYWxHM0NvZGVTaWdu # aW5nRUNDU0hBMzg0MjAyMUNBMS5jcmwwTqBMoEqGSGh0dHA6Ly9jcmw0LmRpZ2lj # ZXJ0LmNvbS9EaWdpQ2VydEdsb2JhbEczQ29kZVNpZ25pbmdFQ0NTSEEzODQyMDIx # Q0ExLmNybDCBjgYIKwYBBQUHAQEEgYEwfzAkBggrBgEFBQcwAYYYaHR0cDovL29j # c3AuZGlnaWNlcnQuY29tMFcGCCsGAQUFBzAChktodHRwOi8vY2FjZXJ0cy5kaWdp # Y2VydC5jb20vRGlnaUNlcnRHbG9iYWxHM0NvZGVTaWduaW5nRUNDU0hBMzg0MjAy # MUNBMS5jcnQwCQYDVR0TBAIwADAKBggqhkjOPQQDAwNoADBlAjBMOsBb80qx6E6S # 2lnnHafuyY2paoDtPjcfddKaB1HKnAy7WLaEVc78xAC84iW3l6ECMQDhOPD5JHtw # YxEH6DxVDle5pLKfuyQHiY1i0I9PrSn1plPUeZDTnYKmms1P66nBvCkwggWNMIIE # daADAgECAhAOmxiO+dAt5+/bUOIIQBhaMA0GCSqGSIb3DQEBDAUAMGUxCzAJBgNV # BAYTAlVTMRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdp # Y2VydC5jb20xJDAiBgNVBAMTG0RpZ2lDZXJ0IEFzc3VyZWQgSUQgUm9vdCBDQTAe # Fw0yMjA4MDEwMDAwMDBaFw0zMTExMDkyMzU5NTlaMGIxCzAJBgNVBAYTAlVTMRUw # EwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20x # ITAfBgNVBAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDCCAiIwDQYJKoZIhvcN # AQEBBQADggIPADCCAgoCggIBAL/mkHNo3rvkXUo8MCIwaTPswqclLskhPfKK2FnC # 4SmnPVirdprNrnsbhA3EMB/zG6Q4FutWxpdtHauyefLKEdLkX9YFPFIPUh/GnhWl # fr6fqVcWWVVyr2iTcMKyunWZanMylNEQRBAu34LzB4TmdDttceItDBvuINXJIB1j # KS3O7F5OyJP4IWGbNOsFxl7sWxq868nPzaw0QF+xembud8hIqGZXV59UWI4MK7dP # pzDZVu7Ke13jrclPXuU15zHL2pNe3I6PgNq2kZhAkHnDeMe2scS1ahg4AxCN2NQ3 # pC4FfYj1gj4QkXCrVYJBMtfbBHMqbpEBfCFM1LyuGwN1XXhm2ToxRJozQL8I11pJ # pMLmqaBn3aQnvKFPObURWBf3JFxGj2T3wWmIdph2PVldQnaHiZdpekjw4KISG2aa # dMreSx7nDmOu5tTvkpI6nj3cAORFJYm2mkQZK37AlLTSYW3rM9nF30sEAMx9HJXD # j/chsrIRt7t/8tWMcCxBYKqxYxhElRp2Yn72gLD76GSmM9GJB+G9t+ZDpBi4pncB # 4Q+UDCEdslQpJYls5Q5SUUd0viastkF13nqsX40/ybzTQRESW+UQUOsxxcpyFiIJ # 33xMdT9j7CFfxCBRa2+xq4aLT8LWRV+dIPyhHsXAj6KxfgommfXkaS+YHS312amy # HeUbAgMBAAGjggE6MIIBNjAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs1+OC # 0nFdZEzfLmc/57qYrhwPTzAfBgNVHSMEGDAWgBRF66Kv9JLLgjEtUYunpyGd823I # DzAOBgNVHQ8BAf8EBAMCAYYweQYIKwYBBQUHAQEEbTBrMCQGCCsGAQUFBzABhhho # dHRwOi8vb2NzcC5kaWdpY2VydC5jb20wQwYIKwYBBQUHMAKGN2h0dHA6Ly9jYWNl # cnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydEFzc3VyZWRJRFJvb3RDQS5jcnQwRQYD # VR0fBD4wPDA6oDigNoY0aHR0cDovL2NybDMuZGlnaWNlcnQuY29tL0RpZ2lDZXJ0 # QXNzdXJlZElEUm9vdENBLmNybDARBgNVHSAECjAIMAYGBFUdIAAwDQYJKoZIhvcN # AQEMBQADggEBAHCgv0NcVec4X6CjdBs9thbX979XB72arKGHLOyFXqkauyL4hxpp # VCLtpIh3bb0aFPQTSnovLbc47/T/gLn4offyct4kvFIDyE7QKt76LVbP+fT3rDB6 # mouyXtTP0UNEm0Mh65ZyoUi0mcudT6cGAxN3J0TU53/oWajwvy8LpunyNDzs9wPH # h6jSTEAZNUZqaVSwuKFWjuyk1T3osdz9HNj0d1pcVIxv76FQPfx2CWiEn2/K2yCN # NWAcAgPLILCsWKAOQGPFmCLBsln1VWvPJ6tsds5vIy30fnFqI2si/xK4VC0nftg6 # 2fC2h5b9W9FcrBjDTZ9ztwGpn1eqXijiuZQwgga0MIIEnKADAgECAhANx6xXBf8h # mS5AQyIMOkmGMA0GCSqGSIb3DQEBCwUAMGIxCzAJBgNVBAYTAlVTMRUwEwYDVQQK # EwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5jb20xITAfBgNV # BAMTGERpZ2lDZXJ0IFRydXN0ZWQgUm9vdCBHNDAeFw0yNTA1MDcwMDAwMDBaFw0z # ODAxMTQyMzU5NTlaMGkxCzAJBgNVBAYTAlVTMRcwFQYDVQQKEw5EaWdpQ2VydCwg # SW5jLjFBMD8GA1UEAxM4RGlnaUNlcnQgVHJ1c3RlZCBHNCBUaW1lU3RhbXBpbmcg # UlNBNDA5NiBTSEEyNTYgMjAyNSBDQTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAw # ggIKAoICAQC0eDHTCphBcr48RsAcrHXbo0ZodLRRF51NrY0NlLWZloMsVO1DahGP # NRcybEKq+RuwOnPhof6pvF4uGjwjqNjfEvUi6wuim5bap+0lgloM2zX4kftn5B1I # pYzTqpyFQ/4Bt0mAxAHeHYNnQxqXmRinvuNgxVBdJkf77S2uPoCj7GH8BLuxBG5A # vftBdsOECS1UkxBvMgEdgkFiDNYiOTx4OtiFcMSkqTtF2hfQz3zQSku2Ws3IfDRe # b6e3mmdglTcaarps0wjUjsZvkgFkriK9tUKJm/s80FiocSk1VYLZlDwFt+cVFBUR # Jg6zMUjZa/zbCclF83bRVFLeGkuAhHiGPMvSGmhgaTzVyhYn4p0+8y9oHRaQT/ao # fEnS5xLrfxnGpTXiUOeSLsJygoLPp66bkDX1ZlAeSpQl92QOMeRxykvq6gbylsXQ # skBBBnGy3tW/AMOMCZIVNSaz7BX8VtYGqLt9MmeOreGPRdtBx3yGOP+rx3rKWDEJ # lIqLXvJWnY0v5ydPpOjL6s36czwzsucuoKs7Yk/ehb//Wx+5kMqIMRvUBDx6z1ev # +7psNOdgJMoiwOrUG2ZdSoQbU2rMkpLiQ6bGRinZbI4OLu9BMIFm1UUl9VnePs6B # aaeEWvjJSjNm2qA+sdFUeEY0qVjPKOWug/G6X5uAiynM7Bu2ayBjUwIDAQABo4IB # XTCCAVkwEgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHQ4EFgQU729TSunkBnx6yuKQ # VvYv1Ensy04wHwYDVR0jBBgwFoAU7NfjgtJxXWRM3y5nP+e6mK4cD08wDgYDVR0P # AQH/BAQDAgGGMBMGA1UdJQQMMAoGCCsGAQUFBwMIMHcGCCsGAQUFBwEBBGswaTAk # BggrBgEFBQcwAYYYaHR0cDovL29jc3AuZGlnaWNlcnQuY29tMEEGCCsGAQUFBzAC # hjVodHRwOi8vY2FjZXJ0cy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkUm9v # dEc0LmNydDBDBgNVHR8EPDA6MDigNqA0hjJodHRwOi8vY3JsMy5kaWdpY2VydC5j # b20vRGlnaUNlcnRUcnVzdGVkUm9vdEc0LmNybDAgBgNVHSAEGTAXMAgGBmeBDAEE # AjALBglghkgBhv1sBwEwDQYJKoZIhvcNAQELBQADggIBABfO+xaAHP4HPRF2cTC9 # vgvItTSmf83Qh8WIGjB/T8ObXAZz8OjuhUxjaaFdleMM0lBryPTQM2qEJPe36zwb # SI/mS83afsl3YTj+IQhQE7jU/kXjjytJgnn0hvrV6hqWGd3rLAUt6vJy9lMDPjTL # xLgXf9r5nWMQwr8Myb9rEVKChHyfpzee5kH0F8HABBgr0UdqirZ7bowe9Vj2AIMD # 8liyrukZ2iA/wdG2th9y1IsA0QF8dTXqvcnTmpfeQh35k5zOCPmSNq1UH410ANVk # o43+Cdmu4y81hjajV/gxdEkMx1NKU4uHQcKfZxAvBAKqMVuqte69M9J6A47OvgRa # Ps+2ykgcGV00TYr2Lr3ty9qIijanrUR3anzEwlvzZiiyfTPjLbnFRsjsYg39OlV8 # cipDoq7+qNNjqFzeGxcytL5TTLL4ZaoBdqbhOhZ3ZRDUphPvSRmMThi0vw9vODRz # W6AxnJll38F0cuJG7uEBYTptMSbhdhGQDpOXgpIUsWTjd6xpR6oaQf/DJbg3s6KC # LPAlZ66RzIg9sC+NJpud/v4+7RWsWCiKi9EOLLHfMR2ZyJ/+xhCx9yHbxtl5TPau # 1j/1MIDpMPx0LckTetiSuEtQvLsNz3Qbp7wGWqbIiOWCnb5WqxL3/BAPvIXKUjPS # xyZsq8WhbaM2tszWkPZPubdcMIIG7TCCBNWgAwIBAgIQCoDvGEuN8QWC0cR2p5V0 # aDANBgkqhkiG9w0BAQsFADBpMQswCQYDVQQGEwJVUzEXMBUGA1UEChMORGlnaUNl # cnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0IFRydXN0ZWQgRzQgVGltZVN0YW1w # aW5nIFJTQTQwOTYgU0hBMjU2IDIwMjUgQ0ExMB4XDTI1MDYwNDAwMDAwMFoXDTM2 # MDkwMzIzNTk1OVowYzELMAkGA1UEBhMCVVMxFzAVBgNVBAoTDkRpZ2lDZXJ0LCBJ # bmMuMTswOQYDVQQDEzJEaWdpQ2VydCBTSEEyNTYgUlNBNDA5NiBUaW1lc3RhbXAg # UmVzcG9uZGVyIDIwMjUgMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIB # ANBGrC0Sxp7Q6q5gVrMrV7pvUf+GcAoB38o3zBlCMGMyqJnfFNZx+wvA69HFTBdw # bHwBSOeLpvPnZ8ZN+vo8dE2/pPvOx/Vj8TchTySA2R4QKpVD7dvNZh6wW2R6kSu9 # RJt/4QhguSssp3qome7MrxVyfQO9sMx6ZAWjFDYOzDi8SOhPUWlLnh00Cll8pjrU # cCV3K3E0zz09ldQ//nBZZREr4h/GI6Dxb2UoyrN0ijtUDVHRXdmncOOMA3CoB/iU # SROUINDT98oksouTMYFOnHoRh6+86Ltc5zjPKHW5KqCvpSduSwhwUmotuQhcg9tw # 2YD3w6ySSSu+3qU8DD+nigNJFmt6LAHvH3KSuNLoZLc1Hf2JNMVL4Q1OpbybpMe4 # 6YceNA0LfNsnqcnpJeItK/DhKbPxTTuGoX7wJNdoRORVbPR1VVnDuSeHVZlc4seA # O+6d2sC26/PQPdP51ho1zBp+xUIZkpSFA8vWdoUoHLWnqWU3dCCyFG1roSrgHjSH # lq8xymLnjCbSLZ49kPmk8iyyizNDIXj//cOgrY7rlRyTlaCCfw7aSUROwnu7zER6 # EaJ+AliL7ojTdS5PWPsWeupWs7NpChUk555K096V1hE0yZIXe+giAwW00aHzrDch # Ic2bQhpp0IoKRR7YufAkprxMiXAJQ1XCmnCfgPf8+3mnAgMBAAGjggGVMIIBkTAM # BgNVHRMBAf8EAjAAMB0GA1UdDgQWBBTkO/zyMe39/dfzkXFjGVBDz2GM6DAfBgNV # HSMEGDAWgBTvb1NK6eQGfHrK4pBW9i/USezLTjAOBgNVHQ8BAf8EBAMCB4AwFgYD # VR0lAQH/BAwwCgYIKwYBBQUHAwgwgZUGCCsGAQUFBwEBBIGIMIGFMCQGCCsGAQUF # BzABhhhodHRwOi8vb2NzcC5kaWdpY2VydC5jb20wXQYIKwYBBQUHMAKGUWh0dHA6 # Ly9jYWNlcnRzLmRpZ2ljZXJ0LmNvbS9EaWdpQ2VydFRydXN0ZWRHNFRpbWVTdGFt # cGluZ1JTQTQwOTZTSEEyNTYyMDI1Q0ExLmNydDBfBgNVHR8EWDBWMFSgUqBQhk5o # dHRwOi8vY3JsMy5kaWdpY2VydC5jb20vRGlnaUNlcnRUcnVzdGVkRzRUaW1lU3Rh # bXBpbmdSU0E0MDk2U0hBMjU2MjAyNUNBMS5jcmwwIAYDVR0gBBkwFzAIBgZngQwB # BAIwCwYJYIZIAYb9bAcBMA0GCSqGSIb3DQEBCwUAA4ICAQBlKq3xHCcEua5gQezR # CESeY0ByIfjk9iJP2zWLpQq1b4URGnwWBdEZD9gBq9fNaNmFj6Eh8/YmRDfxT7C0 # k8FUFqNh+tshgb4O6Lgjg8K8elC4+oWCqnU/ML9lFfim8/9yJmZSe2F8AQ/UdKFO # tj7YMTmqPO9mzskgiC3QYIUP2S3HQvHG1FDu+WUqW4daIqToXFE/JQ/EABgfZXLW # U0ziTN6R3ygQBHMUBaB5bdrPbF6MRYs03h4obEMnxYOX8VBRKe1uNnzQVTeLni2n # HkX/QqvXnNb+YkDFkxUGtMTaiLR9wjxUxu2hECZpqyU1d0IbX6Wq8/gVutDojBIF # eRlqAcuEVT0cKsb+zJNEsuEB7O7/cuvTQasnM9AWcIQfVjnzrvwiCZ85EE8LUkqR # hoS3Y50OHgaY7T/lwd6UArb+BOVAkg2oOvol/DJgddJ35XTxfUlQ+8Hggt8l2Yv7 # roancJIFcbojBcxlRcGG0LIhp6GvReQGgMgYxQbV1S3CrWqZzBt1R9xJgKf47Cdx # VRd/ndUlQ05oxYy2zRWVFjF7mcr4C34Mj3ocCVccAvlKV9jEnstrniLvUxxVZE/r # ptb7IRE2lskKPIJgbaP5t2nGj/ULLi49xTcBZU8atufk+EMF/cWuiC7POGT75qaL # 6vdCvHlshtjdNXOCIUjsarfNZzGCBJgwggSUAgEBMHgwZDELMAkGA1UEBhMCVVMx # FzAVBgNVBAoTDkRpZ2lDZXJ0LCBJbmMuMTwwOgYDVQQDEzNEaWdpQ2VydCBHbG9i # YWwgRzMgQ29kZSBTaWduaW5nIEVDQyBTSEEzODQgMjAyMSBDQTECEA1KNNqGkI/A # Eyy8gTeTryQwDQYJYIZIAWUDBAIBBQCggYQwGAYKKwYBBAGCNwIBDDEKMAigAoAA # oQKAADAZBgkqhkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4w # DAYKKwYBBAGCNwIBFTAvBgkqhkiG9w0BCQQxIgQg91WrGE67K0N9YsgaqW+c88UJ # H3Yg5zZDJNNy41RS8mQwCwYHKoZIzj0CAQUABEgwRgIhAOIw5wMIhXxnznwpO5n4 # lhtTg2n9YlG/hfTz25z2oXavAiEAzU+cMzkmXpch9OZCyP1K+wC/7nF9ipqf4pev # FUrCaUWhggMmMIIDIgYJKoZIhvcNAQkGMYIDEzCCAw8CAQEwfTBpMQswCQYDVQQG # EwJVUzEXMBUGA1UEChMORGlnaUNlcnQsIEluYy4xQTA/BgNVBAMTOERpZ2lDZXJ0 # IFRydXN0ZWQgRzQgVGltZVN0YW1waW5nIFJTQTQwOTYgU0hBMjU2IDIwMjUgQ0Ex # AhAKgO8YS43xBYLRxHanlXRoMA0GCWCGSAFlAwQCAQUAoGkwGAYJKoZIhvcNAQkD # MQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMjYwMjA5MjM0NDAxWjAvBgkq # hkiG9w0BCQQxIgQgpV949y0Ej0TlZpOa9qij0hc89MAfzH9DvxAGOl2TuDwwDQYJ # KoZIhvcNAQEBBQAEggIARvJs80X0kZZ2daqGK0QKKE355xXtnMChR5k9I8F3iu+P # /a4xmvtuTwG9QDdhI4dMA8Wtc8rGk0lbmKy+NxwlKUv1+0Gm55ZUarxocC/ORaov # WsShw5aynZFWnafWpXrJ24ukwIB3T/QTJ+W4xK0Tzq48MO77hkwXefEDJj0xeuVI # ZZMShea1iMHNsOzShpqTRz0OIkke80uJ02e11Fn669A/6Wltey1DdRnDlg+z8IZ/ # c1UISFEai5HA5B1SBPKkjarflnBjCiPVKfQwS7UAhQ4+J4S0PuGiKoU7EZirdO79 # Z9IpoZ7h+lCkPY6HHCzdCGI/Kr9MGUg6231S4c2Bs2H9hP2czvVuG1yWE2uWiXVU # 7sHMrsA1OtGzug2b2twFjEttXtV+bj8x7UGzhPupSAlRP2gN9NBlQ+Y8+VxO5oTn # dvKanf3OoXsrGNdPd1V5ARKk4nb6HnodIfVQmdG8QNWjtQW73wjt61zm2bHGVKEC # yT/Xe3aP91qCxN//9Dkd4UUVzU1mvqX82fQDgWfwgHH8nIa23vPlvew0UzLJXmyn # D/eOl81U7OIWhvQjKzkS73YDVPQqkfQDt4SgiaSgTH+0QPXtIc+GkQA5hnaLMkZt # GkNJxOlueXj5gD9zRQi25CuOnnjuiPnEpETBZflVsEZpujeO1wX5VRQV+FzJa2M= # SIG # End signature block |