Skip to content

Commit

Permalink
Merge pull request #201 from JulianHayward/issue194
Browse files Browse the repository at this point in the history
Issue194
  • Loading branch information
JulianHayward authored Jul 7, 2023
2 parents 9e498af + 512e6be commit 0d58bb5
Show file tree
Hide file tree
Showing 6 changed files with 88 additions and 42 deletions.
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,10 @@ Listed as [security monitoring tool](https://docs.microsoft.com/en-us/azure/arch

## Release history

__Changes__ (2023-Jun-23 / 6.2.3 Minor)

* fix feature 'network' - optimize handling of unknown Subscription Ids

__Changes__ (2023-Jun-16 / 6.2.1 Minor)

* fix feature diagnostic capable resource name containing "+"
Expand Down
4 changes: 4 additions & 0 deletions history.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,10 @@

### Azure Governance Visualizer version 6

__Changes__ (2023-Jun-23 / 6.2.3 Minor)

* fix feature 'network' - optimize handling of unknown Subscription Ids

__Changes__ (2023-Jun-16 / 6.2.1 Minor)

* fix feature diagnostic capable resource name containing "+"
Expand Down
65 changes: 42 additions & 23 deletions pwsh/AzGovVizParallel.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ Param
$AzAPICallVersion = '1.1.72',

[string]
$ProductVersion = '6.2.1',
$ProductVersion = '6.2.3',

[string]
$GithubRepository = 'aka.ms/AzGovViz',
Expand Down Expand Up @@ -7751,26 +7751,45 @@ function processNetwork {
else {
$uri = "$($azAPICallConf['azAPIEndpointUrls'].ARM)/subscriptions/$($remotesubscriptionId)?api-version=2020-01-01"
$remoteTenantId = AzAPICall -AzAPICallConfiguration $azApiCallConf -uri $uri -listenOn 'content' -currentTask "getTenantId for subscriptionId '$($remotesubscriptionId)'"
$arrayRemoteMGPath = @()
foreach ($remoteId in $remoteTenantId) {
$objectGuid = [System.Guid]::empty
if ([System.Guid]::TryParse($remoteId, [System.Management.Automation.PSReference]$ObjectGuid)) {
if ($remoteId -in $MSTenantIds) {
$arrayRemoteMGPath += "$remoteId (MS)"
}
else {
$arrayRemoteMGPath += $remoteId
}
if ($remoteId -eq $azApiCallConf['checkcontext'].tenant.id) {
$peeringXTenant = 'false'
if ($remoteTenantId.id -like '/subscriptions/*') {
#sub actually could be resolved but not available in htSubscriptionsMgPath
Write-Host "SubscriptionId '$($remotesubscriptionId)' (tenantId: '$($remoteTenantId.tenantId)' (current context tenantId: '$($azapiCallConf['checkContext'].tenant.Id)')) was not captured by getSubscriptions/getEntities, however could be fully resolved with direct get call (ARM subscription API)" -ForegroundColor Magenta
$remoteMGPath = $remoteTenantId.tenantId
if ($azapiCallConf['checkContext'].tenant.Id -eq $remoteTenantId.tenantId) {
$peeringXTenant = 'false'
}
else {
$peeringXTenant = 'true'
}
}
else {
$arrayRemoteMGPath = @()
foreach ($remoteId in $remoteTenantId) {
if ($remoteId -eq 'SubscriptionNotFound Tenant unknown') {
$remoteMGPath = 'unknown'
$peeringXTenant = 'n/a'
}
else {
$peeringXTenant = 'true'
$objectGuid = [System.Guid]::empty
if ([System.Guid]::TryParse($remoteId, [System.Management.Automation.PSReference]$ObjectGuid)) {
if ($remoteId -in $MSTenantIds) {
$arrayRemoteMGPath += "$remoteId (MS)"
}
else {
$arrayRemoteMGPath += $remoteId
}
if ($remoteId -eq $azApiCallConf['checkcontext'].tenant.id) {
$peeringXTenant = 'false'
}
else {
$peeringXTenant = 'true'
}
}
$script:htUnknownTenantsForSubscription.($remotesubscriptionId) = @{}
$script:htUnknownTenantsForSubscription.($remotesubscriptionId).TenantId = $arrayRemoteMGPath -join ', '
$remoteMGPath += $arrayRemoteMGPath -join ', '
}
}
$script:htUnknownTenantsForSubscription.($remotesubscriptionId) = @{}
$script:htUnknownTenantsForSubscription.($remotesubscriptionId).TenantId = $arrayRemoteMGPath -join ', '
$remoteMGPath = $arrayRemoteMGPath -join ', '
}
}
}
Expand Down Expand Up @@ -7897,7 +7916,7 @@ function processNetwork {

RemoteSubscriptionName = $remotesubscriptionName
RemoteSubscription = $remotesubscriptionId
RemoteMGPath = $remoteMGPath
RemoteMGPath = $remoteMGPath -join ', '
RemoteVNet = $remotevnetName
RemoteVNetId = $peering.properties.remoteVirtualNetwork.id
RemoteVNetState = $remotevnetState
Expand Down Expand Up @@ -28999,10 +29018,10 @@ function validateLeastPrivilegeForUser {
$uri = "$($azAPICallConf['azAPIEndpointUrls'].ARM)/providers/Microsoft.Management/managementGroups/$($ManagementGroupId)/providers/Microsoft.Authorization/roleAssignments?api-version=2022-04-01&`$filter=principalId eq '$($azapicallConf['htParameters'].userObjectId)'"
$method = 'GET'
$getRoleAssignmentsForExecutingUserAtManagementGroupId = AzAPICall -AzAPICallConfiguration $azapicallConf -uri $uri
$nonReaderRolesAssigned = ($getRoleAssignmentsForExecutingUserAtManagementGroupId.properties.RoleDefinitionId | Sort-Object -Unique).where({ $_ -notlike '*acdd72a7-3385-48ef-bd42-f606fba81ae7' })
$nonReaderRolesAssigned = ($getRoleAssignmentsForExecutingUserAtManagementGroupId.properties.RoleDefinitionId | Sort-object -Unique).where({$_ -notlike '*acdd72a7-3385-48ef-bd42-f606fba81ae7'})
if ($nonReaderRolesAssigned.Count -gt 0) {
Write-Host '* * * LEAST PRIVILEGE ADVICE' -ForegroundColor DarkRed
Write-Host 'The Azure Governance Visualizer script is executed with more permissions than required.'
Write-Host "* * * LEAST PRIVILEGE ADVICE" -ForegroundColor DarkRed
Write-Host "The Azure Governance Visualizer script is executed with more permissions than required."
Write-Host "The executing identity '$($azapicallConf['checkContext'].Account.Id)' ($($azapicallConf['checkContext'].Account.Type)) Id: '$($azapicallConf['htparameters'].userObjectId)' has the following RBAC Role(s) assigned at Management Group scope '$ManagementGroupId':"
foreach ($nonReaderRoleAssigned in $nonReaderRolesAssigned) {
$currentTask = "Get RBAC Role definition '$nonReaderRoleAssigned'"
Expand All @@ -29013,14 +29032,14 @@ function validateLeastPrivilegeForUser {
if ($getRole.properties.roleName -eq 'owner' -or $getRole.properties.roleName -eq 'contributor') {
Write-Host " - $($getRole.properties.roleName) ($($getRole.properties.type)) !!!"
}
else {
else{
Write-Host " - $($getRole.properties.roleName) ($($getRole.properties.type))"
}
}
Write-Host "The required Azure RBAC role at Management Group scope '$ManagementGroupId' is 'Reader' (acdd72a7-3385-48ef-bd42-f606fba81ae7)."
Write-Host "Recommendation: consider executing the script in context of a Service Principal with least privilege. Review the Azure Governance Visualizer Setup Guide at 'https://github.com/JulianHayward/Azure-MG-Sub-Governance-Reporting/blob/master/setup.md'"
Write-Host ' * * * * * * * * * * * * * * * * * * * * * *' -ForegroundColor DarkRed
Pause
pause
}
else {
Write-Host "Azure Governance Visualizer Least Privilege check (Azure Resource side) for executing identity '$($azapicallConf['checkContext'].Account.Id)' ($($azapicallConf['checkContext'].Account.Type)) Id: '$($azapicallConf['htparameters'].userObjectId)' succeeded" -ForegroundColor Green
Expand Down
2 changes: 1 addition & 1 deletion pwsh/dev/devAzGovVizParallel.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ Param
$AzAPICallVersion = '1.1.72',

[string]
$ProductVersion = '6.2.1',
$ProductVersion = '6.2.3',

[string]
$GithubRepository = 'aka.ms/AzGovViz',
Expand Down
53 changes: 36 additions & 17 deletions pwsh/dev/functions/processNetwork.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -64,26 +64,45 @@ function processNetwork {
else {
$uri = "$($azAPICallConf['azAPIEndpointUrls'].ARM)/subscriptions/$($remotesubscriptionId)?api-version=2020-01-01"
$remoteTenantId = AzAPICall -AzAPICallConfiguration $azApiCallConf -uri $uri -listenOn 'content' -currentTask "getTenantId for subscriptionId '$($remotesubscriptionId)'"
$arrayRemoteMGPath = @()
foreach ($remoteId in $remoteTenantId) {
$objectGuid = [System.Guid]::empty
if ([System.Guid]::TryParse($remoteId, [System.Management.Automation.PSReference]$ObjectGuid)) {
if ($remoteId -in $MSTenantIds) {
$arrayRemoteMGPath += "$remoteId (MS)"
}
else {
$arrayRemoteMGPath += $remoteId
}
if ($remoteId -eq $azApiCallConf['checkcontext'].tenant.id) {
$peeringXTenant = 'false'
if ($remoteTenantId.id -like '/subscriptions/*') {
#sub actually could be resolved but not available in htSubscriptionsMgPath
Write-Host "SubscriptionId '$($remotesubscriptionId)' (tenantId: '$($remoteTenantId.tenantId)' (current context tenantId: '$($azapiCallConf['checkContext'].tenant.Id)')) was not captured by getSubscriptions/getEntities, however could be fully resolved with direct get call (ARM subscription API)" -ForegroundColor Magenta
$remoteMGPath = $remoteTenantId.tenantId
if ($azapiCallConf['checkContext'].tenant.Id -eq $remoteTenantId.tenantId) {
$peeringXTenant = 'false'
}
else {
$peeringXTenant = 'true'
}
}
else {
$arrayRemoteMGPath = @()
foreach ($remoteId in $remoteTenantId) {
if ($remoteId -eq 'SubscriptionNotFound Tenant unknown') {
$remoteMGPath = 'unknown'
$peeringXTenant = 'n/a'
}
else {
$peeringXTenant = 'true'
$objectGuid = [System.Guid]::empty
if ([System.Guid]::TryParse($remoteId, [System.Management.Automation.PSReference]$ObjectGuid)) {
if ($remoteId -in $MSTenantIds) {
$arrayRemoteMGPath += "$remoteId (MS)"
}
else {
$arrayRemoteMGPath += $remoteId
}
if ($remoteId -eq $azApiCallConf['checkcontext'].tenant.id) {
$peeringXTenant = 'false'
}
else {
$peeringXTenant = 'true'
}
}
$script:htUnknownTenantsForSubscription.($remotesubscriptionId) = @{}
$script:htUnknownTenantsForSubscription.($remotesubscriptionId).TenantId = $arrayRemoteMGPath -join ', '
$remoteMGPath += $arrayRemoteMGPath -join ', '
}
}
$script:htUnknownTenantsForSubscription.($remotesubscriptionId) = @{}
$script:htUnknownTenantsForSubscription.($remotesubscriptionId).TenantId = $arrayRemoteMGPath -join ', '
$remoteMGPath = $arrayRemoteMGPath -join ', '
}
}
}
Expand Down Expand Up @@ -210,7 +229,7 @@ function processNetwork {

RemoteSubscriptionName = $remotesubscriptionName
RemoteSubscription = $remotesubscriptionId
RemoteMGPath = $remoteMGPath
RemoteMGPath = $remoteMGPath -join ', '
RemoteVNet = $remotevnetName
RemoteVNetId = $peering.properties.remoteVirtualNetwork.id
RemoteVNetState = $remotevnetState
Expand Down
2 changes: 1 addition & 1 deletion version.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{
"ProductVersion": "6.2.1"
"ProductVersion": "6.2.3"
}

0 comments on commit 0d58bb5

Please sign in to comment.