Framework/Helpers/RoleAssignmentHelper.ps1
using namespace Microsoft.Azure.Commands.Resources.Models.Authorization Set-StrictMode -Version Latest class RoleAssignmentHelper { static [PSRoleAssignment[]] GetAzSDKRoleAssignmentByScope([string] $scope, [bool] $recurse, [bool] $includeClassicAdministrators) { [PSRoleAssignment[]] $roleAssignments = @(); try { if($includeClassicAdministrators) { $roleAssignments = Get-AzureRmRoleAssignment -Scope $scope -IncludeClassicAdministrators -ErrorAction Stop; } else { $roleAssignments = Get-AzureRmRoleAssignment -Scope $scope -ErrorAction Stop; } return $roleAssignments; } catch { } $requestUri = [WebRequestHelper]::AzureManagementUri + $scope; $roleAssignments = [RoleAssignmentHelper]::GetRMRoleAssignment($requestUri, $recurse); if($includeClassicAdministrators) { $roleAssignments += [RoleAssignmentHelper]::GetAzSDKClassicAdministrators(); } return $roleAssignments; } static [PSRoleAssignment[]] GetAzSDKRoleAssignment([bool] $recurse, [bool] $includeClassicAdministrators) { [PSRoleAssignment[]] $roleAssignments = @(); try { if($includeClassicAdministrators) { $roleAssignments = Get-AzureRmRoleAssignment -IncludeClassicAdministrators -ErrorAction Stop; } else { $roleAssignments = Get-AzureRmRoleAssignment -ErrorAction Stop; } return $roleAssignments; } catch { } $roleAssignments = [RoleAssignmentHelper]::GetAzSDKRoleAssignment("", "", "", $recurse, $includeClassicAdministrators); return $roleAssignments; } static [PSRoleAssignment[]] GetAzSDKRoleAssignment([string] $resourceGroupName, [bool] $recurse, [bool] $includeClassicAdministrators) { [PSRoleAssignment[]] $roleAssignments = @(); try { if($includeClassicAdministrators) { $roleAssignments = Get-AzureRmRoleAssignment -ResourceGroupName $resourceGroupName -IncludeClassicAdministrators -ErrorAction Stop; } else { $roleAssignments = Get-AzureRmRoleAssignment -ResourceGroupName $resourceGroupName -ErrorAction Stop; } return $roleAssignments; } catch { } $roleAssignments = [RoleAssignmentHelper]::GetAzSDKRoleAssignment($resourceGroupName, "", "", $recurse, $includeClassicAdministrators); return $roleAssignments; } static [PSRoleAssignment[]] GetAzSDKRoleAssignment([string] $resourceGroupName, [string] $resourceName, [string] $resourceType, [bool] $recurse, [bool] $includeClassicAdministrators) { [PSRoleAssignment[]] $roleAssignments = @(); try { if($includeClassicAdministrators) { $roleAssignments = Get-AzureRmRoleAssignment -ResourceGroupName $resourceGroupName -ResourceName $resourceName -ResourceType $resourceType -IncludeClassicAdministrators -ErrorAction Stop; } else { $roleAssignments = Get-AzureRmRoleAssignment -ResourceGroupName $resourceGroupName -ResourceName $resourceName -ResourceType $resourceType -ErrorAction Stop; } return $roleAssignments; } catch { } $currentContext = Get-AzureRmContext -ErrorAction Stop; $subscriptionId = $currentContext.Subscription.Id; $subscriptionPath = "subscriptions/$subscriptionId"; $resourceGroupPath = "/resourceGroups/$resourceGroupName"; $resourceNamePath = "/providers/$resourceType/$resourceName"; $requestUri = [WebRequestHelper]::AzureManagementUri + $subscriptionPath; if(-not [string]::IsNullOrEmpty($resourceGroupName)) { $requestUri += $resourceGroupPath; if((-not [string]::IsNullOrEmpty($resourceType)) -and (-not [string]::IsNullOrEmpty($resourceName))) { $requestUri += $resourceNamePath; } } $roleAssignments = [RoleAssignmentHelper]::GetRMRoleAssignment($requestUri, $recurse); if($includeClassicAdministrators) { $roleAssignments += [RoleAssignmentHelper]::GetAzSDKClassicAdministrators(); } return $roleAssignments; } hidden static [PSRoleAssignment[]] GetRMRoleAssignment([string] $roleAssignmentUri, [bool] $recurse) { $recurseParam = "&`$filter=atScope()"; $roleAssignmentPath = "/providers/Microsoft.Authorization/roleAssignments?api-version=2015-07-01"; $roleAssignmentUri += $roleAssignmentPath; if(-not $recurse) { $roleAssignmentUri += $recurseParam; } $webResponse = [WebRequestHelper]::InvokeGetWebRequest($roleAssignmentUri); [PSRoleAssignment[]] $roleAssignments = @(); $webResponse | ForEach-Object { $roleDefinitionId = $_.properties.roleDefinitionId.Substring($_.properties.roleDefinitionId.LastIndexOf("/") + 1); $roleDefinitionName = ""; $roleDefinition = (Get-AzureRmRoleDefinition -Id $roleDefinitionId -ErrorAction SilentlyContinue) | Select-Object -First 1 if($roleDefinition) { $roleDefinitionName = $roleDefinition.Name; }; $roleAssignments += [PSRoleAssignment]@{ RoleAssignmentId = $_.id; Scope = $_.properties.scope; RoleDefinitionName = $roleDefinitionName; RoleDefinitionId = $roleDefinitionId; ObjectId = $_.properties.principalId; }; } if($roleAssignments.Count -gt 0) { $objectIds = $roleAssignments | Select-Object -Property ObjectId -Unique | ForEach-Object { "$($_.ObjectId)" }; $objectIdResponse = [RoleAssignmentHelper]::GetADObjectsByObjectIds($objectIds); $roleAssignments | ForEach-Object { $currentItem = $_; if($objectIdResponse.Count -ne 0) { $filteredResponse = $objectIdResponse | Where-Object { $_.ObjectId -eq $currentItem.ObjectId } | Select-Object -First 1 if($filteredResponse) { $currentItem.ObjectType = $filteredResponse.objectType; $currentItem.DisplayName = $filteredResponse.displayName; if(($filteredResponse | Get-Member -Name "userPrincipalName")) { $currentItem.SignInName = $filteredResponse.userPrincipalName; } } } else { if(-not [string]::IsNullOrWhiteSpace($currentItem.ObjectId)) { $currentItem.ObjectType = "NOGRAPHACCESS" $currentItem.DisplayName = "NOGRAPHACCESS" $currentItem.SignInName = "NOGRAPHACCESS" } else { $currentItem.ObjectId = [Guid]::Empty.Guid } } } } return $roleAssignments; } hidden static [PSRoleAssignment[]] GetAzSDKClassicAdministrators() { $currentContext = Get-AzureRmContext -ErrorAction Stop; $subscriptionId = $currentContext.Subscription.Id; $subscriptionPath = "subscriptions/$subscriptionId"; $requestUri = [WebRequestHelper]::AzureManagementUri + $subscriptionPath; $requestUri += "/providers/Microsoft.Authorization/classicAdministrators?api-version=2015-06-01"; $webResponse = [WebRequestHelper]::InvokeGetWebRequest($requestUri); [PSRoleAssignment[]] $roleAssignments = @(); $webResponse | ForEach-Object { $roleAssignments += [PSRoleAssignment]@{ SignInName = $_.properties.emailAddress; DisplayName = $_.properties.emailAddress; Scope = "/subscriptions/$subscriptionId"; RoleDefinitionName = $_.properties.role; RoleDefinitionId = $_.id; ObjectId = [Guid]::Empty.Guid; ObjectType = $_.properties.role }; } return $roleAssignments; } hidden static [System.Object[]] GetADObjectsByObjectIds([string[]] $objectIds) { $rmContext = Get-AzureRmContext -ErrorAction Stop; $tenantId = $rmContext.Tenant.Id $uri = [WebRequestHelper]::GraphApiUri + "$tenantId/getObjectsByObjectIds?api-version=1.6" $body = "{`"objectIds`":" + ($objectIds | ConvertTo-Json ) + "}"; $webResponse = @(); try { $webResponse = [WebRequestHelper]::InvokePostWebRequest($uri, $body); } catch { #Access denied exception occurs here. #[EventBase]::PublishGenericException($_); } return $webResponse; } hidden static [bool] HasGraphAccess() { $hasAccess = $false; $rmContext = Get-AzureRmContext -ErrorAction Stop; $tenantId = $rmContext.Tenant.Id $uri = [WebRequestHelper]::GraphApiUri + "$tenantId/users?`$top=1&api-version=1.6" $webResponse = @(); try { $webResponse = [WebRequestHelper]::InvokeGetWebRequest($uri); $hasAccess = $true; } catch { $hasAccess = $false; } return $hasAccess; } } # SIG # Begin signature block # MIIkBQYJKoZIhvcNAQcCoIIj9jCCI/ICAQExDzANBglghkgBZQMEAgEFADB5Bgor # BgEEAYI3AgEEoGswaTA0BgorBgEEAYI3AgEeMCYCAwEAAAQQH8w7YFlLCE63JNLG # KX7zUQIBAAIBAAIBAAIBAAIBADAxMA0GCWCGSAFlAwQCAQUABCDj7SyZ0wAdclff # 6P9N7Re/0w6tpNc2NrOmU7hoynCh1qCCDZMwggYRMIID+aADAgECAhMzAAAAjoeR # pFcaX8o+AAAAAACOMA0GCSqGSIb3DQEBCwUAMH4xCzAJBgNVBAYTAlVTMRMwEQYD # VQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNy # b3NvZnQgQ29ycG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25p # bmcgUENBIDIwMTEwHhcNMTYxMTE3MjIwOTIxWhcNMTgwMjE3MjIwOTIxWjCBgzEL # MAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1v # bmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjENMAsGA1UECxMETU9Q # UjEeMBwGA1UEAxMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMIIBIjANBgkqhkiG9w0B # AQEFAAOCAQ8AMIIBCgKCAQEA0IfUQit+ndnGetSiw+MVktJTnZUXyVI2+lS/qxCv # 6cnnzCZTw8Jzv23WAOUA3OlqZzQw9hYXtAGllXyLuaQs5os7efYjDHmP81LfQAEc # wsYDnetZz3Pp2HE5m/DOJVkt0slbCu9+1jIOXXQSBOyeBFOmawJn+E1Zi3fgKyHg # 78CkRRLPA3sDxjnD1CLcVVx3Qv+csuVVZ2i6LXZqf2ZTR9VHCsw43o17lxl9gtAm # +KWO5aHwXmQQ5PnrJ8by4AjQDfJnwNjyL/uJ2hX5rg8+AJcH0Qs+cNR3q3J4QZgH # uBfMorFf7L3zUGej15Tw0otVj1OmlZPmsmbPyTdo5GPHzwIDAQABo4IBgDCCAXww # HwYDVR0lBBgwFgYKKwYBBAGCN0wIAQYIKwYBBQUHAwMwHQYDVR0OBBYEFKvI1u2y # FdKqjvHM7Ww490VK0Iq7MFIGA1UdEQRLMEmkRzBFMQ0wCwYDVQQLEwRNT1BSMTQw # MgYDVQQFEysyMzAwMTIrYjA1MGM2ZTctNzY0MS00NDFmLWJjNGEtNDM0ODFlNDE1 # ZDA4MB8GA1UdIwQYMBaAFEhuZOVQBdOCqhc3NyK1bajKdQKVMFQGA1UdHwRNMEsw # SaBHoEWGQ2h0dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2lvcHMvY3JsL01pY0Nv # ZFNpZ1BDQTIwMTFfMjAxMS0wNy0wOC5jcmwwYQYIKwYBBQUHAQEEVTBTMFEGCCsG # AQUFBzAChkVodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpb3BzL2NlcnRzL01p # Y0NvZFNpZ1BDQTIwMTFfMjAxMS0wNy0wOC5jcnQwDAYDVR0TAQH/BAIwADANBgkq # hkiG9w0BAQsFAAOCAgEARIkCrGlT88S2u9SMYFPnymyoSWlmvqWaQZk62J3SVwJR # avq/m5bbpiZ9CVbo3O0ldXqlR1KoHksWU/PuD5rDBJUpwYKEpFYx/KCKkZW1v1rO # qQEfZEah5srx13R7v5IIUV58MwJeUTub5dguXwJMCZwaQ9px7eTZ56LadCwXreUM # tRj1VAnUvhxzzSB7pPrI29jbOq76kMWjvZVlrkYtVylY1pLwbNpj8Y8zon44dl7d # 8zXtrJo7YoHQThl8SHywC484zC281TllqZXBA+KSybmr0lcKqtxSCy5WJ6PimJdX # jrypWW4kko6C4glzgtk1g8yff9EEjoi44pqDWLDUmuYx+pRHjn2m4k5589jTajMW # UHDxQruYCen/zJVVWwi/klKoCMTx6PH/QNf5mjad/bqQhdJVPlCtRh/vJQy4njpI # BGPveJiiXQMNAtjcIKvmVrXe7xZmw9dVgh5PgnjJnlQaEGC3F6tAE5GusBnBmjOd # 7jJyzWXMT0aYLQ9RYB58+/7b6Ad5B/ehMzj+CZrbj3u2Or2FhrjMvH0BMLd7Hald # G73MTRf3bkcz1UDfasouUbi1uc/DBNM75ePpEIzrp7repC4zaikvFErqHsEiODUF # he/CBAANa8HYlhRIFa9+UrC4YMRStUqCt4UqAEkqJoMnWkHevdVmSbwLnHhwCbww # ggd6MIIFYqADAgECAgphDpDSAAAAAAADMA0GCSqGSIb3DQEBCwUAMIGIMQswCQYD # VQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9uZDEe # MBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMTIwMAYDVQQDEylNaWNyb3Nv # ZnQgUm9vdCBDZXJ0aWZpY2F0ZSBBdXRob3JpdHkgMjAxMTAeFw0xMTA3MDgyMDU5 # MDlaFw0yNjA3MDgyMTA5MDlaMH4xCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNo # aW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29y # cG9yYXRpb24xKDAmBgNVBAMTH01pY3Jvc29mdCBDb2RlIFNpZ25pbmcgUENBIDIw # MTEwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoICAQCr8PpyEBwurdhuqoIQ # TTS68rZYIZ9CGypr6VpQqrgGOBoESbp/wwwe3TdrxhLYC/A4wpkGsMg51QEUMULT # iQ15ZId+lGAkbK+eSZzpaF7S35tTsgosw6/ZqSuuegmv15ZZymAaBelmdugyUiYS # L+erCFDPs0S3XdjELgN1q2jzy23zOlyhFvRGuuA4ZKxuZDV4pqBjDy3TQJP4494H # DdVceaVJKecNvqATd76UPe/74ytaEB9NViiienLgEjq3SV7Y7e1DkYPZe7J7hhvZ # PrGMXeiJT4Qa8qEvWeSQOy2uM1jFtz7+MtOzAz2xsq+SOH7SnYAs9U5WkSE1JcM5 # bmR/U7qcD60ZI4TL9LoDho33X/DQUr+MlIe8wCF0JV8YKLbMJyg4JZg5SjbPfLGS # rhwjp6lm7GEfauEoSZ1fiOIlXdMhSz5SxLVXPyQD8NF6Wy/VI+NwXQ9RRnez+ADh # vKwCgl/bwBWzvRvUVUvnOaEP6SNJvBi4RHxF5MHDcnrgcuck379GmcXvwhxX24ON # 7E1JMKerjt/sW5+v/N2wZuLBl4F77dbtS+dJKacTKKanfWeA5opieF+yL4TXV5xc # v3coKPHtbcMojyyPQDdPweGFRInECUzF1KVDL3SV9274eCBYLBNdYJWaPk8zhNqw # iBfenk70lrC8RqBsmNLg1oiMCwIDAQABo4IB7TCCAekwEAYJKwYBBAGCNxUBBAMC # AQAwHQYDVR0OBBYEFEhuZOVQBdOCqhc3NyK1bajKdQKVMBkGCSsGAQQBgjcUAgQM # HgoAUwB1AGIAQwBBMAsGA1UdDwQEAwIBhjAPBgNVHRMBAf8EBTADAQH/MB8GA1Ud # IwQYMBaAFHItOgIxkEO5FAVO4eqnxzHRI4k0MFoGA1UdHwRTMFEwT6BNoEuGSWh0 # dHA6Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1Jvb0Nl # ckF1dDIwMTFfMjAxMV8wM18yMi5jcmwwXgYIKwYBBQUHAQEEUjBQME4GCCsGAQUF # BzAChkJodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtpL2NlcnRzL01pY1Jvb0Nl # ckF1dDIwMTFfMjAxMV8wM18yMi5jcnQwgZ8GA1UdIASBlzCBlDCBkQYJKwYBBAGC # Ny4DMIGDMD8GCCsGAQUFBwIBFjNodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vcGtp # b3BzL2RvY3MvcHJpbWFyeWNwcy5odG0wQAYIKwYBBQUHAgIwNB4yIB0ATABlAGcA # YQBsAF8AcABvAGwAaQBjAHkAXwBzAHQAYQB0AGUAbQBlAG4AdAAuIB0wDQYJKoZI # hvcNAQELBQADggIBAGfyhqWY4FR5Gi7T2HRnIpsLlhHhY5KZQpZ90nkMkMFlXy4s # PvjDctFtg/6+P+gKyju/R6mj82nbY78iNaWXXWWEkH2LRlBV2AySfNIaSxzzPEKL # UtCw/WvjPgcuKZvmPRul1LUdd5Q54ulkyUQ9eHoj8xN9ppB0g430yyYCRirCihC7 # pKkFDJvtaPpoLpWgKj8qa1hJYx8JaW5amJbkg/TAj/NGK978O9C9Ne9uJa7lryft # 0N3zDq+ZKJeYTQ49C/IIidYfwzIY4vDFLc5bnrRJOQrGCsLGra7lstnbFYhRRVg4 # MnEnGn+x9Cf43iw6IGmYslmJaG5vp7d0w0AFBqYBKig+gj8TTWYLwLNN9eGPfxxv # FX1Fp3blQCplo8NdUmKGwx1jNpeG39rz+PIWoZon4c2ll9DuXWNB41sHnIc+BncG # 0QaxdR8UvmFhtfDcxhsEvt9Bxw4o7t5lL+yX9qFcltgA1qFGvVnzl6UJS0gQmYAf # 0AApxbGbpT9Fdx41xtKiop96eiL6SJUfq/tHI4D1nvi/a7dLl+LrdXga7Oo3mXkY # S//WsyNodeav+vyL6wuA6mk7r/ww7QRMjt/fdW1jkT3RnVZOT7+AVyKheBEyIXrv # QQqxP/uozKRdwaGIm1dxVk5IRcBCyZt2WwqASGv9eZ/BvW1taslScxMNelDNMYIV # yDCCFcQCAQEwgZUwfjELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24x # EDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlv # bjEoMCYGA1UEAxMfTWljcm9zb2Z0IENvZGUgU2lnbmluZyBQQ0EgMjAxMQITMwAA # AI6HkaRXGl/KPgAAAAAAjjANBglghkgBZQMEAgEFAKCBtjAZBgkqhkiG9w0BCQMx # DAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGCNwIBFTAvBgkq # hkiG9w0BCQQxIgQgoQVxN+LKoGnZWrQQvYQhb2rGRfeV8JrZU9TUmL5s2S4wSgYK # KwYBBAGCNwIBDDE8MDqgGIAWAEEAegBTAEQASwAgADIALgA1AC4AMaEegBxodHRw # czovL2FrYS5tcy9henNka29zc2RvY3MgMA0GCSqGSIb3DQEBAQUABIIBAH6cmFXS # xRdK59G3yMjtQiWs/ftjWxDWRiB4A462hUc4nw6EmYkH5igl624xVcj6alZ7ocEh # Jtw1DB0fj4YmZhZXatwPl1vfwqQocTIKE4r9noKBl7MjUg540D9G4CULYB4+K9xo # Ew2iFGJVk7b/cvVt3ezc3T8ruiGMCY7aEn7lyzaixHPw6q1/JnMn4ZzeBurK5IEL # pKYFX0OFyHJ529a0BlB46D9PDYR+R6u/FZx6K4YnE+fo0vDzAJaQwszsKkgjd1KV # VzJsS8681e8iOXte9caWxXG+NsmwR/ucrv0IGA3M4EbZzDX4ZN+8hI+HtDoj6JMW # HQmhgfuvUk1+cPihghNKMIITRgYKKwYBBAGCNwMDATGCEzYwghMyBgkqhkiG9w0B # BwKgghMjMIITHwIBAzEPMA0GCWCGSAFlAwQCAQUAMIIBOgYLKoZIhvcNAQkQAQSg # ggEpBIIBJTCCASECAQEGCisGAQQBhFkKAwEwMTANBglghkgBZQMEAgEFAAQgP2R1 # s4XwE3kXk3k3R3NdBs3UVQRybkAd+Zx7zM9c11ECBlmSITJGYhgTMjAxNzA5MDUw # NzAzNDIuNTg0WjAEgAIB9KCBuaSBtjCBszELMAkGA1UEBhMCVVMxEzARBgNVBAgT # Cldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29m # dCBDb3Jwb3JhdGlvbjENMAsGA1UECxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBE # U0UgRVNOOjE0OEMtQzRCOS0yMDY2MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1T # dGFtcCBTZXJ2aWNloIIO0DCCBnEwggRZoAMCAQICCmEJgSoAAAAAAAIwDQYJKoZI # hvcNAQELBQAwgYgxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpXYXNoaW5ndG9uMRAw # DgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVNaWNyb3NvZnQgQ29ycG9yYXRpb24x # MjAwBgNVBAMTKU1pY3Jvc29mdCBSb290IENlcnRpZmljYXRlIEF1dGhvcml0eSAy # MDEwMB4XDTEwMDcwMTIxMzY1NVoXDTI1MDcwMTIxNDY1NVowfDELMAkGA1UEBhMC # VVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAcBgNV # BAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0IFRp # bWUtU3RhbXAgUENBIDIwMTAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIB # AQCpHQ28dxGKOiDs/BOX9fp/aZRrdFQQ1aUKAIKF++18aEssX8XD5WHCdrc+Zitb # 8BVTJwQxH0EbGpUdzgkTjnxhMFmxMEQP8WCIhFRDDNdNuDgIs0Ldk6zWczBXJoKj # RQ3Q6vVHgc2/JGAyWGBG8lhHhjKEHnRhZ5FfgVSxz5NMksHEpl3RYRNuKMYa+YaA # u99h/EbBJx0kZxJyGiGKr0tkiVBisV39dx898Fd1rL2KQk1AUdEPnAY+Z3/1ZsAD # lkR+79BL/W7lmsqxqPJ6Kgox8NpOBpG2iAg16HgcsOmZzTznL0S6p/TcZL2kAcEg # CZN4zfy8wMlEXV4WnAEFTyJNAgMBAAGjggHmMIIB4jAQBgkrBgEEAYI3FQEEAwIB # ADAdBgNVHQ4EFgQU1WM6XIoxkPNDe3xGG8UzaFqFbVUwGQYJKwYBBAGCNxQCBAwe # CgBTAHUAYgBDAEEwCwYDVR0PBAQDAgGGMA8GA1UdEwEB/wQFMAMBAf8wHwYDVR0j # BBgwFoAU1fZWy4/oolxiaNE9lJBb186aGMQwVgYDVR0fBE8wTTBLoEmgR4ZFaHR0 # cDovL2NybC5taWNyb3NvZnQuY29tL3BraS9jcmwvcHJvZHVjdHMvTWljUm9vQ2Vy # QXV0XzIwMTAtMDYtMjMuY3JsMFoGCCsGAQUFBwEBBE4wTDBKBggrBgEFBQcwAoY+ # aHR0cDovL3d3dy5taWNyb3NvZnQuY29tL3BraS9jZXJ0cy9NaWNSb29DZXJBdXRf # MjAxMC0wNi0yMy5jcnQwgaAGA1UdIAEB/wSBlTCBkjCBjwYJKwYBBAGCNy4DMIGB # MD0GCCsGAQUFBwIBFjFodHRwOi8vd3d3Lm1pY3Jvc29mdC5jb20vUEtJL2RvY3Mv # Q1BTL2RlZmF1bHQuaHRtMEAGCCsGAQUFBwICMDQeMiAdAEwAZQBnAGEAbABfAFAA # bwBsAGkAYwB5AF8AUwB0AGEAdABlAG0AZQBuAHQALiAdMA0GCSqGSIb3DQEBCwUA # A4ICAQAH5ohRDeLG4Jg/gXEDPZ2joSFvs+umzPUxvs8F4qn++ldtGTCzwsVmyWrf # 9efweL3HqJ4l4/m87WtUVwgrUYJEEvu5U4zM9GASinbMQEBBm9xcF/9c+V4XNZgk # Vkt070IQyK+/f8Z/8jd9Wj8c8pl5SpFSAK84Dxf1L3mBZdmptWvkx872ynoAb0sw # RCQiPM/tA6WWj1kpvLb9BOFwnzJKJ/1Vry/+tuWOM7tiX5rbV0Dp8c6ZZpCM/2pi # f93FSguRJuI57BlKcWOdeyFtw5yjojz6f32WapB4pm3S4Zz5Hfw42JT0xqUKloak # vZ4argRCg7i1gJsiOCC1JeVk7Pf0v35jWSUPei45V3aicaoGig+JFrphpxHLmtgO # R5qAxdDNp9DvfYPw4TtxCd9ddJgiCGHasFAeb73x4QDf5zEHpJM692VHeOj4qEir # 995yfmFrb3epgcunCaw5u+zGy9iCtHLNHfS4hQEegPsbiSpUObJb2sgNVZl6h3M7 # COaYLeqN4DMuEin1wC9UJyH3yKxO2ii4sanblrKnQqLJzxlBTeCG+SqaoxFmMNO7 # dDJL32N79ZmKLxvHIa9Zta7cRDyXUHHXodLFVeNp3lfB0d4wwP3M5k37Db9dT+md # Hhk4L7zPWAUu7w2gUDXa7wknHNWzfjUeCLraNtvTX4/edIhJEjCCBNowggPCoAMC # AQICEzMAAAC0Qzoc/ra6UokAAAAAALQwDQYJKoZIhvcNAQELBQAwfDELMAkGA1UE # BhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNVBAcTB1JlZG1vbmQxHjAc # BgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEmMCQGA1UEAxMdTWljcm9zb2Z0 # IFRpbWUtU3RhbXAgUENBIDIwMTAwHhcNMTYwOTA3MTc1NjU4WhcNMTgwOTA3MTc1 # NjU4WjCBszELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAOBgNV # BAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjENMAsG # A1UECxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNOOjE0OEMtQzRCOS0y # MDY2MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNlMIIBIjAN # BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4IFPu7XRMDo/gwC3zFaf95usurNd # ZBEegtZ61+4g+7PRCAFjl1enwuJMVqi1V9ugxt+z0RixHn6RrBkZUW1z/p4tbSRC # IMTI70Zp0G8cTGFqlDMPlD7bom8lKr8Z0s4DOlIVgEVlG/3Ptf83smhmmWWt7v++ # gU1Dngt4CdYqjz2KtAcz2bBQJFHvf/Uk1BUMj3YY2Fa8tW2jKXTYdQdIQBmOZhiR # AgJwG0Hb+SehGXXGlqj6QS+7esU0pjCgl5PHGmwAWoK2jABnksvMTdJsqePEXnkL # AZWuqKS5Iv75RV4/fRkbYZw3dNmjUcXuSNlUMxSDX7LnD3uwH8mXvpmFcQIDAQAB # o4IBGzCCARcwHQYDVR0OBBYEFAyTq0XUbAt3L/MrV/PpJMSHB/RfMB8GA1UdIwQY # MBaAFNVjOlyKMZDzQ3t8RhvFM2hahW1VMFYGA1UdHwRPME0wS6BJoEeGRWh0dHA6 # Ly9jcmwubWljcm9zb2Z0LmNvbS9wa2kvY3JsL3Byb2R1Y3RzL01pY1RpbVN0YVBD # QV8yMDEwLTA3LTAxLmNybDBaBggrBgEFBQcBAQROMEwwSgYIKwYBBQUHMAKGPmh0 # dHA6Ly93d3cubWljcm9zb2Z0LmNvbS9wa2kvY2VydHMvTWljVGltU3RhUENBXzIw # MTAtMDctMDEuY3J0MAwGA1UdEwEB/wQCMAAwEwYDVR0lBAwwCgYIKwYBBQUHAwgw # DQYJKoZIhvcNAQELBQADggEBAAK1YVugp9JqrCYvtsI0o3T7qHuQsYItqIkSXaT2 # ggtZPSfneh15LPjLcs9Ha+9v3uuSbe6v+16hkYR4419Re8SXMeBQje26mfeIKr9R # auIj5DdH3WbixYUI7P51cet6bUmJJSEdnY4W5Fik5qiVtZu0k6GKLLicITq8AVEf # mOCf8+3qUMy7N4QpavAibKVPrhMReWZkcCejDPq03ky7UH7En3/pgVEE3q4UX+YO # DBCBukasO2IS57XRCjDw0yns+tNwMW4KeiRRwiLmDiK3Q1GqU1Ui9SS159N1eCmh # OltpCuCtfJnPn7SSKAd+qnDEMoZbSg7YRLb1PmcfecPyK1OhggN5MIICYQIBATCB # 46GBuaSBtjCBszELMAkGA1UEBhMCVVMxEzARBgNVBAgTCldhc2hpbmd0b24xEDAO # BgNVBAcTB1JlZG1vbmQxHjAcBgNVBAoTFU1pY3Jvc29mdCBDb3Jwb3JhdGlvbjEN # MAsGA1UECxMETU9QUjEnMCUGA1UECxMebkNpcGhlciBEU0UgRVNOOjE0OEMtQzRC # OS0yMDY2MSUwIwYDVQQDExxNaWNyb3NvZnQgVGltZS1TdGFtcCBTZXJ2aWNloiUK # AQEwCQYFKw4DAhoFAAMVAAfAlZeuLk5uydN19tmJUZiLIG06oIHCMIG/pIG8MIG5 # MQswCQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVk # bW9uZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMQ0wCwYDVQQLEwRN # T1BSMScwJQYDVQQLEx5uQ2lwaGVyIE5UUyBFU046NERFOS0wQzVFLTNFMDkxKzAp # BgNVBAMTIk1pY3Jvc29mdCBUaW1lIFNvdXJjZSBNYXN0ZXIgQ2xvY2swDQYJKoZI # hvcNAQEFBQACBQDdWK0EMCIYDzIwMTcwOTA1MDQ1NjM2WhgPMjAxNzA5MDYwNDU2 # MzZaMHcwPQYKKwYBBAGEWQoEATEvMC0wCgIFAN1YrQQCAQAwCgIBAAICBzoCAf8w # BwIBAAICHBgwCgIFAN1Z/oQCAQAwNgYKKwYBBAGEWQoEAjEoMCYwDAYKKwYBBAGE # WQoDAaAKMAgCAQACAwehIKEKMAgCAQACAwehIDANBgkqhkiG9w0BAQUFAAOCAQEA # LwY679N21lyYyv02M9hqGtWKqwzo5L9jFJwzVISPiB11A44qmS2N0VG0NjLrpoSY # eVBQcopx8q6MpEScwoBLY9jn5KBEjTfWxOyMEXoVPP01zMJ1PqXqVDNQeeHrwtBi # 5ewEB+sHvFeniiQLLavuRZOLLi+MJ7SI2aIifcxk2gzSyzj0NwWpFUZH8uKBhWN9 # qXM0IJojPSw8YeJqcjaHA8M2lWiDzoLFuhvoppkXU5jQA+i7PpjSU7GR9c125iaw # 9G+yScBB/WVbMAbhm29cYwNG4AJ0cWhJP9T+cdJdFqav9Of91V7wy2ExAM5+hTyO # 9oB+8rjkpi8eGCYOTwO5wjGCAvUwggLxAgEBMIGTMHwxCzAJBgNVBAYTAlVTMRMw # EQYDVQQIEwpXYXNoaW5ndG9uMRAwDgYDVQQHEwdSZWRtb25kMR4wHAYDVQQKExVN # aWNyb3NvZnQgQ29ycG9yYXRpb24xJjAkBgNVBAMTHU1pY3Jvc29mdCBUaW1lLVN0 # YW1wIFBDQSAyMDEwAhMzAAAAtEM6HP62ulKJAAAAAAC0MA0GCWCGSAFlAwQCAQUA # oIIBMjAaBgkqhkiG9w0BCQMxDQYLKoZIhvcNAQkQAQQwLwYJKoZIhvcNAQkEMSIE # INn1Xah+yKzijWTBg0Y/YghZ147Dduk4mvZdk5BkBMa+MIHiBgsqhkiG9w0BCRAC # DDGB0jCBzzCBzDCBsQQUB8CVl64uTm7J03X22YlRmIsgbTowgZgwgYCkfjB8MQsw # CQYDVQQGEwJVUzETMBEGA1UECBMKV2FzaGluZ3RvbjEQMA4GA1UEBxMHUmVkbW9u # ZDEeMBwGA1UEChMVTWljcm9zb2Z0IENvcnBvcmF0aW9uMSYwJAYDVQQDEx1NaWNy # b3NvZnQgVGltZS1TdGFtcCBQQ0EgMjAxMAITMwAAALRDOhz+trpSiQAAAAAAtDAW # BBRvckTuxLqEMp+p73tMOlL/8PMB4DANBgkqhkiG9w0BAQsFAASCAQC1nu5mhYtV # Gwq5MenCYs/r8dinoSleLVMYSw4f4SqRVlG9b7a4i6XX9Oa50KBno/mpGlF3O27+ # P3LqEvoQisCY8zdT0LwmQ4twbn0f9Q1X2bu97SF87RFW4CVJdlZLvnPNqgAKdqMb # iqj7i9cwoaVaJCWM++vcvwqCfnXd42KmO0JfHY1lnqX/oUW9RTjR4klSr4/V5sVr # 5FD7Kl3j5c+L6BVTflkCxpjcMGhg5Oyz1/HyLGTQKR7uBUJ5Ci6Hq2HzZhxPma0Q # BO7Pyzb0nm5ieNA6KjP3iNt+haSX7KA/Wr/qUQqmP+FMmB+pmpvZ9vP2H54pxZeA # TUE/BCO56rhy # SIG # End signature block |