【问题标题】:Get subnets and NICs associated with a given NSG for all subscriptions为所有订阅获取与给定 NSG 关联的子网和 NIC
【发布时间】:2021-04-18 14:50:50
【问题描述】:

我是 PS 的新手....试图在给定的订阅中获取 NSG(一旦这对所有订阅都有效)以显示以下属性(NSG 名称、位置、资源组、子网、NIC) .

我正在使用来自Getting list of NSG and corresponding Subnet or NIC 的以下脚本,但它为每个 NSG 列出了多次相同的信息,等于订阅中 NSG 的数量,因此脚本中一定有问题

$azNsgs = Get-AzNetworkSecurityGroup
       
 foreach ( $azNsg in $azNsgs ) {

 if ($azNsg.Subnets.Id -ne $null) {

     $NsgSubnets = $azNsg.Subnets.Id.Split('/')[-1]

}
         Get-AzNetworkSecurityGroup | `
            Select-Object `
            @{name = 'NSG Name'; expression = {$azNsg.Name} },  `
            @{name = 'Location'; expression = {$azNsg.Location} }, `
            @{name = 'Resource Group Name'; expression = {$azNsg.ResourceGroupName} },  `
            @{name = 'Subnets'; expression = $NsgSubnets } 
       
}

还希望脚本忽略 NIC/子网的空值,因为某些 NSG 将分配给子网,而其他 NSG 将分配给 NIC 最后一个 NSG 可以分配给多个子网/NIC,那么我如何获得 $azNsg.Subnets。 Id.Split('/')[-1] 部分适用于 Subnets.Id 或 NetworkInterfaces.Id 中的多个条目,而不仅仅是最后一个?

谢谢

【问题讨论】:

  • 您不需要在foreach 循环内第二次调用Get-AzNetworkSecurityGroup。只需使用$azNsg | Select-Object ....
  • 非常感谢@AdminOfThings .. 这似乎已经解决了那部分.. 你能帮我解决查询的第二部分,我想查看与每个 NSG 关联的子网和/或 NIC 吗?它应该列出所有子网/网卡,而不仅仅是最后一个
  • Index [-1] 获取数组的最后一个元素。如果您不只想要最后一个元素,那么您应该删除该索引。由于您使用if 语句来设置$NsgSubnets,因此当没有子网时它不会被重置。您的foreach 的第一行需要类似于$NsgSubnets = $null
  • 看了链接的帖子后,我想我明白了更多的问题。子网 ID 是一个路径,您只需要该路径的叶子(仅名称)。你可以试试$NsgSubnets = $azNsg.Subnets.foreach({$_.Id.Split('/')[-1]})

标签: powershell azure-nsg


【解决方案1】:

您可以执行以下操作:

$azNsgs = Get-AzNetworkSecurityGroup
       
    foreach ( $azNsg in $azNsgs ) {

        $NsgSubnets = $null

        if (!$azNsg.Subnets.Id) {
            $NsgSubnets = $azNsg.Subnets.foreach({$_.Id.Split('/')[-1]})
        }

         $azNsg |
            Select-Object @{name = 'NSG Name'; expression = {$_.Name}},
                @{name = 'Location'; expression = {$_.Location}},
                @{name = 'Resource Group Name'; expression = {$_.ResourceGroupName}},  
                @{name = 'Subnets'; expression = {$NsgSubnets -join ','}}
       
    }

整体改进包括:

  • 您只需运行Get-AzNetworkSecurityGroup 一次,因为您将其输出存储到变量中。您可以简单地从变量中检索其内容。这使代码执行得更快。
  • 由于您的对象可能有多个子网,您需要处理$azNsg.Subnets 是非空对象数组的情况。使用foreach() 方法,您可以针对该数组的每个元素处理代码。当 PowerShell 完全枚举数组输出时(就像在没有 foreach() 的情况下所做的那样),您的多个子网数组将成为最终输出上的一个大数组。然后[-1] 只返回最后一个Id 值。
  • 在没有else 语句的if 语句内设置$NsgSubnets 会导致稍后在代码执行中出现错误数据。如果网络有子网,$NsgSubnets 将被正确设置并返回。但是,如果下一个网络没有子网,则不会更新 $NsgSubnets 的值。因此,它会在您的Select-Object 命令中输出之前网络的子网信息。
  • 您并不总是需要反引号来继续。 |, 分隔元素自动支持延续。见Natural Line Continuations

【讨论】:

  • 我试过了,但即使某些 NSG(不是全部)关联了子网,它也不会返回任何子网
  • 可能需要将子网连接为单个字符串。我添加了代码来做到这一点。如果这不起作用,请显示$aznsg.subnets 的示例输出。我没有办法验证这一点。
  • 我无法从 $aznsg.subnets 获得任何信息,但是我运行以下命令来查询分配给多个子网的 NSG Get-AzNetworkSecurityGroup -Name <NSG-01> { "Id": "/subscriptions/0000000.....VNET-01/subnets/SUB-NONPROD-01", "IpAllocations": [] }, { "Id": "/subscriptions/000000000..../VNET-01/subnets/SUB-PROD-01", "IpAllocations": []
  • ...根据上述情况,我希望 SUB-NONPROD-01 和 SUB-PROD-01 会显示在子网列中
  • 我已经通过使用@{name = 'Subnets'; expression = { $NsgSubnets | ForEach ({$_.id.split('/')[-1] }) } } 获得了数据输出在不同的行subnet1 subnet2 subnet3 subnet4 但是当尝试使用export-excel将上述子网导出到单个单元格时,我得到System.Object []。令人惊讶的是,如果我使用 export-csv 这工作得很好,所以我假设它的 excel 是这里的罪魁祸首? Export-Excel -Path "$($home)\Documents\Work\Powershell\NSG-Summary-v12.xlsx" -WorksheetName ($azsub.Name) -Append -AutoSize -FreezeTopRow -BoldTopRow -AutoFilter 有什么想法吗?
猜你喜欢
  • 1970-01-01
  • 2021-09-20
  • 2022-01-24
  • 1970-01-01
  • 2015-12-06
  • 2013-07-02
  • 1970-01-01
  • 1970-01-01
  • 2019-11-03
相关资源
最近更新 更多