I'm trying to write some Powershell to get a list of Azure ARM vms (Not classic) and the currently associated IP addresses for their NICs.
In classic, this was part of the VM object, but in ARM it's a seperate object, and I'm struggling to get the Powershell to work in the way I want.
I've got the following code segment:
$nic = (((Get-AzureRmVM).NetworkProfile).NetworkInterfaces).Id
ForEach ($i in $nic) {
$nicname = $i.substring($i.LastIndexOf("/")+1)
Get-AzureRmNetworkInterface -Name $nicname -ResourceGroupName RGTEST | Get-AzureRmNetworkInterfaceIpConfig | select-object PrivateIpAddress,PrivateIpAllocationMethod
}
Which works, but only for VMs in the specified resource group 'RGTEST'.
It seems that Get-AzureRmNetworkInterface can only work when passed in the NIC Name and the ResourceGroupName, but I can't seem to get the RGname from the VM to be passed in.
Probably really easy, but I'm struggling with it!
Obtaining Azure RM VM IP Address Information Using the Get-AzureRmNetworkInterface cmdlet we can use the –ResourceGroupName parameter to work with a subset of the given VM Network Interfaces as they will be in different Resource Groups. This can be edited/adjusted to suit your requirements.
Sign in to the Azure portal. Navigate to the function app. Under Settings, select Properties. The inbound IP address appears under Virtual IP address.
Azure reserves the first four and last IP address for a total of 5 IP addresses within each subnet.
Description. The Get-AzPublicIPAddress cmdlet gets one or more public IP addresses in a resource group.
Below is the script I used to get the Private and Public IP for an Azure ARM VM. If a VM has more than one NIC or IpConfig it would probably need to use a loop.
$rg = Get-AzureRmResourceGroup -Name "MyResourceGroup01"
$vm = Get-AzureRmVM -ResourceGroupName $rg.ResourceGroupName -Name "MyVM01"
$nic = Get-AzureRmNetworkInterface -ResourceGroupName $rg.ResourceGroupName -Name $(Split-Path -Leaf $VM.NetworkProfile.NetworkInterfaces[0].Id)
$nic | Get-AzureRmNetworkInterfaceIpConfig | Select-Object Name,PrivateIpAddress,@{'label'='PublicIpAddress';Expression={Set-Variable -name pip -scope Global -value $(Split-Path -leaf $_.PublicIpAddress.Id);$pip}}
(Get-AzureRmPublicIpAddress -ResourceGroupName $rg.ResourceGroupName -Name $pip).IpAddress
#Output:
Name PrivateIpAddress PublicIpAddress
---- ---------------- ---------------
ipconfig1 10.0.0.10 MyVM01-pip
40.80.217.1
I use this code to get all my ARM VMs, their private IP address and allocation method, it works across resource groups.
$vms = get-azurermvm
$nics = get-azurermnetworkinterface | where VirtualMachine -NE $null #skip Nics with no VM
foreach($nic in $nics)
{
$vm = $vms | where-object -Property Id -EQ $nic.VirtualMachine.id
$prv = $nic.IpConfigurations | select-object -ExpandProperty PrivateIpAddress
$alloc = $nic.IpConfigurations | select-object -ExpandProperty PrivateIpAllocationMethod
Write-Output "$($vm.Name) : $prv , $alloc"
}
Sample Output:
proddc : 10.0.0.4 , Static
stagedc : 10.1.0.4 , Static
For those that are looking for a solution that works across multiple subscriptions in a tenant, here's a script that loops through each subscription and reports on each private IP, NIC, VM, Resource Group and associated subscription. The output is in object format and is exported to a CSV file.
<#
.SYNOPSIS
Returns IP addresses and associated network interfaces and virtual machines across all Azure subscriptions the
user has access to.
.DESCRIPTION
This script returns all private IP addresses, the IP configuration resources they are associated with, the network interfaces and virtual
machines across all subscriptions. This script requires:
1. The Azure module to be installed (https://docs.microsoft.com/en-us/powershell/azure/install-az-ps?view=azps-2.8.0)
2. The user to be logged in to an Azure account using Connect-AzAccount / Connect-AzureRmAccount
3. The user must have subscription wide read permissions assigned for each subscription being queried
.PARAMETER FileName
Optional. Specify the file name and path for a CSV export.
.EXAMPLE
Get-IpAddressAllocation.ps1 -FileName .\AzureIpAddressReport.csv
#>
<#
.AUTHOR
Michael Wheatfill
.LICENSEURI
https://github.com/mwheatfill/mwheatfill.github.io/blob/master/LICENSE.txt
#>
#region Parameters
[CmdletBinding()]
param (
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[String]
$FileName
)
#endregion Parameters
#region Initializations
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
#endregion Initializations
#region Functions
function Get-IpAddresses {
param ()
$networkInterfaces = Get-AzNetworkInterface | Where-Object {$_.VirtualMachine -ne $null}
$virtualMachines = Get-AzVM
$results = @()
foreach($interface in $networkInterfaces) {
$ipConfigurations = $interface.IpConfigurations
foreach($ipConfig in $ipConfigurations) {
$vm = $virtualMachines | Where-Object {$_.Id -eq $interface.VirtualMachine.Id}
$ipDetails = [pscustomobject]@{
PrivateIpAddress = $ipConfig.PrivateIpAddress
VMName = $vm.Name
NetworkInterface = $interface.Name
IpConfigName = $ipConfig.Name
Primary = $ipConfig.Primary
ResourceGroup = $vm.ResourceGroupName
Subscription = $subscription.Name
}
$results += $ipDetails
}
}
return $results
}
#endregion Functions
#region Main
$subscriptions = Get-AzSubscription | Select-Object
$ipAddressesInAllSubscriptions = @()
$progressCount = 0
foreach ($subscription in $subscriptions) {
$progressCount++
$progressComplete = ($progressCount / $subscriptions.count * 100)
$progressMessage = "Gathering IP address informtion for subscription $progressCount of $($subscriptions.Count)"
Write-Progress -Activity $progressMessage -Status ($subscription.Name) -PercentComplete $progressComplete
$subscription | Select-AzSubscription > $null
$ipAddressesInSubscription = Get-IpAddresses -SubscriptionObject $subscription
$ipAddressesInAllSubscriptions += $ipAddressesInSubscription
}
$ipAddressesInAllSubscriptions | Sort-Object -Property Subscription, VMName, NetworkInterface, IpConfigName, Primary | Format-Table
$ipAddressesInAllSubscriptions | Export-Csv -Path $FileName -NoTypeInformation
#endregion Main
Since this question was asked back in 2016, Microsoft decided to no longer maintain the AzureRM
module past Dec 2020, and along with it, the *-AzureRM*
cmdlets. The Az
module replaces it going forward.
However, there's a fast alternative for retrieving the list of Azure VMs with their associated IPs (private and public ones), by using Azure Resource Graph (ARG).
Concretely, for several thousand VMs, spread across several hundred Azure subscriptions, it takes mere seconds with ARG as opposed to 20+ minutes using Az
's Get-AzVM
cmdlet.
The script further down will report correctly even on multiple vmNics and multiple IP configurations per vmNic. It will retrieve all ARM VM data across the Azure subscriptions in the tenant. If running from either a local Powershell session or Cloud Shell, make sure you have the Az.ResourceGraph
module installed first.
Sample output on a small test Azure tenant:
The script follows:
function RunARGquery {
param (
[string[]]$SubscriptionIds,
[string]$ARG_query
)
$fullResultSet = @()
$pageSize = 5000
# Subscription batching code below taken
# from https://docs.microsoft.com/en-us/azure/governance/resource-graph/troubleshoot/general#toomanysubscription
# Create a counter, set the batch size, and prepare a variable for the results
$counter = [PSCustomObject] @{ Value = 0 }
$batchSize = 1000
# Group the subscriptions into batches
$subscriptionsBatch = $subscriptionIds | Group -Property { [math]::Floor($counter.Value++ / $batchSize) }
$currentBatchNo = 0
# Run the query for each batch
foreach ($batch in $subscriptionsBatch) {
$pagesProcessedSoFar = 0
do {
$results = @()
if($pagesProcessedSoFar -eq 0) {
$results = Search-AzGraph -Subscription $batch.Group -Query $ARG_query -First $pageSize
}
else {
$results = Search-AzGraph -Subscription $batch.Group -Query $ARG_query -First $pageSize -Skip ($pagesProcessedSoFar * $pageSize)
}
$pagesProcessedSoFar++
Write-Host "Processed $pagesProcessedSoFar pages so far. A number of $(($results | Measure-Object).count) results returned in the last page"
$fullResultSet += $results
} while(($results | Measure-Object).count -eq $pageSize)
Write-Host "Finished subscription batch $currentBatchNo"
$currentBatchNo++
}
return $fullResultSet
}
# Get the date/time now, for timestamping both output files
$currentDateTime = Get-Date -Uformat "%Y%m%d-%H%M%S"
Write-Host "Getting list of Azure subscriptions..."
# Fetch the full array of subscription IDs
$subscriptions = Get-AzSubscription
$subscriptionIds = $subscriptions.Id
Write-Host "Found $(($subscriptionIds | Measure-Object).count) subscriptions"
# ARG query from Listing 23
$ARM_ARG_query = @"
Resources
| where type =~ 'microsoft.compute/virtualmachines'
| project id, vmId = tolower(tostring(id)), vmName = name
| join (Resources
| where type =~ 'microsoft.network/networkinterfaces'
| mv-expand ipconfig=properties.ipConfigurations
| project vmId = tolower(tostring(properties.virtualMachine.id)), privateIp = ipconfig.properties.privateIPAddress, publicIpId = tostring(ipconfig.properties.publicIPAddress.id)
| join kind=leftouter (Resources
| where type =~ 'microsoft.network/publicipaddresses'
| project publicIpId = id, publicIp = properties.ipAddress
) on publicIpId
| project-away publicIpId, publicIpId1
| summarize privateIps = make_list(privateIp), publicIps = make_list(publicIp) by vmId
) on vmId
| project-away vmId, vmId1
| sort by vmName asc
"@
Write-Host "Running ARM ARG query..."
RunARGquery -SubscriptionIds $subscriptionIds -ARG_query $ARM_ARG_query `
| Select-Object -ExcludeProperty ResourceId `
| Sort-Object -Property vmName `
| Export-Csv -NoTypeInformation "AzureVMs_$currentDateTime.csv"
If you're looking to also retrieve the classic Azure VMs (ASM model), using ARG as well, a script is available here. A detailed discussion around the Azure Resource Graph queries for retrieving the VM data, throttling, permissions, etc can be found in this post.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With