JulianHayward / Azure-MG-Sub-Governance-Reporting

Azure Governance Visualizer aka AzGovViz is a PowerShell script that captures Azure Governance related information such as Azure Policy, RBAC (a lot more) by polling Azure ARM, Storage and Microsoft Graph APIs.
MIT License
814 stars 292 forks source link

Error processing policy definitions #239

Open gkgab-ptr opened 1 week ago

gkgab-ptr commented 1 week ago

v6.4.5

CodeRunPlatform Console

Describe the bug Collecting custom data CustomDataCollection ManagementGroups 9 Management Groups: mg-decommissioned, mg-landingzones, mg-landingzones-avd, mg-landingzones-cae, mg-landingzones-corp, mg-landingzones-online, mg-platform, mg-sandbox, mg-contoso 3 batches of Management Groups to process: Batch#1 - 1 Management Groups: mg-contoso (CONTOSO) Batch#2 - 4 Management Groups: mg-decommissioned (Decommissioned), mg-landingzones (Landing Zones), mg-platform (Platform), mg-sandbox (Sandbox) Batch#3 - 4 Management Groups: mg-landingzones-avd (AVD), mg-landingzones-cae (CAE), mg-landingzones-corp (Corp), mg-landingzones-online (Online) Processing Management Groups L1 (1 Management Groups) Optimal batch size: 1 Processing data in 1 batches [AzAPICall 1.2.1] 'Getting Policy definitions for Management Group: 'CONTOSO' ('mg-contoso')' uri='https://management.azure.com/providers/Microsoft.Management/managementgroups/mg-contoso/providers/Microsoft.Authorization/policyDefinitions?api-version=2021-06-01&$filter=policyType eq 'Custom'' Command 'ConvertFrom-Json' failed: Cannot convert the JSON string because it contains keys with different casing. Please use the -AsHashTable switch instead. The key that was attempted to be added to the existing key 'DeploymentScope' was 'deploymentScope'. [AzAPICall 1.2.1] 'Getting Policy definitions for Management Group: 'CONTOSO' ('mg-contoso')' uri='https://management.azure.com/providers/Microsoft.Management/managementgroups/mg-contoso/providers/Microsoft.Authorization/policyDefinitions?api-version=2021-06-01&$filter=policyType eq 'Custom'' Trying command 'ConvertFrom-Json -AsHashtable' [AzAPICall 1.2.1] 'Getting Policy definitions for Management Group: 'CONTOSO' ('mg-contoso')' uri='https://management.azure.com/providers/Microsoft.Management/managementgroups/mg-contoso/providers/Microsoft.Authorization/policyDefinitions?api-version=2021-06-01&$filter=policyType eq 'Custom'' Command 'ConvertFrom-Json -AsHashtable' succeeded. Please file an issue at the AzGovViz GitHub repository (aka.ms/AzGovViz) and provide a dump (scrub subscription Id and company identifyable names) of the resource (portal JSOn view) - Thank you! [AzAPICall 1.2.1] 'Getting Policy definitions for Management Group: 'CONTOSO' ('mg-contoso')' uri='https://management.azure.com/providers/Microsoft.Management/managementgroups/mg-contoso/providers/Microsoft.Authorization/policyDefinitions?api-version=2021-06-01&$filter=policyType eq 'Custom'' Command 'ConvertFrom-Json -AsHashtable' failed [AzAPICall 1.2.1] 'Getting Policy definitions for Management Group: 'CONTOSO' ('mg-contoso')' uri='https://management.azure.com/providers/Microsoft.Management/managementgroups/mg-contoso/providers/Microsoft.Authorization/policyDefinitions?api-version=2021-06-01&$filter=policyType eq 'Custom'' Command 'ConvertFrom-Json -AsHashtable' failed. Please file an issue at the AzGovViz GitHub repository (aka.ms/AzGovViz) and provide a dump (scrub subscription Id and company identifyable names) of the resource (portal JSOn view) - Thank you!
Exception: C:_code\other\Azure-MG-Sub-Governance-Reporting-6.4.5\pwsh\AzGovVizParallel.ps1:5733:9 Line | 5733 | $batchLevelGroupBatch | ForEach-Object -Parallel { | ~~~~~~~~~~ | throwing - Command ConvertFrom-Json -AsHashtable failed (different casing)

JulianHayward commented 1 week ago

@gkgab-ptr

try this:

$mgId = 'mg-contoso'
$uri = "https://management.azure.com/providers/Microsoft.Management/managementgroups/$($mgId)/providers/Microsoft.Authorization/policyDefinitions?api-version=2021-06-01&`$filter=policyType eq 'Custom'"
$method = 'GET'
$res = Invoke-AzRestMethod -Uri $uri -Method $method
$resObj = ($res.Content | ConvertFrom-Json) #will error out
$resObjAsHashtable = ($res.Content | ConvertFrom-Json -AsHashtable)

dump the $resObjAsHashtable or $res.Content somewhere and sanity check the content (policy definition(s)) for duplicate key: DeploymentScope/deploymentScope

other ref: https://github.com/JulianHayward/Azure-MG-Sub-Governance-Reporting/issues/236

JulianHayward commented 1 week ago

@gkgab-ptr any update from your side?

gkgab-ptr commented 1 week ago

Will try tonight and report - thx!

gkgab-ptr commented 6 days ago

There is a policy with different case match for DeploymentScopes - just adjust and try again?

{
      "properties": {
        "displayName": "Deploy Lighthouse Reader delegation To Subscription",
        "policyType": "Custom",
        "mode": "All",
        "description": "Policy deploys Azure Lighthouse delegation with permission READER to the subscriptions in scope.",
        "metadata": {
          "category": "Lighthouse",
          "version": "1.0.0",
          "createdBy": "anon",
          "createdOn": "anon",
          "updatedBy": null,
          "updatedOn": null
        },
        "parameters": {
          "ReaderPrincipalID": {
            "type": "string",
            "metadata": {
              "description": "Object ID of Reader Group"
            },
            "defaultValue": "anon"
          },
          "effect": {
            "type": "String",
            "metadata": {
              "description": "Enable or disable the execution of the Policy.",
              "displayName": "Effects"
            },
            "allowedValues": [
              "DeployIfNotExists",
              "Disabled"
            ],
            "defaultValue": "DeployIfNotExists"
          },
          "managedByTenantId": {
            "type": "string",
            "metadata": {
              "description": "Tenant ID"
            },
            "defaultValue": "anon"
          },
          "mspOfferDescription": {
            "type": "string",
            "metadata": {
              "description": "Name of the Managed Service Provider offering"
            },
            "defaultValue": "The solution will grant following RBAC role to your subscription: Reader"
          },
          "mspOfferName": {
            "type": "string",
            "metadata": {
              "description": "Specify a unique name for your offer"
            },
            "defaultValue": "Azure Managed Service - Access privileges - reader"
          }
        },
        "policyRule": {
          "if": {
            "allOf": [
              {
                "equals": "Microsoft.Resources/subscriptions",
                "field": "type"
              }
            ]
          },
          "then": {
            "details": {
              "DeploymentScope": "Subscription",
              "ExistenceScope": "Subscription",
              "deployment": {
                "location": "westeurope",
                "properties": {
                  "mode": "incremental",
                  "parameters": {
                    "ReaderPrincipalID": {
                      "value": "[parameters('ReaderPrincipalID')]"
                    },
                    "managedByTenantId": {
                      "value": "[parameters('managedByTenantId')]"
                    },
                    "mspOfferDescription": {
                      "value": "[parameters('mspOfferDescription')]"
                    },
                    "mspOfferName": {
                      "value": "[parameters('mspOfferName')]"
                    }
                  },
                  "template": {
                    "$schema": "http://schema.management.azure.com/schemas/2015-01-01/deploymentTemplate.json#",
                    "contentVersion": "1.0.0.0",
                    "parameters": {
                      "ReaderPrincipalID": {
                        "type": "string"
                      },
                      "managedByTenantId": {
                        "type": "String"
                      },
                      "mspOfferDescription": {
                        "type": "String"
                      },
                      "mspOfferName": {
                        "type": "String"
                      }
                    },
                    "resources": [
                      {
                        "apiVersion": "2019-09-01",
                        "name": "[variables('mspRegistrationName')]",
                        "properties": {
                          "authorizations": "[variables('authorizations')]",
                          "description": "[parameters('mspOfferDescription')]",
                          "managedByTenantId": "[parameters('managedByTenantId')]",
                          "registrationDefinitionName": "[parameters('mspOfferName')]"
                        },
                        "type": "Microsoft.ManagedServices/registrationDefinitions"
                      },
                      {
                        "apiVersion": "2019-09-01",
                        "dependsOn": [
                          "[resourceId('Microsoft.ManagedServices/registrationDefinitions/', variables('mspRegistrationName'))]"
                        ],
                        "name": "[variables('mspAssignmentName')]",
                        "properties": {
                          "registrationDefinitionId": "[resourceId('Microsoft.ManagedServices/registrationDefinitions/', variables('mspRegistrationName'))]"
                        },
                        "type": "Microsoft.ManagedServices/registrationAssignments"
                      }
                    ],
                    "variables": {
                      "authorizations": [
                        {
                          "principalId": "[parameters('ReaderPrincipalID')]",
                          "principalIdDisplayName": "Azure Lighthouse Reader",
                          "roleDefinitionId": "anon"
                        },
                        {
                          "principalId": "[parameters('ReaderPrincipalID')]",
                          "principalIdDisplayName": "Remove Azure Lighthouse Delegation",
                          "roleDefinitionId": "anon"
                        }
                      ],
                      "mspAssignmentName": "[guid(parameters('mspOfferName'))]",
                      "mspRegistrationName": "[guid(parameters('mspOfferName'))]"
                    }
                  }
                }
              },
              "deploymentScope": "Subscription",
              "existenceCondition": {
                "allOf": [
                  {
                    "equals": "[guid(parameters('mspOfferName'))]",
                    "field": "name"
                  }
                ]
              },
              "roleDefinitionIds": [
                "/providers/microsoft.authorization/roleDefinitions/anon"
              ],
              "type": "Microsoft.ManagedServices/registrationAssignments"
            },
            "effect": "[parameters('effect')]"
          }
        }
      },
JulianHayward commented 6 days ago

@gkgab-ptr yes, also see: https://learn.microsoft.com/en-us/azure/governance/policy/concepts/effect-deploy-if-not-exists#deployifnotexists-properties

JulianHayward commented 2 days ago

@gkgab-ptr any update from your side?