Microsoft.Entra.CertificateBasedAuthentication.psm1
# ------------------------------------------------------------------------------ # Copyright (c) Microsoft Corporation. All Rights Reserved. # Licensed under the MIT License. See License in the project root for license information. # ------------------------------------------------------------------------------ Set-StrictMode -Version 5 function Get-EntraUserCBAAuthorizationInfo { [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true, HelpMessage = 'The unique identifier for the user (User Principal Name or UserId).')] [Alias('ObjectId', 'UPN', 'Identity', 'UserPrincipalName')] [ValidateNotNullOrEmpty()] [ValidateScript({ if ($_ -match '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' -or $_ -match '^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$') { return $true } throw "UserId must be a valid email address or GUID." })] [string]$UserId, [Parameter(Mandatory = $false, HelpMessage = 'If specified, returns the raw response from the API.')] [Alias('RawResponse')] [switch]$Raw ) begin { # Ensure connection to Microsoft Entra if (-not (Get-EntraContext)) { $errorMessage = "Not connected to Microsoft Graph. Use 'Connect-Entra -Scopes Directory.ReadWrite.All, User.ReadWrite.All' to authenticate." Write-Error -Message $errorMessage -ErrorAction Stop return } } process { try { $customHeaders = New-EntraCustomHeaders -Command $MyInvocation.MyCommand # Determine if UserId is a GUID (ObjectId) or a UserPrincipalName $isGuid = $UserId -match "^[{]?[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}[}]?$" $filter = if ($isGuid) { "id eq '$UserId'" } else { "userPrincipalName eq '$UserId'" } # First look up the user to get the ID if not already a GUID $uri = "/v1.0/users?`$filter=$filter" $lookupCustomHeaders = @{} + $customHeaders + @{"ConsistencyLevel" = "eventual" } $userLookup = Invoke-MgGraphRequest -Uri $uri -Method GET -Headers $lookupCustomHeaders -ErrorAction Stop if ($userLookup.value.Count -eq 0) { throw "User '$UserId' not found in Entra ID" } $userId = $userLookup.value[0].id # Now fetch the authorization info $apiCallUrl = "/v1.0/users/$userId`?`$select=id,displayName,userPrincipalName,userType,authorizationInfo" $response = Invoke-MgGraphRequest -Uri $apiCallUrl -Method GET -Headers $customHeaders -ErrorAction Stop # If Raw switch is specified, return the raw response if ($Raw) { return $response } # Create a structured object for the certificate user IDs $certificateUserIds = @() if ($response.authorizationInfo -and $response.authorizationInfo.certificateUserIds) { foreach ($certId in $response.authorizationInfo.certificateUserIds) { if ($certId -match 'X509:<([^>]+)>(.+)') { $type = $matches[1] $value = $matches[2] # Create a descriptive name for the certificate type $typeName = switch ($type) { "PN" { "PrincipalName" } "S" { "Subject" } "I" { "Issuer" } "SR" { "SerialNumber" } "SKI" { "SubjectKeyIdentifier" } "SHA1-PUKEY" { "SHA1PublicKey" } default { $type } } $certificateUserIds += [PSCustomObject]@{ Type = $type TypeName = $typeName Value = $value OriginalString = $certId } } else { # For any ID that doesn't match the expected format $certificateUserIds += [PSCustomObject]@{ Type = "Unknown" TypeName = "Unknown" Value = $certId OriginalString = $certId } } } } # Create a structured AuthorizationInfo object $authInfo = [PSCustomObject]@{ CertificateUserIds = $certificateUserIds RawAuthorizationInfo = $response.authorizationInfo } # Create a custom output object with the properties of interest $result = [PSCustomObject]@{ Id = $response.id DisplayName = $response.displayName UserPrincipalName = $response.userPrincipalName UserType = $response.userType AuthorizationInfo = $authInfo } return $result } catch { $errorDetails = $_.Exception.Message Write-Error "Failed to retrieve authorization info: $errorDetails" throw } } end { # Cleanup if needed } } Set-Alias -Name Get-EntraUserAuthorizationInfo -Value Get-EntraUserCBAAuthorizationInfo -Description "Gets a user's authorization information from Microsoft Entra ID" -Scope Global -Force function Get-EntraUserCertificateUserIdsFromCertificate { [CmdletBinding(DefaultParameterSetName = 'Default')] param ( [Parameter(Mandatory = $false, HelpMessage = "Path to the certificate file. The file can be in .cer or .pem format.")] [string]$Path, [Parameter(Mandatory = $false, HelpMessage = "Certificate object. If provided, the Path parameter is ignored.")] [Alias('CertificateObject', 'Cert')] [System.Security.Cryptography.X509Certificates.X509Certificate2]$Certificate, [Parameter(Mandatory = $false, ParameterSetName = 'Default', HelpMessage = "The certificate mapping type to use. Valid values are: PrincipalName, RFC822Name, IssuerAndSubject, Subject, SKI, SHA1PublicKey, IssuerAndSerialNumber.")] [ValidateSet("PrincipalName", "RFC822Name", "IssuerAndSubject", "Subject", "SKI", "SHA1PublicKey", "IssuerAndSerialNumber")] [string]$CertificateMapping ) function Get-Certificate { param ( [string]$filePath ) if ($filePath.EndsWith(".cer")) { return [System.Security.Cryptography.X509Certificates.X509Certificate]::new($filePath) } elseif ($filePath.EndsWith(".pem")) { $pemContent = Get-Content -Path $filePath -Raw $pemContent = $pemContent -replace "-----BEGIN CERTIFICATE-----", "" $pemContent = $pemContent -replace "-----END CERTIFICATE-----", "" $pemContent = $pemContent -replace "(\r\n|\n|\r)", "" $pemBytes = [Convert]::FromBase64String($pemContent) $certificate = [System.Security.Cryptography.X509Certificates.X509Certificate]::new($pemBytes) return $certificate } else { throw "Unsupported certificate format. Please provide a .cer or .pem file." } } function Get-DistinguishedNameAsString { param ( [System.Security.Cryptography.X509Certificates.X500DistinguishedName]$distinguishedName ) $dn = $distinguishedName.Decode([System.Security.Cryptography.X509Certificates.X500DistinguishedNameFlags]::UseNewLines -bor [System.Security.Cryptography.X509Certificates.X500DistinguishedNameFlags]::DoNotUsePlusSign) $dn = $dn -replace "(\r\n|\n|\r)", "," return $dn.TrimEnd(',') } function Get-SerialNumberAsLittleEndianHexString { param ( [System.Security.Cryptography.X509Certificates.X509Certificate2]$cert ) $littleEndianSerialNumber = $cert.GetSerialNumber() if ($littleEndianSerialNumber.Length -eq 0) { return "" } [System.Array]::Reverse($littleEndianSerialNumber) $hexString = -join ($littleEndianSerialNumber | ForEach-Object { $_.ToString("x2") }) return $hexString } function Get-SubjectKeyIdentifier { param ( [System.Security.Cryptography.X509Certificates.X509Certificate2]$cert ) foreach ($extension in $cert.Extensions) { if ($extension.Oid.Value -eq "2.5.29.14") { $ski = New-Object System.Security.Cryptography.X509Certificates.X509SubjectKeyIdentifierExtension -ArgumentList $extension, $false return $ski.SubjectKeyIdentifier } } return "" } # Function to generate certificate mapping fields function Get-CertificateMappingFields { param ( [System.Security.Cryptography.X509Certificates.X509Certificate2]$cert ) $subject = Get-DistinguishedNameAsString -distinguishedName $cert.SubjectName $issuer = Get-DistinguishedNameAsString -distinguishedName $cert.IssuerName $serialNumber = Get-SerialNumberAsLittleEndianHexString -cert $cert $thumbprint = $cert.Thumbprint $principalName = $cert.GetNameInfo([System.Security.Cryptography.X509Certificates.X509NameType]::UpnName, $false) $emailName = $cert.GetNameInfo([System.Security.Cryptography.X509Certificates.X509NameType]::EmailName, $false) $subjectKeyIdentifier = Get-SubjectKeyIdentifier -cert $cert $sha1PublicKey = $cert.GetCertHashString() return @{ "SubjectName" = $subject "IssuerName" = $issuer "SerialNumber" = $serialNumber "Thumbprint" = $thumbprint "PrincipalName" = $principalName "EmailName" = $emailName "SubjectKeyIdentifier" = $subjectKeyIdentifier "Sha1PublicKey" = $sha1PublicKey } } function Get-CertificateUserIds { param ( [System.Security.Cryptography.X509Certificates.X509Certificate2]$cert ) $mappingFields = Get-CertificateMappingFields -cert $cert $certUserIDs = @{ "PrincipalName" = "" "RFC822Name" = "" "IssuerAndSubject" = "" "Subject" = "" "SKI" = "" "SHA1PublicKey" = "" "IssuerAndSerialNumber" = "" } if (-not [string]::IsNullOrWhiteSpace($mappingFields.PrincipalName)) { $certUserIDs.PrincipalName = "X509:<PN>$($mappingFields.PrincipalName)" } if (-not [string]::IsNullOrWhiteSpace($mappingFields.EmailName)) { $certUserIDs.RFC822Name = "X509:<RFC822>$($mappingFields.EmailName)" } if ((-not [string]::IsNullOrWhiteSpace($mappingFields.IssuerName)) -and (-not [string]::IsNullOrWhiteSpace($mappingFields.SubjectName))) { $certUserIDs.IssuerAndSubject = "X509:<I>$($mappingFields.IssuerName)<S>$($mappingFields.SubjectName)" } if (-not [string]::IsNullOrWhiteSpace($mappingFields.SubjectName)) { $certUserIDs.Subject = "X509:<S>$($mappingFields.SubjectName)" } if (-not [string]::IsNullOrWhiteSpace($mappingFields.SubjectKeyIdentifier)) { $certUserIDs.SKI = "X509:<SKI>$($mappingFields.SubjectKeyIdentifier)" } if (-not [string]::IsNullOrWhiteSpace($mappingFields.Sha1PublicKey)) { $certUserIDs.SHA1PublicKey = "X509:<SHA1-PUKEY>$($mappingFields.Sha1PublicKey)" } if ((-not [string]::IsNullOrWhiteSpace($mappingFields.IssuerName)) -and (-not [string]::IsNullOrWhiteSpace($mappingFields.SerialNumber))) { $certUserIDs.IssuerAndSerialNumber = "X509:<I>$($mappingFields.IssuerName)<SR>$($mappingFields.SerialNumber)" } return $certUserIDs } function Main { $cert = $Certificate if ($null -eq $cert) { $cert = Get-Certificate -filePath $Path } $mappings = Get-CertificateUserIds -cert $cert if ($CertificateMapping -eq "") { return $mappings } else { $value = $mappings[$CertificateMapping] return "$($value)" } } # Call main function return Main } function Set-EntraUserCBACertificateUserId { [CmdletBinding(DefaultParameterSetName = 'CertPath')] [OutputType([Microsoft.Graph.PowerShell.Models.MicrosoftGraphUser])] param ( [Parameter(Mandatory = $true, HelpMessage = 'The unique identifier for the user (User Principal Name or UserId).', Position = 0)] [Alias('ObjectId', 'UPN', 'Identity', 'UserPrincipalName')] [ValidateNotNullOrEmpty()] [ValidateScript({ if ($_ -match '^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$' -or $_ -match '^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$') { return $true } throw "UserId must be a valid email address or GUID." })] [string]$UserId, [Parameter(Mandatory = $true, ParameterSetName = 'CertPath', HelpMessage = "Path to the certificate file. The file can be in .cer or .pem format.")] [Alias('CertificatePath')] [ValidateScript({ Test-Path $_ -PathType Leaf })] [string]$CertPath, [Parameter(Mandatory = $true, ParameterSetName = 'CertObject', HelpMessage = "Certificate object.")] [Alias('CertificateObject', 'Certificate')] [ValidateNotNull()] [System.Security.Cryptography.X509Certificates.X509Certificate2]$Cert, [Parameter(Mandatory = $true, HelpMessage = "The certificate mapping type to use.")] [ValidateSet("PrincipalName", "RFC822Name", "IssuerAndSubject", "Subject", "SKI", "SHA1PublicKey", "IssuerAndSerialNumber")] [ValidateNotNullOrEmpty()] [string[]]$CertificateMapping ) begin { # Ensure connection to Microsoft Entra if (-not (Get-EntraContext)) { $errorMessage = "Not connected to Microsoft Graph. Use 'Connect-Entra -Scopes Directory.ReadWrite.All, User.ReadWrite.All' to authenticate." Write-Error -Message $errorMessage -ErrorAction Stop return } } process { try { # Define custom headers for the request $customHeaders = New-EntraCustomHeaders -Command $MyInvocation.MyCommand # Get certificate user IDs based on parameter set Write-Verbose "Retrieving certificate user IDs" if ($PSCmdlet.ParameterSetName -eq 'CertPath') { $allCertUserIds = Get-EntraUserCertificateUserIdsFromCertificate -Path $CertPath Write-Verbose "Certificate loaded from path: $CertPath" } else { $allCertUserIds = Get-EntraUserCertificateUserIdsFromCertificate -Certificate $Cert Write-Verbose "Certificate loaded from certificate object" } if (-not $allCertUserIds) { throw "Failed to extract certificate user IDs from the certificate" } # Filter the certificate user IDs based on the requested mappings $certUserIdObj = @() foreach ($mapping in $CertificateMapping) { if ($allCertUserIds.$mapping) { $certUserIdObj += $allCertUserIds.$mapping Write-Verbose "Added mapping type: $mapping" } else { Write-Warning "Mapping type '$mapping' not found in the certificate" } } if ($certUserIdObj.Count -eq 0) { throw "No valid certificate mappings found for the specified mapping types" } # Check if user exists Write-Verbose "Verifying user exists: $UserId" # Determine if UserId is a UPN or GUID if ($UserId -match '^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$') { $userFilter = "id eq '$UserId'" } else { $userFilter = "userPrincipalName eq '$UserId'" } $userQuery = Invoke-MgGraphRequest -Method GET -Uri "/v1.0/users?`$filter=$userFilter&`$select=id" -ErrorAction Stop if (-not $userQuery.value -or $userQuery.value.Count -eq 0) { throw "User '$UserId' not found in Entra ID" } $userId = $userQuery.value[0].id Write-Verbose "User found with ID: $userId" # Prepare the request body $body = @{ authorizationInfo = @{ certificateUserIds = $certUserIdObj } } $jsonBody = ConvertTo-Json -InputObject $body -Depth 10 Write-Verbose "Updating certificate user IDs for user: $userId" $apiCallUrl = "/v1.0/users/$userId" $response = Invoke-MgGraphRequest -Uri $apiCallUrl -Method PATCH -Body $jsonBody -Headers $customHeaders -ErrorAction Stop Write-Verbose "Certificate User IDs successfully updated" return $response } catch { $errorDetails = $_.Exception.Message Write-Error "Failed to update certificate user IDs: $errorDetails" throw } } end { # Cleanup if needed } } Set-Alias -Name Update-EntraUserCBACertificateUserId -Value Set-EntraUserCBACertificateUserId -Description "Update certificate-based authentication for a user using a certificate file or object" -Scope Global -Force Export-ModuleMember -Function @('Get-EntraUserCBAAuthorizationInfo', 'Get-EntraUserCertificateUserIdsFromCertificate', 'Set-EntraUserCBACertificateUserId') # Typedefs # ------------------------------------------------------------------------------ # Type definitions required for commands inputs # ------------------------------------------------------------------------------ $def = @" namespace Microsoft.Open.AzureAD.Graph.PowerShell.Custom { using System.Linq; public enum KeyType{ Symmetric = 0, AsymmetricX509Cert = 1, } public enum KeyUsage{ Sign = 0, Verify = 1, Decrypt = 2, Encrypt = 3, } } namespace Microsoft.Open.AzureAD.Model { using System.Linq; public class AlternativeSecurityId { public System.String IdentityProvider; public System.Byte[] Key; public System.Nullable<System.Int32> Type; } public class AppRole { public System.Collections.Generic.List<System.String> AllowedMemberTypes; public System.String Description; public System.String DisplayName; public System.String Id; public System.Nullable<System.Boolean> IsEnabled; public System.String Origin; public System.String Value; } public class AssignedLicense { public System.Collections.Generic.List<System.String> DisabledPlans; public System.String SkuId; } public class AssignedLicenses { public System.Collections.Generic.List<Microsoft.Open.AzureAD.Model.AssignedLicense> AddLicenses; public System.Collections.Generic.List<System.String> RemoveLicenses; } public class CertificateAuthorityInformation { public enum AuthorityTypeEnum{ RootAuthority = 0, IntermediateAuthority = 1, } public System.Nullable<AuthorityTypeEnum> AuthorityType; public System.String CrlDistributionPoint; public System.String DeltaCrlDistributionPoint; public System.Byte[] TrustedCertificate; public System.String TrustedIssuer; public System.String TrustedIssuerSki; } public class CrossCloudVerificationCodeBody { public System.String CrossCloudVerificationCode; public CrossCloudVerificationCodeBody() { } public CrossCloudVerificationCodeBody(System.String value) { CrossCloudVerificationCode = value; } } public class GroupIdsForMembershipCheck { public System.Collections.Generic.List<System.String> GroupIds; public GroupIdsForMembershipCheck() { } public GroupIdsForMembershipCheck(System.Collections.Generic.List<System.String> value) { GroupIds = value; } } public class KeyCredential { public System.Byte[] CustomKeyIdentifier; public System.Nullable<System.DateTime> EndDate; public System.String KeyId; public System.Nullable<System.DateTime> StartDate; public System.String Type; public System.String Usage; public System.Byte[] Value; } public class PasswordCredential { public System.Byte[] CustomKeyIdentifier; public System.Nullable<System.DateTime> EndDate; public System.String KeyId; public System.Nullable<System.DateTime> StartDate; public System.String Value; } public class PasswordProfile { public System.String Password; public System.Nullable<System.Boolean> ForceChangePasswordNextLogin; public System.Nullable<System.Boolean> EnforceChangePasswordPolicy; } public class PrivacyProfile { public System.String ContactEmail; public System.String StatementUrl; } public class SignInName { public System.String Type; public System.String Value; } } namespace Microsoft.Open.MSGraph.Model { using System.Linq; public class AddIn { public System.String Id; public System.String Type; public System.Collections.Generic.List<Microsoft.Open.MSGraph.Model.KeyValue> Properties; } public class ApiApplication { public System.Nullable<System.Boolean> AcceptMappedClaims; public System.Collections.Generic.List<System.String> KnownClientApplications; public System.Collections.Generic.List<Microsoft.Open.MSGraph.Model.PreAuthorizedApplication> PreAuthorizedApplications; public System.Nullable<System.Int32> RequestedAccessTokenVersion; public System.Collections.Generic.List<Microsoft.Open.MSGraph.Model.PermissionScope> Oauth2PermissionScopes; } public class AppRole { public System.Collections.Generic.List<System.String> AllowedMemberTypes; public System.String Description; public System.String DisplayName; public System.String Id; public System.Nullable<System.Boolean> IsEnabled; public System.String Origin; public System.String Value; } public class ConditionalAccessApplicationCondition { public System.Collections.Generic.List<System.String> IncludeApplications; public System.Collections.Generic.List<System.String> ExcludeApplications; public System.Collections.Generic.List<System.String> IncludeUserActions; public System.Collections.Generic.List<System.String> IncludeProtectionLevels; } public class ConditionalAccessApplicationEnforcedRestrictions { public System.Nullable<System.Boolean> IsEnabled; public ConditionalAccessApplicationEnforcedRestrictions() { } public ConditionalAccessApplicationEnforcedRestrictions(System.Nullable<System.Boolean> value) { IsEnabled = value; } } public class ConditionalAccessCloudAppSecurity { public enum CloudAppSecurityTypeEnum{ McasConfigured = 0, MonitorOnly = 1, BlockDownloads = 2, } public System.Nullable<CloudAppSecurityTypeEnum> CloudAppSecurityType; public System.Nullable<System.Boolean> IsEnabled; } public class ConditionalAccessConditionSet { public Microsoft.Open.MSGraph.Model.ConditionalAccessApplicationCondition Applications; public Microsoft.Open.MSGraph.Model.ConditionalAccessUserCondition Users; public Microsoft.Open.MSGraph.Model.ConditionalAccessPlatformCondition Platforms; public Microsoft.Open.MSGraph.Model.ConditionalAccessLocationCondition Locations; public enum ConditionalAccessRiskLevel{ Low = 0, Medium = 1, High = 2, Hidden = 3, None = 4, UnknownFutureValue = 5, } public System.Collections.Generic.List<ConditionalAccessRiskLevel> SignInRiskLevels; public enum ConditionalAccessClientApp{ All = 0, Browser = 1, MobileAppsAndDesktopClients = 2, ExchangeActiveSync = 3, EasSupported = 4, Other = 5, } public System.Collections.Generic.List<ConditionalAccessClientApp> ClientAppTypes; } public class ConditionalAccessGrantControls { public System.String _Operator; public enum ConditionalAccessGrantControl{ Block = 0, Mfa = 1, CompliantDevice = 2, DomainJoinedDevice = 3, ApprovedApplication = 4, CompliantApplication = 5, PasswordChange = 6, } public System.Collections.Generic.List<ConditionalAccessGrantControl> BuiltInControls; public System.Collections.Generic.List<System.String> CustomAuthenticationFactors; public System.Collections.Generic.List<System.String> TermsOfUse; } public class ConditionalAccessLocationCondition { public System.Collections.Generic.List<System.String> IncludeLocations; public System.Collections.Generic.List<System.String> ExcludeLocations; } public class ConditionalAccessPersistentBrowser { public enum ModeEnum{ Always = 0, Never = 1, } public System.Nullable<ModeEnum> Mode; public System.Nullable<System.Boolean> IsEnabled; } public class ConditionalAccessPlatformCondition { public enum ConditionalAccessDevicePlatforms{ Android = 0, IOS = 1, Windows = 2, WindowsPhone = 3, MacOS = 4, All = 5, } public System.Collections.Generic.List<ConditionalAccessDevicePlatforms> IncludePlatforms; public System.Collections.Generic.List<ConditionalAccessDevicePlatforms> ExcludePlatforms; } public class ConditionalAccessSessionControls { public Microsoft.Open.MSGraph.Model.ConditionalAccessApplicationEnforcedRestrictions ApplicationEnforcedRestrictions; public Microsoft.Open.MSGraph.Model.ConditionalAccessCloudAppSecurity CloudAppSecurity; public Microsoft.Open.MSGraph.Model.ConditionalAccessSignInFrequency SignInFrequency; public Microsoft.Open.MSGraph.Model.ConditionalAccessPersistentBrowser PersistentBrowser; } public class ConditionalAccessSignInFrequency { public enum TypeEnum{ Days = 0, Hours = 1, } public System.Nullable<TypeEnum> Type; public System.Nullable<System.Int32> Value; public System.Nullable<System.Boolean> IsEnabled; } public class ConditionalAccessUserCondition { public System.Collections.Generic.List<System.String> IncludeUsers; public System.Collections.Generic.List<System.String> ExcludeUsers; public System.Collections.Generic.List<System.String> IncludeGroups; public System.Collections.Generic.List<System.String> ExcludeGroups; public System.Collections.Generic.List<System.String> IncludeRoles; public System.Collections.Generic.List<System.String> ExcludeRoles; } public enum CountriesAndRegion{ AD = 0, AE = 1, AF = 2, AG = 3, AI = 4, AL = 5, AM = 6, AN = 7, AO = 8, AQ = 9, AR = 10, AS = 11, AT = 12, AU = 13, AW = 14, AX = 15, AZ = 16, BA = 17, BB = 18, BD = 19, BE = 20, BF = 21, BG = 22, BH = 23, BI = 24, BJ = 25, BL = 26, BM = 27, BN = 28, BO = 29, BQ = 30, BR = 31, BS = 32, BT = 33, BV = 34, BW = 35, BY = 36, BZ = 37, CA = 38, CC = 39, CD = 40, CF = 41, CG = 42, CH = 43, CI = 44, CK = 45, CL = 46, CM = 47, CN = 48, CO = 49, CR = 50, CU = 51, CV = 52, CW = 53, CX = 54, CY = 55, CZ = 56, DE = 57, DJ = 58, DK = 59, DM = 60, DO = 61, DZ = 62, EC = 63, EE = 64, EG = 65, EH = 66, ER = 67, ES = 68, ET = 69, FI = 70, FJ = 71, FK = 72, FM = 73, FO = 74, FR = 75, GA = 76, GB = 77, GD = 78, GE = 79, GF = 80, GG = 81, GH = 82, GI = 83, GL = 84, GM = 85, GN = 86, GP = 87, GQ = 88, GR = 89, GS = 90, GT = 91, GU = 92, GW = 93, GY = 94, HK = 95, HM = 96, HN = 97, HR = 98, HT = 99, HU = 100, ID = 101, IE = 102, IL = 103, IM = 104, IN = 105, IO = 106, IQ = 107, IR = 108, IS = 109, IT = 110, JE = 111, JM = 112, JO = 113, JP = 114, KE = 115, KG = 116, KH = 117, KI = 118, KM = 119, KN = 120, KP = 121, KR = 122, KW = 123, KY = 124, KZ = 125, LA = 126, LB = 127, LC = 128, LI = 129, LK = 130, LR = 131, LS = 132, LT = 133, LU = 134, LV = 135, LY = 136, MA = 137, MC = 138, MD = 139, ME = 140, MF = 141, MG = 142, MH = 143, MK = 144, ML = 145, MM = 146, MN = 147, MO = 148, MP = 149, MQ = 150, MR = 151, MS = 152, MT = 153, MU = 154, MV = 155, MW = 156, MX = 157, MY = 158, MZ = 159, NA = 160, NC = 161, NE = 162, NF = 163, NG = 164, NI = 165, NL = 166, NO = 167, NP = 168, NR = 169, NU = 170, NZ = 171, OM = 172, PA = 173, PE = 174, PF = 175, PG = 176, PH = 177, PK = 178, PL = 179, PM = 180, PN = 181, PR = 182, PS = 183, PT = 184, PW = 185, PY = 186, QA = 187, RE = 188, RO = 189, RS = 190, RU = 191, RW = 192, SA = 193, SB = 194, SC = 195, SD = 196, SE = 197, SG = 198, SH = 199, SI = 200, SJ = 201, SK = 202, SL = 203, SM = 204, SN = 205, SO = 206, SR = 207, SS = 208, ST = 209, SV = 210, SX = 211, SY = 212, SZ = 213, TC = 214, TD = 215, TF = 216, TG = 217, TH = 218, TJ = 219, TK = 220, TL = 221, TM = 222, TN = 223, TO = 224, TR = 225, TT = 226, TV = 227, TW = 228, TZ = 229, UA = 230, UG = 231, UM = 232, US = 233, UY = 234, UZ = 235, VA = 236, VC = 237, VE = 238, VG = 239, VI = 240, VN = 241, VU = 242, WF = 243, WS = 244, YE = 245, YT = 246, ZA = 247, ZM = 248, ZW = 249, } public class DefaultUserRolePermissions { public System.Nullable<System.Boolean> AllowedToCreateApps; public System.Nullable<System.Boolean> AllowedToCreateSecurityGroups; public System.Nullable<System.Boolean> AllowedToReadOtherUsers; public System.Collections.Generic.List<System.String> PermissionGrantPoliciesAssigned; } public class DelegatedPermissionClassification { public enum ClassificationEnum{ Low = 0, Medium = 1, High = 2, } public System.Nullable<ClassificationEnum> Classification; public System.String Id; public System.String PermissionId; public System.String PermissionName; } public class EmailAddress { public System.String Name; public System.String Address; } public class ImplicitGrantSettings { public System.Nullable<System.Boolean> EnableIdTokenIssuance; public System.Nullable<System.Boolean> EnableAccessTokenIssuance; } public class InformationalUrl { public System.String TermsOfServiceUrl; public System.String MarketingUrl; public System.String PrivacyStatementUrl; public System.String SupportUrl; public System.String LogoUrl; } public class InvitedUserMessageInfo { public System.Collections.Generic.List<Microsoft.Open.MSGraph.Model.Recipient> CcRecipients; public System.String CustomizedMessageBody; public System.String MessageLanguage; } public class IpRange { public System.String CidrAddress; public IpRange() { } public IpRange(System.String value) { CidrAddress = value; } } public class KeyCredential { public System.Byte[] CustomKeyIdentifier; public System.String DisplayName; public System.Nullable<System.DateTime> EndDateTime; public System.String KeyId; public System.Nullable<System.DateTime> StartDateTime; public System.String Type; public System.String Usage; public System.Byte[] Key; } public class KeyValue { public System.String Key; public System.String Value; } public class MsDirectoryObject { public System.String Id; public System.String OdataType; } public class MsRoleMemberInfo { public System.String Id; } public class OptionalClaim { public System.String Name; public System.String Source; public System.Nullable<System.Boolean> Essential; public System.Collections.Generic.List<System.String> AdditionalProperties; } public class OptionalClaims { public System.Collections.Generic.List<Microsoft.Open.MSGraph.Model.OptionalClaim> IdToken; public System.Collections.Generic.List<Microsoft.Open.MSGraph.Model.OptionalClaim> AccessToken; public System.Collections.Generic.List<Microsoft.Open.MSGraph.Model.OptionalClaim> Saml2Token; } public class ParentalControlSettings { public enum LegalAgeGroupRuleEnum{ Allow = 0, RequireConsentForPrivacyServices = 1, RequireConsentForMinors = 2, RequireConsentForKids = 3, BlockMinors = 4, } public System.Nullable<LegalAgeGroupRuleEnum> LegalAgeGroupRule; public System.Collections.Generic.List<System.String> CountriesBlockedForMinors; } public class PasswordCredential { public System.Byte[] CustomKeyIdentifier; public System.Nullable<System.DateTime> EndDateTime; public System.String DisplayName; public System.String KeyId; public System.Nullable<System.DateTime> StartDateTime; public System.String SecretText; public System.String Hint; } public class PermissionScope { public System.String AdminConsentDescription; public System.String AdminConsentDisplayName; public System.String Id; public System.Nullable<System.Boolean> IsEnabled; public System.String Type; public System.String UserConsentDescription; public System.String UserConsentDisplayName; public System.String Value; } public class PreAuthorizedApplication { public System.String AppId; public System.Collections.Generic.List<System.String> DelegatedPermissionIds; } public class PublicClientApplication { public System.Collections.Generic.List<System.String> RedirectUris; public PublicClientApplication() { } public PublicClientApplication(System.Collections.Generic.List<System.String> value) { RedirectUris = value; } } public class Recipient { public Microsoft.Open.MSGraph.Model.EmailAddress EmailAddress; public Recipient() { } public Recipient(Microsoft.Open.MSGraph.Model.EmailAddress value) { EmailAddress = value; } } public class RequiredResourceAccess { public System.String ResourceAppId; public System.Collections.Generic.List<Microsoft.Open.MSGraph.Model.ResourceAccess> ResourceAccess; } public class ResourceAccess { public System.String Id; public System.String Type; } public class RolePermission { public System.Collections.Generic.List<System.String> AllowedResourceActions; public System.String Condition; } public class SetVerifiedPublisherRequest { public System.String VerifiedPublisherId; public SetVerifiedPublisherRequest() { } public SetVerifiedPublisherRequest(System.String value) { VerifiedPublisherId = value; } } public class User { public System.String Id; public System.String OdataType; } public class WebApplication { public System.String HomePageUrl; public System.String LogoutUrl; public System.Collections.Generic.List<System.String> RedirectUris; public Microsoft.Open.MSGraph.Model.ImplicitGrantSettings ImplicitGrantSettings; } } "@ try { Add-Type -TypeDefinition $def -ErrorAction SilentlyContinue } catch { # No error message will be displayed, and type will be added if it doesn't exist } # ------------------------------------------------------------------------------ # End of Type definitions required for commands inputs # ------------------------------------------------------------------------------ # SIG # Begin signature block # MIIoRgYJKoZIhvcNAQcCoIIoNzCCKDMCAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCBc0N/GNtjNZs+5 # 4Jcd2j9xn4QUr2a0WAisVUrRmtKfx6CCDXYwggX0MIID3KADAgECAhMzAAAEBGx0 # Bv9XKydyAAAAAAQEMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMjQwOTEyMjAxMTE0WhcNMjUwOTExMjAxMTE0WjB0MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMR4wHAYDVQQDExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQC0KDfaY50MDqsEGdlIzDHBd6CqIMRQWW9Af1LHDDTuFjfDsvna0nEuDSYJmNyz # NB10jpbg0lhvkT1AzfX2TLITSXwS8D+mBzGCWMM/wTpciWBV/pbjSazbzoKvRrNo # DV/u9omOM2Eawyo5JJJdNkM2d8qzkQ0bRuRd4HarmGunSouyb9NY7egWN5E5lUc3 # a2AROzAdHdYpObpCOdeAY2P5XqtJkk79aROpzw16wCjdSn8qMzCBzR7rvH2WVkvF # HLIxZQET1yhPb6lRmpgBQNnzidHV2Ocxjc8wNiIDzgbDkmlx54QPfw7RwQi8p1fy # 4byhBrTjv568x8NGv3gwb0RbAgMBAAGjggFzMIIBbzAfBgNVHSUEGDAWBgorBgEE # AYI3TAgBBggrBgEFBQcDAzAdBgNVHQ4EFgQU8huhNbETDU+ZWllL4DNMPCijEU4w # RQYDVR0RBD4wPKQ6MDgxHjAcBgNVBAsTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEW # MBQGA1UEBRMNMjMwMDEyKzUwMjkyMzAfBgNVHSMEGDAWgBRIbmTlUAXTgqoXNzci # tW2oynUClTBUBgNVHR8ETTBLMEmgR6BFhkNodHRwOi8vd3d3Lm1pY3Jvc29mdC5j # b20vcGtpb3BzL2NybC9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3JsMGEG # CCsGAQUFBwEBBFUwUzBRBggrBgEFBQcwAoZFaHR0cDovL3d3dy5taWNyb3NvZnQu # Y29tL3BraW9wcy9jZXJ0cy9NaWNDb2RTaWdQQ0EyMDExXzIwMTEtMDctMDguY3J0 # MAwGA1UdEwEB/wQCMAAwDQYJKoZIhvcNAQELBQADggIBAIjmD9IpQVvfB1QehvpC # Ge7QeTQkKQ7j3bmDMjwSqFL4ri6ae9IFTdpywn5smmtSIyKYDn3/nHtaEn0X1NBj # L5oP0BjAy1sqxD+uy35B+V8wv5GrxhMDJP8l2QjLtH/UglSTIhLqyt8bUAqVfyfp # h4COMRvwwjTvChtCnUXXACuCXYHWalOoc0OU2oGN+mPJIJJxaNQc1sjBsMbGIWv3 # cmgSHkCEmrMv7yaidpePt6V+yPMik+eXw3IfZ5eNOiNgL1rZzgSJfTnvUqiaEQ0X # dG1HbkDv9fv6CTq6m4Ty3IzLiwGSXYxRIXTxT4TYs5VxHy2uFjFXWVSL0J2ARTYL # E4Oyl1wXDF1PX4bxg1yDMfKPHcE1Ijic5lx1KdK1SkaEJdto4hd++05J9Bf9TAmi # u6EK6C9Oe5vRadroJCK26uCUI4zIjL/qG7mswW+qT0CW0gnR9JHkXCWNbo8ccMk1 # sJatmRoSAifbgzaYbUz8+lv+IXy5GFuAmLnNbGjacB3IMGpa+lbFgih57/fIhamq # 5VhxgaEmn/UjWyr+cPiAFWuTVIpfsOjbEAww75wURNM1Imp9NJKye1O24EspEHmb # DmqCUcq7NqkOKIG4PVm3hDDED/WQpzJDkvu4FrIbvyTGVU01vKsg4UfcdiZ0fQ+/ # V0hf8yrtq9CkB8iIuk5bBxuPMIIHejCCBWKgAwIBAgIKYQ6Q0gAAAAAAAzANBgkq # hkiG9w0BAQsFADCBiDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjEyMDAGA1UEAxMpTWljcm9zb2Z0IFJvb3QgQ2VydGlmaWNhdGUgQXV0aG9yaXR5 # IDIwMTEwHhcNMTEwNzA4MjA1OTA5WhcNMjYwNzA4MjEwOTA5WjB+MQswCQYDVQQG # EwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwG # A1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSgwJgYDVQQDEx9NaWNyb3NvZnQg # Q29kZSBTaWduaW5nIFBDQSAyMDExMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIIC # CgKCAgEAq/D6chAcLq3YbqqCEE00uvK2WCGfQhsqa+laUKq4BjgaBEm6f8MMHt03 # a8YS2AvwOMKZBrDIOdUBFDFC04kNeWSHfpRgJGyvnkmc6Whe0t+bU7IKLMOv2akr # rnoJr9eWWcpgGgXpZnboMlImEi/nqwhQz7NEt13YxC4Ddato88tt8zpcoRb0Rrrg # OGSsbmQ1eKagYw8t00CT+OPeBw3VXHmlSSnnDb6gE3e+lD3v++MrWhAfTVYoonpy # 4BI6t0le2O3tQ5GD2Xuye4Yb2T6xjF3oiU+EGvKhL1nkkDstrjNYxbc+/jLTswM9 # sbKvkjh+0p2ALPVOVpEhNSXDOW5kf1O6nA+tGSOEy/S6A4aN91/w0FK/jJSHvMAh # dCVfGCi2zCcoOCWYOUo2z3yxkq4cI6epZuxhH2rhKEmdX4jiJV3TIUs+UsS1Vz8k # A/DRelsv1SPjcF0PUUZ3s/gA4bysAoJf28AVs70b1FVL5zmhD+kjSbwYuER8ReTB # w3J64HLnJN+/RpnF78IcV9uDjexNSTCnq47f7Fufr/zdsGbiwZeBe+3W7UvnSSmn # Eyimp31ngOaKYnhfsi+E11ecXL93KCjx7W3DKI8sj0A3T8HhhUSJxAlMxdSlQy90 # lfdu+HggWCwTXWCVmj5PM4TasIgX3p5O9JawvEagbJjS4NaIjAsCAwEAAaOCAe0w # ggHpMBAGCSsGAQQBgjcVAQQDAgEAMB0GA1UdDgQWBBRIbmTlUAXTgqoXNzcitW2o # ynUClTAZBgkrBgEEAYI3FAIEDB4KAFMAdQBiAEMAQTALBgNVHQ8EBAMCAYYwDwYD # VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBRyLToCMZBDuRQFTuHqp8cx0SOJNDBa # BgNVHR8EUzBRME+gTaBLhklodHRwOi8vY3JsLm1pY3Jvc29mdC5jb20vcGtpL2Ny # bC9wcm9kdWN0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3JsMF4GCCsG # AQUFBwEBBFIwUDBOBggrBgEFBQcwAoZCaHR0cDovL3d3dy5taWNyb3NvZnQuY29t # L3BraS9jZXJ0cy9NaWNSb29DZXJBdXQyMDExXzIwMTFfMDNfMjIuY3J0MIGfBgNV # HSAEgZcwgZQwgZEGCSsGAQQBgjcuAzCBgzA/BggrBgEFBQcCARYzaHR0cDovL3d3 # dy5taWNyb3NvZnQuY29tL3BraW9wcy9kb2NzL3ByaW1hcnljcHMuaHRtMEAGCCsG # AQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAHAAbwBsAGkAYwB5AF8AcwB0AGEAdABl # AG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUAA4ICAQBn8oalmOBUeRou09h0ZyKb # C5YR4WOSmUKWfdJ5DJDBZV8uLD74w3LRbYP+vj/oCso7v0epo/Np22O/IjWll11l # hJB9i0ZQVdgMknzSGksc8zxCi1LQsP1r4z4HLimb5j0bpdS1HXeUOeLpZMlEPXh6 # I/MTfaaQdION9MsmAkYqwooQu6SpBQyb7Wj6aC6VoCo/KmtYSWMfCWluWpiW5IP0 # wI/zRive/DvQvTXvbiWu5a8n7dDd8w6vmSiXmE0OPQvyCInWH8MyGOLwxS3OW560 # STkKxgrCxq2u5bLZ2xWIUUVYODJxJxp/sfQn+N4sOiBpmLJZiWhub6e3dMNABQam # ASooPoI/E01mC8CzTfXhj38cbxV9Rad25UAqZaPDXVJihsMdYzaXht/a8/jyFqGa # J+HNpZfQ7l1jQeNbB5yHPgZ3BtEGsXUfFL5hYbXw3MYbBL7fQccOKO7eZS/sl/ah # XJbYANahRr1Z85elCUtIEJmAH9AAKcWxm6U/RXceNcbSoqKfenoi+kiVH6v7RyOA # 9Z74v2u3S5fi63V4GuzqN5l5GEv/1rMjaHXmr/r8i+sLgOppO6/8MO0ETI7f33Vt # Y5E90Z1WTk+/gFcioXgRMiF670EKsT/7qMykXcGhiJtXcVZOSEXAQsmbdlsKgEhr # /Xmfwb1tbWrJUnMTDXpQzTGCGiYwghoiAgEBMIGVMH4xCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNp # Z25pbmcgUENBIDIwMTECEzMAAAQEbHQG/1crJ3IAAAAABAQwDQYJYIZIAWUDBAIB # BQCgga4wGQYJKoZIhvcNAQkDMQwGCisGAQQBgjcCAQQwHAYKKwYBBAGCNwIBCzEO # MAwGCisGAQQBgjcCARUwLwYJKoZIhvcNAQkEMSIEIF1Rj26Ldyi9kABi5oz8ZgEm # LwTP35e4lXdPZYtlhqafMEIGCisGAQQBgjcCAQwxNDAyoBSAEgBNAGkAYwByAG8A # cwBvAGYAdKEagBhodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20wDQYJKoZIhvcNAQEB # BQAEggEAY/D3SH3dQ4VXVrzrg4CR0ArWF2dY6O5Ln/9BdACu7b2baNDXzKTpnYu/ # Fme2Cb9oq3W47g7P2aZQlyah7CHv0ybu47saURgFe3XBjRjg6wE9ZT06aHlx5opE # Lg4yjL458FuEor1hBuwuFNeqbW3+XDdLphRNiaEfMxK9hUFkRQZ7SL1gW9W/A9Ue # +aG8ammBrWOfpS3c8xSRv4HsRXWgwSfwm/CDL5UNKabN+9+dvXE+l/r4ZfSFHtFw # uHKESS5UyCMasPAPe3eBkRtDBsFc6A0ko4RCeegVNlnmlk2ceCI5aYRBqm1khG5Q # 4ai84MubV9iKidUCfNxsR5B8CwgUGKGCF7AwghesBgorBgEEAYI3AwMBMYIXnDCC # F5gGCSqGSIb3DQEHAqCCF4kwgheFAgEDMQ8wDQYJYIZIAWUDBAIBBQAwggFaBgsq # hkiG9w0BCRABBKCCAUkEggFFMIIBQQIBAQYKKwYBBAGEWQoDATAxMA0GCWCGSAFl # AwQCAQUABCDXpiA5dT509kNR2tmGJxkoUPN2Udfvw4e4HuDO0iNTlgIGaC3xmMfE # GBMyMDI1MDUzMDE1NDc0MS44MjlaMASAAgH0oIHZpIHWMIHTMQswCQYDVQQGEwJV # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJl # bGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVT # TjoyQTFBLTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg # U2VydmljZaCCEf4wggcoMIIFEKADAgECAhMzAAAB+R9njXWrpPGxAAEAAAH5MA0G # CSqGSIb3DQEBCwUAMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9u # MRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRp # b24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMB4XDTI0 # MDcyNTE4MzEwOVoXDTI1MTAyMjE4MzEwOVowgdMxCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xLTArBgNVBAsTJE1pY3Jvc29mdCBJcmVsYW5kIE9w # ZXJhdGlvbnMgTGltaXRlZDEnMCUGA1UECxMeblNoaWVsZCBUU1MgRVNOOjJBMUEt # MDVFMC1EOTQ3MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNl # MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAtD1MH3yAHWHNVslC+CBT # j/Mpd55LDPtQrhN7WeqFhReC9xKXSjobW1ZHzHU8V2BOJUiYg7fDJ2AxGVGyovUt # gGZg2+GauFKk3ZjjsLSsqehYIsUQrgX+r/VATaW8/ONWy6lOyGZwZpxfV2EX4qAh # 6mb2hadAuvdbRl1QK1tfBlR3fdeCBQG+ybz9JFZ45LN2ps8Nc1xr41N8Qi3KVJLY # X0ibEbAkksR4bbszCzvY+vdSrjWyKAjR6YgYhaBaDxE2KDJ2sQRFFF/egCxKgogd # F3VIJoCE/Wuy9MuEgypea1Hei7lFGvdLQZH5Jo2QR5uN8hiMc8Z47RRJuIWCOeyI # J1YnRiiibpUZ72+wpv8LTov0yH6C5HR/D8+AT4vqtP57ITXsD9DPOob8tjtsefPc # QJebUNiqyfyTL5j5/J+2d+GPCcXEYoeWZ+nrsZSfrd5DHM4ovCmD3lifgYnzjOry # 4ghQT/cvmdHwFr6yJGphW/HG8GQd+cB4w7wGpOhHVJby44kGVK8MzY9s32Dy1THn # Jg8p7y1sEGz/A1y84Zt6gIsITYaccHhBKp4cOVNrfoRVUx2G/0Tr7Dk3fpCU8u+5 # olqPPwKgZs57jl+lOrRVsX1AYEmAnyCyGrqRAzpGXyk1HvNIBpSNNuTBQk7FBvu+ # Ypi6A7S2V2Tj6lzYWVBvuGECAwEAAaOCAUkwggFFMB0GA1UdDgQWBBSJ7aO6nJXJ # I9eijzS5QkR2RlngADAfBgNVHSMEGDAWgBSfpxVdAF5iXYP05dJlpxtTNRnpcjBf # BgNVHR8EWDBWMFSgUqBQhk5odHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3Bz # L2NybC9NaWNyb3NvZnQlMjBUaW1lLVN0YW1wJTIwUENBJTIwMjAxMCgxKS5jcmww # bAYIKwYBBQUHAQEEYDBeMFwGCCsGAQUFBzAChlBodHRwOi8vd3d3Lm1pY3Jvc29m # dC5jb20vcGtpb3BzL2NlcnRzL01pY3Jvc29mdCUyMFRpbWUtU3RhbXAlMjBQQ0El # MjAyMDEwKDEpLmNydDAMBgNVHRMBAf8EAjAAMBYGA1UdJQEB/wQMMAoGCCsGAQUF # BwMIMA4GA1UdDwEB/wQEAwIHgDANBgkqhkiG9w0BAQsFAAOCAgEAZiAJgFbkf7jf # hx/mmZlnGZrpae+HGpxWxs8I79vUb8GQou50M1ns7iwG2CcdoXaq7VgpVkNf1uvI # hrGYpKCBXQ+SaJ2O0BvwuJR7UsgTaKN0j/yf3fpHD0ktH+EkEuGXs9DBLyt71iut # Vkwow9iQmSk4oIK8S8ArNGpSOzeuu9TdJjBjsasmuJ+2q5TjmrgEKyPe3TApAio8 # cdw/b1cBAmjtI7tpNYV5PyRI3K1NhuDgfEj5kynGF/uizP1NuHSxF/V1ks/2tCEo # riicM4k1PJTTA0TCjNbkpmBcsAMlxTzBnWsqnBCt9d+Ud9Va3Iw9Bs4ccrkgBjLt # g3vYGYar615ofYtU+dup+LuU0d2wBDEG1nhSWHaO+u2y6Si3AaNINt/pOMKU6l4A # W0uDWUH39OHH3EqFHtTssZXaDOjtyRgbqMGmkf8KI3qIVBZJ2XQpnhEuRbh+Agpm # Rn/a410Dk7VtPg2uC422WLC8H8IVk/FeoiSS4vFodhncFetJ0ZK36wxAa3FiPgBe # bRWyVtZ763qDDzxDb0mB6HL9HEfTbN+4oHCkZa1HKl8B0s8RiFBMf/W7+O7EPZ+w # MH8wdkjZ7SbsddtdRgRARqR8IFPWurQ+sn7ftEifaojzuCEahSAcq86yjwQeTPN9 # YG9b34RTurnkpD+wPGTB1WccMpsLlM0wggdxMIIFWaADAgECAhMzAAAAFcXna54C # m0mZAAAAAAAVMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYDVQQGEwJVUzETMBEGA1UE # CBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9z # b2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3NvZnQgUm9vdCBDZXJ0aWZp # Y2F0ZSBBdXRob3JpdHkgMjAxMDAeFw0yMTA5MzAxODIyMjVaFw0zMDA5MzAxODMy # MjVaMHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQH # EwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNV # BAMTHU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwMIICIjANBgkqhkiG9w0B # AQEFAAOCAg8AMIICCgKCAgEA5OGmTOe0ciELeaLL1yR5vQ7VgtP97pwHB9KpbE51 # yMo1V/YBf2xK4OK9uT4XYDP/XE/HZveVU3Fa4n5KWv64NmeFRiMMtY0Tz3cywBAY # 6GB9alKDRLemjkZrBxTzxXb1hlDcwUTIcVxRMTegCjhuje3XD9gmU3w5YQJ6xKr9 # cmmvHaus9ja+NSZk2pg7uhp7M62AW36MEBydUv626GIl3GoPz130/o5Tz9bshVZN # 7928jaTjkY+yOSxRnOlwaQ3KNi1wjjHINSi947SHJMPgyY9+tVSP3PoFVZhtaDua # Rr3tpK56KTesy+uDRedGbsoy1cCGMFxPLOJiss254o2I5JasAUq7vnGpF1tnYN74 # kpEeHT39IM9zfUGaRnXNxF803RKJ1v2lIH1+/NmeRd+2ci/bfV+AutuqfjbsNkz2 # K26oElHovwUDo9Fzpk03dJQcNIIP8BDyt0cY7afomXw/TNuvXsLz1dhzPUNOwTM5 # TI4CvEJoLhDqhFFG4tG9ahhaYQFzymeiXtcodgLiMxhy16cg8ML6EgrXY28MyTZk # i1ugpoMhXV8wdJGUlNi5UPkLiWHzNgY1GIRH29wb0f2y1BzFa/ZcUlFdEtsluq9Q # BXpsxREdcu+N+VLEhReTwDwV2xo3xwgVGD94q0W29R6HXtqPnhZyacaue7e3Pmri # Lq0CAwEAAaOCAd0wggHZMBIGCSsGAQQBgjcVAQQFAgMBAAEwIwYJKwYBBAGCNxUC # BBYEFCqnUv5kxJq+gpE8RjUpzxD/LwTuMB0GA1UdDgQWBBSfpxVdAF5iXYP05dJl # pxtTNRnpcjBcBgNVHSAEVTBTMFEGDCsGAQQBgjdMg30BATBBMD8GCCsGAQUFBwIB # FjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL0RvY3MvUmVwb3NpdG9y # eS5odG0wEwYDVR0lBAwwCgYIKwYBBQUHAwgwGQYJKwYBBAGCNxQCBAweCgBTAHUA # YgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0jBBgwFoAU # 1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0cDovL2Ny # bC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2VyQXV0XzIw # MTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+aHR0cDov # L3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRfMjAxMC0w # Ni0yMy5jcnQwDQYJKoZIhvcNAQELBQADggIBAJ1VffwqreEsH2cBMSRb4Z5yS/yp # b+pcFLY+TkdkeLEGk5c9MTO1OdfCcTY/2mRsfNB1OW27DzHkwo/7bNGhlBgi7ulm # ZzpTTd2YurYeeNg2LpypglYAA7AFvonoaeC6Ce5732pvvinLbtg/SHUB2RjebYIM # 9W0jVOR4U3UkV7ndn/OOPcbzaN9l9qRWqveVtihVJ9AkvUCgvxm2EhIRXT0n4ECW # OKz3+SmJw7wXsFSFQrP8DJ6LGYnn8AtqgcKBGUIZUnWKNsIdw2FzLixre24/LAl4 # FOmRsqlb30mjdAy87JGA0j3mSj5mO0+7hvoyGtmW9I/2kQH2zsZ0/fZMcm8Qq3Uw # xTSwethQ/gpY3UA8x1RtnWN0SCyxTkctwRQEcb9k+SS+c23Kjgm9swFXSVRk2XPX # fx5bRAGOWhmRaw2fpCjcZxkoJLo4S5pu+yFUa2pFEUep8beuyOiJXk+d0tBMdrVX # VAmxaQFEfnyhYWxz/gq77EFmPWn9y8FBSX5+k77L+DvktxW/tM4+pTFRhLy/AsGC # onsXHRWJjXD+57XQKBqJC4822rpM+Zv/Cuk0+CQ1ZyvgDbjmjJnW4SLq8CdCPSWU # 5nR0W2rRnj7tfqAxM328y+l7vzhwRNGQ8cirOoo6CGJ/2XBjU02N7oJtpQUQwXEG # ahC0HVUzWLOhcGbyoYIDWTCCAkECAQEwggEBoYHZpIHWMIHTMQswCQYDVQQGEwJV # UzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEeMBwGA1UE # ChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMS0wKwYDVQQLEyRNaWNyb3NvZnQgSXJl # bGFuZCBPcGVyYXRpb25zIExpbWl0ZWQxJzAlBgNVBAsTHm5TaGllbGQgVFNTIEVT # TjoyQTFBLTA1RTAtRDk0NzElMCMGA1UEAxMcTWljcm9zb2Z0IFRpbWUtU3RhbXAg # U2VydmljZaIjCgEBMAcGBSsOAwIaAxUAqs5WjWO7zVAKmIcdwhqgZvyp6UaggYMw # gYCkfjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UE # BxMHUmVkbW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYD # VQQDEx1NaWNyb3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMDANBgkqhkiG9w0BAQsF # AAIFAOvkTLkwIhgPMjAyNTA1MzAxNTI2NDlaGA8yMDI1MDUzMTE1MjY0OVowdzA9 # BgorBgEEAYRZCgQBMS8wLTAKAgUA6+RMuQIBADAKAgEAAgIHkAIB/zAHAgEAAgIS # pTAKAgUA6+WeOQIBADA2BgorBgEEAYRZCgQCMSgwJjAMBgorBgEEAYRZCgMCoAow # CAIBAAIDB6EgoQowCAIBAAIDAYagMA0GCSqGSIb3DQEBCwUAA4IBAQCIpiS+hm1X # hy7hz08kOWBuGIwZs92GHvSbevUaW43HTzlB1S06jmfpbB1uwUoBHCsT+O+2JGi6 # iRvHSKzOH3wl/RLvy4jsFlh8zVfIf5o4HcJS1yJpsUl1PXFITTOyLENontxhYw1K # 8Ygz3Ny3lnys5xn5/nNx7NwYIqITZVhaGumE49S+bh19Zjhy6uxb72fS0zgLHfMe # MR5uqcdIedblmPzIf6Rp6/BDhcK9tkurKeYtSiMLt4cAfC89uxkr2dMMA62/JH1m # 00N3jfrQgncX3IwPa6kCuSgz7POOlnbhtDMidGRK+rAbceMAWMSbIe/q+P1reLU3 # 8buhttcfoQSzMYIEDTCCBAkCAQEwgZMwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgT # Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m # dCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRpbWUtU3RhbXAgUENB # IDIwMTACEzMAAAH5H2eNdauk8bEAAQAAAfkwDQYJYIZIAWUDBAIBBQCgggFKMBoG # CSqGSIb3DQEJAzENBgsqhkiG9w0BCRABBDAvBgkqhkiG9w0BCQQxIgQgS+aTqhdh # z6i0uxxBekX8/KxVEE0KJFfecL9MG/yXNP8wgfoGCyqGSIb3DQEJEAIvMYHqMIHn # MIHkMIG9BCA5I4zIHvCN+2T66RUOLCZrUEVdoKlKl8VeCO5SbGLYEDCBmDCBgKR+ # MHwxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdS # ZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMT # HU1pY3Jvc29mdCBUaW1lLVN0YW1wIFBDQSAyMDEwAhMzAAAB+R9njXWrpPGxAAEA # AAH5MCIEIMdyubzxJ7NW/IxksBUBs+QQqqLFMc06mYFQ6nLIx7iIMA0GCSqGSIb3 # DQEBCwUABIICABKbhTyFGBlT2DLx//y2T+uta4UpaCCwLUPok6T85dBkOXz5VgEp # uSP5ChvXtjftzHc5EDubjBIVVFDISbLzQ8HjOUfBkAl96xyXKE9AYUDtIeOdxepk # sU/A86jlusZaEREYPJRN6gN+PAgCpeaJ2sk2Tqqv9mBGXecx3ebAMWo6o05inYuW # P33pU0udP2PLcFvIIdMjjd8EPUskFJEomlQnOWw6vxKYLc+kWtQX/vOekseyOnEF # YkM/cGfiErmD8VSUByXD76JhD3F2x5/Nc9GGRY16JZY5iD5hQLm/hqFdeHiGItxp # rprJTKvUNWxduBSZkSGnJQ+fVcy6l5Glim103ZJQlFTymCPQBc9nDLfWI2nP+68H # DpA66tiR07SaZ8WfSSNDL/wQ9lK9zi1TAwsmu2mF2kydqWQ0dAIXqTWOXMqeu4G3 # sH65MOV1qKWIreAFh4GLxeO0UapHcUhORbDDyIdV6tyvifLExyPMXj7sHKGhC33E # JiEddDv74lyK0LjV4IyCiqoq+sqfUWJ1qFqUXVXZXQGUitJsZmPKECFvkVk+KYI1 # wAvqj3m9LDHZmuU4bSp9IgMyt4xdbQpGejn2jDU3IvI6d70KWhrjL2fvi4MBcWbE # mImzXT3Tfzso3cYNdTaNtVGq4ZQk66/qmfWKZgSbApeQA1wReyHydU47 # SIG # End signature block |