Aug 03 2022 06:27 AM
Hi folks,
This is a quick script to retrieve IP addresses assigned to Azure guest network interfaces. The two key benefits this has over the portal is:
You will need the "Az.Network" module to run this script, and you should have already run Connect-AzAccount prior to calling it (since it's not a great idea to rely on implicit loading.)
It's basic but you should be able to extend this to suit your needs.
Note: If you choose to filter using the optional parameters, you may scope out public IP addresses since the parameters are passed to Get-AzPublicIpAddress and Get-AzNetworkInterface alike. You can change this behaviour yourself if you like, but I'd normally expect related resources to be co-located which is why it's written this way.
[cmdletbinding(DefaultParameterSetName="_default")]
Param(
[parameter(ParameterSetName="_default")][string] $Name = $null,
[parameter(ParameterSetName="_default")][string] $ResourceGroupName = $null,
[parameter(ParameterSetName="_default")][string] $VirtualMachineScaleSetName = $null,
[parameter(ParameterSetName="_default")][string] $VirtualMachineIndex = $null,
[parameter(ParameterSetName="_byResourceId")][string] $ResourceId = $null,
[parameter()][string] $Location = $null
)
#region Arguments for splatting.
$ArgumentsForInterface = [hashtable]::new();
$ArgumentsForPublicIPs = [hashtable]::new();
if (-not [string]::IsNullOrWhiteSpace($Name))
{
$ArgumentsForInterface.Add("Name", $Name);
$ArgumentsForPublicIPs.Add("NetworkInterfaceName", $Name);
}
if (-not [string]::IsNullOrWhiteSpace($ResourceGroupName))
{
$ArgumentsForInterface.Add("ResourceGroupName", $ResourceGroupName);
$ArgumentsForPublicIPs.Add("ResourceGroupName", $ResourceGroupName);
}
if (-not [string]::IsNullOrWhiteSpace($VirtualMachineScaleSetName))
{
$ArgumentsForInterface.Add("VirtualMachineScaleSetName", $VirtualMachineScaleSetName);
$ArgumentsForPublicIPs.Add("VirtualMachineScaleSetName", $VirtualMachineScaleSetName);
}
if (-not [string]::IsNullOrWhiteSpace($VirtualMachineIndex))
{
$ArgumentsForInterface.Add("VirtualMachineIndex", $VirtualMachineIndex);
$ArgumentsForPublicIPs.Add("VirtualMachineIndex", $VirtualMachineIndex);
}
if (-not [string]::IsNullOrWhiteSpace($ResourceId))
{
$ArgumentsForInterface.Add("ResourceId", $ResourceId);
$ArgumentsForPublicIPs.Add("ResourceId", $ResourceId);
}
#endregion
#region Build public IP list.
# Fetch all the public IP addresses. This may scale poorly for very large organisations but will save on expensive round trips for anyone not in that category.
# We're using a strongly-typed [System.Collections.Generic.Dictionary] - in line with best practice, since we'll be creating the hash. See https://docs.microsoft.com/en-us/dotnet/standard/collections/selecting-a-collection-class.
$PublicIPs = [System.Collections.Generic.Dictionary[[int], [PSCustomObject]]]::new();
try
{
Get-AzPublicIpAddress @ArgumentsForPublicIPs |
Where-Object { [string]::IsNullOrWhiteSpace($Location) -or ($Location.Equals($_.Location, [System.StringComparison]::OrdinalIgnoreCase)) } |
ForEach-Object {
if (-not $PublicIPs.ContainsKey($_.Id.GetHashCode()))
{
$null = $PublicIPs.Add(
$_.Id.GetHashCode(),
[PSCustomObject] @{
objectId = $_.ResourceGuid;
name = $_.Name;
location = $_.Location;
group = $_.ResourceGroupName;
status = $_.ProvisioningState;
type = "public";
family = $_.PublicIpAddressVersion;
allocation = $_.PublicIpAllocationMethod;
address = $_.IpAddress;
customDns = $_.DnsSettings -and $_.DnsSettings.DnsServers -and ($_.DnsSettings.DnsServers.Count -gt 0);
id = $_.Id;
}
);
}
}
}
catch
{
throw;
}
#endregion
Get-AzNetworkInterface @ArgumentsForInterface |
Where-Object { [string]::IsNullOrWhiteSpace($Location) -or ($Location.Equals($_.Location, [System.StringComparison]::OrdinalIgnoreCase)) } |
ForEach-Object {
$Interface = $_;
$Machine = $null;
if ($Interface.VirtualMachine -and ($Sections = $Interface.VirtualMachine.Id.Split("/")).Length -gt 5)
{
$Machine = $Sections[-1];
}
#region Process the IpConfigurations list.
foreach ($Entry in $Interface.IpConfigurations)
{
# Start with the common guest attributes.
$Hash = @{
objectId = $Interface.ResourceGuid;
name = $Interface.Name;
location = $Interface.Location;
group = $Interface.ResourceGroupName;
machine = $Machine;
id = $Interface.Id;
};
# Add any private address information and output that as an individual object.
if ($Entry.PrivateIpAddress)
{
$Hash["status"] = $Entry.ProvisioningState;
$Hash["type"] = "private";
$Hash["family"] = $Entry.PrivateIpAddressVersion;
$Hash["allocation"] = $Entry.PrivateIpAllocationMethod;
$Hash["address"] = $Entry.PrivateIpAddress;
$Hash["customDns"] = $Interface.DnsSettings -and $Interface.DnsSettings.DnsServers -and ($Interface.DnsSettings.DnsServers.Count -gt 0);
[PSCustomObject] $Hash | Select-Object -Property objectId, name, location, group, machine, status, type, family, allocation, address, customDns, id;
}
# Now do the same for public address information and output that as individual objects.
if ($Entry.PublicIpAddress)
{
$PublicIP = [PSCustomObject]::new();
foreach ($PublicIpEntry in $Entry.PublicIpAddress)
{
if ($PublicIPs.TryGetValue($PublicIpEntry.Id.GetHashCode(), [ref] $PublicIP))
{
$Hash["status"] = $PublicIP.status;
$Hash["type"] = $PublicIP.type;
$Hash["family"] = $PublicIP.family;
$Hash["allocation"] = $PublicIP.allocation;
$Hash["address"] = $PublicIP.address;
$Hash["customDns"] = $PublicIP.customDns;
[PSCustomObject] $Hash | Select-Object -Property objectId, name, location, group, machine, status, type, family, allocation, address, customDns, id;
}
}
}
}
#endregion
}
Cheers,
Lain