output/20260723_081532/govviz/repo/pwsh/dev/functions/processNetwork.ps1

function processNetwork {
    $start = Get-Date
    Write-Host "Processing Network enrichment ($($arrayVNets.Count) Virtual Networks)"

    $htVNets = @{}
    foreach ($vnet in $arrayVNets) {
        $htVNets.($vnet.id) = $vnet
    }

    $script:htSubnets = @{}
    $script:arrayVirtualNetworks = [System.Collections.ArrayList]@()
    $script:arraySubnets = [System.Collections.ArrayList]@()

    foreach ($vnet in $arrayVNets) {

        #region peerings
        $vnetIdSplit = ($vnet.id -split '/')
        $subscriptionId = $vnetIdSplit[2]

        $subscriptionName = 'n/a'
        $MGPath = 'n/a'
        if ($htSubscriptionsMgPath.($subscriptionId)) {
            $subHelper = $htSubscriptionsMgPath.($subscriptionId)
            $subscriptionName = $subHelper.displayName
            $MGPath = $subHelper.ParentNameChainDelimited
        }

        $subnetsWithPrivateEndPointsCount = 0
        if ($vnet.properties.subnets.properties.privateEndpoints.id.Count -gt 0) {
            $subnetsWithPrivateEndPointsCount = $vnet.properties.subnets.where({ $_.properties.privateEndpoints.id.Count -gt 0 }).Count
        }

        $subnetsWithConnectedDevicesCount = 0
        if ($vnet.properties.subnets.properties.ipConfigurations.id.Count -gt 0) {
            $subnetsWithConnectedDevicesCount = $vnet.properties.subnets.where({ $_.properties.ipConfigurations.id.Count -gt 0 }).Count
        }

        $vnetResourceGroup = $vnetIdSplit[4]
        if ($vnet.properties.virtualNetworkPeerings.id.Count -gt 0) {
            foreach ($peering in $vnet.properties.virtualNetworkPeerings) {
                $remotevnetIdSplit = ($peering.properties.remoteVirtualNetwork.id -split '/')
                $remotesubscriptionId = $remotevnetIdSplit[2]

                $remotesubscriptionName = 'n/a'
                $remoteMGPath = 'n/a'
                $peeringXTenant = 'unknown'
                if ($htSubscriptionsMgPath.($remotesubscriptionId)) {
                    $peeringXTenant = 'false'
                    $remotesubHelper = $htSubscriptionsMgPath.($remotesubscriptionId)
                    $remotesubscriptionName = $remotesubHelper.displayName
                    $remoteMGPath = $remotesubHelper.ParentNameChainDelimited
                }
                else {
                    if ($htUnknownTenantsForSubscription.($remotesubscriptionId)) {
                        $remoteTenantId = $htUnknownTenantsForSubscription.($remotesubscriptionId).TenantId
                        $remoteMGPath = $remoteTenantId
                        if ($remoteTenantId -eq $azApiCallConf['checkcontext'].tenant.id) {
                            $peeringXTenant = 'false'
                        }
                        else {
                            $peeringXTenant = 'true'
                        }
                    }
                    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)'"
                        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 = [System.Collections.ArrayList]@()
                            foreach ($remoteId in $remoteTenantId) {
                                if ($remoteId -eq 'SubscriptionNotFound Tenant unknown') {
                                    $remoteMGPath = 'unknown'
                                    $peeringXTenant = 'n/a'
                                }
                                else {
                                    $objectGuid = [System.Guid]::empty
                                    if ([System.Guid]::TryParse($remoteId, [System.Management.Automation.PSReference]$ObjectGuid)) {
                                        if ($remoteId -in $MSTenantIds) {
                                            $null = $arrayRemoteMGPath.Add("$remoteId (MS)")
                                        }
                                        else {
                                            $null = $arrayRemoteMGPath.Add($remoteId)
                                        }
                                        if ($remoteId -eq $azApiCallConf['checkcontext'].tenant.id) {
                                            $peeringXTenant = 'false'
                                        }
                                        else {
                                            $peeringXTenant = 'true'
                                        }
                                    }
                                    $script:htUnknownTenantsForSubscription.($remotesubscriptionId) = @{
                                        TenantId = $arrayRemoteMGPath -join ', '
                                    }
                                    $remoteMGPath += $arrayRemoteMGPath -join ', '
                                }
                            }
                        }
                    }
                }

                $remotevnetName = $remotevnetIdSplit[8]
                $remotevnetResourceGroup = $remotevnetIdSplit[4]

                if ($htVNets.($peering.properties.remoteVirtualNetwork.id)) {
                    $remotevnetState = 'existent'
                    $remoteLocation = $htVNets.($peering.properties.remoteVirtualNetwork.id).location
                    $remotePeeringsCount = $htVNets.($peering.properties.remoteVirtualNetwork.id).properties.virtualNetworkPeerings.id.Count
                    $remoteDhcpoptionsDnsservers = $htVNets.($peering.properties.remoteVirtualNetwork.id).properties.dhcpoptions.dnsservers
                    $remoteSubnetsCount = $htVNets.($peering.properties.remoteVirtualNetwork.id).properties.subnets.id.Count
                    $remoteSubnetsWithNSGCount = $htVNets.($peering.properties.remoteVirtualNetwork.id).properties.subnets.properties.networkSecurityGroup.id.Count
                    $remoteSubnetsWithRouteTable = $htVNets.($peering.properties.remoteVirtualNetwork.id).properties.subnets.properties.routeTable.id.Count
                    $remoteSubnetsWithDelegations = $htVNets.($peering.properties.remoteVirtualNetwork.id).properties.subnets.properties.delegations.id.Count
                    $remotePrivateEndPoints = $htVNets.($peering.properties.remoteVirtualNetwork.id).properties.subnets.properties.privateEndpoints.id.Count
                    $remoteSubnetsWithPrivateEndPoints = $htVNets.($peering.properties.remoteVirtualNetwork.id).properties.subnets.where({ $_.properties.privateEndpoints.id.Count -gt 0 }).Count
                    $remoteConnectedDevices = $htVNets.($peering.properties.remoteVirtualNetwork.id).properties.subnets.properties.ipConfigurations.id.Count
                    $remoteSubnetsWithConnectedDevices = $htVNets.($peering.properties.remoteVirtualNetwork.id).properties.subnets.where({ $_.properties.ipConfigurations.id.Count -gt 0 }).Count
                    $remoteDdosProtection = $htVNets.($peering.properties.remoteVirtualNetwork.id).properties.enableDdosProtection
                    $remotePeering = $htVNets.($peering.properties.remoteVirtualNetwork.id).properties.virtualNetworkPeerings.where({ $_.properties.remoteVirtualNetwork.id -eq $vnet.id })
                    if ($remotePeering.count -eq 1) {
                        $remotePeeringName = $remotePeering.name
                        $remotePeeringState = $remotePeering.Properties.peeringState
                        $remotePeeringSyncLevel = $remotePeering.Properties.peeringSyncLevel
                        $remoteAllowVirtualNetworkAccess = $remotePeering.properties.allowVirtualNetworkAccess
                        $remoteAllowForwardedTraffic = $remotePeering.properties.allowForwardedTraffic
                        $remoteAllowGatewayTransit = $remotePeering.properties.allowGatewayTransit
                        $remoteUseRemoteGateways = $remotePeering.properties.useRemoteGateways
                        $remoteDoNotVerifyRemoteGateways = $remotePeering.properties.doNotVerifyRemoteGateways
                        $remotePeerCompleteVnets = $remotePeering.properties.peerCompleteVnets
                        $remoteRouteServiceVips = $remotePeering.properties.routeServiceVips
                    }
                    else {
                        $remotePeeringName = 'n/a'
                        $remotePeeringState = 'n/a'
                        $remotePeeringSyncLevel = 'n/a'
                        $remoteAllowVirtualNetworkAccess = 'n/a'
                        $remoteAllowForwardedTraffic = 'n/a'
                        $remoteAllowGatewayTransit = 'n/a'
                        $remoteUseRemoteGateways = 'n/a'
                        $remoteDoNotVerifyRemoteGateways = 'n/a'
                        $remotePeerCompleteVnets = 'n/a'
                        $remoteRouteServiceVips = 'n/a'
                    }

                }
                else {
                    if ($getMgParentName -eq 'Tenant Root') {
                        $remotevnetState = 'non-existent'
                    }
                    else {
                        $remotevnetState = 'n/a'
                    }
                    $remoteLocation = 'n/a'
                    $remotePeeringsCount = 'n/a'
                    $remoteDhcpoptionsDnsservers = 'n/a'
                    $remoteSubnetsCount = 'n/a'
                    $remoteSubnetsWithNSGCount = 'n/a'
                    $remoteSubnetsWithRouteTable = 'n/a'
                    $remoteSubnetsWithDelegations = 'n/a'
                    $remotePrivateEndPoints = 'n/a'
                    $remoteSubnetsWithPrivateEndPoints = 'n/a'
                    $remoteConnectedDevices = 'n/a'
                    $remoteSubnetsWithConnectedDevices = 'n/a'
                    $remoteDdosProtection = 'n/a'
                    $remotePeeringName = 'n/a'
                    $remotePeeringState = 'n/a'
                    $remotePeeringSyncLevel = 'n/a'
                    $remoteAllowVirtualNetworkAccess = 'n/a'
                    $remoteAllowForwardedTraffic = 'n/a'
                    $remoteAllowGatewayTransit = 'n/a'
                    $remoteUseRemoteGateways = 'n/a'
                    $remoteDoNotVerifyRemoteGateways = 'n/a'
                    $remotePeerCompleteVnets = 'n/a'
                    $remoteRouteServiceVips = 'n/a'
                }

                $null = $script:arrayVirtualNetworks.Add([PSCustomObject]@{
                        SubscriptionName                                = $subscriptionName
                        Subscription                                    = ($vnet.id -split '/')[2]
                        MGPath                                          = $MGPath
                        VNet                                            = $vnet.name
                        VNetId                                          = $vnet.id
                        VNetResourceGroup                               = $vnetResourceGroup
                        Location                                        = $vnet.location
                        AddressSpaceAddressPrefixes                     = ($vnet.properties.addressSpace.addressPrefixes -join "$CsvDelimiterOpposite ")
                        DhcpoptionsDnsservers                           = ($vnet.properties.dhcpoptions.dnsservers -join "$CsvDelimiterOpposite ")
                        SubnetsCount                                    = $vnet.properties.subnets.id.Count
                        SubnetsWithNSGCount                             = $vnet.properties.subnets.properties.networkSecurityGroup.id.Count
                        SubnetsWithRouteTableCount                      = $vnet.properties.subnets.properties.routeTable.id.Count
                        SubnetsWithDelegationsCount                     = $vnet.properties.subnets.properties.delegations.id.Count
                        PrivateEndpointsCount                           = $vnet.properties.subnets.properties.privateEndpoints.id.Count
                        SubnetsWithPrivateEndPointsCount                = $subnetsWithPrivateEndPointsCount
                        ConnectedDevices                                = $vnet.properties.subnets.properties.ipConfigurations.id.Count
                        SubnetsWithConnectedDevicesCount                = $subnetsWithConnectedDevicesCount
                        DdosProtection                                  = $vnet.properties.enableDdosProtection

                        PeeringsCount                                   = $vnet.properties.virtualNetworkPeerings.id.Count
                        PeeringXTenant                                  = $peeringXTenant
                        PeeringName                                     = $peering.name
                        PeeringState                                    = $peering.properties.peeringState
                        PeeringSyncLevel                                = $peering.properties.peeringSyncLevel
                        AllowVirtualNetworkAccess                       = $peering.properties.allowVirtualNetworkAccess
                        AllowForwardedTraffic                           = $peering.properties.allowForwardedTraffic
                        AllowGatewayTransit                             = $peering.properties.allowGatewayTransit
                        UseRemoteGateways                               = $peering.properties.useRemoteGateways
                        DoNotVerifyRemoteGateways                       = $peering.properties.doNotVerifyRemoteGateways
                        PeerCompleteVnets                               = $peering.properties.peerCompleteVnets
                        RouteServiceVips                                = $peering.properties.routeServiceVips

                        RemotePeeringsCount                             = $remotePeeringsCount
                        RemotePeeringName                               = $remotePeeringName
                        RemotePeeringState                              = $remotePeeringState
                        RemotePeeringSyncLevel                          = $remotePeeringSyncLevel
                        RemoteAllowVirtualNetworkAccess                 = $RemoteAllowVirtualNetworkAccess
                        RemoteAllowForwardedTraffic                     = $RemoteAllowForwardedTraffic
                        RemoteAllowGatewayTransit                       = $RemoteAllowGatewayTransit
                        RemoteUseRemoteGateways                         = $RemoteUseRemoteGateways
                        RemoteDoNotVerifyRemoteGateways                 = $RemoteDoNotVerifyRemoteGateways
                        RemotePeerCompleteVnets                         = $RemotePeerCompleteVnets
                        RemoteRouteServiceVips                          = $RemoteRouteServiceVips

                        RemoteSubscriptionName                          = $remotesubscriptionName
                        RemoteSubscription                              = $remotesubscriptionId
                        RemoteMGPath                                    = $remoteMGPath -join ', '
                        RemoteVNet                                      = $remotevnetName
                        RemoteVNetId                                    = $peering.properties.remoteVirtualNetwork.id
                        RemoteVNetState                                 = $remotevnetState
                        RemoteVNetResourceGroup                         = $remotevnetResourceGroup
                        RemoteVNetLocation                              = $remoteLocation
                        RemoteAddressSpaceAddressPrefixes               = ($peering.properties.remoteAddressSpace.addressPrefixes -join "$CsvDelimiterOpposite ")
                        RemoteVirtualNetworkAddressSpaceAddressPrefixes = ($peering.properties.remoteVirtualNetworkAddressSpace.addressPrefixes -join "$CsvDelimiterOpposite ")

                        RemoteDhcpoptionsDnsservers                     = ($remoteDhcpoptionsDnsservers -join "$CsvDelimiterOpposite ")
                        RemoteSubnetsCount                              = $remoteSubnetsCount
                        RemoteSubnetsWithNSGCount                       = $remoteSubnetsWithNSGCount
                        RemoteSubnetsWithRouteTable                     = $remoteSubnetsWithRouteTable
                        RemoteSubnetsWithDelegations                    = $remoteSubnetsWithDelegations
                        RemotePrivateEndPoints                          = $remotePrivateEndPoints
                        RemoteSubnetsWithPrivateEndPoints               = $remoteSubnetsWithPrivateEndPoints
                        RemoteConnectedDevices                          = $remoteConnectedDevices
                        RemoteSubnetsWithConnectedDevices               = $remoteSubnetsWithConnectedDevices
                        RemoteDdosProtection                            = $remoteDdosProtection
                    })
            }

        }
        else {
            $null = $script:arrayVirtualNetworks.Add([PSCustomObject]@{
                    SubscriptionName                                = $subscriptionName
                    Subscription                                    = ($vnet.id -split '/')[2]
                    MGPath                                          = $MGPath
                    VNet                                            = $vnet.name
                    VNetId                                          = $vnet.id
                    VNetResourceGroup                               = $vnetResourceGroup
                    Location                                        = $vnet.location

                    AddressSpaceAddressPrefixes                     = ($vnet.properties.addressSpace.addressPrefixes -join "$CsvDelimiterOpposite ")
                    DhcpoptionsDnsservers                           = ($vnet.properties.dhcpoptions.dnsservers -join "$CsvDelimiterOpposite ")
                    SubnetsCount                                    = $vnet.properties.subnets.id.Count
                    SubnetsWithNSGCount                             = $vnet.properties.subnets.properties.networkSecurityGroup.id.Count
                    SubnetsWithRouteTableCount                      = $vnet.properties.subnets.properties.routeTable.id.Count
                    SubnetsWithDelegationsCount                     = $vnet.properties.subnets.properties.delegations.id.Count
                    PrivateEndpointsCount                           = $vnet.properties.subnets.properties.privateEndpoints.id.Count
                    SubnetsWithPrivateEndPointsCount                = $subnetsWithPrivateEndPointsCount
                    ConnectedDevices                                = $vnet.properties.subnets.properties.ipConfigurations.id.Count
                    SubnetsWithConnectedDevicesCount                = $subnetsWithConnectedDevicesCount
                    DdosProtection                                  = $vnet.properties.enableDdosProtection

                    PeeringsCount                                   = $vnet.properties.virtualNetworkPeerings.id.Count
                    PeeringXTenant                                  = 'n/a'
                    PeeringName                                     = ''
                    PeeringState                                    = ''
                    PeeringSyncLevel                                = ''
                    AllowVirtualNetworkAccess                       = ''
                    AllowForwardedTraffic                           = ''
                    AllowGatewayTransit                             = ''
                    UseRemoteGateways                               = ''
                    DoNotVerifyRemoteGateways                       = ''
                    PeerCompleteVnets                               = ''
                    RouteServiceVips                                = ''

                    RemotePeeringsCount                             = ''
                    RemotePeeringName                               = ''
                    RemotePeeringState                              = ''
                    RemotePeeringSyncLevel                          = ''
                    RemoteAllowVirtualNetworkAccess                 = ''
                    RemoteAllowForwardedTraffic                     = ''
                    RemoteAllowGatewayTransit                       = ''
                    RemoteUseRemoteGateways                         = ''
                    RemoteDoNotVerifyRemoteGateways                 = ''
                    RemotePeerCompleteVnets                         = ''
                    RemoteRouteServiceVips                          = ''

                    RemoteSubscriptionName                          = ''
                    RemoteSubscription                              = ''
                    RemoteMGPath                                    = ''
                    RemoteVNet                                      = ''
                    RemoteVNetId                                    = ''
                    RemoteVNetState                                 = ''
                    RemoteVNetResourceGroup                         = ''
                    RemoteVNetLocation                              = ''
                    RemoteAddressSpaceAddressPrefixes               = ''
                    RemoteVirtualNetworkAddressSpaceAddressPrefixes = ''
                    RemoteDhcpoptionsDnsservers                     = ''
                    RemoteSubnetsCount                              = ''
                    RemoteSubnetsWithNSGCount                       = ''
                    RemoteSubnetsWithRouteTable                     = ''
                    RemoteSubnetsWithDelegations                    = ''
                    RemotePrivateEndPoints                          = ''
                    RemoteSubnetsWithPrivateEndPoints               = ''
                    RemoteConnectedDevices                          = ''
                    RemoteSubnetsWithConnectedDevices               = ''
                    RemoteDdosProtection                            = ''
                })
        }
        #endregion peerings

        #region subnets

        if ($vnet.properties.subnets.Count -gt 0) {
            foreach ($subnet in $vnet.properties.subnets) {

                $script:htSubnets.($subnet.id) = @{
                    SubscriptionName = $subscriptionName
                    Subscription     = ($vnet.id -split '/')[2]
                    MGPath           = $MGPath
                    VNet             = $vnet.name
                    VNetId           = $vnet.id
                    Location         = $vnet.location
                    ResourceGroup    = $vnetResourceGroup
                }

                $arrayServiceEndPoints = @()
                if ($subnet.properties.serviceEndpoints.service.Count -gt 0) {
                    $arrayServiceEndPoints = foreach ($serviceEndpoint in $subnet.properties.serviceEndpoints) {
                        "$($serviceEndpoint.service) ($(($serviceEndpoint.locations | Sort-Object) -join ', '))"
                    }
                }

                $delegation = ''
                if ($subnet.properties.delegations.Count -gt 0) {
                    $delegation = "$($subnet.properties.delegations.properties.serviceName) ($(($subnet.properties.delegations.properties.actions | Sort-Object) -join ', '))"
                }

                #region IP address usage
                #https://github.com/ElanShudnow/AzureCode/blob/242b923eada55fa795b930473a50dedf14bdc409/PowerShell/AzSubnetAvailability/AzSubnetAvailability.ps1
                # Gets the mask from the IP configuration (I.e 10.0.0.0/24, turns to just "24")

                if (-not [string]::IsNullOrWhiteSpace($subnet.properties.addressPrefix)) {
                    $AddressPrefix = $subnet.properties.addressPrefix
                    $subnetNet = $AddressPrefix -replace '/.*'
                    $subnetNetOutput = $subnetNet
                }

                #ignore IPv6
                if (-not [string]::IsNullOrWhiteSpace($subnet.properties.addressPrefixes)) {
                    $arr = foreach ($entry in $subnet.properties.addressPrefixes) {
                        if ($entry -match '^(([01]?\d?\d|2[0-4]\d|25[0-5])\.){3}([01]?\d?\d|2[0-4]\d|25[0-5])\/(\d{1}|[0-2]{1}\d{1}|3[0-2])$') {
                            $AddressPrefix = $entry
                            $AddressPrefix -replace '/.*'
                            $subnetNet = $AddressPrefix -replace '/.*'
                        }
                        else {
                            "(ignoring IPv6 $entry)"
                        }
                    }
                    $subnetNetOutput = $arr
                }

                $Mask = $AddressPrefix.substring($AddressPrefix.Length - 2, 2)

                #Amount of available IP Addresses minus the 3 IPs that Azure consumes, minus net and broadcast
                #https://learn.microsoft.com/azure/virtual-network/virtual-networks-faq#are-there-any-restrictions-on-using-ip-addresses-within-these-subnets
                switch ($Mask) {
                    '30' { $AvailableAddresses = [Math]::Pow(2, 2) - 5 }
                    '29' { $AvailableAddresses = [Math]::Pow(2, 3) - 5 }
                    '28' { $AvailableAddresses = [Math]::Pow(2, 4) - 5 }
                    '27' { $AvailableAddresses = [Math]::Pow(2, 5) - 5 }
                    '26' { $AvailableAddresses = [Math]::Pow(2, 6) - 5 }
                    '25' { $AvailableAddresses = [Math]::Pow(2, 7) - 5 }
                    '24' { $AvailableAddresses = [Math]::Pow(2, 8) - 5 }
                    '23' { $AvailableAddresses = [Math]::Pow(2, 9) - 5 }
                    '22' { $AvailableAddresses = [Math]::Pow(2, 10) - 5 }
                    '21' { $AvailableAddresses = [Math]::Pow(2, 11) - 5 }
                    '20' { $AvailableAddresses = [Math]::Pow(2, 12) - 5 }
                    '19' { $AvailableAddresses = [Math]::Pow(2, 13) - 5 }
                    '18' { $AvailableAddresses = [Math]::Pow(2, 14) - 5 }
                    '17' { $AvailableAddresses = [Math]::Pow(2, 15) - 5 }
                    '16' { $AvailableAddresses = [Math]::Pow(2, 16) - 5 }
                    '15' { $AvailableAddresses = [Math]::Pow(2, 17) - 5 }
                    '14' { $AvailableAddresses = [Math]::Pow(2, 18) - 5 }
                    '13' { $AvailableAddresses = [Math]::Pow(2, 19) - 5 }
                    '12' { $AvailableAddresses = [Math]::Pow(2, 20) - 5 }
                    '11' { $AvailableAddresses = [Math]::Pow(2, 21) - 5 }
                    '10' { $AvailableAddresses = [Math]::Pow(2, 22) - 5 }
                    '9' { $AvailableAddresses = [Math]::Pow(2, 23) - 5 }
                    '8' { $AvailableAddresses = [Math]::Pow(2, 24) - 5 }
                }

                $IPsLeft = $AvailableAddresses - $subnet.properties.ipConfigurations.Count
                $PercentIPsUsed = [math]::Round((($subnet.properties.ipConfigurations.Count / $AvailableAddresses) * 100), 1)
                $subnetIPAddressUsageCritical = $false
                if ($PercentIPsUsed -gt $NetworkSubnetIPAddressUsageCriticalPercentage) {
                    $subnetIPAddressUsageCritical = $true
                }

                #endregion IP address usage

                $subnetPrefix = $AddressPrefix -replace '.*/'

                $subnetmask = ([IPAddress]"$([system.convert]::ToInt64(('1'*$subnetPrefix).PadRight(32,'0'),2))").IPAddressToString
                $IPBits = [int[]]$subnetNet.Split('.')
                $MaskBits = [int[]]$subnetmask.Split('.')
                $NetworkIDBits = 0..3 | ForEach-Object { $IPBits[$_] -band $MaskBits[$_] }
                $Broadcast = (0..3 | ForEach-Object { $NetworkIDBits[$_] + ($MaskBits[$_] -bxor 255) }) -join '.'
                $Range = "$subnetNet - $Broadcast"

                $null = $script:arraySubnets.Add([PSCustomObject]@{
                        SubscriptionName                  = $subscriptionName
                        Subscription                      = ($vnet.id -split '/')[2]
                        MGPath                            = $MGPath
                        VNet                              = $vnet.name
                        VNetId                            = $vnet.id
                        VNetResourceGroup                 = $vnetResourceGroup
                        Location                          = $vnet.location
                        SubnetName                        = $subnet.name
                        SubnetId                          = $subnet.id
                        SubnetNet                         = $subnetNetOutput -join "$CsvDelimiterOpposite "
                        SubnetPrefix                      = $subnetPrefix
                        Subnetmask                        = $subnetmask
                        Range                             = $Range
                        ConnectedDevices                  = $subnet.properties.ipConfigurations.Count
                        AvailableIPAddresses              = $IPsLeft
                        UsedIPAddressesPercent            = "$PercentIPsUsed %"
                        SubnetIPAddressUsageCritical      = $subnetIPAddressUsageCritical
                        PrivateEndpointNetworkPolicies    = $subnet.properties.privateEndpointNetworkPolicies
                        PrivateLinkServiceNetworkPolicies = $subnet.properties.privateLinkServiceNetworkPolicies
                        ServiceEndpointsCount             = $subnet.properties.serviceEndpoints.service.Count
                        ServiceEndpoints                  = $arrayServiceEndPoints -join ', '
                        Delegation                        = $delegation
                        NetworkSecurityGroup              = $subnet.properties.networkSecurityGroup.id
                        RouteTable                        = $subnet.properties.routeTable
                        NatGateway                        = ''
                        PrivateEndpoints                  = $subnet.properties.privateEndpoints.Count
                    })
            }
        }
        #endregion subnets
    }

    $end = Get-Date
    Write-Host " Processing Network enrichment duration: $((New-TimeSpan -Start $start -End $end).TotalSeconds) seconds"
}