Setting the file. One moment. Collect Azure Network Info · AKS Network Capture · microsoft/azure-skills · Skills Docsscripts/collect-azure-network-info.ps1
PowerShell·201 lines·8 KB
9 } else {
10 Join-Path "." "aks-network-captures/network-captures"
11 }),
12 [switch]$Help
13)
14
15function Write-Usage {
16 @"
17Usage: collect-azure-network-info.ps1 -ResourceGroup <rg> -ClusterName <name> [-OutputDir <path>]
18
19Collect AKS VNET, subnet, NSG, route, load-balancer, public-IP, peering,
20and private-DNS configuration into one JSON evidence file.
21"@
22}
23
24function Stop-Usage {
25 param([string]$Message)
26 [Console]::Error.WriteLine("Error: $Message")
27 [Console]::Error.WriteLine((Write-Usage))
28 exit 2
29}
30
31function Stop-Failure {
32 param([string]$Message)
33 [Console]::Error.WriteLine("Error: $Message")
34 exit 1
35}
36
37function Invoke-AzText {
38 param([string[]]$AzArguments, [string]$FailureMessage)
39 $output = (& az @AzArguments 2>&1) -join "`n"
40 if ($LASTEXITCODE -ne 0) {
41 Stop-Failure "$FailureMessage`n$output"
42 }
43 return $output.Trim()
44}
45
46function Invoke-AzJson {
47 param([string[]]$AzArguments, [string]$FailureMessage)
48 $raw = Invoke-AzText -AzArguments $AzArguments -FailureMessage $FailureMessage
49 try {
50 return $raw | ConvertFrom-Json -ErrorAction Stop
51 } catch {
52 Stop-Failure "$FailureMessage returned invalid JSON: $($_.Exception.Message)"
53 }
54}
55
56if ($Help) {
57 Write-Usage
58 exit 0
59}
60if ([string]::IsNullOrWhiteSpace($ResourceGroup)) {
61 Stop-Usage "-ResourceGroup is required"
62}
63if ([string]::IsNullOrWhiteSpace($ClusterName)) {
64 Stop-Usage "-ClusterName is required"
65}
66if ($ResourceGroup -match "[`r`n]") {
67 Stop-Usage "-ResourceGroup must be a single line"
68}
69if ($ClusterName -notmatch "^[A-Za-z0-9][A-Za-z0-9_-]{0,61}[A-Za-z0-9]$" -and
70 $ClusterName -notmatch "^[A-Za-z0-9]$") {
71 Stop-Usage "-ClusterName has an invalid format"
72}
73if ([string]::IsNullOrWhiteSpace($OutputDir) -or $OutputDir -match "[`r`n]") {
74 Stop-Usage "-OutputDir must be a non-empty single-line path"
75}
76if (-not (Get-Command az -ErrorAction SilentlyContinue)) {
77 Stop-Failure "Azure CLI (az) is not installed or not on PATH"
78}
79
80$existingUserAgent = $env:AZURE_HTTP_USER_AGENT
81$env:AZURE_HTTP_USER_AGENT = if ($existingUserAgent) {
82 "$existingUserAgent AKS-Skills"
83} else {
84 "AKS-Skills"
85}
86
87& az account show --output none
88if ($LASTEXITCODE -ne 0) {
89 Stop-Failure "not logged in to Azure CLI; run 'az login' first"
90}
91
92$nodeResourceGroup = Invoke-AzText -AzArguments @(
93 "aks", "show", "--resource-group", $ResourceGroup, "--name", $ClusterName,
94 "--query", "nodeResourceGroup", "-o", "tsv"
95) -FailureMessage "could not retrieve the AKS node resource group"
96if ([string]::IsNullOrWhiteSpace($nodeResourceGroup)) {
97 Stop-Failure "AKS cluster has no node resource group"
98}
99$vnetSubnetId = Invoke-AzText -AzArguments @(
100 "aks", "show", "--resource-group", $ResourceGroup, "--name", $ClusterName,
101 "--query", "agentPoolProfiles[0].vnetSubnetId", "-o", "tsv"
102) -FailureMessage "could not retrieve the AKS subnet"
103$networkPlugin = Invoke-AzText -AzArguments @(
104 "aks", "show", "--resource-group", $ResourceGroup, "--name", $ClusterName,
105 "--query", "networkProfile.networkPlugin", "-o", "tsv"
106) -FailureMessage "could not retrieve the AKS network plugin"
107$networkPolicy = Invoke-AzText -AzArguments @(
108 "aks", "show", "--resource-group", $ResourceGroup, "--name", $ClusterName,
109 "--query", "networkProfile.networkPolicy", "-o", "tsv"
110) -FailureMessage "could not retrieve the AKS network policy"
111if ([string]::IsNullOrWhiteSpace($networkPolicy)) {
112 $networkPolicy = "none"
113}
114
115$timestamp = (Get-Date).ToUniversalTime().ToString("yyyyMMdd-HHmmss")
116$result = [ordered]@{
117 cluster = [ordered]@{
118 name = $ClusterName
119 resourceGroup = $ResourceGroup
120 nodeResourceGroup = $nodeResourceGroup
121 networkPlugin = $networkPlugin
122 networkPolicy = $networkPolicy
123 timestamp = $timestamp
124 }
125 vnet = @{}
126 subnets = @()
127 nodeSubnet = @{}
128 nsgs = @()
129 routeTables = @()
130 loadBalancers = @()
131 publicIPs = @()
132 vnetPeerings = @()
133 privateDnsZones = @()
134}
135
136if (-not [string]::IsNullOrWhiteSpace($vnetSubnetId)) {
137 $segments = $vnetSubnetId.Trim("/").Split("/")
138 $vnetIndex = [Array]::IndexOf($segments, "virtualNetworks")
139 $subnetIndex = [Array]::IndexOf($segments, "subnets")
140 $resourceGroupIndex = [Array]::IndexOf($segments, "resourceGroups")
141 if ($vnetIndex -lt 0 -or $subnetIndex -lt 0 -or $resourceGroupIndex -lt 0) {
142 Stop-Failure "AKS returned an invalid VNET subnet resource ID"
143 }
144 $vnetName = $segments[$vnetIndex + 1]
145 $subnetName = $segments[$subnetIndex + 1]
146 $vnetResourceGroup = $segments[$resourceGroupIndex + 1]
147
148 $result.vnet = Invoke-AzJson -AzArguments @(
149 "network", "vnet", "show", "--resource-group", $vnetResourceGroup,
150 "--name", $vnetName, "-o", "json"
151 ) -FailureMessage "could not collect VNET information"
152 $result.subnets = @(Invoke-AzJson -AzArguments @(
153 "network", "vnet", "subnet", "list", "--resource-group", $vnetResourceGroup,
154 "--vnet-name", $vnetName, "-o", "json"
155 ) -FailureMessage "could not collect subnet information")
156 $result.nodeSubnet = Invoke-AzJson -AzArguments @(
157 "network", "vnet", "subnet", "show", "--resource-group", $vnetResourceGroup,
158 "--vnet-name", $vnetName, "--name", $subnetName,
159 "--query", "{name:name,addressPrefix:addressPrefix,udr:routeTable,nsg:networkSecurityGroup,delegations:delegations,serviceEndpoints:serviceEndpoints,privateEndpointNetworkPolicies:privateEndpointNetworkPolicies}",
160 "-o", "json"
161 ) -FailureMessage "could not collect the cluster subnet details"
162 $result.vnetPeerings = @(Invoke-AzJson -AzArguments @(
163 "network", "vnet", "peering", "list", "--resource-group", $vnetResourceGroup,
164 "--vnet-name", $vnetName, "-o", "json"
165 ) -FailureMessage "could not collect VNET peerings")
166}
167
168$result.nsgs = @(Invoke-AzJson -AzArguments @(
169 "network", "nsg", "list", "--resource-group", $nodeResourceGroup, "-o", "json"
170) -FailureMessage "could not collect network security groups")
171$result.routeTables = @(Invoke-AzJson -AzArguments @(
172 "network", "route-table", "list", "--resource-group", $nodeResourceGroup, "-o", "json"
173) -FailureMessage "could not collect route tables")
174$result.loadBalancers = @(Invoke-AzJson -AzArguments @(
175 "network", "lb", "list", "--resource-group", $nodeResourceGroup, "-o", "json"
176) -FailureMessage "could not collect load balancers")
177$result.publicIPs = @(Invoke-AzJson -AzArguments @(
178 "network", "public-ip", "list", "--resource-group", $nodeResourceGroup, "-o", "json"
179) -FailureMessage "could not collect public IPs")
180$result.privateDnsZones = @(Invoke-AzJson -AzArguments @(
181 "network", "private-dns", "zone", "list", "-o", "json"
182) -FailureMessage "could not collect private DNS zones")
183
184try {
185 New-Item -ItemType Directory -Path $OutputDir -Force -ErrorAction Stop | Out-Null
186 $outputFile = Join-Path $OutputDir "azure-network-info-$ClusterName-$timestamp.json"
187 $result | ConvertTo-Json -Depth 100 | Set-Content -LiteralPath $outputFile -Encoding UTF8 -ErrorAction Stop
188} catch {
189 Stop-Failure "could not write the evidence file: $($_.Exception.Message)"
190}
191
192Write-Output "Azure network information saved to: $outputFile"
193Write-Output "Cluster: $ClusterName"
194Write-Output "Network Plugin: $networkPlugin"
195Write-Output "Network Policy: $networkPolicy"
196Write-Output "NSGs: $($result.nsgs.Count)"
197Write-Output "Route Tables: $($result.routeTables.Count)"
198Write-Output "Load Balancers: $($result.loadBalancers.Count)"
199Write-Output "Public IPs: $($result.publicIPs.Count)"
200Write-Output "VNET Peerings: $($result.vnetPeerings.Count)"
201Write-Output "Private DNS Zones: $($result.privateDnsZones.Count)"