Azure security

How to export public IP addresses in Azure

Export every public IP address with Azure PowerShell and Resource Graph, download them as CSV from Resource Graph Explorer, or run Altivane's Azure Network Rules Open to the Internet report.

By the Published

To export public IP addresses in Azure, query Resource Graph for every public IP address resource across your subscriptions and save the address, version, allocation method, SKU and what each is attached to. A dynamic address has no IP until it's attached to something, and an address attached to nothing is still listed, so check what holds each one.

Choose the method that fits the job
MethodBest fit
PowerShellA repeatable CSV of every public IP address across your enabled subscriptions.
Admin centreA one-off download from Resource Graph Explorer without installing tools.
AltivaneRecommended for regular network reviews, with the inbound rules open to the internet beside the addresses.

Before you start

Use an Azure account with read access to the subscriptions you want to export. The built-in Reader role is enough for Resource Graph queries, assigned at each subscription or a scope above. The Microsoft references list no separate Resource Graph licence.

Know what the list covers: public IP address resources, the kind you attach to network interfaces, load balancers, gateways, firewalls and Bastion hosts. Resource Graph is a near real-time index, so a change made a moment ago may not show yet. The examples read Azure and export a CSV; they don't attach, release or change any address. The script's finally block disconnects the account and clears its saved Azure contexts.

Option 1

Export public IP addresses with PowerShell

Install the modules once, sign in, and query the subscriptions the account can read. The script follows every page of results and works out what holds each address from its IP configuration or NAT gateway.

PowerShell
Install-Module -Name Az.Accounts, Az.ResourceGraph -Repository PSGallery -Scope CurrentUser
PowerShell
$ErrorActionPreference = 'Stop'
Connect-AzAccount -ErrorAction Stop
try {
    $subscriptionIds = @(
        Get-AzSubscription | Where-Object State -eq 'Enabled' | Select-Object -ExpandProperty Id
    )
    if ($subscriptionIds.Count -eq 0) {
        Write-Output 'No enabled subscriptions are available to this account.'
        return
    }
    $query = @(
        'Resources'
        '| where type =~ "microsoft.network/publicipaddresses"'
        '| project id, name, resourceGroup, subscriptionId, location,'
        '    address = tostring(properties.ipAddress),'
        '    version = tostring(properties.publicIPAddressVersion),'
        '    allocation = tostring(properties.publicIPAllocationMethod),'
        '    sku = tostring(sku.name),'
        '    ipConfiguration = tostring(properties.ipConfiguration.id),'
        '    natGateway = tostring(properties.natGateway.id)'
        '| order by id asc'
    ) -join ' '
    $records = [System.Collections.Generic.List[object]]::new()
    $skipToken = $null
    do {
        $arguments = @{ Query = $query; Subscription = $subscriptionIds; First = 1000 }
        if ($skipToken) { $arguments.SkipToken = $skipToken }
        $page = Search-AzGraph @arguments
        foreach ($record in $page.Data) { $records.Add($record) }
        $skipToken = $page.SkipToken
    } while ($skipToken)
    if ($records.Count -eq 0) {
        Write-Output 'No public IP addresses were found in these subscriptions.'
        return
    }
    $rows = @($records | ForEach-Object {
        $holder = if ($_.ipConfiguration) { $_.ipConfiguration } else { $_.natGateway }
        # Cut an IP configuration's ID back to the resource that owns it.
        $attached = 'Nothing'
        if ($holder) { $attached = $holder -replace '/[^/]*configurations/[^/]+$' }
        [pscustomobject]@{
            Name          = $_.name
            ResourceGroup = $_.resourceGroup
            Subscription  = $_.subscriptionId
            Location      = $_.location
            Address       = if ($_.address) { $_.address } else { 'Not assigned' }
            Version       = $_.version
            Allocation    = $_.allocation
            Sku           = $_.sku
            AttachedTo    = $attached
            ResourceId    = $_.id
        }
    })
    $rows | Export-Csv -Path './public-ip-addresses.csv' -NoTypeInformation -Encoding utf8
    $unused = @($rows | Where-Object AttachedTo -eq 'Nothing')
    Write-Output "$($rows.Count) addresses saved to public-ip-addresses.csv."
    Write-Output "$($unused.Count) are attached to nothing."
} finally {
    Disconnect-AzAccount | Out-Null
}

The CSV holds each address's name, resource group, subscription, location, IP, version, allocation method, SKU, the resource ID of what holds it and its own resource ID. AttachedTo is cut back from the IP configuration to the network interface, load balancer or gateway that owns it, or says Nothing. Address says Not assigned for a dynamic address that isn't attached. Keep id in the query: Resource Graph paging needs it.

Option 2

Download public IP addresses from Resource Graph Explorer

  1. Sign in to the Azure portal with an account that can read the subscriptions.
  2. Search for resource graph and choose Resource Graph Explorer.
  3. To change its scope, choose Directory, then choose the directory, management group or subscription to query.
  4. Paste this read-only query in Query 1 and choose Run query:
    KQL
    Resources
    | where type =~ 'microsoft.network/publicipaddresses'
    | project id, name, resourceGroup, subscriptionId, location,
        address = tostring(properties.ipAddress),
        version = tostring(properties.publicIPAddressVersion),
        allocation = tostring(properties.publicIPAllocationMethod),
        sku = tostring(sku.name),
        ipConfiguration = tostring(properties.ipConfiguration.id),
        natGateway = tostring(properties.natGateway.id)
    | order by id asc
  5. Review the addresses in Results, then choose Download as CSV to keep them.

The download holds up to 55,000 records, and an empty ipConfiguration and natGateway means the address is attached to nothing. This suits an occasional export; for one you repeat each month with what holds each address worked out, use PowerShell or Altivane.

Common questions

Why does an address have no IP?

Its allocation method is dynamic. A dynamic address is given an IP only when it's attached to a resource, and the IP is released when that resource is stopped or deleted. A static address keeps its IP until the address itself is deleted.

Do addresses attached to nothing cost money?

Public IPv4 addresses carry a charge; IPv6 addresses don't. To find the ones attached to nothing, see how to find unused public IP addresses in Azure.

What should I do with Basic SKU addresses?

Upgrade them. Microsoft retired Basic SKU public IP addresses on 30 September 2025 and publishes guidance for moving them to Standard.

Microsoft references

Technical references checked on 7 November 2026. The example scripts have been reviewed and syntax checked; they have not been run against a live tenant.

Talk to us about Altivane

Questions, or pricing? Get in touch.

Contact us