Azure governance

How to export the activity log in Azure

Export the activity log with Azure PowerShell, download it as CSV from Activity log in the Azure portal, or run Altivane's Azure Activity Log report for each subscription's last 7 days.

By the Published

To export the activity log in Azure, read each subscription's events with Get-AzActivityLog for the days you need and save the finished operations to a CSV. Azure keeps the activity log for 90 days, and 1 operation can be logged as several events as it starts and ends, so keep the final status to list it once.

Choose the method that fits the job
MethodBest fit
PowerShellA CSV of finished operations across your enabled subscriptions, for the days you choose.
Admin centreA quick CSV of what the activity log shows, filtered as you set it.
AltivaneRecommended for weekly reviews, with each subscription's last 7 days in 1 workbook.

Before you start

Use an account with the Monitoring Reader or Reader role on each subscription. Azure collects the activity log by default and doesn't charge for it during the 90 days it keeps it. Entries usually appear 3 to 20 minutes after the operation.

Know what the log holds. It records management operations, such as creating a virtual machine or changing a key vault access policy, and usually not reads. Operations inside a resource, such as reading a secret from a key vault, are in resource logs instead, which need a diagnostic setting. The examples read and export; they change nothing. The script's finally block disconnects the account and clears its saved Azure contexts.

Option 1

Export the activity log with PowerShell

Install the modules once. Get-AzActivityLog reads the subscription in the current context and returns at most 1,000 events for each call by default, so the script reads each subscription 1 day at a time and warns when a day reaches that limit: read that day again in shorter windows.

PowerShell
Install-Module -Name Az.Accounts, Az.Monitor -Repository PSGallery -Scope CurrentUser
PowerShell
$ErrorActionPreference = 'Stop'
Connect-AzAccount -ErrorAction Stop
try {
    $days = 7
    $subscriptions = @(Get-AzSubscription | Where-Object State -eq 'Enabled')
    if ($subscriptions.Count -eq 0) {
        Write-Output 'No enabled subscriptions are available to this account.'
        return
    }
    $end = Get-Date
    $rows = [System.Collections.Generic.List[object]]::new()
    foreach ($subscription in $subscriptions) {
        Set-AzContext -Subscription $subscription.Id | Out-Null
        for ($day = $days; $day -ge 1; $day--) {
            $from = $end.AddDays(-$day)
            $window = @{ StartTime = $from; EndTime = $from.AddDays(1); DetailedOutput = $true }
            $events = @(Get-AzActivityLog @window)
            if ($events.Count -ge 1000) {
                Write-Warning "$($subscription.Name): a day hit 1,000 events."
            }
            foreach ($entry in $events) {
                if ($entry.Category -ne 'Administrative') { continue }
                if ($entry.Status -notin 'Succeeded', 'Failed') { continue }
                $rows.Add([pscustomobject]@{
                    When          = $entry.EventTimestamp
                    Subscription  = $subscription.Name
                    Operation     = $entry.OperationName
                    Status        = $entry.Status
                    Caller        = $entry.Caller
                    ResourceGroup = $entry.ResourceGroupName
                    ResourceId    = $entry.ResourceId
                })
            }
        }
    }
    if ($rows.Count -eq 0) {
        Write-Output "No finished operations were logged in the last $days days."
    } else {
        $rows | Sort-Object When -Descending |
            Export-Csv -Path './activity-log.csv' -NoTypeInformation -Encoding utf8
        Write-Output "$($rows.Count) operations saved to activity-log.csv."
    }
} finally {
    Disconnect-AzAccount | Out-Null
}

The CSV keeps administrative operations that succeeded or failed, newest first, with who ran each, the resource group and the resource ID. Set $days up to 90 for a longer export. To see every stage of an operation, remove the Status line; the events of 1 operation share its OperationId.

Option 2

Download the activity log in the Azure portal

  1. Sign in to the Azure portal with an account that can read the subscriptions.
  2. Search for Monitor and open it, then select Activity log. Opened from Monitor, the only filter set is the subscription.
  3. Set Subscription and Timespan. Select Add Filter to narrow by resource, resource type, operation, event category or who started the event.
  4. Select Download as CSV. A long timespan takes a while to export, so shorten it if the download is slow.

Leave Export Activity Logs alone: it creates a diagnostic setting, which changes the subscription. The download suits 1 look at a short period; for the same file each week across subscriptions, use PowerShell or Altivane.

Common questions

Why can't I export more than 90 days?

Azure deletes activity log events after 90 days. To keep them longer, a diagnostic setting sends them to a storage account or a Log Analytics workspace, where retention past 90 days is charged. It is also the only way to keep who created a resource after that.

Why aren't reads in the log?

The activity log records changes and actions on resources, and usually not reads. Reads inside a resource, such as a query against a database, are in its resource logs, which Azure only collects through a diagnostic setting.

How do I see which settings an operation changed?

The activity log says who ran an operation and how it ended, not each property it changed. Resource changes in Azure Resource Graph show the properties before and after. See how to find recent resource changes in Azure.

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