diff --git a/README.md b/README.md index 0bf2ea31..145b2c45 100644 --- a/README.md +++ b/README.md @@ -59,11 +59,18 @@ Listed as [security monitoring tool](https://docs.microsoft.com/en-us/azure/arch ## Release history -__Changes__ (2022-Dec-02 / Major) +__Changes__ (2022-Dec-04 / Major) * PSRule for Azure fix | Get resources using ARM API inside Foreach-Object -parallel loop - -Passed tests: Powershell Core 7.2.6 on Windows +* Private Endpoints + * fix resource identification + * add cross tenant detection +* Storage Account Access Analysis - add insights on 'Allowed Copy Scope' and 'Allow Cross Tenant Replication' +* Updated [API reference](#api-reference) +* Cosmetics +* Bugfixes + +Passed tests: Powershell Core 7.3.0 on Windows Passed tests: Powershell Core 7.2.7 Azure DevOps hosted agent ubuntu-22.04 Passed tests: Powershell Core 7.2.7 Github Actions hosted agent ubuntu-latest Passed tests: Powershell Core 7.2.6 GitHub Codespaces mcr.microsoft.com/powershell:latest @@ -515,6 +522,7 @@ AzGovViz polls the following APIs | MS Graph | v1.0 | /servicePrincipals | | ARM | 2021-05-01-preview | /`resourceId`/providers/Microsoft.Insights/diagnosticSettingsCategories | | ARM | 2018-11-01-preview | /`scopeId`/providers/Microsoft.Blueprint/blueprints/`blueprintName` | +| ARM | 2021-04-01 | /providers | | ARM | 2021-06-01 | /providers/Microsoft.Authorization/policyDefinitions | | ARM | 2021-06-01 | /providers/Microsoft.Authorization/policySetDefinitions | | ARM | 2020-02-01 | /providers/Microsoft.Management/getEntities | diff --git a/history.md b/history.md index 5ce63377..0f8fbc99 100644 --- a/history.md +++ b/history.md @@ -4,9 +4,16 @@ ### AzGovViz version 6 -__Changes__ (2022-Dec-02 / Major) +__Changes__ (2022-Dec-04 / Major) * PSRule for Azure fix | Get resources using ARM API inside Foreach-Object -parallel loop +* Private Endpoints + * fix resource identification + * add cross tenant detection +* Storage Account Access Analysis - add insights on 'Allowed Copy Scope' and 'Allow Cross Tenant Replication' +* Updated [API reference](#api-reference) +* Cosmetics +* Bugfixes __Changes__ (2022-Nov-29 / Major) diff --git a/pwsh/AzGovVizParallel.ps1 b/pwsh/AzGovVizParallel.ps1 index 2ce6448c..51a92330 100644 --- a/pwsh/AzGovVizParallel.ps1 +++ b/pwsh/AzGovVizParallel.ps1 @@ -359,10 +359,10 @@ Param $Product = 'AzGovViz', [string] - $AzAPICallVersion = '1.1.57', + $AzAPICallVersion = '1.1.58', [string] - $ProductVersion = 'v6_major_20221202_5', + $ProductVersion = 'v6_major_20221204_1', [string] $GithubRepository = 'aka.ms/AzGovViz', @@ -4958,6 +4958,7 @@ function processDataCollection { $arrayVNets = $using:arrayVNets $arrayPrivateEndPoints = $using:arrayPrivateEndPoints $htResourceProvidersRef = $using:htResourceProvidersRef + $arrayPrivateEndPointsFromResourceProperties = $using:arrayPrivateEndPointsFromResourceProperties #other $function:addRowToTable = $using:funcAddRowToTable $function:namingValidation = $using:funcNamingValidation @@ -7124,7 +7125,6 @@ function processNetwork { $script:htSubnets = @{} $script:arrayVirtualNetworks = [System.Collections.ArrayList]@() $script:arraySubnets = [System.Collections.ArrayList]@() - $htUnknownTenantsForSubscription = @{} foreach ($vnet in $arrayVNets) { @@ -7191,9 +7191,9 @@ function processNetwork { $peeringXTenant = 'true' } } - $htUnknownTenantsForSubscription.($remotesubscriptionId) = @{} - $htUnknownTenantsForSubscription.($remotesubscriptionId).TenantId = $arrayRemoteMGPath -join ', ' - $remoteMGPath = $arrayRemoteMGPath -join ', ' + $script:htUnknownTenantsForSubscription.($remotesubscriptionId) = @{} + $script:htUnknownTenantsForSubscription.($remotesubscriptionId).TenantId = $arrayRemoteMGPath -join ', ' + $remoteMGPath = $arrayRemoteMGPath -join ' or ' } } } @@ -7552,14 +7552,108 @@ function processNetwork { } function processPrivateEndpoints { $start = Get-Date - Write-Host "Processing Private Endpoints enrichment ($($arrayPrivateEndPoints.Count) Private Endpoints)" + Write-Host 'Processing Private Endpoints enrichment' + + $script:arrayPrivateEndpointsEnriched = [System.Collections.ArrayList]@() + + if ($arrayPrivateEndPointsFromResourceProperties.Count -gt 0) { + $privateEndPointsFromResourcePropertiesToProcess = ($arrayPrivateEndPointsFromResourceProperties.where({ $arrayPrivateEndPoints.id -notcontains $_.privateEndpointConnection.Properties.privateEndpoint.id })) + $privateEndPointsFromResourcePropertiesToProcessCount = $privateEndPointsFromResourcePropertiesToProcess.Count + Write-Host " Processing Private Endpoints enrichment for $privateEndPointsFromResourcePropertiesToProcessCount Private Endpoint(s) where the Private Endpoint was not returned from the PE API endpoint but from a resource property" + if ($privateEndPointsFromResourcePropertiesToProcessCount -gt 0) { + foreach ($entry in $privateEndPointsFromResourcePropertiesToProcess) { + $peResIdSplit = $entry.privateEndpointConnection.Properties.privateEndpoint.id -split '/' + $crossSubscriptionPE = 'n/a' + $peSubscriptionId = $peResIdSplit[2] + if ($peSubscriptionId -ne $entry.ResourceSubscriptionId) { + $crossSubscriptionPE = $true + } + else { + $crossSubscriptionPE = $false + } + + $peMGPath = 'n/a' + $peXTenant = 'n/a' + if ($htUnknownTenantsForSubscription.($peSubscriptionId)) { + $remoteTenantId = $htUnknownTenantsForSubscription.($peSubscriptionId).TenantId + $peMGPath = $remoteTenantId + if ($remoteTenantId -eq $azApiCallConf['checkcontext'].tenant.id) { + $peXTenant = 'false' + } + else { + $peXTenant = 'true' + } + } + else { + $uri = "$($azAPICallConf['azAPIEndpointUrls'].ARM)/subscriptions/$($peSubscriptionId)?api-version=2020-01-01" + $remoteTenantId = AzAPICall -AzAPICallConfiguration $azApiCallConf -uri $uri -listenOn 'content' -currentTask "getTenantId for subscriptionId '$($peSubscriptionId)'" + $arrayRemoteMGPath = @() + foreach ($remoteId in $remoteTenantId) { + $objectGuid = [System.Guid]::empty + if ([System.Guid]::TryParse($remoteId, [System.Management.Automation.PSReference]$ObjectGuid)) { + $arrayRemoteMGPath += $remoteId + if ($remoteId -eq $azApiCallConf['checkcontext'].tenant.id) { + $peXTenant = 'false' + } + else { + $peXTenant = 'true' + } + } + $script:htUnknownTenantsForSubscription.($peSubscriptionId) = @{} + $script:htUnknownTenantsForSubscription.($peSubscriptionId).TenantId = $arrayRemoteMGPath -join ', ' + $peMGPath = $arrayRemoteMGPath -join ' or ' + } + } + + $null = $script:arrayPrivateEndpointsEnriched.Add([PSCustomObject]@{ + PEName = $entry.privateEndpointConnection.name + PEId = $entry.privateEndpointConnection.Properties.privateEndpoint.id + PELocation = 'n/a' + PEResourceGroup = $peResIdSplit[4] + PESubscriptionName = 'n/a' + PESubscription = $peSubscriptionId + PEMGPath = $peMGPath + PEConnectionType = 'n/a' + PEConnectionState = $entry.privateEndpointConnection.Properties.privateLinkServiceConnectionState.status + CrossSubscriptionPE = $crossSubscriptionPE + CrossTenantPE = $peXTenant + + Resource = $entry.ResourceName + ResourceType = $entry.ResourceType + ResourceId = $entry.ResourceId + TargetSubresource = 'n/a' + NICName = 'n/a' + FQDN = 'n/a' + ipAddresses = 'n/a' + ResourceResourceGroup = $entry.ResourceResourceGroup + ResourceSubscriptionName = $entry.ResourceSubscriptionName + ResourceSubscriptionId = $entry.ResourceSubscriptionId + ResourceMGPath = $entry.ResourceMGPath + + Subnet = 'n/a' + SubnetId = 'n/a' + SubnetVNet = 'n/a' + SubnetVNetId = 'n/a' + SubnetVNetLocation = 'n/a' + SubnetVNetResourceGroup = 'n/a' + SubnetSubscriptionName = 'n/a' + SubnetSubscription = 'n/a' + SubnetMGPath = 'n/a' + }) + } + } + } + Write-Host " Processing Private Endpoints enrichment for $($arrayPrivateEndPoints.Count) Private Endpoint(s) where the Private Endpoint was returned from the PE API endpoint" $htVPrivateEndPoints = @{} foreach ($pe in $arrayPrivateEndPoints) { $htVPrivateEndPoints.($pe.id) = $pe } - $script:arrayPrivateEndpointsEnriched = [System.Collections.ArrayList]@() + $htVPrivateEndPoints = @{} + foreach ($pe in $arrayPrivateEndPoints) { + $htVPrivateEndPoints.($pe.id) = $pe + } foreach ($pe in $arrayPrivateEndPoints) { @@ -7608,23 +7702,34 @@ function processPrivateEndpoints { $peConnectionState = $pe.properties.manualPrivateLinkServiceConnections.properties.privateLinkServiceConnectionState.status } - $resourceSubscriptionId = $resourceSplit[2] + $resourceSubscriptionId = 'n/a' + $resource = 'n/a' + $resourceType = 'n/a' + $resourceResourceGroup = 'n/a' $resourceSubscriptionName = 'n/a' $resourceMGPath = 'n/a' - if ($htSubscriptionsMgPath.($resourceSubscriptionId)) { - $subHelper = $htSubscriptionsMgPath.($resourceSubscriptionId) - $resourceSubscriptionName = $subHelper.displayName - $resourceMGPath = $subHelper.ParentNameChainDelimited - } + $crossSubscriptionPE = 'n/a' - if ($SubnetSubscription -eq $resourceSubscriptionId) { - $crossSubscriptionPE = $false - } - else { - $crossSubscriptionPE = $true - } + $ObjectGuid = [System.Guid]::empty + if ([System.Guid]::TryParse($resourceSplit[2], [System.Management.Automation.PSReference]$ObjectGuid)) { + $resourceSubscriptionId = $resourceSplit[2] + $resource = $resourceSplit[8] + $resourceType = "$($resourceSplit[6])/$($resourceSplit[7])" + $resourceResourceGroup = $resourceSplit[4] + if ($htSubscriptionsMgPath.($resourceSubscriptionId)) { + $subHelper = $htSubscriptionsMgPath.($resourceSubscriptionId) + $resourceSubscriptionName = $subHelper.displayName + $resourceMGPath = $subHelper.ParentNameChainDelimited + } + if ($SubnetSubscription -eq $resourceSubscriptionId) { + $crossSubscriptionPE = $false + } + else { + $crossSubscriptionPE = $true + } + } $null = $script:arrayPrivateEndpointsEnriched.Add([PSCustomObject]@{ PEName = $pe.name @@ -7637,15 +7742,16 @@ function processPrivateEndpoints { PEConnectionType = $peConnectionType PEConnectionState = $peConnectionState CrossSubscriptionPE = $crossSubscriptionPE + CrossTenantPE = 'false' - Resource = $resourceSplit[8] - ResourceType = "$($resourceSplit[6])/$($resourceSplit[7])" + Resource = $resource + ResourceType = $resourceType ResourceId = $resourceId TargetSubresource = $targetSubresource -join ', ' NICName = $pe.properties.customNetworkInterfaceName FQDN = $pe.properties.customDnsConfigs.fqdn -join ', ' ipAddresses = $pe.properties.customDnsConfigs.ipAddresses -join ', ' - ResourceResourceGroup = $resourceSplit[4] + ResourceResourceGroup = $resourceResourceGroup ResourceSubscriptionName = $resourceSubscriptionName ResourceSubscriptionId = $resourceSubscriptionId ResourceMGPath = $resourceMGPath @@ -7705,8 +7811,8 @@ function processScopeInsightsMgOrSub($mgOrSub, $mgChild, $subscriptionId, $subsc }) } $resourcesAllChildSubscriptions.count_ | ForEach-Object { $resourcesAllChildSubscriptionTotal += $_ } - $resourcesAllChildSubscriptionResourceTypeCount = (($resourcesAllChildSubscriptions | Sort-Object -Property type -Unique) | measure-object).count - $resourcesAllChildSubscriptionLocationCount = (($resourcesAllChildSubscriptions | Sort-Object -Property location -Unique) | measure-object).count + $resourcesAllChildSubscriptionResourceTypeCount = (($resourcesAllChildSubscriptions | Sort-Object -Property type -Unique) | Measure-Object).count + $resourcesAllChildSubscriptionLocationCount = (($resourcesAllChildSubscriptions | Sort-Object -Property location -Unique) | Measure-Object).count } #childrenMgInfo $mgAllChildMgs = [System.Collections.ArrayList]@() @@ -7808,16 +7914,16 @@ function processScopeInsightsMgOrSub($mgOrSub, $mgChild, $subscriptionId, $subsc } [void]$htmlScopeInsights.AppendLine(@" -

Subscription Name: $($subscriptionDetailsReleatedQuery.subscription -replace '<', '<' -replace '>', '>')

-

Subscription Id: $($subscriptionDetailsReleatedQuery.subscriptionId)

-

Subscription Path: $subPath

-

State: $subscriptionState

-

QuotaId: $subscriptionQuotaId

-

Microsoft Defender for Cloud Secure Score: $subscriptionASCPoints Video , Blog , docs

-

Microsoft Defender for Cloud 'Email notifications' state: $MDfCEmailNotificationsState

-

Microsoft Defender for Cloud 'Email notifications' severity: $MDfCEmailNotificationsSeverity

-

Microsoft Defender for Cloud 'Email notifications' roles: $MDfCEmailNotificationsRoles

-

Microsoft Defender for Cloud 'Email notifications' emails: $MDfCEmailNotificationsEmails

+Subscription Name: $($subscriptionDetailsReleatedQuery.subscription -replace '<', '<' -replace '>', '>') +Subscription Id: $($subscriptionDetailsReleatedQuery.subscriptionId) +Subscription Path: $subPath +State: $subscriptionState +QuotaId: $subscriptionQuotaId + Microsoft Defender for Cloud Secure Score: $subscriptionASCPoints Video , Blog , docs + Microsoft Defender for Cloud 'Email notifications' state: $MDfCEmailNotificationsState + Microsoft Defender for Cloud 'Email notifications' severity: $MDfCEmailNotificationsSeverity + Microsoft Defender for Cloud 'Email notifications' roles: $MDfCEmailNotificationsRoles + Microsoft Defender for Cloud 'Email notifications' emails: $MDfCEmailNotificationsEmails "@) @@ -7841,7 +7947,7 @@ function processScopeInsightsMgOrSub($mgOrSub, $mgChild, $subscriptionId, $subsc $htmlTableId = "ScopeInsights_DefenderPlans_$($subscriptionId -replace '-','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
"@) @@ -7954,19 +8060,19 @@ tf.init();}} if ($subscriptionSkippedMDfC.Count -gt 0) { if ($subscriptionSkippedMDfC.reason -eq 'SubScriptionNotRegistered') { [void]$htmlScopeInsights.AppendLine(@" -

Microsoft Defender for Cloud plans - Subscription skipped ($($subscriptionSkippedMDfC.reason)) (ResourceProvider: Microsoft.Security) docs

+ Microsoft Defender for Cloud plans - Subscription skipped ($($subscriptionSkippedMDfC.reason)) (ResourceProvider: Microsoft.Security) docs "@) } else { [void]$htmlScopeInsights.AppendLine(@" -

Microsoft Defender for Cloud plans - Subscription skipped ($($subscriptionSkippedMDfC.reason))

+ Microsoft Defender for Cloud plans - Subscription skipped ($($subscriptionSkippedMDfC.reason)) "@) } } else { [void]$htmlScopeInsights.AppendLine(@' -

No Microsoft Defender for Cloud plans docs

+ No Microsoft Defender for Cloud plans docs '@) } } @@ -7983,7 +8089,7 @@ tf.init();}} $htmlTableId = "ScopeInsights_DiagnosticsSub_$($subscriptionId -replace '-','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma @@ -8108,7 +8214,7 @@ tf.init();}} } else { [void]$htmlScopeInsights.AppendLine(@' -

No Subscription Diagnostic settings docs

+ No Subscription Diagnostic settings docs '@) } [void]$htmlScopeInsights.AppendLine(@' @@ -8126,7 +8232,7 @@ tf.init();}} $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" +$tagsSubscriptionCount Subscription Tags | Limit: ($tagsSubscriptionCount/$LimitTagsSubscription)
   Download CSV semicolon | comma
@@ -8197,7 +8303,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$tagsSubscriptionCount Subscription Tags

+ $tagsSubscriptionCount Subscription Tags "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -8228,7 +8334,7 @@ extensions: [{ name: 'sort' }] $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" +Tag Name Usage ($tagNamesUniqueCount unique Tag Names applied at $($tagNamesUsedInScopes)
   Resource naming and tagging decision guide docs
   Download CSV semicolon | comma @@ -8304,7 +8410,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

Tag Name Usage ($tagsUsageCount Tags) docs

+ Tag Name Usage ($tagsUsageCount Tags) docs "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -8329,7 +8435,7 @@ extensions: [{ name: 'sort' }] $currency = $htAzureConsumptionSubscriptions.($subscriptionId).Currency $consumedServiceCount = ($consumptionData.ResourceType | Sort-Object -Unique | Measure-Object).Count $resourceCount = ($consumptionData.ResourceId | Sort-Object -Unique | Measure-Object).Count - $subConsumptionDataGrouped = $consumptionData | Group-Object -property ResourceType, ChargeType, MeterCategory + $subConsumptionDataGrouped = $consumptionData | Group-Object -Property ResourceType, ChargeType, MeterCategory foreach ($consumptionline in $subConsumptionDataGrouped) { @@ -8365,7 +8471,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_Consumption_$($subscriptionId -replace '-','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -8448,13 +8554,13 @@ tf.init();}} } else { [void]$htmlScopeInsights.AppendLine(@' -

No Consumption data available

+ No Consumption data available '@) } } else { [void]$htmlScopeInsights.AppendLine(@' -

No Consumption data available as switch parameter -DoAzureConsumption was not applied

+ No Consumption data available as switch parameter -DoAzureConsumption was not applied '@) } @@ -8470,12 +8576,12 @@ tf.init();}} #region ScopeInsightsResourceGroups if ($subscriptionResourceGroupsCount -gt 0) { [void]$htmlScopeInsights.AppendLine(@" -

$subscriptionResourceGroupsCount Resource Groups | Limit: ($subscriptionResourceGroupsCount/$LimitResourceGroups)

+ $subscriptionResourceGroupsCount Resource Groups | Limit: ($subscriptionResourceGroupsCount/$LimitResourceGroups) "@) } else { [void]$htmlScopeInsights.AppendLine(@" -

$subscriptionResourceGroupsCount Resource Groups

+ $subscriptionResourceGroupsCount Resource Groups "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -8565,7 +8671,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$(($htResourceProvidersAll.Keys).count) Resource Providers

+ $(($htResourceProvidersAll.Keys).count) Resource Providers "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -8586,7 +8692,7 @@ extensions: [{ name: 'sort' }] [void]$htmlScopeInsights.AppendLine(@" +$tfCount enabled Subscription Features
   Set up preview features in Azure subscription docs
@@ -8654,7 +8760,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@' -

0 enabled Subscription Features docs

+ 0 enabled Subscription Features docs '@) } [void]$htmlScopeInsights.AppendLine(@' @@ -8679,7 +8785,7 @@ extensions: [{ name: 'sort' }] [void]$htmlScopeInsights.AppendLine(@" +Resource Locks
   Considerations before applying locks docs
@@ -8749,7 +8855,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@' -

0 Resource Locks docs

+ 0 Resource Locks docs '@) } [void]$htmlScopeInsights.AppendLine(@' @@ -8765,9 +8871,9 @@ extensions: [{ name: 'sort' }] if ($mgOrSub -eq 'mg') { [void]$htmlScopeInsights.AppendLine(@" - - - + + +

$(($mgAllChildMgs).count -1) ManagementGroups below this scope

$(($mgAllChildSubscriptions).count) Subscriptions below this scope

Microsoft Defender for Cloud Secure Score: $managementGroupASCPoints Video , Blog , docs

$(($mgAllChildMgs).count -1) ManagementGroups below this scope
$(($mgAllChildSubscriptions).count) Subscriptions below this scope
Microsoft Defender for Cloud Secure Score: $managementGroupASCPoints Video , Blog , docs
"@) @@ -8778,7 +8884,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_DiagnosticsMg_$($mgChild -replace '\(','_' -replace '\)','_' -replace '-','_' -replace '\.','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma @@ -8903,7 +9009,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@' -

No Management Group Diagnostic settings docs

+ No Management Group Diagnostic settings docs '@) } #endregion ScopeInsightsDiagnosticsMg @@ -8922,10 +9028,10 @@ extensions: [{ name: 'sort' }] if (($consumptionData | Measure-Object).Count -gt 0) { $arrayTotalCostSummaryMg = @() $arrayConsumptionData = [System.Collections.ArrayList]@() - $consumptionDataGroupedByCurrency = $consumptionData | Group-Object -property Currency + $consumptionDataGroupedByCurrency = $consumptionData | Group-Object -Property Currency foreach ($currency in $consumptionDataGroupedByCurrency) { $totalCost = 0 - $tenantSummaryConsumptionDataGrouped = $currency.group | Group-Object -property ResourceType, ChargeType, MeterCategory + $tenantSummaryConsumptionDataGrouped = $currency.group | Group-Object -Property ResourceType, ChargeType, MeterCategory $subsCount = ($tenantSummaryConsumptionDataGrouped.group.subscriptionId | Sort-Object -Unique).Count $consumedServiceCount = ($tenantSummaryConsumptionDataGrouped.group.ResourceType | Sort-Object -Unique).Count $resourceCount = ($tenantSummaryConsumptionDataGrouped.group.ResourceId | Sort-Object -Unique).Count @@ -8964,7 +9070,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_Consumption_$($mgChild -replace '\(','_' -replace '\)','_' -replace '-','_' -replace '\.','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | @@ -9052,13 +9158,13 @@ tf.init();}} } else { [void]$htmlScopeInsights.AppendLine(@' -

No Consumption data available for Subscriptions under this ManagementGroup

+ No Consumption data available for Subscriptions under this ManagementGroup '@) } } else { [void]$htmlScopeInsights.AppendLine(@' -

No Consumption data available

+ No Consumption data available '@) } @@ -9069,7 +9175,7 @@ tf.init();}} } else { [void]$htmlScopeInsights.AppendLine(@' -

No Consumption data available as switch parameter -DoAzureConsumption was not applied

+ No Consumption data available as switch parameter -DoAzureConsumption was not applied '@) } #endregion ScopeInsightsConsumptionMg @@ -9090,7 +9196,7 @@ tf.init();}} $htmlTableId = "ScopeInsights_Resources_$($mgChild -replace '\(','_' -replace '\)','_' -replace '-','_' -replace '\.','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -9164,7 +9270,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$resourcesAllChildSubscriptionResourceTypeCount ResourceTypes (all Subscriptions below this scope)

+ $resourcesAllChildSubscriptionResourceTypeCount ResourceTypes (all Subscriptions below this scope) "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -9179,7 +9285,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_Resources_$($subscriptionId -replace '-','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -9253,7 +9359,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$resourcesSubscriptionResourceTypeCount ResourceTypes

+ $resourcesSubscriptionResourceTypeCount ResourceTypes "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -9276,7 +9382,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_CAFResourceNamingALL_$($subscriptionId -replace '-','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   CAF - Recommended abbreviations for Azure resource types docs
   Resource details can be found in the CSV output *_ResourcesAll.csv
@@ -9310,7 +9416,7 @@ extensions: [{ name: 'sort' }] $passed = 0 $failed = 0 foreach ($result in $resourceTypeGroupedByCAFResourceNamingResult) { - $resultNameSplitted = $result.Name -split ", " + $resultNameSplitted = $result.Name -split ', ' if ($resultNameSplitted[0] -eq 'passed') { $passed = $result.Count } @@ -9391,9 +9497,9 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { "@) } else { - [void]$htmlScopeInsights.AppendLine(@" -

No CAF Naming Recommendation Compliance data available

-"@) + [void]$htmlScopeInsights.AppendLine(@' + No CAF Naming Recommendation Compliance data available +'@) } [void]$htmlScopeInsights.AppendLine(@' @@ -9420,13 +9526,13 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { $orphanedIncludingCost = $false - $hintTableTH = "" + $hintTableTH = '' } $htmlTableId = "ScopeInsights_OrphanedResources_$($subscriptionId -replace '-','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   'Azure Orphan Resources' ARG queries and workbooks GitHub
   Resource details can be found in the CSV output *_ResourcesOrphaned.csv
@@ -9447,23 +9553,23 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { $htmlScopeInsightsOrphanedResources = foreach ($resourceType in $orphanedResourcesThisSubscriptionGroupedByType | Sort-Object -Property Name) { if ($orphanedIncludingCost) { - if ($resourceType.Group.Intent[0] -eq "cost savings") { + if ($resourceType.Group.Intent[0] -eq 'cost savings') { $orphCost = ($resourceType.Group.Cost | Measure-Object -Sum).Sum $orphCurrency = $resourceType.Group.Currency[0] } else { - $orphCost = "" - $orphCurrency = "" + $orphCost = '' + $orphCurrency = '' } } else { - if ($resourceType.Group.Intent[0] -eq "cost savings") { + if ($resourceType.Group.Intent[0] -eq 'cost savings') { $orphCost = "use parameter -DoAzureConsumption to show potential savings" - $orphCurrency = "" + $orphCurrency = '' } else { - $orphCost = "" - $orphCurrency = "" + $orphCost = '' + $orphCurrency = '' } } @@ -9531,15 +9637,15 @@ extensions: [{ name: 'sort' }] "@) } else { - [void]$htmlScopeInsights.AppendLine(@" -

0 Orphaned Resources

-"@) + [void]$htmlScopeInsights.AppendLine(@' + 0 Orphaned Resources +'@) } } else { - [void]$htmlScopeInsights.AppendLine(@" -

0 Orphaned Resources

-"@) + [void]$htmlScopeInsights.AppendLine(@' + 0 Orphaned Resources +'@) } [void]$htmlScopeInsights.AppendLine(@' @@ -9553,7 +9659,7 @@ extensions: [{ name: 'sort' }] #resourcesDiagnosticsCapable #region ScopeInsightsDiagnosticsCapable if ($mgOrSub -eq 'mg') { - $resourceTypesUnique = ($resourcesAllChildSubscriptions | select-object type -Unique).type + $resourceTypesUnique = ($resourcesAllChildSubscriptions | Select-Object type -Unique).type $resourceTypesSummarizedArray = [System.Collections.ArrayList]@() foreach ($resourceTypeUnique in $resourceTypesUnique) { $resourcesTypeCountTotal = 0 @@ -9583,7 +9689,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_resourcesDiagnosticsCapable_$($mgchild -replace '\(','_' -replace '\)','_' -replace '-','_' -replace '\.','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -9670,7 +9776,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$resourcesAllChildSubscriptionResourceTypeCount ResourceTypes (1st party) Diagnostics capable (all Subscriptions below this scope)

+ $resourcesAllChildSubscriptionResourceTypeCount ResourceTypes (1st party) Diagnostics capable (all Subscriptions below this scope) "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -9680,7 +9786,7 @@ extensions: [{ name: 'sort' }] } if ($mgOrSub -eq 'sub') { - $resourceTypesUnique = ($resourcesSubscription | select-object type -Unique).type + $resourceTypesUnique = ($resourcesSubscription | Select-Object type -Unique).type $resourceTypesSummarizedArray = [System.Collections.ArrayList]@() foreach ($resourceTypeUnique in $resourceTypesUnique) { $resourcesTypeCountTotal = 0 @@ -9711,7 +9817,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_resourcesDiagnosticsCapable_$($subscriptionId -replace '-','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -9798,7 +9904,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$resourcesSubscriptionResourceTypeCount ResourceTypes (1st party) Diagnostics capable

+ $resourcesSubscriptionResourceTypeCount ResourceTypes (1st party) Diagnostics capable "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -9819,7 +9925,7 @@ extensions: [{ name: 'sort' }] $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" +UserAssigned Managed Identities assigned to Resources / vice versa
   Managed identity 'user-assigned' vs 'system-assigned' docs
   Download CSV semicolon | comma @@ -9938,7 +10044,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ } else { [void]$htmlScopeInsights.AppendLine(@' -

No UserAssigned Managed Identities assigned to Resources / vice versa - at all

+ No UserAssigned Managed Identities assigned to Resources / vice versa - at all '@) } [void]$htmlScopeInsights.AppendLine(@' @@ -9963,7 +10069,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ } } - $grpThisManagementGroup = $allPSRuleResultsUnderThisMg | group-object -Property resourceType, pillar, category, severity, rule, result + $grpThisManagementGroup = $allPSRuleResultsUnderThisMg | Group-Object -Property resourceType, pillar, category, severity, rule, result if ($grpThisManagementGroup) { $grpThisManagementGroupCount = $grpThisManagementGroup.Count @@ -9972,8 +10078,8 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" -
+ $grpThisManagementGroupCount 'PSRule for Azure' results +
   Learn about PSRule for Azure
   Download CSV semicolon | comma
@@ -10075,7 +10181,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ } else { [void]$htmlScopeInsights.AppendLine(@' -

No PSRule for Azure results

+ No PSRule for Azure results '@) } [void]$htmlScopeInsights.AppendLine(@' @@ -10086,7 +10192,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ if ($mgOrSub -eq 'sub') { $grpThisSubscription = $grpPSRuleSubscriptions.where({ $_.Name -eq $subscriptionId }) - $grpThisSubscriptionGrouped = $grpThisSubscription.Group | group-object -Property resourceType, pillar, category, severity, result + $grpThisSubscriptionGrouped = $grpThisSubscription.Group | Group-Object -Property resourceType, pillar, category, severity, rule, result if ($grpThisSubscriptionGrouped) { $grpThisSubscriptionGroupedCount = $grpThisSubscriptionGrouped.Count @@ -10095,7 +10201,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" +$grpThisSubscriptionGroupedCount PSRule for Azure results
   Learn about PSRule for Azure
   Download CSV semicolon | comma @@ -10195,7 +10301,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ } else { [void]$htmlScopeInsights.AppendLine(@' -

No PSRule results

+ No PSRule results '@) } [void]$htmlScopeInsights.AppendLine(@' @@ -10207,7 +10313,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ } else { [void]$htmlScopeInsights.AppendLine(@' -

PSRule for Azure - use parameter -DoPSRule - PSRule for Azure

+ PSRule for Azure - use parameter -DoPSRule - PSRule for Azure '@) } } @@ -10277,7 +10383,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ $randomFunctionName = "func_$htmlTableId" $noteOrNot = '' [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
  *Depending on the number of rows and your computer´s performance the table may respond with delay, download the csv for better filtering experience @@ -10463,7 +10569,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlScopeInsights.AppendLine(@" -

$(($policiesAssigned).count) Policy assignments

+ $(($policiesAssigned).count) Policy assignments "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -10537,7 +10643,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { $randomFunctionName = "func_$htmlTableId" $noteOrNot = '' [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -10709,7 +10815,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlScopeInsights.AppendLine(@" -

$(($policySetsAssigned).count) PolicySet assignments

+ $(($policySetsAssigned).count) PolicySet assignments "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -10731,7 +10837,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { $faimage = "" [void]$htmlScopeInsights.AppendLine(@" -

$faImage Policy Assignment Limit: 0/$limit

+ $faImage Policy Assignment Limit: 0/$limit "@) } else { @@ -10749,7 +10855,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { $faimage = "" } [void]$htmlScopeInsights.AppendLine(@" -

$faImage Policy Assignment Limit: $($scopePolicyAssignmentsLimit.PolicyAndPolicySetAssignmentAtScopeCount)/$($limit)

+ $faImage Policy Assignment Limit: $($scopePolicyAssignmentsLimit.PolicyAndPolicySetAssignmentAtScopeCount)/$($limit) "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -10797,7 +10903,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -10893,7 +10999,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$scopePoliciesCount Custom Policy definitions scoped

+ $scopePoliciesCount Custom Policy definitions scoped "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -10940,7 +11046,7 @@ extensions: [{ name: 'sort' }] } } [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -11024,7 +11130,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$scopePolicySetsCount Custom PolicySet definitions scoped

+ $scopePolicySetsCount Custom PolicySet definitions scoped "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -11047,7 +11153,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_BlueprintAssignment_$($htmlTableIdentifier -replace '\(','_' -replace '\)','_' -replace '-','_' -replace '\.','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -11130,7 +11236,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$blueprintsAssignedCount Blueprints assigned

+ $blueprintsAssignedCount Blueprints assigned "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -11155,7 +11261,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_BlueprintScoped_$($htmlTableIdentifier -replace '\(','_' -replace '\)','_' -replace '-','_' -replace '\.','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -11232,7 +11338,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$blueprintsScopedCount Blueprints scoped

+ $blueprintsScopedCount Blueprints scoped "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -11248,7 +11354,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_ClassicAdministrators_$($subscriptionId -replace '\(','_' -replace '\)','_' -replace '-','_' -replace '\.','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -11318,9 +11424,9 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ "@) } else { - [void]$htmlScopeInsights.AppendLine(@" -

No Classic Administrators

-"@) + [void]$htmlScopeInsights.AppendLine(@' + No Classic Administrators +'@) } [void]$htmlScopeInsights.AppendLine(@' @@ -11433,7 +11539,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ $randomFunctionName = "func_$htmlTableId" $noteOrNot = '' [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
  *Depending on the number of rows and your computer´s performance the table may respond with delay, download the csv for better filtering experience @@ -11558,7 +11664,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlScopeInsights.AppendLine(@" -

$(($rbacAll).count) Role assignments

+ $(($rbacAll).count) Role assignments "@) } @@ -11790,6 +11896,26 @@ function processStorageAccountAnalysis { $publicNetworkAccess = $storageAccount.properties.publicNetworkAccess } + if ([string]::IsNullOrWhiteSpace($storageAccount.properties.allowedCopyScope)) { + $allowedCopyScope = 'From any Storage Account' + } + else { + $allowedCopyScope = $storageAccount.properties.allowedCopyScope + } + + if ([string]::IsNullOrWhiteSpace($storageAccount.properties.allowCrossTenantReplication)) { + if ($allowedCopyScope -ne 'From any Storage Account') { + $allowCrossTenantReplication = "likely disabled (allowedCopyScope=$allowedCopyScope)" + } + else { + $allowCrossTenantReplication = 'likely enabled' + } + } + else { + $allowCrossTenantReplication = $storageAccount.properties.allowCrossTenantReplication + } + + $temp = [System.Collections.ArrayList]@() $null = $temp.Add([PSCustomObject]@{ storageAccount = $storageAccount.name @@ -11826,6 +11952,8 @@ function processStorageAccountAnalysis { minimumTlsVersion = $storageAccount.properties.minimumTlsVersion allowSharedKeyAccess = $allowSharedKeyAccess requireInfrastructureEncryption = $requireInfrastructureEncryption + allowedCopyScope = $allowedCopyScope + allowCrossTenantReplication = $allowCrossTenantReplication }) if ($StorageAccountAccessAnalysisSubscriptionTags[0] -ne 'undefined' -and $StorageAccountAccessAnalysisSubscriptionTags.Count -gt 0) { @@ -13083,7 +13211,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ } else { [void]$htmlTenantSummary.AppendLine(@" -

$tenantCustomPoliciesCount Custom Policy definitions ($scopeNamingSummary)

+

$tenantCustomPoliciesCount Custom Policy definitions ($scopeNamingSummary)

"@) } } @@ -13246,7 +13374,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ } else { [void]$htmlTenantSummary.AppendLine(@" -

$tenantCustomPoliciesCount Custom Policy definitions ($scopeNamingSummary)

+

$tenantCustomPoliciesCount Custom Policy definitions ($scopeNamingSummary)

"@) } } @@ -13369,7 +13497,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($customPoliciesOrphaned).count) Orphaned Custom Policy definitions ($scopeNamingSummary)

+

$(($customPoliciesOrphaned).count) Orphaned Custom Policy definitions ($scopeNamingSummary)

"@) } } @@ -13493,7 +13621,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$($arrayCustomPoliciesOrphanedFinalIncludingResourceGroups.count) Orphaned Custom Policy definitions ($scopeNamingSummary)

+

$($arrayCustomPoliciesOrphanedFinalIncludingResourceGroups.count) Orphaned Custom Policy definitions ($scopeNamingSummary)

"@) } } @@ -13872,7 +14000,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$tenantCustomPolicySetsCount Custom PolicySet definitions ($scopeNamingSummary)

+

$tenantCustomPolicySetsCount Custom PolicySet definitions ($scopeNamingSummary)

"@) } } @@ -14004,7 +14132,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$tenantCustomPolicySetsCount Custom PolicySet definitions ($scopeNamingSummary)

+

$tenantCustomPolicySetsCount Custom PolicySet definitions ($scopeNamingSummary)

"@) } } @@ -14109,7 +14237,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($arraycustompolicySetSetsOrphanedFinalIncludingResourceGroups).count) Orphaned Custom PolicySet definitions ($scopeNamingSummary)

+

$(($arraycustompolicySetSetsOrphanedFinalIncludingResourceGroups).count) Orphaned Custom PolicySet definitions ($scopeNamingSummary)

"@) } } @@ -14228,7 +14356,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($arraycustompolicySetsOrphanedFinalIncludingResourceGroups).count) Orphaned Custom PolicySet definitions ($scopeNamingSummary)

+

$(($arraycustompolicySetsOrphanedFinalIncludingResourceGroups).count) Orphaned Custom PolicySet definitions ($scopeNamingSummary)

"@) } } @@ -14457,13 +14585,13 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@' -

Azure Landing Zones (ALZ) Policy Version Checker

+

Azure Landing Zones (ALZ) Policy Version Checker

'@) } } else { [void]$htmlTenantSummary.AppendLine(@" -

Azure Landing Zones (ALZ) Policy Version Checker (parameter -NoALZPolicyVersionChecker = $NoALZPolicyVersionChecker)

+

Azure Landing Zones (ALZ) Policy Version Checker (parameter -NoALZPolicyVersionChecker = $NoALZPolicyVersionChecker)

"@) } #endregion SUMMARYALZPolicies @@ -14584,7 +14712,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($policySetsDeprecated).count) PolicySets / deprecated Built-in Policy

+

$(($policySetsDeprecated).count) PolicySets / deprecated Built-in Policy

"@) } #endregion SUMMARYPolicySetsDeprecatedPolicy @@ -14736,7 +14864,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($policyAssignmentsDeprecated).count) Policy assignments / deprecated Built-in Policy

+

$(($policyAssignmentsDeprecated).count) Policy assignments / deprecated Built-in Policy

"@) } #endregion SUMMARYPolicyAssignmentsDeprecatedPolicy @@ -15059,7 +15187,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$($policyExemptionsCount) Policy exemptions

+

$($policyExemptionsCount) Policy exemptions

"@) } #endregion SUMMARYPolicyExemptions @@ -15144,7 +15272,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$($policyAssignmentsOrphanedCount) Policy assignments orphaned

+

$($policyAssignmentsOrphanedCount) Policy assignments orphaned

"@) } #endregion SUMMARYPolicyAssignmentsOrphaned @@ -16119,7 +16247,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($arrayPolicyAssignmentsEnriched).count) Policy assignments

+

$(($arrayPolicyAssignmentsEnriched).count) Policy assignments

"@) } $endSummaryPolicyAssignmentsAllHTML = Get-Date @@ -16283,7 +16411,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$tenantCustomRolesCount Custom Role definitions ($scopeNamingSummary)

+

$tenantCustomRolesCount Custom Role definitions ($scopeNamingSummary)

"@) } #endregion SUMMARYtenanttotalcustomroles @@ -16403,7 +16531,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($arrayCustomRolesOrphanedFinalIncludingResourceGroups).count) Orphaned Custom Role definitions ($scopeNamingSummary)

+

$(($arrayCustomRolesOrphanedFinalIncludingResourceGroups).count) Orphaned Custom Role definitions ($scopeNamingSummary)

"@) } #not renant root @@ -16533,7 +16661,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($arrayCustomRolesOrphanedFinalIncludingResourceGroups).count) Orphaned Custom Role definitions ($scopeNamingSummary)

+

$(($arrayCustomRolesOrphanedFinalIncludingResourceGroups).count) Orphaned Custom Role definitions ($scopeNamingSummary)

"@) } } @@ -16632,7 +16760,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($roleAssignmentsOrphanedUnique).count) Orphaned Role assignments ($scopeNamingSummary)

+

$(($roleAssignmentsOrphanedUnique).count) Orphaned Role assignments ($scopeNamingSummary)

"@) } #endregion SUMMARYOrphanedRoleAssignments @@ -16732,7 +16860,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@' -

No ClassicAdministrators

+

No ClassicAdministrators

'@) } #endregion SUMMARYClassicAdministrators @@ -17050,7 +17178,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@" -

$($rbacAllCount) Role assignments

+

$($rbacAllCount) Role assignments

"@) } @@ -17205,7 +17333,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@' -

No PIM Eligibility

+

No PIM Eligibility

'@) } @@ -17215,12 +17343,12 @@ extensions: [{ name: 'sort' }] else { if ($azAPICallConf['htParameters'].accountType -ne 'User' -and $NoPIMEligibility) { [void]$htmlTenantSummary.AppendLine(@" -

No PIM Eligibility - parameter -NoPIMEligibility = $NoPIMEligibility

+

No PIM Eligibility - parameter -NoPIMEligibility = $NoPIMEligibility

"@) } else { [void]$htmlTenantSummary.AppendLine(@' -

No PIM Eligibility - run AzGovViz with a Service Principal to get PIM Eligibility insights

+

No PIM Eligibility - run AzGovViz with a Service Principal to get PIM Eligibility insights

'@) } } @@ -17324,7 +17452,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($customRolesOwnerHtAll).count) Custom Role definitions Owner permissions ($scopeNamingSummary)

+

$(($customRolesOwnerHtAll).count) Custom Role definitions Owner permissions ($scopeNamingSummary)

"@) } #endregion SUMMARYSecurityCustomRoles @@ -17445,7 +17573,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$($tenantAllRolesCanDoRoleAssignmentsCount) Role definitions can apply Role assignments

+

$($tenantAllRolesCanDoRoleAssignmentsCount) Role definitions can apply Role assignments

"@) } #endregion SUMMARYSecurityRolesCanDoRoleAssignments @@ -17544,7 +17672,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($roleAssignmentsOwnerAssignmentSP).count) Owner permission assignments to ServicePrincipal ($scopeNamingSummary)

+

$(($roleAssignmentsOwnerAssignmentSP).count) Owner permission assignments to ServicePrincipal ($scopeNamingSummary)

"@) } $endSUMMARYSecurityOwnerAssignmentSP = Get-Date @@ -17657,7 +17785,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($roleAssignmentsOwnerAssignmentNotGroup).count) Owner permission assignments to notGroup ($scopeNamingSummary)

+

$(($roleAssignmentsOwnerAssignmentNotGroup).count) Owner permission assignments to notGroup ($scopeNamingSummary)

"@) } $endSUMMARYSecurityOwnerAssignmentNotGroup = Get-Date @@ -17768,7 +17896,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($roleAssignmentsUserAccessAdministratorAssignmentNotGroup).count) UserAccessAdministrator permission assignments to notGroup ($scopeNamingSummary)

+

$(($roleAssignmentsUserAccessAdministratorAssignmentNotGroup).count) UserAccessAdministrator permission assignments to notGroup ($scopeNamingSummary)

"@) } $endSUMMARYSecurityUserAccessAdministratorAssignmentNotGroup = Get-Date @@ -17882,7 +18010,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$($highPrivilegedGuestUserRoleAssignmentsCount) Guest Users with high permissions ($scopeNamingSummary)

+

$($highPrivilegedGuestUserRoleAssignmentsCount) Guest Users with high permissions ($scopeNamingSummary)

"@) } $endSUMMARYSecurityGuestUserHighPriviledgesAssignments = Get-Date @@ -18188,7 +18316,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$blueprintDefinitionsOrphanedCount Orphaned Blueprint definitions

+

$blueprintDefinitionsOrphanedCount Orphaned Blueprint definitions

"@) } #endregion SUMMARYBlueprintsOrphaned @@ -18434,14 +18562,14 @@ extensions: [{ name: 'sort' }] #region SUMMARYMGdefault Write-Host ' processing TenantSummary ManagementGroups - default Management Group' [void]$htmlTenantSummary.AppendLine(@" -

Hierarchy Settings | Default Management Group Id: '$($defaultManagementGroupId)' docs

+

Hierarchy Settings | Default Management Group Id: '$($defaultManagementGroupId)' docs

"@) #endregion SUMMARYMGdefault #region SUMMARYMGRequireAuthorizationForGroupCreation Write-Host ' processing TenantSummary ManagementGroups - requireAuthorizationForGroupCreation Management Group' [void]$htmlTenantSummary.AppendLine(@" -

Hierarchy Settings | Require authorization for Management Group creation: '$($requireAuthorizationForGroupCreation)' docs

+

Hierarchy Settings | Require authorization for Management Group creation: '$($requireAuthorizationForGroupCreation)' docs

"@) #endregion SUMMARYMGRequireAuthorizationForGroupCreation @@ -18779,7 +18907,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$outOfScopeSubscriptionsCount Subscriptions out-of-scope

+

$outOfScopeSubscriptionsCount Subscriptions out-of-scope

"@) } #endregion SUMMARYOutOfScopeSubscriptions @@ -18870,7 +18998,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

Tag Name Usage ($tagsUsageCount Tags) docs

+

Tag Name Usage ($tagsUsageCount Tags) docs

"@) } #endregion SUMMARYTagNameUsage @@ -18963,14 +19091,14 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

Resources ($resourcesResourceTypeCount ResourceTypes)

+

Resources ($resourcesResourceTypeCount ResourceTypes)

"@) } } else { [void]$htmlTenantSummary.AppendLine(@' -

Resources (0 ResourceTypes)

+

Resources (0 ResourceTypes)

'@) } $endSUMMARYResources = Get-Date @@ -19069,14 +19197,14 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

Resources ($resourcesResourceTypeCount ResourceTypes)

+

Resources ($resourcesResourceTypeCount ResourceTypes)

"@) } } else { [void]$htmlTenantSummary.AppendLine(@' -

Resources (0 ResourceTypes)

+

Resources (0 ResourceTypes)

'@) } $endSUMMARYResources = Get-Date @@ -19312,7 +19440,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@' -

No CAF Naming Recommendation Compliance data

+

No CAF Naming Recommendation Compliance data

'@) } $endSUMMARYCAFResourceNamingALL = Get-Date @@ -19456,7 +19584,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@' -

No Orphaned Resources

+

No Orphaned Resources

'@) } $endSUMMARYOrphanedResources = Get-Date @@ -19613,7 +19741,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$resourceProvidersAllCount Resource Providers

+

$resourceProvidersAllCount Resource Providers

"@) } $endSUMMARYSubResourceProviders = Get-Date @@ -19766,7 +19894,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$resourceProvidersAllCount Resource Providers

+

$resourceProvidersAllCount Resource Providers

"@) } $endsumRPDetailed = Get-Date @@ -19872,7 +20000,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@' -

No enabled Subscriptions Features docs

+

No enabled Subscriptions Features docs

'@) } $endSubFeatures = Get-Date @@ -19967,7 +20095,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@' -

No Resource Locks at all docs

+

No Resource Locks at all docs

'@) } $endResourceLocks = Get-Date @@ -20721,6 +20849,8 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: {
+ + @@ -20757,6 +20887,8 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { + + "@) @@ -20813,6 +20945,8 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { col_24: 'select', col_25: 'select', col_26: 'select', + col_27: 'select', + col_28: 'select', col_types: [ 'caseinsensitivestring', 'caseinsensitivestring', @@ -20840,6 +20974,8 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { 'caseinsensitivestring', 'caseinsensitivestring', 'caseinsensitivestring', + 'caseinsensitivestring', + 'caseinsensitivestring', 'caseinsensitivestring' ], extensions: [{ name: 'sort' }] @@ -20860,7 +20996,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@" -

Storage Account Access Analysis disabled - parameter -NoStorageAccountAccessAnalysis = $($azAPICallConf['htParameters'].NoStorageAccountAccessAnalysis)

+

Storage Account Access Analysis disabled - parameter -NoStorageAccountAccessAnalysis = $($azAPICallConf['htParameters'].NoStorageAccountAccessAnalysis)

"@) } #endregion SUMMARYStorageAccountAnalysis @@ -21018,7 +21154,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@' -

No Virtual Networks

+

No Virtual Networks

'@) } $endVNets = Get-Date @@ -21026,7 +21162,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@" -

Virtual Networks - Network Analysis disabled - parameter -NoNetwork = $($azAPICallConf['htParameters'].NoNetwork)

+

Virtual Networks - Network Analysis disabled - parameter -NoNetwork = $($azAPICallConf['htParameters'].NoNetwork)

"@) } #endregion SUMMARYVNets @@ -21198,7 +21334,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@' -

No Subnets

+

No Subnets

'@) } $endSubnets = Get-Date @@ -21206,7 +21342,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@" -

Subnets - Network Analysis disabled - parameter -NoNetwork = $($azAPICallConf['htParameters'].NoNetwork)

+

Subnets - Network Analysis disabled - parameter -NoNetwork = $($azAPICallConf['htParameters'].NoNetwork)

"@) } #endregion SUMMARYSubnets @@ -21513,7 +21649,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@' -

No Virtual Network Peerings

+

No Virtual Network Peerings

'@) } $endVNetPeerings = Get-Date @@ -21521,7 +21657,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@" -

Virtual Network Peerings - Network Analysis disabled - parameter -NoNetwork = $($azAPICallConf['htParameters'].NoNetwork)

+

Virtual Network Peerings - Network Analysis disabled - parameter -NoNetwork = $($azAPICallConf['htParameters'].NoNetwork)

"@) } #endregion SUMMARYVNetPeerings @@ -21546,11 +21682,16 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { if ($crossSubPECount -gt 0) { $crossSubPEText = " ($crossSubPECount cross Subscription)" } + $crossTenantPECount = ($privateEndPoints.where({ $_.crossTenantPE -eq $true })).Count + $crossTenantPEText = '' + if ($crossTenantPECount -gt 0) { + $crossTenantPEText = " ($crossTenantPECount cross Tenant)" + } $htmlTableId = 'TenantSummary_PrivateEndpoints' $tfCount = $privateEndPointsCount [void]$htmlTenantSummary.AppendLine(@" - +
Download CSV semicolon | comma
Minimum Tls Version Allow SharedKey Access Require Infrastructure EncryptionAllowed Copy ScopeAllow Cross Tenant Replication
$($result.minimumTlsVersion) $($result.allowSharedKeyAccess) $($result.requireInfrastructureEncryption)$($result.allowedCopyScope)$($result.allowCrossTenantReplication)
@@ -21567,6 +21708,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { + @@ -21608,6 +21750,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { + @@ -21675,9 +21818,10 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { col_7: 'select', col_8: 'select', col_9: 'select', - col_11: 'select', - col_13: 'select', - col_25: 'select', + col_10: 'select', + col_12: 'select', + col_14: 'select', + col_26: 'select', col_types: [ 'caseinsensitivestring', 'caseinsensitivestring', @@ -21707,6 +21851,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { 'caseinsensitivestring', 'caseinsensitivestring', 'caseinsensitivestring', + 'caseinsensitivestring', 'caseinsensitivestring' ], extensions: [{ name: 'sort' }] @@ -21719,7 +21864,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@' -

No Private Endpoints

+

No Private Endpoints

'@) } $endPrivateEndpoints = Get-Date @@ -21727,7 +21872,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@" -

Private Endpoints - Network Analysis disabled - parameter -NoNetwork = $($azAPICallConf['htParameters'].NoNetwork)

+

Private Endpoints - Network Analysis disabled - parameter -NoNetwork = $($azAPICallConf['htParameters'].NoNetwork)

"@) } #endregion SUMMARYPrivateEndpoints @@ -21746,7 +21891,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { '@) [void]$htmlTenantSummary.AppendLine( @' -

Management Groups

+

Management Groups

'@) #region SUMMARYDiagnosticsManagementGroups @@ -21757,10 +21902,10 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { $tfCount = $diagnosticSettingsMgCount $htmlTableId = 'TenantSummary_DiagnosticsManagementGroups' [void]$htmlTenantSummary.AppendLine(@" - +
- Management Group Diagnostic Settings - Create Or Update - REST API docs
- Download CSV semicolon | comma + Management Group Diagnostic Settings - Create Or Update - REST API docs
+ Download CSV semicolon | comma
PE Type PE State Cross Subscription PECross Tenant PE Resource Resource Type$($result.PEConnectionType) $($result.PEConnectionState) $($result.CrossSubscriptionPE)$($result.CrossTenantPE) $($result.Resource) $($result.ResourceType)
@@ -21897,7 +22042,7 @@ extensions: [{ name: 'sort' }] else { [void]$htmlTenantSummary.AppendLine(@' -

No Management Groups configured for Diagnostic settings docs

+

No Management Groups configured for Diagnostic settings docs

'@) } @@ -21906,10 +22051,10 @@ extensions: [{ name: 'sort' }] $tfCount = $arrayMgsWithoutDiagnosticsCount $htmlTableId = 'TenantSummary_NoDiagnosticsManagementGroups' [void]$htmlTenantSummary.AppendLine(@" - +
- Management Group Diagnostic Settings - Create Or Update - REST API docs
- Download CSV semicolon | comma + Management Group Diagnostic Settings - Create Or Update - REST API docs
+ Download CSV semicolon | comma
@@ -21983,14 +22128,14 @@ extensions: [{ name: 'sort' }] else { [void]$htmlTenantSummary.AppendLine(@' -

All Management Groups are configured for Diagnostic settings docs

+

All Management Groups are configured for Diagnostic settings docs

'@) } #endregion SUMMARYDiagnosticsManagementGroups #region subscriptions [void]$htmlTenantSummary.AppendLine( @' -

Subscriptions

+

Subscriptions

'@) #region SUMMARYDiagnosticsSubscriptions @@ -22001,10 +22146,10 @@ extensions: [{ name: 'sort' }] $tfCount = $diagnosticSettingsSubCount $htmlTableId = 'TenantSummary_DiagnosticsSubscriptions' [void]$htmlTenantSummary.AppendLine(@" - +
- Create diagnostic setting docs
- Download CSV semicolon | comma + Create diagnostic setting docs
+ Download CSV semicolon | comma
@@ -22137,7 +22282,7 @@ extensions: [{ name: 'sort' }] else { [void]$htmlTenantSummary.AppendLine(@' -

No Subscriptions configured for Diagnostic settings docs

+

No Subscriptions configured for Diagnostic settings docs

'@) } @@ -22146,10 +22291,10 @@ extensions: [{ name: 'sort' }] $tfCount = $diagnosticSettingsSubNoDiagCount $htmlTableId = 'TenantSummary_NoDiagnosticsSubscriptions' [void]$htmlTenantSummary.AppendLine(@" - +
- Create diagnostic setting docs
- Download CSV semicolon | comma + Create diagnostic setting docs
+ Download CSV semicolon | comma
@@ -22223,7 +22368,7 @@ extensions: [{ name: 'sort' }] else { [void]$htmlTenantSummary.AppendLine(@' -

All Subscriptions are configured for Diagnostic settings docs

+

All Subscriptions are configured for Diagnostic settings docs

'@) } #endregion SUMMARYDiagnosticsSubscriptions @@ -22233,7 +22378,7 @@ extensions: [{ name: 'sort' }] if ($azAPICallConf['htParameters'].NoResources -eq $false) { #region resources [void]$htmlTenantSummary.AppendLine( @' -

Resources

+

Resources

'@) #region SUMMARYResourcesDiagnosticsCapable @@ -22247,11 +22392,11 @@ extensions: [{ name: 'sort' }] $tfCount = $resourceTypesDiagnosticsArraySortedCount $htmlTableId = 'TenantSummary_ResourcesDiagnosticsCapable' [void]$htmlTenantSummary.AppendLine(@" - +
- Create Custom Policies for Azure ResourceTypes that support Diagnostics Logs and Metrics Create-AzDiagPolicy
- Supported categories for Azure Resource Logs docs
- Download CSV semicolon | comma + Create Custom Policies for Azure ResourceTypes that support Diagnostics Logs and Metrics Create-AzDiagPolicy
+ Supported categories for Azure Resource Logs docs
+ Download CSV semicolon | comma
@@ -22348,7 +22493,7 @@ extensions: [{ name: 'sort' }] else { [void]$htmlTenantSummary.AppendLine(@' -

No Resources (1st party) Diagnostics capable

+

No Resources (1st party) Diagnostics capable

'@) } #endregion SUMMARYResourcesDiagnosticsCapable @@ -22606,10 +22751,10 @@ extensions: [{ name: 'sort' }] $htmlTableId = 'TenantSummary_DiagnosticsLifecycle' [void]$htmlTenantSummary.AppendLine(@" - +
- Create Custom Policies for Azure ResourceTypes that support Diagnostics Logs and Metrics Create-AzDiagPolicy
- Supported categories for Azure Resource Logs docs + Create Custom Policies for Azure ResourceTypes that support Diagnostics Logs and Metrics Create-AzDiagPolicy
+ Supported categories for Azure Resource Logs docs
@@ -22741,19 +22886,19 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@' -

No ResourceDiagnostics Policy Lifecycle recommendations

+

No ResourceDiagnostics Policy Lifecycle recommendations

'@) } } else { [void]$htmlTenantSummary.AppendLine(@' -

No ResourceDiagnostics Policy Lifecycle recommendations

+

No ResourceDiagnostics Policy Lifecycle recommendations

'@) } } else { [void]$htmlTenantSummary.AppendLine(@' -

No ResourceDiagnostics Policy Lifecycle recommendations

+

No ResourceDiagnostics Policy Lifecycle recommendations

'@) } $endsumDiagLifecycle = Get-Date @@ -22780,30 +22925,30 @@ extensions: [{ name: 'sort' }] #region tenantSummaryLimitsTenant [void]$htmlTenantSummary.AppendLine( @' -

Tenant

+

Tenant

'@) #policySets if ($tenantCustompolicySetsCount -gt (($LimitPOLICYPolicySetDefinitionsScopedTenant * $LimitCriticalPercentage) / 100)) { [void]$htmlTenantSummary.AppendLine(@" -

PolicySet definitions: $tenantCustompolicySetsCount/$LimitPOLICYPolicySetDefinitionsScopedTenant docs

+

PolicySet definitions: $tenantCustompolicySetsCount/$LimitPOLICYPolicySetDefinitionsScopedTenant docs

"@) } else { [void]$htmlTenantSummary.AppendLine(@" -

PolicySet definitions: $tenantCustompolicySetsCount/$LimitPOLICYPolicySetDefinitionsScopedTenant docs

+

PolicySet definitions: $tenantCustompolicySetsCount/$LimitPOLICYPolicySetDefinitionsScopedTenant docs

"@) } #CustomRoleDefinitions if ($tenantCustomRolesCount -gt (($LimitRBACCustomRoleDefinitionsTenant * $LimitCriticalPercentage) / 100)) { [void]$htmlTenantSummary.AppendLine(@" -

Custom Role definitions: $tenantCustomRolesCount/$LimitRBACCustomRoleDefinitionsTenant docs

+

Custom Role definitions: $tenantCustomRolesCount/$LimitRBACCustomRoleDefinitionsTenant docs

"@) } else { [void]$htmlTenantSummary.AppendLine(@" -

Custom Role definitions: $tenantCustomRolesCount/$LimitRBACCustomRoleDefinitionsTenant docs

+

Custom Role definitions: $tenantCustomRolesCount/$LimitRBACCustomRoleDefinitionsTenant docs

"@) } @@ -22811,7 +22956,7 @@ extensions: [{ name: 'sort' }] #region tenantSummaryLimitsManagementGroups [void]$htmlTenantSummary.AppendLine( @' -

Management Groups

+

Management Groups

'@) #region SUMMARYMgsapproachingLimitsPolicyAssignments @@ -22821,10 +22966,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($mgsApproachingLimitPolicyAssignments | Measure-Object).count $htmlTableId = 'TenantSummary_MgsapproachingLimitsPolicyAssignments' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure Policy Limits docs
- Download CSV semicolon | comma + Azure Policy Limits docs
+ Download CSV semicolon | comma
@@ -22896,7 +23041,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($mgsApproachingLimitPolicyAssignments | Measure-Object).count) Management Groups approaching Limit ($LimitPOLICYPolicyAssignmentsManagementGroup) for PolicyAssignment docs

+

$(($mgsApproachingLimitPolicyAssignments | Measure-Object).count) Management Groups approaching Limit ($LimitPOLICYPolicyAssignmentsManagementGroup) for PolicyAssignment docs

"@) } #endregion SUMMARYMgsapproachingLimitsPolicyAssignments @@ -22908,10 +23053,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($mgsApproachingLimitPolicyScope | Measure-Object).count $htmlTableId = 'TenantSummary_MgsapproachingLimitsPolicyScope' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure Policy Limits docs
- Download CSV semicolon | comma + Azure Policy Limits docs
+ Download CSV semicolon | comma
@@ -22983,7 +23128,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$($mgsApproachingLimitPolicyScope.count) Management Groups approaching Limit ($LimitPOLICYPolicyDefinitionsScopedManagementGroup) for Policy Scope docs

+

$($mgsApproachingLimitPolicyScope.count) Management Groups approaching Limit ($LimitPOLICYPolicyDefinitionsScopedManagementGroup) for Policy Scope docs

"@) } #endregion SUMMARYMgsapproachingLimitsPolicyScope @@ -22995,10 +23140,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($mgsApproachingLimitPolicySetScope | Measure-Object).count $htmlTableId = 'TenantSummary_MgsapproachingLimitsPolicySetScope' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure Policy Limits docs
- Download CSV semicolon | comma + Azure Policy Limits docs
+ Download CSV semicolon | comma
@@ -23070,7 +23215,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($mgsApproachingLimitPolicySetScope | Measure-Object).count) Management Groups approaching Limit ($LimitPOLICYPolicySetDefinitionsScopedManagementGroup) for PolicySet Scope docs

+

$(($mgsApproachingLimitPolicySetScope | Measure-Object).count) Management Groups approaching Limit ($LimitPOLICYPolicySetDefinitionsScopedManagementGroup) for PolicySet Scope docs

"@) } #endregion SUMMARYMgsapproachingLimitsPolicySetScope @@ -23083,10 +23228,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($mgsApproachingRoleAssignmentLimit).count $htmlTableId = 'TenantSummary_MgsapproachingLimitsRoleAssignment' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure RBAC Limits docs
- Download CSV semicolon | comma + Azure RBAC Limits docs
+ Download CSV semicolon | comma
@@ -23158,7 +23303,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($mgApproachingRoleAssignmentLimit | Measure-Object).count) Management Groups approaching Limit ($LimitRBACRoleAssignmentsManagementGroup) for RoleAssignment docs

+

$(($mgApproachingRoleAssignmentLimit | Measure-Object).count) Management Groups approaching Limit ($LimitRBACRoleAssignmentsManagementGroup) for RoleAssignment docs

"@) } #endregion SUMMARYMgsapproachingLimitsRoleAssignment @@ -23167,7 +23312,7 @@ extensions: [{ name: 'sort' }] #region tenantSummaryLimitsSubscriptions [void]$htmlTenantSummary.AppendLine( @' -

Subscriptions

+

Subscriptions

'@) #region SUMMARYSubsapproachingLimitsResourceGroups @@ -23177,10 +23322,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($subscriptionsApproachingLimitFromResourceGroupsAll | Measure-Object).count $htmlTableId = 'TenantSummary_SubsapproachingLimitsResourceGroups' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure Subscription Resource Group Limit docs
- Download CSV semicolon | comma + Azure Subscription Resource Group Limit docs
+ Download CSV semicolon | comma
@@ -23253,7 +23398,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" - $(($subscriptionsApproachingLimitFromResourceGroupsAll | Measure-Object).count) Subscriptions approaching Limit ($LimitResourceGroups) for ResourceGroups docs

+ $(($subscriptionsApproachingLimitFromResourceGroupsAll | Measure-Object).count) Subscriptions approaching Limit ($LimitResourceGroups) for ResourceGroups docs

"@) } #endregion SUMMARYSubsapproachingLimitsResourceGroups @@ -23265,10 +23410,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($subscriptionsApproachingLimitTags | Measure-Object).count $htmlTableId = 'TenantSummary_SubsapproachingLimitsSubscriptionTags' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure Subscription Tag Limit docs
- Download CSV semicolon | comma + Azure Subscription Tag Limit docs
+ Download CSV semicolon | comma
@@ -23340,7 +23485,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$($subscriptionsApproachingLimitTags.count) Subscriptions approaching Limit ($LimitTagsSubscription) for Tags docs

+

$($subscriptionsApproachingLimitTags.count) Subscriptions approaching Limit ($LimitTagsSubscription) for Tags docs

"@) } #endregion SUMMARYSubsapproachingLimitsSubscriptionTags @@ -23352,10 +23497,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($subscriptionsApproachingLimitPolicyAssignments | Measure-Object).count $htmlTableId = 'TenantSummary_SubsapproachingLimitsPolicyAssignments' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure Policy Limits docs
- Download CSV semicolon | comma + Azure Policy Limits docs
+ Download CSV semicolon | comma
@@ -23427,7 +23572,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($subscriptionsApproachingLimitPolicyAssignments | Measure-Object).count) Subscriptions approaching Limit ($LimitPOLICYPolicyAssignmentsSubscription) for PolicyAssignment docs

+

$(($subscriptionsApproachingLimitPolicyAssignments | Measure-Object).count) Subscriptions approaching Limit ($LimitPOLICYPolicyAssignmentsSubscription) for PolicyAssignment docs

"@) } #endregion SUMMARYSubsapproachingLimitsPolicyAssignments @@ -23439,10 +23584,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($subscriptionsApproachingLimitPolicyScope | Measure-Object).count $htmlTableId = 'TenantSummary_SubsapproachingLimitsPolicyScope' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure Policy Limits docs
- Download CSV semicolon | comma + Azure Policy Limits docs
+ Download CSV semicolon | comma
@@ -23514,7 +23659,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$($subscriptionsApproachingLimitPolicyScope.count) Subscriptions approaching Limit ($LimitPOLICYPolicyDefinitionsScopedSubscription) for Policy Scope docs

+

$($subscriptionsApproachingLimitPolicyScope.count) Subscriptions approaching Limit ($LimitPOLICYPolicyDefinitionsScopedSubscription) for Policy Scope docs

"@) } #endregion SUMMARYSubsapproachingLimitsPolicyScope @@ -23526,10 +23671,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($subscriptionsApproachingLimitPolicySetScope | Measure-Object).count $htmlTableId = 'TenantSummary_SubsapproachingLimitsPolicySetScope' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure Policy Limits docs
- Download CSV semicolon | comma + Azure Policy Limits docs
+ Download CSV semicolon | comma
@@ -23601,7 +23746,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($subscriptionsApproachingLimitPolicyScope | Measure-Object).count) Subscriptions approaching Limit ($LimitPOLICYPolicySetDefinitionsScopedSubscription) for PolicySet Scope docs

+

$(($subscriptionsApproachingLimitPolicyScope | Measure-Object).count) Subscriptions approaching Limit ($LimitPOLICYPolicySetDefinitionsScopedSubscription) for PolicySet Scope docs

"@) } #endregion SUMMARYSubsapproachingLimitsPolicySetScope @@ -23616,10 +23761,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($subscriptionsApproachingRoleAssignmentLimit).count $htmlTableId = 'TenantSummary_SubsapproachingLimitsRoleAssignment' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure RBAC Limits docs
- Download CSV semicolon | comma + Azure RBAC Limits docs
+ Download CSV semicolon | comma
@@ -23691,7 +23836,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" - $(($subscriptionsApproachingRoleAssignmentLimit | Measure-Object).count) Subscriptions approaching Limit ($availableSubscriptionsRoleAssignmentLimits) for RoleAssignment docs

+ $(($subscriptionsApproachingRoleAssignmentLimit | Measure-Object).count) Subscriptions approaching Limit ($availableSubscriptionsRoleAssignmentLimits) for RoleAssignment docs

"@) } #endregion SUMMARYSubsapproachingLimitsRoleAssignment @@ -23790,7 +23935,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@' -

No ServicePrincipals where the API returned 'Request_ResourceNotFound'

+

No ServicePrincipals where the API returned 'Request_ResourceNotFound'

'@) } #endregion AADSPNotFound @@ -23871,7 +24016,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@' -

No Applications where the API returned 'Request_ResourceNotFound'

+

No Applications where the API returned 'Request_ResourceNotFound'

'@) } #endregion AADAppNotFound @@ -24189,7 +24334,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$servicePrincipalsOfTypeManagedIdentityCount AAD ServicePrincipals type=ManagedIdentity

+

$servicePrincipalsOfTypeManagedIdentityCount AAD ServicePrincipals type=ManagedIdentity

"@) } @@ -24359,7 +24504,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$servicePrincipalsOfTypeApplicationCount AAD ServicePrincipals type=Application

+

$servicePrincipalsOfTypeApplicationCount AAD ServicePrincipals type=Application

"@) } @@ -24368,7 +24513,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@' -

No information on AAD ServicePrincipals type=Application as Guest account does not have enough permissions

+

No information on AAD ServicePrincipals type=Application as Guest account does not have enough permissions

'@) } #endregion AADSPCredExpiry @@ -24498,7 +24643,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$appsWithOtherOrgIdCount External (appOwnerOrganizationId) AAD ServicePrincipals type=Application

+

$appsWithOtherOrgIdCount External (appOwnerOrganizationId) AAD ServicePrincipals type=Application

"@) } @@ -24615,7 +24760,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@' -

No information on Consumption

+

No information on Consumption

'@) } @@ -24625,7 +24770,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@' -

No information on Consumption as switch parameter -DoAzureConsumption was not applied

+

No information on Consumption as switch parameter -DoAzureConsumption was not applied

'@) } @@ -24968,7 +25113,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$customPolicyCreatedOrUpdatedCount Created/Updated custom Policy definitions

+

$customPolicyCreatedOrUpdatedCount Created/Updated custom Policy definitions

"@) } #endregion ChangeTrackingCustomPolicy @@ -25117,7 +25262,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$customPolicySetCreatedOrUpdatedCount Created/Updated custom PolicySet definitions

+

$customPolicySetCreatedOrUpdatedCount Created/Updated custom PolicySet definitions

"@) } #endregion ChangeTrackingCustomPolicySet @@ -25413,7 +25558,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$policyAssignmentsCreatedOrUpdatedCount Created/Updated Policy assignments

+

$policyAssignmentsCreatedOrUpdatedCount Created/Updated Policy assignments

"@) } #endregion ChangeTrackingPolicyAssignments @@ -25559,7 +25704,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$customRoleDefinitionsCreatedOrUpdatedCount Created/Updated custom Role definitions

+

$customRoleDefinitionsCreatedOrUpdatedCount Created/Updated custom Role definitions

"@) } #endregion ChangeTrackingCustomRoles @@ -25732,7 +25877,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$customRoleDefinitionsCreatedOrUpdatedCount Created/Updated custom Role definitions

+

$customRoleDefinitionsCreatedOrUpdatedCount Created/Updated custom Role definitions

"@) } #endregion ChangeTrackingRoleAssignments @@ -25856,7 +26001,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$resourcesCreatedOrChangedCount Created/Changed Resources

+

$resourcesCreatedOrChangedCount Created/Changed Resources

"@) } #endregion ChangeTrackingResources @@ -25893,7 +26038,7 @@ tf.init();}} $tfCount = $namingPolicyCount $htmlTableId = 'TenantSummary_NamingPolicy' [void]$htmlTenantSummary.AppendLine(@" - +
Download CSV semicolon | comma
@@ -25995,7 +26140,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

Policy $($namingPolicyCount) Naming findings

+

Policy $($namingPolicyCount) Naming findings

"@) } @@ -26004,7 +26149,7 @@ extensions: [{ name: 'sort' }] $tfCount = $namingPolicySetCount $htmlTableId = 'TenantSummary_NamingPolicySet' [void]$htmlTenantSummary.AppendLine(@" - +
Download CSV semicolon | comma
@@ -26106,7 +26251,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

PolicySet $($namingPolicySetCount) Naming findings

+

PolicySet $($namingPolicySetCount) Naming findings

"@) } @@ -26115,7 +26260,7 @@ extensions: [{ name: 'sort' }] $tfCount = $namingPolicyAssignmentCount $htmlTableId = 'TenantSummary_NamingPolicyAssignment' [void]$htmlTenantSummary.AppendLine(@" - +
Download CSV semicolon | comma
@@ -26217,7 +26362,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

Policy assignment $($namingPolicyAssignmentCount) Naming findings

+

Policy assignment $($namingPolicyAssignmentCount) Naming findings

"@) } @@ -26226,7 +26371,7 @@ extensions: [{ name: 'sort' }] $tfCount = $namingManagementGroupCount $htmlTableId = 'TenantSummary_NamingManagementGroup' [void]$htmlTenantSummary.AppendLine(@" - +
Download CSV semicolon | comma
@@ -26312,7 +26457,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

Management Group $($namingManagementGroupCount) Naming findings

+

Management Group $($namingManagementGroupCount) Naming findings

"@) } @@ -26322,7 +26467,7 @@ extensions: [{ name: 'sort' }] $tfCount = $namingSubscriptionCount $htmlTableId = 'TenantSummary_NamingSubscription' [void]$htmlTenantSummary.AppendLine(@" - +
Download CSV semicolon | comma
@@ -26407,7 +26552,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

Subscription $($namingSubscriptionCount) Naming findings

+

Subscription $($namingSubscriptionCount) Naming findings

"@) } @@ -26417,7 +26562,7 @@ extensions: [{ name: 'sort' }] $tfCount = $namingRoleCount $htmlTableId = 'TenantSummary_NamingRole' [void]$htmlTenantSummary.AppendLine(@" - +
Download CSV semicolon | comma
@@ -26502,7 +26647,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

RBAC $($namingRoleCount) Naming Findings

+

RBAC $($namingRoleCount) Naming Findings

"@) } @@ -28265,63 +28410,74 @@ function dataCollectionResources { $subscriptionQuotaId ) + #region resources LIST $currentTask = "Getting Resources for Subscription: '$($scopeDisplayName)' ('$scopeId') [quotaId:'$subscriptionQuotaId']" $uri = "$($azAPICallConf['azAPIEndpointUrls'].ARM)/subscriptions/$($scopeId)/resources?`$expand=createdTime,changedTime,properties&api-version=2021-04-01" $method = 'GET' $resourcesSubscriptionResult = AzAPICall -AzAPICallConfiguration $azAPICallConf -uri $uri -method $method -currentTask $currentTask -caller 'CustomDataCollection' #Write-Host 'arm resList count:'$resourcesSubscriptionResult.Count + #endregion resources LIST + + #region resources GET + if ($resourcesSubscriptionResult.Count -gt 0) { + $arrayResourcesWithProperties = [System.Collections.ArrayList]::Synchronized((New-Object System.Collections.ArrayList)) + $resourcesSubscriptionResult | ForEach-Object -Parallel { + $resource = $_ + + #region using + $arrayResourcesWithProperties = $using:arrayResourcesWithProperties + $htResourceProvidersRef = $using:htResourceProvidersRef + $arrayPrivateEndPointsFromResourceProperties = $using:arrayPrivateEndPointsFromResourceProperties + $scopeId = $using:scopeId + $scopeDisplayName = $using:scopeDisplayName + $ChildMgParentNameChainDelimited = $using:ChildMgParentNameChainDelimited + $azAPICallConf = $using:azAPICallConf + #endregion using - #region PSRule - if ($azAPICallConf['htParameters'].DoPSRule -eq $true) { - if ($resourcesSubscriptionResult.Count -gt 0) { - - $arrayResourcesWithProperties = [System.Collections.ArrayList]::Synchronized((New-Object System.Collections.ArrayList)) - $resourcesSubscriptionResult | ForEach-Object -Parallel { - $resource = $_ - $resourceId = $resource.id - $arrayResourcesWithProperties = $using:arrayResourcesWithProperties - $azAPICallConf = $using:azAPICallConf - $htResourceProvidersRef = $using:htResourceProvidersRef - - if ($htResourceProvidersRef.($resource.type)) { - $apiVersionToUse = $htResourceProvidersRef.($resource.type).APIFirst - $currentTask = "Getting Resource for PSRule API-version: '$apiVersionToUse'; ResourceType: '$($resource.type)'; ResourceId: '$resourceId'" - $uri = "$($azAPICallConf['azAPIEndpointUrls'].ARM)$($resourceId)?api-version=$apiVersionToUse" - $method = 'GET' - $resourceResult = AzAPICall -AzAPICallConfiguration $azAPICallConf -uri $uri -method $method -currentTask $currentTask -caller 'CustomDataCollection' -listenOn Content -unhandledErrorAction Continue - if ($resourceResult -ne 'ResourceOrResourcegroupNotFound') { - $null = $script:arrayResourcesWithProperties.Add($resourceResult) + if ($htResourceProvidersRef.($resource.type)) { + $apiVersionToUse = $htResourceProvidersRef.($resource.type).APIFirst + $currentTask = "Getting Resource for PSRule API-version: '$apiVersionToUse'; ResourceType: '$($resource.type)'; ResourceId: '$($resource.id)'" + $uri = "$($azAPICallConf['azAPIEndpointUrls'].ARM)$($resource.id)?api-version=$apiVersionToUse" + $method = 'GET' + $resourceResult = AzAPICall -AzAPICallConfiguration $azAPICallConf -uri $uri -method $method -currentTask $currentTask -caller 'CustomDataCollection' -listenOn Content -unhandledErrorAction Continue + + if ($resourceResult -ne 'ResourceOrResourcegroupNotFound') { + $null = $script:arrayResourcesWithProperties.Add($resourceResult) + + if ($resourceResult.properties.privateEndpointConnections.Count -gt 0) { + foreach ($privateEndpointConnection in $resourceResult.properties.privateEndpointConnections) { + $resourceResultIdSplit = $resourceResult.id -split '/' + $null = $script:arrayPrivateEndPointsFromResourceProperties.Add([PSCustomObject]@{ + ResourceName = $resourceResult.name + ResourceType = $resourceResult.type + ResourceId = $resourceResult.id + ResourceResourceGroup = $resourceResultIdSplit[4] + ResourceSubscriptionId = $scopeId + ResourceSubscriptionName = $scopeDisplayName + ResourceMGPath = $ChildMgParentNameChainDelimited + privateEndpointConnection = $privateEndpointConnection + }) + } } - } - else { - Write-Host 'Please report at AzGovViz Repo ... No API-version matches!' - Write-Host 'ResourceType:' $resource.type - Write-Host 'ResourceId:' $resourceId - } - } -ThrottleLimit $azAPICallConf['htParameters'].ThrottleLimit - #Write-Host 'arm resGet count:' $arrayResourcesWithProperties.Count + } + } + else { + Write-Host "Please report at AzGovViz Repo ... No API-version matches! ResourceType: '$($resource.type)'; ResourceId: '$($resource.id)'" + } - # $currentTask = "Getting Resources (ARG) for Subscription: '$($scopeDisplayName)' ('$scopeId') [quotaId:'$subscriptionQuotaId']" - # $uri = "$($azAPICallConf['azAPIEndpointUrls'].ARM)/providers/Microsoft.ResourceGraph/resources?api-version=2021-03-01" - # $method = 'POST' + } -ThrottleLimit $azAPICallConf['htParameters'].ThrottleLimit + } + #Write-Host 'arm resGet count:' $arrayResourcesWithProperties.Count + #endregion resources GET - # $body = @" - # { - # "query": "Resources", - # "subscriptions":[ - # "$($scopeId)" - # ], - # "options": { - # "`$top": 100 - # } - # } - # "@ - # $resourcesSubscriptionResultARG = AzAPICall -AzAPICallConfiguration $azAPICallConf -uri $uri -method $method -currentTask $currentTask -body $body -listenOn Content + if ($resourcesSubscriptionResult.Count -ne $arrayResourcesWithProperties.Count) { + Write-Host " FYI: Getting Resources for Subscription: '$($scopeDisplayName)' ('$scopeId') [quotaId:'$subscriptionQuotaId'] - ARM list count: $($resourcesSubscriptionResult.Count); ARG get count: $($arrayResourcesWithProperties.Count)" + } - if ($resourcesSubscriptionResult.Count -ne $arrayResourcesWithProperties.Count) { - Write-Host " FYI: Getting Resources for Subscription: '$($scopeDisplayName)' ('$scopeId') [quotaId:'$subscriptionQuotaId'] - ARM list count: $($resourcesSubscriptionResult.Count); ARG get count: $($arrayResourcesWithProperties.Count)" - } + #region PSRule + if ($azAPICallConf['htParameters'].DoPSRule -eq $true) { + if ($resourcesSubscriptionResult.Count -gt 0) { $startPSRule = Get-Date try { @@ -32142,17 +32298,17 @@ function processScopeInsights($mgChild, $mgChildOf) { } if ($mgName -eq $mgId) { - $mgNameAndOrId = "$($mgName -replace '<', '<' -replace '>', '>')" + $mgNameAndOrId = "$($mgName -replace '<', '<' -replace '>', '>')" } else { - $mgNameAndOrId = "$($mgName -replace '<', '<' -replace '>', '>') ($mgId)" + $mgNameAndOrId = "$($mgName -replace '<', '<' -replace '>', '>') ($mgId)" } $script:html += @"
- + "@ if ($mgId -eq $defaultManagementGroupId) { $script:html += @' @@ -32193,7 +32349,7 @@ function processScopeInsightsMGSubs($mgChild) { $script:html += @"

Highlight Management Group in HierarchyMap

Highlight Management Group in HierarchyMap
- +
"@ } @@ -32202,7 +32358,7 @@ function processScopeInsightsMGSubs($mgChild) { if ($subscriptionLinkedCount -gt 1) { if (-not $NoScopeInsights) { $script:html += @" - +
"@ } @@ -32211,14 +32367,14 @@ function processScopeInsightsMGSubs($mgChild) { else { if (-not $NoScopeInsights) { $script:html += @" - $($subEntry.subscription -replace '<', '<' -replace '>', '>') ($($subEntry.subscriptionId)) + $($subEntry.subscription -replace '<', '<' -replace '>', '>') ($($subEntry.subscriptionId)) "@ } } if (-not $NoScopeInsights) { $script:html += @" - + "@ } @@ -32251,7 +32407,7 @@ function processScopeInsightsMGSubs($mgChild) { $script:html += @"

Highlight Subscription in HierarchyMap

Highlight Subscription in HierarchyMap
-

$subscriptionLinkedCount Subscriptions linked $subscriptionsOutOfScopelinkedDetail

+ $subscriptionLinkedCount Subscriptions linked $subscriptionsOutOfScopelinkedDetail "@ } } @@ -32504,6 +32660,8 @@ if ($azAPICallConf['htParameters'].HierarchyMapOnly -eq $false) { $htDefenderEmailContacts = [System.Collections.Hashtable]::Synchronized((New-Object System.Collections.Hashtable)) $arrayVNets = [System.Collections.ArrayList]::Synchronized((New-Object System.Collections.ArrayList)) $arrayPrivateEndPoints = [System.Collections.ArrayList]::Synchronized((New-Object System.Collections.ArrayList)) + $arrayPrivateEndPointsFromResourceProperties = [System.Collections.ArrayList]::Synchronized((New-Object System.Collections.ArrayList)) + $htUnknownTenantsForSubscription = @{} } if (-not $HierarchyMapOnly) { @@ -32568,7 +32726,7 @@ if ($azAPICallConf['htParameters'].HierarchyMapOnly -eq $false) { $startDataCollection = Get-Date $startGetRPs = Get-Date - $currentTask = 'Getting RPs' + $currentTask = 'Getting Tenant Resource Providers' Write-Host $currentTask $uri = 'https://management.azure.com/providers?api-version=2021-04-01' $method = 'GET' @@ -32585,7 +32743,7 @@ if ($azAPICallConf['htParameters'].HierarchyMapOnly -eq $false) { } } $endGetRPs = Get-Date - Write-Host "Getting RPs duration: $((New-TimeSpan -Start $startGetRPs -End $endGetRPs).TotalMinutes) minutes ($((New-TimeSpan -Start $startGetRPs -End $endGetRPs).TotalSeconds) seconds)" + Write-Host " Getting Tenant Resource Providers duration: $((New-TimeSpan -Start $startGetRPs -End $endGetRPs).TotalMinutes) minutes ($((New-TimeSpan -Start $startGetRPs -End $endGetRPs).TotalSeconds) seconds)" processDataCollection -mgId $ManagementGroupId @@ -33064,7 +33222,7 @@ $html = @" link.media = "screen,print"; document.getElementsByTagName( "head" )[0].appendChild( link ); - + diff --git a/pwsh/dev/devAzGovVizParallel.ps1 b/pwsh/dev/devAzGovVizParallel.ps1 index 517f1af5..e33db0cd 100644 --- a/pwsh/dev/devAzGovVizParallel.ps1 +++ b/pwsh/dev/devAzGovVizParallel.ps1 @@ -359,10 +359,10 @@ Param $Product = 'AzGovViz', [string] - $AzAPICallVersion = '1.1.57', + $AzAPICallVersion = '1.1.58', [string] - $ProductVersion = 'v6_major_20221202_5', + $ProductVersion = 'v6_major_20221204_1', [string] $GithubRepository = 'aka.ms/AzGovViz', @@ -914,6 +914,8 @@ if ($azAPICallConf['htParameters'].HierarchyMapOnly -eq $false) { $htDefenderEmailContacts = [System.Collections.Hashtable]::Synchronized((New-Object System.Collections.Hashtable)) $arrayVNets = [System.Collections.ArrayList]::Synchronized((New-Object System.Collections.ArrayList)) $arrayPrivateEndPoints = [System.Collections.ArrayList]::Synchronized((New-Object System.Collections.ArrayList)) + $arrayPrivateEndPointsFromResourceProperties = [System.Collections.ArrayList]::Synchronized((New-Object System.Collections.ArrayList)) + $htUnknownTenantsForSubscription = @{} } if (-not $HierarchyMapOnly) { @@ -978,7 +980,7 @@ if ($azAPICallConf['htParameters'].HierarchyMapOnly -eq $false) { $startDataCollection = Get-Date $startGetRPs = Get-Date - $currentTask = 'Getting RPs' + $currentTask = 'Getting Tenant Resource Providers' Write-Host $currentTask $uri = 'https://management.azure.com/providers?api-version=2021-04-01' $method = 'GET' @@ -995,7 +997,7 @@ if ($azAPICallConf['htParameters'].HierarchyMapOnly -eq $false) { } } $endGetRPs = Get-Date - Write-Host "Getting RPs duration: $((New-TimeSpan -Start $startGetRPs -End $endGetRPs).TotalMinutes) minutes ($((New-TimeSpan -Start $startGetRPs -End $endGetRPs).TotalSeconds) seconds)" + Write-Host " Getting Tenant Resource Providers duration: $((New-TimeSpan -Start $startGetRPs -End $endGetRPs).TotalMinutes) minutes ($((New-TimeSpan -Start $startGetRPs -End $endGetRPs).TotalSeconds) seconds)" processDataCollection -mgId $ManagementGroupId @@ -1474,7 +1476,7 @@ $html = @" link.media = "screen,print"; document.getElementsByTagName( "head" )[0].appendChild( link ); - + diff --git a/pwsh/dev/functions/dataCollection/dataCollectionFunctions.ps1 b/pwsh/dev/functions/dataCollection/dataCollectionFunctions.ps1 index 5021bc21..d776a0fa 100644 --- a/pwsh/dev/functions/dataCollection/dataCollectionFunctions.ps1 +++ b/pwsh/dev/functions/dataCollection/dataCollectionFunctions.ps1 @@ -437,64 +437,75 @@ function dataCollectionResources { $subscriptionQuotaId ) + #region resources LIST $currentTask = "Getting Resources for Subscription: '$($scopeDisplayName)' ('$scopeId') [quotaId:'$subscriptionQuotaId']" $uri = "$($azAPICallConf['azAPIEndpointUrls'].ARM)/subscriptions/$($scopeId)/resources?`$expand=createdTime,changedTime,properties&api-version=2021-04-01" $method = 'GET' $resourcesSubscriptionResult = AzAPICall -AzAPICallConfiguration $azAPICallConf -uri $uri -method $method -currentTask $currentTask -caller 'CustomDataCollection' #Write-Host 'arm resList count:'$resourcesSubscriptionResult.Count + #endregion resources LIST + + #region resources GET + if ($resourcesSubscriptionResult.Count -gt 0) { + $arrayResourcesWithProperties = [System.Collections.ArrayList]::Synchronized((New-Object System.Collections.ArrayList)) + $resourcesSubscriptionResult | ForEach-Object -Parallel { + $resource = $_ + + #region using + $arrayResourcesWithProperties = $using:arrayResourcesWithProperties + $htResourceProvidersRef = $using:htResourceProvidersRef + $arrayPrivateEndPointsFromResourceProperties = $using:arrayPrivateEndPointsFromResourceProperties + $scopeId = $using:scopeId + $scopeDisplayName = $using:scopeDisplayName + $ChildMgParentNameChainDelimited = $using:ChildMgParentNameChainDelimited + $azAPICallConf = $using:azAPICallConf + #endregion using + + if ($htResourceProvidersRef.($resource.type)) { + $apiVersionToUse = $htResourceProvidersRef.($resource.type).APIFirst + $currentTask = "Getting Resource for PSRule API-version: '$apiVersionToUse'; ResourceType: '$($resource.type)'; ResourceId: '$($resource.id)'" + $uri = "$($azAPICallConf['azAPIEndpointUrls'].ARM)$($resource.id)?api-version=$apiVersionToUse" + $method = 'GET' + $resourceResult = AzAPICall -AzAPICallConfiguration $azAPICallConf -uri $uri -method $method -currentTask $currentTask -caller 'CustomDataCollection' -listenOn Content -unhandledErrorAction Continue + + if ($resourceResult -ne 'ResourceOrResourcegroupNotFound') { + $null = $script:arrayResourcesWithProperties.Add($resourceResult) + + if ($resourceResult.properties.privateEndpointConnections.Count -gt 0) { + foreach ($privateEndpointConnection in $resourceResult.properties.privateEndpointConnections) { + $resourceResultIdSplit = $resourceResult.id -split '/' + $null = $script:arrayPrivateEndPointsFromResourceProperties.Add([PSCustomObject]@{ + ResourceName = $resourceResult.name + ResourceType = $resourceResult.type + ResourceId = $resourceResult.id + ResourceResourceGroup = $resourceResultIdSplit[4] + ResourceSubscriptionId = $scopeId + ResourceSubscriptionName = $scopeDisplayName + ResourceMGPath = $ChildMgParentNameChainDelimited + privateEndpointConnection = $privateEndpointConnection + }) + } + } + + } + } + else { + Write-Host "Please report at AzGovViz Repo ... No API-version matches! ResourceType: '$($resource.type)'; ResourceId: '$($resource.id)'" + } + + } -ThrottleLimit $azAPICallConf['htParameters'].ThrottleLimit + } + #Write-Host 'arm resGet count:' $arrayResourcesWithProperties.Count + #endregion resources GET + + if ($resourcesSubscriptionResult.Count -ne $arrayResourcesWithProperties.Count) { + Write-Host " FYI: Getting Resources for Subscription: '$($scopeDisplayName)' ('$scopeId') [quotaId:'$subscriptionQuotaId'] - ARM list count: $($resourcesSubscriptionResult.Count); ARG get count: $($arrayResourcesWithProperties.Count)" + } #region PSRule if ($azAPICallConf['htParameters'].DoPSRule -eq $true) { if ($resourcesSubscriptionResult.Count -gt 0) { - $arrayResourcesWithProperties = [System.Collections.ArrayList]::Synchronized((New-Object System.Collections.ArrayList)) - $resourcesSubscriptionResult | ForEach-Object -Parallel { - $resource = $_ - $resourceId = $resource.id - $arrayResourcesWithProperties = $using:arrayResourcesWithProperties - $azAPICallConf = $using:azAPICallConf - $htResourceProvidersRef = $using:htResourceProvidersRef - - if ($htResourceProvidersRef.($resource.type)) { - $apiVersionToUse = $htResourceProvidersRef.($resource.type).APIFirst - $currentTask = "Getting Resource for PSRule API-version: '$apiVersionToUse'; ResourceType: '$($resource.type)'; ResourceId: '$resourceId'" - $uri = "$($azAPICallConf['azAPIEndpointUrls'].ARM)$($resourceId)?api-version=$apiVersionToUse" - $method = 'GET' - $resourceResult = AzAPICall -AzAPICallConfiguration $azAPICallConf -uri $uri -method $method -currentTask $currentTask -caller 'CustomDataCollection' -listenOn Content -unhandledErrorAction Continue - if ($resourceResult -ne 'ResourceOrResourcegroupNotFound') { - $null = $script:arrayResourcesWithProperties.Add($resourceResult) - } - } - else { - Write-Host 'Please report at AzGovViz Repo ... No API-version matches!' - Write-Host 'ResourceType:' $resource.type - Write-Host 'ResourceId:' $resourceId - } - - } -ThrottleLimit $azAPICallConf['htParameters'].ThrottleLimit - #Write-Host 'arm resGet count:' $arrayResourcesWithProperties.Count - - # $currentTask = "Getting Resources (ARG) for Subscription: '$($scopeDisplayName)' ('$scopeId') [quotaId:'$subscriptionQuotaId']" - # $uri = "$($azAPICallConf['azAPIEndpointUrls'].ARM)/providers/Microsoft.ResourceGraph/resources?api-version=2021-03-01" - # $method = 'POST' - - # $body = @" - # { - # "query": "Resources", - # "subscriptions":[ - # "$($scopeId)" - # ], - # "options": { - # "`$top": 100 - # } - # } - # "@ - # $resourcesSubscriptionResultARG = AzAPICall -AzAPICallConfiguration $azAPICallConf -uri $uri -method $method -currentTask $currentTask -body $body -listenOn Content - - if ($resourcesSubscriptionResult.Count -ne $arrayResourcesWithProperties.Count) { - Write-Host " FYI: Getting Resources for Subscription: '$($scopeDisplayName)' ('$scopeId') [quotaId:'$subscriptionQuotaId'] - ARM list count: $($resourcesSubscriptionResult.Count); ARG get count: $($arrayResourcesWithProperties.Count)" - } - $startPSRule = Get-Date try { <# diff --git a/pwsh/dev/functions/html/htmlFunctions.ps1 b/pwsh/dev/functions/html/htmlFunctions.ps1 index 47dbef86..8893e8a0 100644 --- a/pwsh/dev/functions/html/htmlFunctions.ps1 +++ b/pwsh/dev/functions/html/htmlFunctions.ps1 @@ -224,17 +224,17 @@ function processScopeInsights($mgChild, $mgChildOf) { } if ($mgName -eq $mgId) { - $mgNameAndOrId = "$($mgName -replace '<', '<' -replace '>', '>')" + $mgNameAndOrId = "$($mgName -replace '<', '<' -replace '>', '>')" } else { - $mgNameAndOrId = "$($mgName -replace '<', '<' -replace '>', '>') ($mgId)" + $mgNameAndOrId = "$($mgName -replace '<', '<' -replace '>', '>') ($mgId)" } $script:html += @"
- + "@ if ($mgId -eq $defaultManagementGroupId) { $script:html += @' @@ -275,7 +275,7 @@ function processScopeInsightsMGSubs($mgChild) { $script:html += @"

Highlight Management Group in HierarchyMap

Highlight Management Group in HierarchyMap
- +
"@ } @@ -284,7 +284,7 @@ function processScopeInsightsMGSubs($mgChild) { if ($subscriptionLinkedCount -gt 1) { if (-not $NoScopeInsights) { $script:html += @" - +
"@ } @@ -293,14 +293,14 @@ function processScopeInsightsMGSubs($mgChild) { else { if (-not $NoScopeInsights) { $script:html += @" - $($subEntry.subscription -replace '<', '<' -replace '>', '>') ($($subEntry.subscriptionId)) + $($subEntry.subscription -replace '<', '<' -replace '>', '>') ($($subEntry.subscriptionId)) "@ } } if (-not $NoScopeInsights) { $script:html += @" - + "@ } @@ -333,7 +333,7 @@ function processScopeInsightsMGSubs($mgChild) { $script:html += @" - - - - - - - - - + + + + + + + + + +

Highlight Subscription in HierarchyMap

Highlight Subscription in HierarchyMap
-

$subscriptionLinkedCount Subscriptions linked $subscriptionsOutOfScopelinkedDetail

+ $subscriptionLinkedCount Subscriptions linked $subscriptionsOutOfScopelinkedDetail "@ } } diff --git a/pwsh/dev/functions/processDataCollection.ps1 b/pwsh/dev/functions/processDataCollection.ps1 index e18ae329..aaf8bfb0 100644 --- a/pwsh/dev/functions/processDataCollection.ps1 +++ b/pwsh/dev/functions/processDataCollection.ps1 @@ -356,6 +356,7 @@ function processDataCollection { $arrayVNets = $using:arrayVNets $arrayPrivateEndPoints = $using:arrayPrivateEndPoints $htResourceProvidersRef = $using:htResourceProvidersRef + $arrayPrivateEndPointsFromResourceProperties = $using:arrayPrivateEndPointsFromResourceProperties #other $function:addRowToTable = $using:funcAddRowToTable $function:namingValidation = $using:funcNamingValidation diff --git a/pwsh/dev/functions/processNetwork.ps1 b/pwsh/dev/functions/processNetwork.ps1 index e247f719..1f5e75ab 100644 --- a/pwsh/dev/functions/processNetwork.ps1 +++ b/pwsh/dev/functions/processNetwork.ps1 @@ -10,7 +10,6 @@ function processNetwork { $script:htSubnets = @{} $script:arrayVirtualNetworks = [System.Collections.ArrayList]@() $script:arraySubnets = [System.Collections.ArrayList]@() - $htUnknownTenantsForSubscription = @{} foreach ($vnet in $arrayVNets) { @@ -77,9 +76,9 @@ function processNetwork { $peeringXTenant = 'true' } } - $htUnknownTenantsForSubscription.($remotesubscriptionId) = @{} - $htUnknownTenantsForSubscription.($remotesubscriptionId).TenantId = $arrayRemoteMGPath -join ', ' - $remoteMGPath = $arrayRemoteMGPath -join ', ' + $script:htUnknownTenantsForSubscription.($remotesubscriptionId) = @{} + $script:htUnknownTenantsForSubscription.($remotesubscriptionId).TenantId = $arrayRemoteMGPath -join ', ' + $remoteMGPath = $arrayRemoteMGPath -join ' or ' } } } diff --git a/pwsh/dev/functions/processPrivateEndpoints.ps1 b/pwsh/dev/functions/processPrivateEndpoints.ps1 index c45d36f9..7c625640 100644 --- a/pwsh/dev/functions/processPrivateEndpoints.ps1 +++ b/pwsh/dev/functions/processPrivateEndpoints.ps1 @@ -1,13 +1,107 @@ function processPrivateEndpoints { $start = Get-Date - Write-Host "Processing Private Endpoints enrichment ($($arrayPrivateEndPoints.Count) Private Endpoints)" + Write-Host 'Processing Private Endpoints enrichment' + $script:arrayPrivateEndpointsEnriched = [System.Collections.ArrayList]@() + + if ($arrayPrivateEndPointsFromResourceProperties.Count -gt 0) { + $privateEndPointsFromResourcePropertiesToProcess = ($arrayPrivateEndPointsFromResourceProperties.where({ $arrayPrivateEndPoints.id -notcontains $_.privateEndpointConnection.Properties.privateEndpoint.id })) + $privateEndPointsFromResourcePropertiesToProcessCount = $privateEndPointsFromResourcePropertiesToProcess.Count + Write-Host " Processing Private Endpoints enrichment for $privateEndPointsFromResourcePropertiesToProcessCount Private Endpoint(s) where the Private Endpoint was not returned from the PE API endpoint but from a resource property" + if ($privateEndPointsFromResourcePropertiesToProcessCount -gt 0) { + foreach ($entry in $privateEndPointsFromResourcePropertiesToProcess) { + $peResIdSplit = $entry.privateEndpointConnection.Properties.privateEndpoint.id -split '/' + $crossSubscriptionPE = 'n/a' + $peSubscriptionId = $peResIdSplit[2] + if ($peSubscriptionId -ne $entry.ResourceSubscriptionId) { + $crossSubscriptionPE = $true + } + else { + $crossSubscriptionPE = $false + } + + $peMGPath = 'n/a' + $peXTenant = 'n/a' + if ($htUnknownTenantsForSubscription.($peSubscriptionId)) { + $remoteTenantId = $htUnknownTenantsForSubscription.($peSubscriptionId).TenantId + $peMGPath = $remoteTenantId + if ($remoteTenantId -eq $azApiCallConf['checkcontext'].tenant.id) { + $peXTenant = 'false' + } + else { + $peXTenant = 'true' + } + } + else { + $uri = "$($azAPICallConf['azAPIEndpointUrls'].ARM)/subscriptions/$($peSubscriptionId)?api-version=2020-01-01" + $remoteTenantId = AzAPICall -AzAPICallConfiguration $azApiCallConf -uri $uri -listenOn 'content' -currentTask "getTenantId for subscriptionId '$($peSubscriptionId)'" + $arrayRemoteMGPath = @() + foreach ($remoteId in $remoteTenantId) { + $objectGuid = [System.Guid]::empty + if ([System.Guid]::TryParse($remoteId, [System.Management.Automation.PSReference]$ObjectGuid)) { + $arrayRemoteMGPath += $remoteId + if ($remoteId -eq $azApiCallConf['checkcontext'].tenant.id) { + $peXTenant = 'false' + } + else { + $peXTenant = 'true' + } + } + $script:htUnknownTenantsForSubscription.($peSubscriptionId) = @{} + $script:htUnknownTenantsForSubscription.($peSubscriptionId).TenantId = $arrayRemoteMGPath -join ', ' + $peMGPath = $arrayRemoteMGPath -join ' or ' + } + } + + $null = $script:arrayPrivateEndpointsEnriched.Add([PSCustomObject]@{ + PEName = $entry.privateEndpointConnection.name + PEId = $entry.privateEndpointConnection.Properties.privateEndpoint.id + PELocation = 'n/a' + PEResourceGroup = $peResIdSplit[4] + PESubscriptionName = 'n/a' + PESubscription = $peSubscriptionId + PEMGPath = $peMGPath + PEConnectionType = 'n/a' + PEConnectionState = $entry.privateEndpointConnection.Properties.privateLinkServiceConnectionState.status + CrossSubscriptionPE = $crossSubscriptionPE + CrossTenantPE = $peXTenant + + Resource = $entry.ResourceName + ResourceType = $entry.ResourceType + ResourceId = $entry.ResourceId + TargetSubresource = 'n/a' + NICName = 'n/a' + FQDN = 'n/a' + ipAddresses = 'n/a' + ResourceResourceGroup = $entry.ResourceResourceGroup + ResourceSubscriptionName = $entry.ResourceSubscriptionName + ResourceSubscriptionId = $entry.ResourceSubscriptionId + ResourceMGPath = $entry.ResourceMGPath + + Subnet = 'n/a' + SubnetId = 'n/a' + SubnetVNet = 'n/a' + SubnetVNetId = 'n/a' + SubnetVNetLocation = 'n/a' + SubnetVNetResourceGroup = 'n/a' + SubnetSubscriptionName = 'n/a' + SubnetSubscription = 'n/a' + SubnetMGPath = 'n/a' + }) + } + } + } + + Write-Host " Processing Private Endpoints enrichment for $($arrayPrivateEndPoints.Count) Private Endpoint(s) where the Private Endpoint was returned from the PE API endpoint" $htVPrivateEndPoints = @{} foreach ($pe in $arrayPrivateEndPoints) { $htVPrivateEndPoints.($pe.id) = $pe } - $script:arrayPrivateEndpointsEnriched = [System.Collections.ArrayList]@() + $htVPrivateEndPoints = @{} + foreach ($pe in $arrayPrivateEndPoints) { + $htVPrivateEndPoints.($pe.id) = $pe + } foreach ($pe in $arrayPrivateEndPoints) { @@ -56,23 +150,34 @@ function processPrivateEndpoints { $peConnectionState = $pe.properties.manualPrivateLinkServiceConnections.properties.privateLinkServiceConnectionState.status } - $resourceSubscriptionId = $resourceSplit[2] + $resourceSubscriptionId = 'n/a' + $resource = 'n/a' + $resourceType = 'n/a' + $resourceResourceGroup = 'n/a' $resourceSubscriptionName = 'n/a' $resourceMGPath = 'n/a' - if ($htSubscriptionsMgPath.($resourceSubscriptionId)) { - $subHelper = $htSubscriptionsMgPath.($resourceSubscriptionId) - $resourceSubscriptionName = $subHelper.displayName - $resourceMGPath = $subHelper.ParentNameChainDelimited - } - - if ($SubnetSubscription -eq $resourceSubscriptionId) { - $crossSubscriptionPE = $false + $crossSubscriptionPE = 'n/a' + + $ObjectGuid = [System.Guid]::empty + if ([System.Guid]::TryParse($resourceSplit[2], [System.Management.Automation.PSReference]$ObjectGuid)) { + $resourceSubscriptionId = $resourceSplit[2] + $resource = $resourceSplit[8] + $resourceType = "$($resourceSplit[6])/$($resourceSplit[7])" + $resourceResourceGroup = $resourceSplit[4] + + if ($htSubscriptionsMgPath.($resourceSubscriptionId)) { + $subHelper = $htSubscriptionsMgPath.($resourceSubscriptionId) + $resourceSubscriptionName = $subHelper.displayName + $resourceMGPath = $subHelper.ParentNameChainDelimited + } + + if ($SubnetSubscription -eq $resourceSubscriptionId) { + $crossSubscriptionPE = $false + } + else { + $crossSubscriptionPE = $true + } } - else { - $crossSubscriptionPE = $true - } - - $null = $script:arrayPrivateEndpointsEnriched.Add([PSCustomObject]@{ PEName = $pe.name @@ -85,15 +190,16 @@ function processPrivateEndpoints { PEConnectionType = $peConnectionType PEConnectionState = $peConnectionState CrossSubscriptionPE = $crossSubscriptionPE + CrossTenantPE = 'false' - Resource = $resourceSplit[8] - ResourceType = "$($resourceSplit[6])/$($resourceSplit[7])" + Resource = $resource + ResourceType = $resourceType ResourceId = $resourceId TargetSubresource = $targetSubresource -join ', ' NICName = $pe.properties.customNetworkInterfaceName FQDN = $pe.properties.customDnsConfigs.fqdn -join ', ' ipAddresses = $pe.properties.customDnsConfigs.ipAddresses -join ', ' - ResourceResourceGroup = $resourceSplit[4] + ResourceResourceGroup = $resourceResourceGroup ResourceSubscriptionName = $resourceSubscriptionName ResourceSubscriptionId = $resourceSubscriptionId ResourceMGPath = $resourceMGPath diff --git a/pwsh/dev/functions/processScopeInsightsMgOrSub.ps1 b/pwsh/dev/functions/processScopeInsightsMgOrSub.ps1 index d9c3c8b3..af54b728 100644 --- a/pwsh/dev/functions/processScopeInsightsMgOrSub.ps1 +++ b/pwsh/dev/functions/processScopeInsightsMgOrSub.ps1 @@ -37,8 +37,8 @@ function processScopeInsightsMgOrSub($mgOrSub, $mgChild, $subscriptionId, $subsc }) } $resourcesAllChildSubscriptions.count_ | ForEach-Object { $resourcesAllChildSubscriptionTotal += $_ } - $resourcesAllChildSubscriptionResourceTypeCount = (($resourcesAllChildSubscriptions | Sort-Object -Property type -Unique) | measure-object).count - $resourcesAllChildSubscriptionLocationCount = (($resourcesAllChildSubscriptions | Sort-Object -Property location -Unique) | measure-object).count + $resourcesAllChildSubscriptionResourceTypeCount = (($resourcesAllChildSubscriptions | Sort-Object -Property type -Unique) | Measure-Object).count + $resourcesAllChildSubscriptionLocationCount = (($resourcesAllChildSubscriptions | Sort-Object -Property location -Unique) | Measure-Object).count } #childrenMgInfo $mgAllChildMgs = [System.Collections.ArrayList]@() @@ -140,16 +140,16 @@ function processScopeInsightsMgOrSub($mgOrSub, $mgChild, $subscriptionId, $subsc } [void]$htmlScopeInsights.AppendLine(@" -

Subscription Name: $($subscriptionDetailsReleatedQuery.subscription -replace '<', '<' -replace '>', '>')

Subscription Id: $($subscriptionDetailsReleatedQuery.subscriptionId)

Subscription Path: $subPath

State: $subscriptionState

QuotaId: $subscriptionQuotaId

Microsoft Defender for Cloud Secure Score: $subscriptionASCPoints Video , Blog , docs

Microsoft Defender for Cloud 'Email notifications' state: $MDfCEmailNotificationsState

Microsoft Defender for Cloud 'Email notifications' severity: $MDfCEmailNotificationsSeverity

Microsoft Defender for Cloud 'Email notifications' roles: $MDfCEmailNotificationsRoles

Microsoft Defender for Cloud 'Email notifications' emails: $MDfCEmailNotificationsEmails

Subscription Name: $($subscriptionDetailsReleatedQuery.subscription -replace '<', '<' -replace '>', '>')
Subscription Id: $($subscriptionDetailsReleatedQuery.subscriptionId)
Subscription Path: $subPath
State: $subscriptionState
QuotaId: $subscriptionQuotaId
Microsoft Defender for Cloud Secure Score: $subscriptionASCPoints Video , Blog , docs
Microsoft Defender for Cloud 'Email notifications' state: $MDfCEmailNotificationsState
Microsoft Defender for Cloud 'Email notifications' severity: $MDfCEmailNotificationsSeverity
Microsoft Defender for Cloud 'Email notifications' roles: $MDfCEmailNotificationsRoles
Microsoft Defender for Cloud 'Email notifications' emails: $MDfCEmailNotificationsEmails
"@) @@ -173,7 +173,7 @@ function processScopeInsightsMgOrSub($mgOrSub, $mgChild, $subscriptionId, $subsc $htmlTableId = "ScopeInsights_DefenderPlans_$($subscriptionId -replace '-','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
"@) @@ -286,19 +286,19 @@ tf.init();}} if ($subscriptionSkippedMDfC.Count -gt 0) { if ($subscriptionSkippedMDfC.reason -eq 'SubScriptionNotRegistered') { [void]$htmlScopeInsights.AppendLine(@" -

Microsoft Defender for Cloud plans - Subscription skipped ($($subscriptionSkippedMDfC.reason)) (ResourceProvider: Microsoft.Security) docs

+ Microsoft Defender for Cloud plans - Subscription skipped ($($subscriptionSkippedMDfC.reason)) (ResourceProvider: Microsoft.Security) docs "@) } else { [void]$htmlScopeInsights.AppendLine(@" -

Microsoft Defender for Cloud plans - Subscription skipped ($($subscriptionSkippedMDfC.reason))

+ Microsoft Defender for Cloud plans - Subscription skipped ($($subscriptionSkippedMDfC.reason)) "@) } } else { [void]$htmlScopeInsights.AppendLine(@' -

No Microsoft Defender for Cloud plans docs

+ No Microsoft Defender for Cloud plans docs '@) } } @@ -315,7 +315,7 @@ tf.init();}} $htmlTableId = "ScopeInsights_DiagnosticsSub_$($subscriptionId -replace '-','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma @@ -440,7 +440,7 @@ tf.init();}} } else { [void]$htmlScopeInsights.AppendLine(@' -

No Subscription Diagnostic settings docs

+ No Subscription Diagnostic settings docs '@) } [void]$htmlScopeInsights.AppendLine(@' @@ -458,7 +458,7 @@ tf.init();}} $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" +$tagsSubscriptionCount Subscription Tags | Limit: ($tagsSubscriptionCount/$LimitTagsSubscription)
   Download CSV semicolon | comma
@@ -529,7 +529,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$tagsSubscriptionCount Subscription Tags

+ $tagsSubscriptionCount Subscription Tags "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -560,7 +560,7 @@ extensions: [{ name: 'sort' }] $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" +Tag Name Usage ($tagNamesUniqueCount unique Tag Names applied at $($tagNamesUsedInScopes)
   Resource naming and tagging decision guide docs
   Download CSV semicolon | comma @@ -636,7 +636,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

Tag Name Usage ($tagsUsageCount Tags) docs

+ Tag Name Usage ($tagsUsageCount Tags) docs "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -661,7 +661,7 @@ extensions: [{ name: 'sort' }] $currency = $htAzureConsumptionSubscriptions.($subscriptionId).Currency $consumedServiceCount = ($consumptionData.ResourceType | Sort-Object -Unique | Measure-Object).Count $resourceCount = ($consumptionData.ResourceId | Sort-Object -Unique | Measure-Object).Count - $subConsumptionDataGrouped = $consumptionData | Group-Object -property ResourceType, ChargeType, MeterCategory + $subConsumptionDataGrouped = $consumptionData | Group-Object -Property ResourceType, ChargeType, MeterCategory foreach ($consumptionline in $subConsumptionDataGrouped) { @@ -697,7 +697,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_Consumption_$($subscriptionId -replace '-','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -780,13 +780,13 @@ tf.init();}} } else { [void]$htmlScopeInsights.AppendLine(@' -

No Consumption data available

+ No Consumption data available '@) } } else { [void]$htmlScopeInsights.AppendLine(@' -

No Consumption data available as switch parameter -DoAzureConsumption was not applied

+ No Consumption data available as switch parameter -DoAzureConsumption was not applied '@) } @@ -802,12 +802,12 @@ tf.init();}} #region ScopeInsightsResourceGroups if ($subscriptionResourceGroupsCount -gt 0) { [void]$htmlScopeInsights.AppendLine(@" -

$subscriptionResourceGroupsCount Resource Groups | Limit: ($subscriptionResourceGroupsCount/$LimitResourceGroups)

+ $subscriptionResourceGroupsCount Resource Groups | Limit: ($subscriptionResourceGroupsCount/$LimitResourceGroups) "@) } else { [void]$htmlScopeInsights.AppendLine(@" -

$subscriptionResourceGroupsCount Resource Groups

+ $subscriptionResourceGroupsCount Resource Groups "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -897,7 +897,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$(($htResourceProvidersAll.Keys).count) Resource Providers

+ $(($htResourceProvidersAll.Keys).count) Resource Providers "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -918,7 +918,7 @@ extensions: [{ name: 'sort' }] [void]$htmlScopeInsights.AppendLine(@" +$tfCount enabled Subscription Features
   Set up preview features in Azure subscription docs
@@ -986,7 +986,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@' -

0 enabled Subscription Features docs

+ 0 enabled Subscription Features docs '@) } [void]$htmlScopeInsights.AppendLine(@' @@ -1011,7 +1011,7 @@ extensions: [{ name: 'sort' }] [void]$htmlScopeInsights.AppendLine(@" +Resource Locks
   Considerations before applying locks docs
@@ -1081,7 +1081,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@' -

0 Resource Locks docs

+ 0 Resource Locks docs '@) } [void]$htmlScopeInsights.AppendLine(@' @@ -1097,9 +1097,9 @@ extensions: [{ name: 'sort' }] if ($mgOrSub -eq 'mg') { [void]$htmlScopeInsights.AppendLine(@" - - - + + +

$(($mgAllChildMgs).count -1) ManagementGroups below this scope

$(($mgAllChildSubscriptions).count) Subscriptions below this scope

Microsoft Defender for Cloud Secure Score: $managementGroupASCPoints Video , Blog , docs

$(($mgAllChildMgs).count -1) ManagementGroups below this scope
$(($mgAllChildSubscriptions).count) Subscriptions below this scope
Microsoft Defender for Cloud Secure Score: $managementGroupASCPoints Video , Blog , docs
"@) @@ -1110,7 +1110,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_DiagnosticsMg_$($mgChild -replace '\(','_' -replace '\)','_' -replace '-','_' -replace '\.','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma @@ -1235,7 +1235,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@' -

No Management Group Diagnostic settings docs

+ No Management Group Diagnostic settings docs '@) } #endregion ScopeInsightsDiagnosticsMg @@ -1254,10 +1254,10 @@ extensions: [{ name: 'sort' }] if (($consumptionData | Measure-Object).Count -gt 0) { $arrayTotalCostSummaryMg = @() $arrayConsumptionData = [System.Collections.ArrayList]@() - $consumptionDataGroupedByCurrency = $consumptionData | Group-Object -property Currency + $consumptionDataGroupedByCurrency = $consumptionData | Group-Object -Property Currency foreach ($currency in $consumptionDataGroupedByCurrency) { $totalCost = 0 - $tenantSummaryConsumptionDataGrouped = $currency.group | Group-Object -property ResourceType, ChargeType, MeterCategory + $tenantSummaryConsumptionDataGrouped = $currency.group | Group-Object -Property ResourceType, ChargeType, MeterCategory $subsCount = ($tenantSummaryConsumptionDataGrouped.group.subscriptionId | Sort-Object -Unique).Count $consumedServiceCount = ($tenantSummaryConsumptionDataGrouped.group.ResourceType | Sort-Object -Unique).Count $resourceCount = ($tenantSummaryConsumptionDataGrouped.group.ResourceId | Sort-Object -Unique).Count @@ -1296,7 +1296,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_Consumption_$($mgChild -replace '\(','_' -replace '\)','_' -replace '-','_' -replace '\.','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | @@ -1384,13 +1384,13 @@ tf.init();}} } else { [void]$htmlScopeInsights.AppendLine(@' -

No Consumption data available for Subscriptions under this ManagementGroup

+ No Consumption data available for Subscriptions under this ManagementGroup '@) } } else { [void]$htmlScopeInsights.AppendLine(@' -

No Consumption data available

+ No Consumption data available '@) } @@ -1401,7 +1401,7 @@ tf.init();}} } else { [void]$htmlScopeInsights.AppendLine(@' -

No Consumption data available as switch parameter -DoAzureConsumption was not applied

+ No Consumption data available as switch parameter -DoAzureConsumption was not applied '@) } #endregion ScopeInsightsConsumptionMg @@ -1422,7 +1422,7 @@ tf.init();}} $htmlTableId = "ScopeInsights_Resources_$($mgChild -replace '\(','_' -replace '\)','_' -replace '-','_' -replace '\.','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -1496,7 +1496,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$resourcesAllChildSubscriptionResourceTypeCount ResourceTypes (all Subscriptions below this scope)

+ $resourcesAllChildSubscriptionResourceTypeCount ResourceTypes (all Subscriptions below this scope) "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -1511,7 +1511,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_Resources_$($subscriptionId -replace '-','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -1585,7 +1585,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$resourcesSubscriptionResourceTypeCount ResourceTypes

+ $resourcesSubscriptionResourceTypeCount ResourceTypes "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -1608,7 +1608,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_CAFResourceNamingALL_$($subscriptionId -replace '-','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   CAF - Recommended abbreviations for Azure resource types docs
   Resource details can be found in the CSV output *_ResourcesAll.csv
@@ -1642,7 +1642,7 @@ extensions: [{ name: 'sort' }] $passed = 0 $failed = 0 foreach ($result in $resourceTypeGroupedByCAFResourceNamingResult) { - $resultNameSplitted = $result.Name -split ", " + $resultNameSplitted = $result.Name -split ', ' if ($resultNameSplitted[0] -eq 'passed') { $passed = $result.Count } @@ -1723,9 +1723,9 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { "@) } else { - [void]$htmlScopeInsights.AppendLine(@" -

No CAF Naming Recommendation Compliance data available

-"@) + [void]$htmlScopeInsights.AppendLine(@' + No CAF Naming Recommendation Compliance data available +'@) } [void]$htmlScopeInsights.AppendLine(@' @@ -1752,13 +1752,13 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { $orphanedIncludingCost = $false - $hintTableTH = "" + $hintTableTH = '' } $htmlTableId = "ScopeInsights_OrphanedResources_$($subscriptionId -replace '-','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   'Azure Orphan Resources' ARG queries and workbooks GitHub
   Resource details can be found in the CSV output *_ResourcesOrphaned.csv
@@ -1779,23 +1779,23 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { $htmlScopeInsightsOrphanedResources = foreach ($resourceType in $orphanedResourcesThisSubscriptionGroupedByType | Sort-Object -Property Name) { if ($orphanedIncludingCost) { - if ($resourceType.Group.Intent[0] -eq "cost savings") { + if ($resourceType.Group.Intent[0] -eq 'cost savings') { $orphCost = ($resourceType.Group.Cost | Measure-Object -Sum).Sum $orphCurrency = $resourceType.Group.Currency[0] } else { - $orphCost = "" - $orphCurrency = "" + $orphCost = '' + $orphCurrency = '' } } else { - if ($resourceType.Group.Intent[0] -eq "cost savings") { + if ($resourceType.Group.Intent[0] -eq 'cost savings') { $orphCost = "use parameter -DoAzureConsumption to show potential savings" - $orphCurrency = "" + $orphCurrency = '' } else { - $orphCost = "" - $orphCurrency = "" + $orphCost = '' + $orphCurrency = '' } } @@ -1863,15 +1863,15 @@ extensions: [{ name: 'sort' }] "@) } else { - [void]$htmlScopeInsights.AppendLine(@" -

0 Orphaned Resources

-"@) + [void]$htmlScopeInsights.AppendLine(@' + 0 Orphaned Resources +'@) } } else { - [void]$htmlScopeInsights.AppendLine(@" -

0 Orphaned Resources

-"@) + [void]$htmlScopeInsights.AppendLine(@' + 0 Orphaned Resources +'@) } [void]$htmlScopeInsights.AppendLine(@' @@ -1885,7 +1885,7 @@ extensions: [{ name: 'sort' }] #resourcesDiagnosticsCapable #region ScopeInsightsDiagnosticsCapable if ($mgOrSub -eq 'mg') { - $resourceTypesUnique = ($resourcesAllChildSubscriptions | select-object type -Unique).type + $resourceTypesUnique = ($resourcesAllChildSubscriptions | Select-Object type -Unique).type $resourceTypesSummarizedArray = [System.Collections.ArrayList]@() foreach ($resourceTypeUnique in $resourceTypesUnique) { $resourcesTypeCountTotal = 0 @@ -1915,7 +1915,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_resourcesDiagnosticsCapable_$($mgchild -replace '\(','_' -replace '\)','_' -replace '-','_' -replace '\.','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -2002,7 +2002,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$resourcesAllChildSubscriptionResourceTypeCount ResourceTypes (1st party) Diagnostics capable (all Subscriptions below this scope)

+ $resourcesAllChildSubscriptionResourceTypeCount ResourceTypes (1st party) Diagnostics capable (all Subscriptions below this scope) "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -2012,7 +2012,7 @@ extensions: [{ name: 'sort' }] } if ($mgOrSub -eq 'sub') { - $resourceTypesUnique = ($resourcesSubscription | select-object type -Unique).type + $resourceTypesUnique = ($resourcesSubscription | Select-Object type -Unique).type $resourceTypesSummarizedArray = [System.Collections.ArrayList]@() foreach ($resourceTypeUnique in $resourceTypesUnique) { $resourcesTypeCountTotal = 0 @@ -2043,7 +2043,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_resourcesDiagnosticsCapable_$($subscriptionId -replace '-','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -2130,7 +2130,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$resourcesSubscriptionResourceTypeCount ResourceTypes (1st party) Diagnostics capable

+ $resourcesSubscriptionResourceTypeCount ResourceTypes (1st party) Diagnostics capable "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -2151,7 +2151,7 @@ extensions: [{ name: 'sort' }] $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" +UserAssigned Managed Identities assigned to Resources / vice versa
   Managed identity 'user-assigned' vs 'system-assigned' docs
   Download CSV semicolon | comma @@ -2270,7 +2270,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ } else { [void]$htmlScopeInsights.AppendLine(@' -

No UserAssigned Managed Identities assigned to Resources / vice versa - at all

+ No UserAssigned Managed Identities assigned to Resources / vice versa - at all '@) } [void]$htmlScopeInsights.AppendLine(@' @@ -2295,7 +2295,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ } } - $grpThisManagementGroup = $allPSRuleResultsUnderThisMg | group-object -Property resourceType, pillar, category, severity, rule, result + $grpThisManagementGroup = $allPSRuleResultsUnderThisMg | Group-Object -Property resourceType, pillar, category, severity, rule, result if ($grpThisManagementGroup) { $grpThisManagementGroupCount = $grpThisManagementGroup.Count @@ -2304,8 +2304,8 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" -
+ $grpThisManagementGroupCount 'PSRule for Azure' results +
   Learn about PSRule for Azure
   Download CSV semicolon | comma
@@ -2407,7 +2407,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ } else { [void]$htmlScopeInsights.AppendLine(@' -

No PSRule for Azure results

+ No PSRule for Azure results '@) } [void]$htmlScopeInsights.AppendLine(@' @@ -2418,7 +2418,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ if ($mgOrSub -eq 'sub') { $grpThisSubscription = $grpPSRuleSubscriptions.where({ $_.Name -eq $subscriptionId }) - $grpThisSubscriptionGrouped = $grpThisSubscription.Group | group-object -Property resourceType, pillar, category, severity, result + $grpThisSubscriptionGrouped = $grpThisSubscription.Group | Group-Object -Property resourceType, pillar, category, severity, rule, result if ($grpThisSubscriptionGrouped) { $grpThisSubscriptionGroupedCount = $grpThisSubscriptionGrouped.Count @@ -2427,7 +2427,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" +$grpThisSubscriptionGroupedCount PSRule for Azure results
   Learn about PSRule for Azure
   Download CSV semicolon | comma @@ -2527,7 +2527,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ } else { [void]$htmlScopeInsights.AppendLine(@' -

No PSRule results

+ No PSRule results '@) } [void]$htmlScopeInsights.AppendLine(@' @@ -2539,7 +2539,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ } else { [void]$htmlScopeInsights.AppendLine(@' -

PSRule for Azure - use parameter -DoPSRule - PSRule for Azure

+ PSRule for Azure - use parameter -DoPSRule - PSRule for Azure '@) } } @@ -2609,7 +2609,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ $randomFunctionName = "func_$htmlTableId" $noteOrNot = '' [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
  *Depending on the number of rows and your computer´s performance the table may respond with delay, download the csv for better filtering experience @@ -2795,7 +2795,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlScopeInsights.AppendLine(@" -

$(($policiesAssigned).count) Policy assignments

+ $(($policiesAssigned).count) Policy assignments "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -2869,7 +2869,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { $randomFunctionName = "func_$htmlTableId" $noteOrNot = '' [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -3041,7 +3041,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlScopeInsights.AppendLine(@" -

$(($policySetsAssigned).count) PolicySet assignments

+ $(($policySetsAssigned).count) PolicySet assignments "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -3063,7 +3063,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { $faimage = "" [void]$htmlScopeInsights.AppendLine(@" -

$faImage Policy Assignment Limit: 0/$limit

+ $faImage Policy Assignment Limit: 0/$limit "@) } else { @@ -3081,7 +3081,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { $faimage = "" } [void]$htmlScopeInsights.AppendLine(@" -

$faImage Policy Assignment Limit: $($scopePolicyAssignmentsLimit.PolicyAndPolicySetAssignmentAtScopeCount)/$($limit)

+ $faImage Policy Assignment Limit: $($scopePolicyAssignmentsLimit.PolicyAndPolicySetAssignmentAtScopeCount)/$($limit) "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -3129,7 +3129,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -3225,7 +3225,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$scopePoliciesCount Custom Policy definitions scoped

+ $scopePoliciesCount Custom Policy definitions scoped "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -3272,7 +3272,7 @@ extensions: [{ name: 'sort' }] } } [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -3356,7 +3356,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$scopePolicySetsCount Custom PolicySet definitions scoped

+ $scopePolicySetsCount Custom PolicySet definitions scoped "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -3379,7 +3379,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_BlueprintAssignment_$($htmlTableIdentifier -replace '\(','_' -replace '\)','_' -replace '-','_' -replace '\.','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -3462,7 +3462,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$blueprintsAssignedCount Blueprints assigned

+ $blueprintsAssignedCount Blueprints assigned "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -3487,7 +3487,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_BlueprintScoped_$($htmlTableIdentifier -replace '\(','_' -replace '\)','_' -replace '-','_' -replace '\.','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -3564,7 +3564,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlScopeInsights.AppendLine(@" -

$blueprintsScopedCount Blueprints scoped

+ $blueprintsScopedCount Blueprints scoped "@) } [void]$htmlScopeInsights.AppendLine(@' @@ -3580,7 +3580,7 @@ extensions: [{ name: 'sort' }] $htmlTableId = "ScopeInsights_ClassicAdministrators_$($subscriptionId -replace '\(','_' -replace '\)','_' -replace '-','_' -replace '\.','_')" $randomFunctionName = "func_$htmlTableId" [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
@@ -3650,9 +3650,9 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ "@) } else { - [void]$htmlScopeInsights.AppendLine(@" -

No Classic Administrators

-"@) + [void]$htmlScopeInsights.AppendLine(@' + No Classic Administrators +'@) } [void]$htmlScopeInsights.AppendLine(@' @@ -3765,7 +3765,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ $randomFunctionName = "func_$htmlTableId" $noteOrNot = '' [void]$htmlScopeInsights.AppendLine(@" - +
   Download CSV semicolon | comma
  *Depending on the number of rows and your computer´s performance the table may respond with delay, download the csv for better filtering experience @@ -3890,7 +3890,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlScopeInsights.AppendLine(@" -

$(($rbacAll).count) Role assignments

+ $(($rbacAll).count) Role assignments "@) } diff --git a/pwsh/dev/functions/processStorageAccountAnalysis.ps1 b/pwsh/dev/functions/processStorageAccountAnalysis.ps1 index 06ee2396..b8889576 100644 --- a/pwsh/dev/functions/processStorageAccountAnalysis.ps1 +++ b/pwsh/dev/functions/processStorageAccountAnalysis.ps1 @@ -186,12 +186,32 @@ function processStorageAccountAnalysis { } if ([string]::IsNullOrWhiteSpace($storageAccount.properties.publicNetworkAccess)) { - $publicNetworkAccess = 'likely enabled' + $publicNetworkAccess = 'likely Enabled' } else { $publicNetworkAccess = $storageAccount.properties.publicNetworkAccess } + if ([string]::IsNullOrWhiteSpace($storageAccount.properties.allowedCopyScope)) { + $allowedCopyScope = 'From any Storage Account' + } + else { + $allowedCopyScope = $storageAccount.properties.allowedCopyScope + } + + if ([string]::IsNullOrWhiteSpace($storageAccount.properties.allowCrossTenantReplication)) { + if ($allowedCopyScope -ne 'From any Storage Account') { + $allowCrossTenantReplication = "likely False (allowedCopyScope=$allowedCopyScope)" + } + else { + $allowCrossTenantReplication = 'likely True' + } + } + else { + $allowCrossTenantReplication = $storageAccount.properties.allowCrossTenantReplication + } + + $temp = [System.Collections.ArrayList]@() $null = $temp.Add([PSCustomObject]@{ storageAccount = $storageAccount.name @@ -228,6 +248,8 @@ function processStorageAccountAnalysis { minimumTlsVersion = $storageAccount.properties.minimumTlsVersion allowSharedKeyAccess = $allowSharedKeyAccess requireInfrastructureEncryption = $requireInfrastructureEncryption + allowedCopyScope = $allowedCopyScope + allowCrossTenantReplication = $allowCrossTenantReplication }) if ($StorageAccountAccessAnalysisSubscriptionTags[0] -ne 'undefined' -and $StorageAccountAccessAnalysisSubscriptionTags.Count -gt 0) { diff --git a/pwsh/dev/functions/processTenantSummary.ps1 b/pwsh/dev/functions/processTenantSummary.ps1 index 28d55f56..5fd7945f 100644 --- a/pwsh/dev/functions/processTenantSummary.ps1 +++ b/pwsh/dev/functions/processTenantSummary.ps1 @@ -1214,7 +1214,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ } else { [void]$htmlTenantSummary.AppendLine(@" -

$tenantCustomPoliciesCount Custom Policy definitions ($scopeNamingSummary)

+

$tenantCustomPoliciesCount Custom Policy definitions ($scopeNamingSummary)

"@) } } @@ -1377,7 +1377,7 @@ paging: {results_per_page: ['Records: ', [$spectrum]]},/*state: {types: ['local_ } else { [void]$htmlTenantSummary.AppendLine(@" -

$tenantCustomPoliciesCount Custom Policy definitions ($scopeNamingSummary)

+

$tenantCustomPoliciesCount Custom Policy definitions ($scopeNamingSummary)

"@) } } @@ -1500,7 +1500,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($customPoliciesOrphaned).count) Orphaned Custom Policy definitions ($scopeNamingSummary)

+

$(($customPoliciesOrphaned).count) Orphaned Custom Policy definitions ($scopeNamingSummary)

"@) } } @@ -1624,7 +1624,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$($arrayCustomPoliciesOrphanedFinalIncludingResourceGroups.count) Orphaned Custom Policy definitions ($scopeNamingSummary)

+

$($arrayCustomPoliciesOrphanedFinalIncludingResourceGroups.count) Orphaned Custom Policy definitions ($scopeNamingSummary)

"@) } } @@ -2003,7 +2003,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$tenantCustomPolicySetsCount Custom PolicySet definitions ($scopeNamingSummary)

+

$tenantCustomPolicySetsCount Custom PolicySet definitions ($scopeNamingSummary)

"@) } } @@ -2135,7 +2135,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$tenantCustomPolicySetsCount Custom PolicySet definitions ($scopeNamingSummary)

+

$tenantCustomPolicySetsCount Custom PolicySet definitions ($scopeNamingSummary)

"@) } } @@ -2240,7 +2240,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($arraycustompolicySetSetsOrphanedFinalIncludingResourceGroups).count) Orphaned Custom PolicySet definitions ($scopeNamingSummary)

+

$(($arraycustompolicySetSetsOrphanedFinalIncludingResourceGroups).count) Orphaned Custom PolicySet definitions ($scopeNamingSummary)

"@) } } @@ -2359,7 +2359,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($arraycustompolicySetsOrphanedFinalIncludingResourceGroups).count) Orphaned Custom PolicySet definitions ($scopeNamingSummary)

+

$(($arraycustompolicySetsOrphanedFinalIncludingResourceGroups).count) Orphaned Custom PolicySet definitions ($scopeNamingSummary)

"@) } } @@ -2588,13 +2588,13 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@' -

Azure Landing Zones (ALZ) Policy Version Checker

+

Azure Landing Zones (ALZ) Policy Version Checker

'@) } } else { [void]$htmlTenantSummary.AppendLine(@" -

Azure Landing Zones (ALZ) Policy Version Checker (parameter -NoALZPolicyVersionChecker = $NoALZPolicyVersionChecker)

+

Azure Landing Zones (ALZ) Policy Version Checker (parameter -NoALZPolicyVersionChecker = $NoALZPolicyVersionChecker)

"@) } #endregion SUMMARYALZPolicies @@ -2715,7 +2715,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($policySetsDeprecated).count) PolicySets / deprecated Built-in Policy

+

$(($policySetsDeprecated).count) PolicySets / deprecated Built-in Policy

"@) } #endregion SUMMARYPolicySetsDeprecatedPolicy @@ -2867,7 +2867,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($policyAssignmentsDeprecated).count) Policy assignments / deprecated Built-in Policy

+

$(($policyAssignmentsDeprecated).count) Policy assignments / deprecated Built-in Policy

"@) } #endregion SUMMARYPolicyAssignmentsDeprecatedPolicy @@ -3190,7 +3190,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$($policyExemptionsCount) Policy exemptions

+

$($policyExemptionsCount) Policy exemptions

"@) } #endregion SUMMARYPolicyExemptions @@ -3275,7 +3275,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$($policyAssignmentsOrphanedCount) Policy assignments orphaned

+

$($policyAssignmentsOrphanedCount) Policy assignments orphaned

"@) } #endregion SUMMARYPolicyAssignmentsOrphaned @@ -4250,7 +4250,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($arrayPolicyAssignmentsEnriched).count) Policy assignments

+

$(($arrayPolicyAssignmentsEnriched).count) Policy assignments

"@) } $endSummaryPolicyAssignmentsAllHTML = Get-Date @@ -4414,7 +4414,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$tenantCustomRolesCount Custom Role definitions ($scopeNamingSummary)

+

$tenantCustomRolesCount Custom Role definitions ($scopeNamingSummary)

"@) } #endregion SUMMARYtenanttotalcustomroles @@ -4534,7 +4534,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($arrayCustomRolesOrphanedFinalIncludingResourceGroups).count) Orphaned Custom Role definitions ($scopeNamingSummary)

+

$(($arrayCustomRolesOrphanedFinalIncludingResourceGroups).count) Orphaned Custom Role definitions ($scopeNamingSummary)

"@) } #not renant root @@ -4664,7 +4664,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($arrayCustomRolesOrphanedFinalIncludingResourceGroups).count) Orphaned Custom Role definitions ($scopeNamingSummary)

+

$(($arrayCustomRolesOrphanedFinalIncludingResourceGroups).count) Orphaned Custom Role definitions ($scopeNamingSummary)

"@) } } @@ -4763,7 +4763,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($roleAssignmentsOrphanedUnique).count) Orphaned Role assignments ($scopeNamingSummary)

+

$(($roleAssignmentsOrphanedUnique).count) Orphaned Role assignments ($scopeNamingSummary)

"@) } #endregion SUMMARYOrphanedRoleAssignments @@ -4863,7 +4863,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@' -

No ClassicAdministrators

+

No ClassicAdministrators

'@) } #endregion SUMMARYClassicAdministrators @@ -5181,7 +5181,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@" -

$($rbacAllCount) Role assignments

+

$($rbacAllCount) Role assignments

"@) } @@ -5336,7 +5336,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@' -

No PIM Eligibility

+

No PIM Eligibility

'@) } @@ -5346,12 +5346,12 @@ extensions: [{ name: 'sort' }] else { if ($azAPICallConf['htParameters'].accountType -ne 'User' -and $NoPIMEligibility) { [void]$htmlTenantSummary.AppendLine(@" -

No PIM Eligibility - parameter -NoPIMEligibility = $NoPIMEligibility

+

No PIM Eligibility - parameter -NoPIMEligibility = $NoPIMEligibility

"@) } else { [void]$htmlTenantSummary.AppendLine(@' -

No PIM Eligibility - run AzGovViz with a Service Principal to get PIM Eligibility insights

+

No PIM Eligibility - run AzGovViz with a Service Principal to get PIM Eligibility insights

'@) } } @@ -5455,7 +5455,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($customRolesOwnerHtAll).count) Custom Role definitions Owner permissions ($scopeNamingSummary)

+

$(($customRolesOwnerHtAll).count) Custom Role definitions Owner permissions ($scopeNamingSummary)

"@) } #endregion SUMMARYSecurityCustomRoles @@ -5576,7 +5576,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$($tenantAllRolesCanDoRoleAssignmentsCount) Role definitions can apply Role assignments

+

$($tenantAllRolesCanDoRoleAssignmentsCount) Role definitions can apply Role assignments

"@) } #endregion SUMMARYSecurityRolesCanDoRoleAssignments @@ -5675,7 +5675,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($roleAssignmentsOwnerAssignmentSP).count) Owner permission assignments to ServicePrincipal ($scopeNamingSummary)

+

$(($roleAssignmentsOwnerAssignmentSP).count) Owner permission assignments to ServicePrincipal ($scopeNamingSummary)

"@) } $endSUMMARYSecurityOwnerAssignmentSP = Get-Date @@ -5788,7 +5788,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($roleAssignmentsOwnerAssignmentNotGroup).count) Owner permission assignments to notGroup ($scopeNamingSummary)

+

$(($roleAssignmentsOwnerAssignmentNotGroup).count) Owner permission assignments to notGroup ($scopeNamingSummary)

"@) } $endSUMMARYSecurityOwnerAssignmentNotGroup = Get-Date @@ -5899,7 +5899,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($roleAssignmentsUserAccessAdministratorAssignmentNotGroup).count) UserAccessAdministrator permission assignments to notGroup ($scopeNamingSummary)

+

$(($roleAssignmentsUserAccessAdministratorAssignmentNotGroup).count) UserAccessAdministrator permission assignments to notGroup ($scopeNamingSummary)

"@) } $endSUMMARYSecurityUserAccessAdministratorAssignmentNotGroup = Get-Date @@ -6013,7 +6013,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$($highPrivilegedGuestUserRoleAssignmentsCount) Guest Users with high permissions ($scopeNamingSummary)

+

$($highPrivilegedGuestUserRoleAssignmentsCount) Guest Users with high permissions ($scopeNamingSummary)

"@) } $endSUMMARYSecurityGuestUserHighPriviledgesAssignments = Get-Date @@ -6319,7 +6319,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$blueprintDefinitionsOrphanedCount Orphaned Blueprint definitions

+

$blueprintDefinitionsOrphanedCount Orphaned Blueprint definitions

"@) } #endregion SUMMARYBlueprintsOrphaned @@ -6565,14 +6565,14 @@ extensions: [{ name: 'sort' }] #region SUMMARYMGdefault Write-Host ' processing TenantSummary ManagementGroups - default Management Group' [void]$htmlTenantSummary.AppendLine(@" -

Hierarchy Settings | Default Management Group Id: '$($defaultManagementGroupId)' docs

+

Hierarchy Settings | Default Management Group Id: '$($defaultManagementGroupId)' docs

"@) #endregion SUMMARYMGdefault #region SUMMARYMGRequireAuthorizationForGroupCreation Write-Host ' processing TenantSummary ManagementGroups - requireAuthorizationForGroupCreation Management Group' [void]$htmlTenantSummary.AppendLine(@" -

Hierarchy Settings | Require authorization for Management Group creation: '$($requireAuthorizationForGroupCreation)' docs

+

Hierarchy Settings | Require authorization for Management Group creation: '$($requireAuthorizationForGroupCreation)' docs

"@) #endregion SUMMARYMGRequireAuthorizationForGroupCreation @@ -6910,7 +6910,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$outOfScopeSubscriptionsCount Subscriptions out-of-scope

+

$outOfScopeSubscriptionsCount Subscriptions out-of-scope

"@) } #endregion SUMMARYOutOfScopeSubscriptions @@ -7001,7 +7001,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

Tag Name Usage ($tagsUsageCount Tags) docs

+

Tag Name Usage ($tagsUsageCount Tags) docs

"@) } #endregion SUMMARYTagNameUsage @@ -7094,14 +7094,14 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

Resources ($resourcesResourceTypeCount ResourceTypes)

+

Resources ($resourcesResourceTypeCount ResourceTypes)

"@) } } else { [void]$htmlTenantSummary.AppendLine(@' -

Resources (0 ResourceTypes)

+

Resources (0 ResourceTypes)

'@) } $endSUMMARYResources = Get-Date @@ -7200,14 +7200,14 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

Resources ($resourcesResourceTypeCount ResourceTypes)

+

Resources ($resourcesResourceTypeCount ResourceTypes)

"@) } } else { [void]$htmlTenantSummary.AppendLine(@' -

Resources (0 ResourceTypes)

+

Resources (0 ResourceTypes)

'@) } $endSUMMARYResources = Get-Date @@ -7443,7 +7443,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@' -

No CAF Naming Recommendation Compliance data

+

No CAF Naming Recommendation Compliance data

'@) } $endSUMMARYCAFResourceNamingALL = Get-Date @@ -7587,7 +7587,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@' -

No Orphaned Resources

+

No Orphaned Resources

'@) } $endSUMMARYOrphanedResources = Get-Date @@ -7744,7 +7744,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$resourceProvidersAllCount Resource Providers

+

$resourceProvidersAllCount Resource Providers

"@) } $endSUMMARYSubResourceProviders = Get-Date @@ -7897,7 +7897,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$resourceProvidersAllCount Resource Providers

+

$resourceProvidersAllCount Resource Providers

"@) } $endsumRPDetailed = Get-Date @@ -8003,7 +8003,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@' -

No enabled Subscriptions Features docs

+

No enabled Subscriptions Features docs

'@) } $endSubFeatures = Get-Date @@ -8098,7 +8098,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@' -

No Resource Locks at all docs

+

No Resource Locks at all docs

'@) } $endResourceLocks = Get-Date @@ -8852,6 +8852,8 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: {
+ + @@ -8888,6 +8890,8 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { + + "@) @@ -8944,6 +8948,8 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { col_24: 'select', col_25: 'select', col_26: 'select', + col_27: 'select', + col_28: 'select', col_types: [ 'caseinsensitivestring', 'caseinsensitivestring', @@ -8971,6 +8977,8 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { 'caseinsensitivestring', 'caseinsensitivestring', 'caseinsensitivestring', + 'caseinsensitivestring', + 'caseinsensitivestring', 'caseinsensitivestring' ], extensions: [{ name: 'sort' }] @@ -8991,7 +8999,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@" -

Storage Account Access Analysis disabled - parameter -NoStorageAccountAccessAnalysis = $($azAPICallConf['htParameters'].NoStorageAccountAccessAnalysis)

+

Storage Account Access Analysis disabled - parameter -NoStorageAccountAccessAnalysis = $($azAPICallConf['htParameters'].NoStorageAccountAccessAnalysis)

"@) } #endregion SUMMARYStorageAccountAnalysis @@ -9149,7 +9157,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@' -

No Virtual Networks

+

No Virtual Networks

'@) } $endVNets = Get-Date @@ -9157,7 +9165,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@" -

Virtual Networks - Network Analysis disabled - parameter -NoNetwork = $($azAPICallConf['htParameters'].NoNetwork)

+

Virtual Networks - Network Analysis disabled - parameter -NoNetwork = $($azAPICallConf['htParameters'].NoNetwork)

"@) } #endregion SUMMARYVNets @@ -9329,7 +9337,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@' -

No Subnets

+

No Subnets

'@) } $endSubnets = Get-Date @@ -9337,7 +9345,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@" -

Subnets - Network Analysis disabled - parameter -NoNetwork = $($azAPICallConf['htParameters'].NoNetwork)

+

Subnets - Network Analysis disabled - parameter -NoNetwork = $($azAPICallConf['htParameters'].NoNetwork)

"@) } #endregion SUMMARYSubnets @@ -9644,7 +9652,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@' -

No Virtual Network Peerings

+

No Virtual Network Peerings

'@) } $endVNetPeerings = Get-Date @@ -9652,7 +9660,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@" -

Virtual Network Peerings - Network Analysis disabled - parameter -NoNetwork = $($azAPICallConf['htParameters'].NoNetwork)

+

Virtual Network Peerings - Network Analysis disabled - parameter -NoNetwork = $($azAPICallConf['htParameters'].NoNetwork)

"@) } #endregion SUMMARYVNetPeerings @@ -9677,11 +9685,16 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { if ($crossSubPECount -gt 0) { $crossSubPEText = " ($crossSubPECount cross Subscription)" } + $crossTenantPECount = ($privateEndPoints.where({ $_.crossTenantPE -eq $true })).Count + $crossTenantPEText = '' + if ($crossTenantPECount -gt 0) { + $crossTenantPEText = " ($crossTenantPECount cross Tenant)" + } $htmlTableId = 'TenantSummary_PrivateEndpoints' $tfCount = $privateEndPointsCount [void]$htmlTenantSummary.AppendLine(@" - +
Download CSV semicolon | comma
Minimum Tls Version Allow SharedKey Access Require Infrastructure EncryptionAllowed Copy ScopeAllow Cross Tenant Replication
$($result.minimumTlsVersion) $($result.allowSharedKeyAccess) $($result.requireInfrastructureEncryption)$($result.allowedCopyScope)$($result.allowCrossTenantReplication)
@@ -9698,6 +9711,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { + @@ -9739,6 +9753,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { + @@ -9806,9 +9821,10 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { col_7: 'select', col_8: 'select', col_9: 'select', - col_11: 'select', - col_13: 'select', - col_25: 'select', + col_10: 'select', + col_12: 'select', + col_14: 'select', + col_26: 'select', col_types: [ 'caseinsensitivestring', 'caseinsensitivestring', @@ -9838,6 +9854,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { 'caseinsensitivestring', 'caseinsensitivestring', 'caseinsensitivestring', + 'caseinsensitivestring', 'caseinsensitivestring' ], extensions: [{ name: 'sort' }] @@ -9850,7 +9867,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@' -

No Private Endpoints

+

No Private Endpoints

'@) } $endPrivateEndpoints = Get-Date @@ -9858,7 +9875,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { } else { [void]$htmlTenantSummary.AppendLine(@" -

Private Endpoints - Network Analysis disabled - parameter -NoNetwork = $($azAPICallConf['htParameters'].NoNetwork)

+

Private Endpoints - Network Analysis disabled - parameter -NoNetwork = $($azAPICallConf['htParameters'].NoNetwork)

"@) } #endregion SUMMARYPrivateEndpoints @@ -9877,7 +9894,7 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { '@) [void]$htmlTenantSummary.AppendLine( @' -

Management Groups

+

Management Groups

'@) #region SUMMARYDiagnosticsManagementGroups @@ -9888,10 +9905,10 @@ btn_reset: true, highlight_keywords: true, alternate_rows: true, auto_filter: { $tfCount = $diagnosticSettingsMgCount $htmlTableId = 'TenantSummary_DiagnosticsManagementGroups' [void]$htmlTenantSummary.AppendLine(@" - +
- Management Group Diagnostic Settings - Create Or Update - REST API docs
- Download CSV semicolon | comma + Management Group Diagnostic Settings - Create Or Update - REST API docs
+ Download CSV semicolon | comma
PE Type PE State Cross Subscription PECross Tenant PE Resource Resource Type$($result.PEConnectionType) $($result.PEConnectionState) $($result.CrossSubscriptionPE)$($result.CrossTenantPE) $($result.Resource) $($result.ResourceType)
@@ -10028,7 +10045,7 @@ extensions: [{ name: 'sort' }] else { [void]$htmlTenantSummary.AppendLine(@' -

No Management Groups configured for Diagnostic settings docs

+

No Management Groups configured for Diagnostic settings docs

'@) } @@ -10037,10 +10054,10 @@ extensions: [{ name: 'sort' }] $tfCount = $arrayMgsWithoutDiagnosticsCount $htmlTableId = 'TenantSummary_NoDiagnosticsManagementGroups' [void]$htmlTenantSummary.AppendLine(@" - +
- Management Group Diagnostic Settings - Create Or Update - REST API docs
- Download CSV semicolon | comma + Management Group Diagnostic Settings - Create Or Update - REST API docs
+ Download CSV semicolon | comma
@@ -10114,14 +10131,14 @@ extensions: [{ name: 'sort' }] else { [void]$htmlTenantSummary.AppendLine(@' -

All Management Groups are configured for Diagnostic settings docs

+

All Management Groups are configured for Diagnostic settings docs

'@) } #endregion SUMMARYDiagnosticsManagementGroups #region subscriptions [void]$htmlTenantSummary.AppendLine( @' -

Subscriptions

+

Subscriptions

'@) #region SUMMARYDiagnosticsSubscriptions @@ -10132,10 +10149,10 @@ extensions: [{ name: 'sort' }] $tfCount = $diagnosticSettingsSubCount $htmlTableId = 'TenantSummary_DiagnosticsSubscriptions' [void]$htmlTenantSummary.AppendLine(@" - +
- Create diagnostic setting docs
- Download CSV semicolon | comma + Create diagnostic setting docs
+ Download CSV semicolon | comma
@@ -10268,7 +10285,7 @@ extensions: [{ name: 'sort' }] else { [void]$htmlTenantSummary.AppendLine(@' -

No Subscriptions configured for Diagnostic settings docs

+

No Subscriptions configured for Diagnostic settings docs

'@) } @@ -10277,10 +10294,10 @@ extensions: [{ name: 'sort' }] $tfCount = $diagnosticSettingsSubNoDiagCount $htmlTableId = 'TenantSummary_NoDiagnosticsSubscriptions' [void]$htmlTenantSummary.AppendLine(@" - +
- Create diagnostic setting docs
- Download CSV semicolon | comma + Create diagnostic setting docs
+ Download CSV semicolon | comma
@@ -10354,7 +10371,7 @@ extensions: [{ name: 'sort' }] else { [void]$htmlTenantSummary.AppendLine(@' -

All Subscriptions are configured for Diagnostic settings docs

+

All Subscriptions are configured for Diagnostic settings docs

'@) } #endregion SUMMARYDiagnosticsSubscriptions @@ -10364,7 +10381,7 @@ extensions: [{ name: 'sort' }] if ($azAPICallConf['htParameters'].NoResources -eq $false) { #region resources [void]$htmlTenantSummary.AppendLine( @' -

Resources

+

Resources

'@) #region SUMMARYResourcesDiagnosticsCapable @@ -10378,11 +10395,11 @@ extensions: [{ name: 'sort' }] $tfCount = $resourceTypesDiagnosticsArraySortedCount $htmlTableId = 'TenantSummary_ResourcesDiagnosticsCapable' [void]$htmlTenantSummary.AppendLine(@" - +
- Create Custom Policies for Azure ResourceTypes that support Diagnostics Logs and Metrics Create-AzDiagPolicy
- Supported categories for Azure Resource Logs docs
- Download CSV semicolon | comma + Create Custom Policies for Azure ResourceTypes that support Diagnostics Logs and Metrics Create-AzDiagPolicy
+ Supported categories for Azure Resource Logs docs
+ Download CSV semicolon | comma
@@ -10479,7 +10496,7 @@ extensions: [{ name: 'sort' }] else { [void]$htmlTenantSummary.AppendLine(@' -

No Resources (1st party) Diagnostics capable

+

No Resources (1st party) Diagnostics capable

'@) } #endregion SUMMARYResourcesDiagnosticsCapable @@ -10737,10 +10754,10 @@ extensions: [{ name: 'sort' }] $htmlTableId = 'TenantSummary_DiagnosticsLifecycle' [void]$htmlTenantSummary.AppendLine(@" - +
- Create Custom Policies for Azure ResourceTypes that support Diagnostics Logs and Metrics Create-AzDiagPolicy
- Supported categories for Azure Resource Logs docs + Create Custom Policies for Azure ResourceTypes that support Diagnostics Logs and Metrics Create-AzDiagPolicy
+ Supported categories for Azure Resource Logs docs
@@ -10872,19 +10889,19 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@' -

No ResourceDiagnostics Policy Lifecycle recommendations

+

No ResourceDiagnostics Policy Lifecycle recommendations

'@) } } else { [void]$htmlTenantSummary.AppendLine(@' -

No ResourceDiagnostics Policy Lifecycle recommendations

+

No ResourceDiagnostics Policy Lifecycle recommendations

'@) } } else { [void]$htmlTenantSummary.AppendLine(@' -

No ResourceDiagnostics Policy Lifecycle recommendations

+

No ResourceDiagnostics Policy Lifecycle recommendations

'@) } $endsumDiagLifecycle = Get-Date @@ -10911,30 +10928,30 @@ extensions: [{ name: 'sort' }] #region tenantSummaryLimitsTenant [void]$htmlTenantSummary.AppendLine( @' -

Tenant

+

Tenant

'@) #policySets if ($tenantCustompolicySetsCount -gt (($LimitPOLICYPolicySetDefinitionsScopedTenant * $LimitCriticalPercentage) / 100)) { [void]$htmlTenantSummary.AppendLine(@" -

PolicySet definitions: $tenantCustompolicySetsCount/$LimitPOLICYPolicySetDefinitionsScopedTenant docs

+

PolicySet definitions: $tenantCustompolicySetsCount/$LimitPOLICYPolicySetDefinitionsScopedTenant docs

"@) } else { [void]$htmlTenantSummary.AppendLine(@" -

PolicySet definitions: $tenantCustompolicySetsCount/$LimitPOLICYPolicySetDefinitionsScopedTenant docs

+

PolicySet definitions: $tenantCustompolicySetsCount/$LimitPOLICYPolicySetDefinitionsScopedTenant docs

"@) } #CustomRoleDefinitions if ($tenantCustomRolesCount -gt (($LimitRBACCustomRoleDefinitionsTenant * $LimitCriticalPercentage) / 100)) { [void]$htmlTenantSummary.AppendLine(@" -

Custom Role definitions: $tenantCustomRolesCount/$LimitRBACCustomRoleDefinitionsTenant docs

+

Custom Role definitions: $tenantCustomRolesCount/$LimitRBACCustomRoleDefinitionsTenant docs

"@) } else { [void]$htmlTenantSummary.AppendLine(@" -

Custom Role definitions: $tenantCustomRolesCount/$LimitRBACCustomRoleDefinitionsTenant docs

+

Custom Role definitions: $tenantCustomRolesCount/$LimitRBACCustomRoleDefinitionsTenant docs

"@) } @@ -10942,7 +10959,7 @@ extensions: [{ name: 'sort' }] #region tenantSummaryLimitsManagementGroups [void]$htmlTenantSummary.AppendLine( @' -

Management Groups

+

Management Groups

'@) #region SUMMARYMgsapproachingLimitsPolicyAssignments @@ -10952,10 +10969,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($mgsApproachingLimitPolicyAssignments | Measure-Object).count $htmlTableId = 'TenantSummary_MgsapproachingLimitsPolicyAssignments' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure Policy Limits docs
- Download CSV semicolon | comma + Azure Policy Limits docs
+ Download CSV semicolon | comma
@@ -11027,7 +11044,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($mgsApproachingLimitPolicyAssignments | Measure-Object).count) Management Groups approaching Limit ($LimitPOLICYPolicyAssignmentsManagementGroup) for PolicyAssignment docs

+

$(($mgsApproachingLimitPolicyAssignments | Measure-Object).count) Management Groups approaching Limit ($LimitPOLICYPolicyAssignmentsManagementGroup) for PolicyAssignment docs

"@) } #endregion SUMMARYMgsapproachingLimitsPolicyAssignments @@ -11039,10 +11056,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($mgsApproachingLimitPolicyScope | Measure-Object).count $htmlTableId = 'TenantSummary_MgsapproachingLimitsPolicyScope' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure Policy Limits docs
- Download CSV semicolon | comma + Azure Policy Limits docs
+ Download CSV semicolon | comma
@@ -11114,7 +11131,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$($mgsApproachingLimitPolicyScope.count) Management Groups approaching Limit ($LimitPOLICYPolicyDefinitionsScopedManagementGroup) for Policy Scope docs

+

$($mgsApproachingLimitPolicyScope.count) Management Groups approaching Limit ($LimitPOLICYPolicyDefinitionsScopedManagementGroup) for Policy Scope docs

"@) } #endregion SUMMARYMgsapproachingLimitsPolicyScope @@ -11126,10 +11143,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($mgsApproachingLimitPolicySetScope | Measure-Object).count $htmlTableId = 'TenantSummary_MgsapproachingLimitsPolicySetScope' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure Policy Limits docs
- Download CSV semicolon | comma + Azure Policy Limits docs
+ Download CSV semicolon | comma
@@ -11201,7 +11218,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($mgsApproachingLimitPolicySetScope | Measure-Object).count) Management Groups approaching Limit ($LimitPOLICYPolicySetDefinitionsScopedManagementGroup) for PolicySet Scope docs

+

$(($mgsApproachingLimitPolicySetScope | Measure-Object).count) Management Groups approaching Limit ($LimitPOLICYPolicySetDefinitionsScopedManagementGroup) for PolicySet Scope docs

"@) } #endregion SUMMARYMgsapproachingLimitsPolicySetScope @@ -11214,10 +11231,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($mgsApproachingRoleAssignmentLimit).count $htmlTableId = 'TenantSummary_MgsapproachingLimitsRoleAssignment' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure RBAC Limits docs
- Download CSV semicolon | comma + Azure RBAC Limits docs
+ Download CSV semicolon | comma
@@ -11289,7 +11306,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($mgApproachingRoleAssignmentLimit | Measure-Object).count) Management Groups approaching Limit ($LimitRBACRoleAssignmentsManagementGroup) for RoleAssignment docs

+

$(($mgApproachingRoleAssignmentLimit | Measure-Object).count) Management Groups approaching Limit ($LimitRBACRoleAssignmentsManagementGroup) for RoleAssignment docs

"@) } #endregion SUMMARYMgsapproachingLimitsRoleAssignment @@ -11298,7 +11315,7 @@ extensions: [{ name: 'sort' }] #region tenantSummaryLimitsSubscriptions [void]$htmlTenantSummary.AppendLine( @' -

Subscriptions

+

Subscriptions

'@) #region SUMMARYSubsapproachingLimitsResourceGroups @@ -11308,10 +11325,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($subscriptionsApproachingLimitFromResourceGroupsAll | Measure-Object).count $htmlTableId = 'TenantSummary_SubsapproachingLimitsResourceGroups' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure Subscription Resource Group Limit docs
- Download CSV semicolon | comma + Azure Subscription Resource Group Limit docs
+ Download CSV semicolon | comma
@@ -11384,7 +11401,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" - $(($subscriptionsApproachingLimitFromResourceGroupsAll | Measure-Object).count) Subscriptions approaching Limit ($LimitResourceGroups) for ResourceGroups docs

+ $(($subscriptionsApproachingLimitFromResourceGroupsAll | Measure-Object).count) Subscriptions approaching Limit ($LimitResourceGroups) for ResourceGroups docs

"@) } #endregion SUMMARYSubsapproachingLimitsResourceGroups @@ -11396,10 +11413,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($subscriptionsApproachingLimitTags | Measure-Object).count $htmlTableId = 'TenantSummary_SubsapproachingLimitsSubscriptionTags' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure Subscription Tag Limit docs
- Download CSV semicolon | comma + Azure Subscription Tag Limit docs
+ Download CSV semicolon | comma
@@ -11471,7 +11488,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$($subscriptionsApproachingLimitTags.count) Subscriptions approaching Limit ($LimitTagsSubscription) for Tags docs

+

$($subscriptionsApproachingLimitTags.count) Subscriptions approaching Limit ($LimitTagsSubscription) for Tags docs

"@) } #endregion SUMMARYSubsapproachingLimitsSubscriptionTags @@ -11483,10 +11500,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($subscriptionsApproachingLimitPolicyAssignments | Measure-Object).count $htmlTableId = 'TenantSummary_SubsapproachingLimitsPolicyAssignments' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure Policy Limits docs
- Download CSV semicolon | comma + Azure Policy Limits docs
+ Download CSV semicolon | comma
@@ -11558,7 +11575,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($subscriptionsApproachingLimitPolicyAssignments | Measure-Object).count) Subscriptions approaching Limit ($LimitPOLICYPolicyAssignmentsSubscription) for PolicyAssignment docs

+

$(($subscriptionsApproachingLimitPolicyAssignments | Measure-Object).count) Subscriptions approaching Limit ($LimitPOLICYPolicyAssignmentsSubscription) for PolicyAssignment docs

"@) } #endregion SUMMARYSubsapproachingLimitsPolicyAssignments @@ -11570,10 +11587,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($subscriptionsApproachingLimitPolicyScope | Measure-Object).count $htmlTableId = 'TenantSummary_SubsapproachingLimitsPolicyScope' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure Policy Limits docs
- Download CSV semicolon | comma + Azure Policy Limits docs
+ Download CSV semicolon | comma
@@ -11645,7 +11662,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$($subscriptionsApproachingLimitPolicyScope.count) Subscriptions approaching Limit ($LimitPOLICYPolicyDefinitionsScopedSubscription) for Policy Scope docs

+

$($subscriptionsApproachingLimitPolicyScope.count) Subscriptions approaching Limit ($LimitPOLICYPolicyDefinitionsScopedSubscription) for Policy Scope docs

"@) } #endregion SUMMARYSubsapproachingLimitsPolicyScope @@ -11657,10 +11674,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($subscriptionsApproachingLimitPolicySetScope | Measure-Object).count $htmlTableId = 'TenantSummary_SubsapproachingLimitsPolicySetScope' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure Policy Limits docs
- Download CSV semicolon | comma + Azure Policy Limits docs
+ Download CSV semicolon | comma
@@ -11732,7 +11749,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

$(($subscriptionsApproachingLimitPolicyScope | Measure-Object).count) Subscriptions approaching Limit ($LimitPOLICYPolicySetDefinitionsScopedSubscription) for PolicySet Scope docs

+

$(($subscriptionsApproachingLimitPolicyScope | Measure-Object).count) Subscriptions approaching Limit ($LimitPOLICYPolicySetDefinitionsScopedSubscription) for PolicySet Scope docs

"@) } #endregion SUMMARYSubsapproachingLimitsPolicySetScope @@ -11747,10 +11764,10 @@ extensions: [{ name: 'sort' }] $tfCount = ($subscriptionsApproachingRoleAssignmentLimit).count $htmlTableId = 'TenantSummary_SubsapproachingLimitsRoleAssignment' [void]$htmlTenantSummary.AppendLine(@" - +
- Azure RBAC Limits docs
- Download CSV semicolon | comma + Azure RBAC Limits docs
+ Download CSV semicolon | comma
@@ -11822,7 +11839,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" - $(($subscriptionsApproachingRoleAssignmentLimit | Measure-Object).count) Subscriptions approaching Limit ($availableSubscriptionsRoleAssignmentLimits) for RoleAssignment docs

+ $(($subscriptionsApproachingRoleAssignmentLimit | Measure-Object).count) Subscriptions approaching Limit ($availableSubscriptionsRoleAssignmentLimits) for RoleAssignment docs

"@) } #endregion SUMMARYSubsapproachingLimitsRoleAssignment @@ -11921,7 +11938,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@' -

No ServicePrincipals where the API returned 'Request_ResourceNotFound'

+

No ServicePrincipals where the API returned 'Request_ResourceNotFound'

'@) } #endregion AADSPNotFound @@ -12002,7 +12019,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@' -

No Applications where the API returned 'Request_ResourceNotFound'

+

No Applications where the API returned 'Request_ResourceNotFound'

'@) } #endregion AADAppNotFound @@ -12320,7 +12337,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$servicePrincipalsOfTypeManagedIdentityCount AAD ServicePrincipals type=ManagedIdentity

+

$servicePrincipalsOfTypeManagedIdentityCount AAD ServicePrincipals type=ManagedIdentity

"@) } @@ -12490,7 +12507,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$servicePrincipalsOfTypeApplicationCount AAD ServicePrincipals type=Application

+

$servicePrincipalsOfTypeApplicationCount AAD ServicePrincipals type=Application

"@) } @@ -12499,7 +12516,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@' -

No information on AAD ServicePrincipals type=Application as Guest account does not have enough permissions

+

No information on AAD ServicePrincipals type=Application as Guest account does not have enough permissions

'@) } #endregion AADSPCredExpiry @@ -12629,7 +12646,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$appsWithOtherOrgIdCount External (appOwnerOrganizationId) AAD ServicePrincipals type=Application

+

$appsWithOtherOrgIdCount External (appOwnerOrganizationId) AAD ServicePrincipals type=Application

"@) } @@ -12746,7 +12763,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@' -

No information on Consumption

+

No information on Consumption

'@) } @@ -12756,7 +12773,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@' -

No information on Consumption as switch parameter -DoAzureConsumption was not applied

+

No information on Consumption as switch parameter -DoAzureConsumption was not applied

'@) } @@ -13099,7 +13116,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$customPolicyCreatedOrUpdatedCount Created/Updated custom Policy definitions

+

$customPolicyCreatedOrUpdatedCount Created/Updated custom Policy definitions

"@) } #endregion ChangeTrackingCustomPolicy @@ -13248,7 +13265,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$customPolicySetCreatedOrUpdatedCount Created/Updated custom PolicySet definitions

+

$customPolicySetCreatedOrUpdatedCount Created/Updated custom PolicySet definitions

"@) } #endregion ChangeTrackingCustomPolicySet @@ -13544,7 +13561,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$policyAssignmentsCreatedOrUpdatedCount Created/Updated Policy assignments

+

$policyAssignmentsCreatedOrUpdatedCount Created/Updated Policy assignments

"@) } #endregion ChangeTrackingPolicyAssignments @@ -13690,7 +13707,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$customRoleDefinitionsCreatedOrUpdatedCount Created/Updated custom Role definitions

+

$customRoleDefinitionsCreatedOrUpdatedCount Created/Updated custom Role definitions

"@) } #endregion ChangeTrackingCustomRoles @@ -13863,7 +13880,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$customRoleDefinitionsCreatedOrUpdatedCount Created/Updated custom Role definitions

+

$customRoleDefinitionsCreatedOrUpdatedCount Created/Updated custom Role definitions

"@) } #endregion ChangeTrackingRoleAssignments @@ -13987,7 +14004,7 @@ tf.init();}} } else { [void]$htmlTenantSummary.AppendLine(@" -

$resourcesCreatedOrChangedCount Created/Changed Resources

+

$resourcesCreatedOrChangedCount Created/Changed Resources

"@) } #endregion ChangeTrackingResources @@ -14024,7 +14041,7 @@ tf.init();}} $tfCount = $namingPolicyCount $htmlTableId = 'TenantSummary_NamingPolicy' [void]$htmlTenantSummary.AppendLine(@" - +
Download CSV semicolon | comma
@@ -14126,7 +14143,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

Policy $($namingPolicyCount) Naming findings

+

Policy $($namingPolicyCount) Naming findings

"@) } @@ -14135,7 +14152,7 @@ extensions: [{ name: 'sort' }] $tfCount = $namingPolicySetCount $htmlTableId = 'TenantSummary_NamingPolicySet' [void]$htmlTenantSummary.AppendLine(@" - +
Download CSV semicolon | comma
@@ -14237,7 +14254,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

PolicySet $($namingPolicySetCount) Naming findings

+

PolicySet $($namingPolicySetCount) Naming findings

"@) } @@ -14246,7 +14263,7 @@ extensions: [{ name: 'sort' }] $tfCount = $namingPolicyAssignmentCount $htmlTableId = 'TenantSummary_NamingPolicyAssignment' [void]$htmlTenantSummary.AppendLine(@" - +
Download CSV semicolon | comma
@@ -14348,7 +14365,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

Policy assignment $($namingPolicyAssignmentCount) Naming findings

+

Policy assignment $($namingPolicyAssignmentCount) Naming findings

"@) } @@ -14357,7 +14374,7 @@ extensions: [{ name: 'sort' }] $tfCount = $namingManagementGroupCount $htmlTableId = 'TenantSummary_NamingManagementGroup' [void]$htmlTenantSummary.AppendLine(@" - +
Download CSV semicolon | comma
@@ -14443,7 +14460,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

Management Group $($namingManagementGroupCount) Naming findings

+

Management Group $($namingManagementGroupCount) Naming findings

"@) } @@ -14453,7 +14470,7 @@ extensions: [{ name: 'sort' }] $tfCount = $namingSubscriptionCount $htmlTableId = 'TenantSummary_NamingSubscription' [void]$htmlTenantSummary.AppendLine(@" - +
Download CSV semicolon | comma
@@ -14538,7 +14555,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

Subscription $($namingSubscriptionCount) Naming findings

+

Subscription $($namingSubscriptionCount) Naming findings

"@) } @@ -14548,7 +14565,7 @@ extensions: [{ name: 'sort' }] $tfCount = $namingRoleCount $htmlTableId = 'TenantSummary_NamingRole' [void]$htmlTenantSummary.AppendLine(@" - +
Download CSV semicolon | comma
@@ -14633,7 +14650,7 @@ extensions: [{ name: 'sort' }] } else { [void]$htmlTenantSummary.AppendLine(@" -

RBAC $($namingRoleCount) Naming Findings

+

RBAC $($namingRoleCount) Naming Findings

"@) } diff --git a/version.txt b/version.txt index 58d1fa09..7af6aa7e 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -v6_major_20221202_5 \ No newline at end of file +v6_major_20221204_1 \ No newline at end of file