To find recent resource changes in Azure, query the resourcechanges table in Azure Resource Graph for each change's time, type, who made it and the properties it changed. Changes can be queried for 14 days, and only changes made through Azure Resource Manager are recorded, not data written inside a resource.
| Method | Best fit |
|---|---|
| PowerShell | A CSV of every change in the last 7 days across your enabled subscriptions. |
| Admin centre | A quick look at the changes behind an incident, grouped and filtered as you need. |
| Altivane | Recommended for change reviews, with each change's old and new values in a workbook. |
Before you start
Use an account with read access to the subscriptions, such as the Reader role: Resource Graph returns nothing for resources you can't read. Change Analysis in Resource Graph costs nothing extra and needs no setup. A change record is usually there in less than 5 minutes, and some of its details can arrive before others.
Know what is left out. Resource Graph doesn't see changes made through a resource's own data API, such as writing to a table in a storage account, or file and configuration changes in App Service. A created or deleted resource has a record with no changed properties, and a property that appears with a new API version isn't shown as a change. The examples read and export; they change nothing. The script's finally block disconnects the account and clears its saved Azure contexts.
Option 1
Find recent resource changes with PowerShell
Install the modules once. The script queries Resource Graph across the enabled subscriptions, follows every page of results, and saves 1 row for each change.
Install-Module -Name Az.Accounts, Az.ResourceGraph -Repository PSGallery -Scope CurrentUser$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 = @(
'resourcechanges'
'| extend changeTime = todatetime(properties.changeAttributes.timestamp)'
'| where changeTime > ago(7d)'
'| project id, changeTime, subscriptionId,'
'changeType = tostring(properties.changeType),'
'resourceId = tostring(properties.targetResourceId),'
'resourceType = tostring(properties.targetResourceType),'
'changedBy = tostring(properties.changeAttributes.changedBy),'
'clientType = tostring(properties.changeAttributes.clientType),'
'changes = properties.changes'
'| order by id asc'
) -join ' '
$rows = [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) { $rows.Add($record) }
$skipToken = $page.SkipToken
} while ($skipToken)
if ($rows.Count -eq 0) {
Write-Output 'No resource changes were recorded in the last 7 days.'
} else {
$rows | Sort-Object changeTime -Descending | ForEach-Object {
[pscustomobject]@{
When = $_.changeTime
Change = $_.changeType
ResourceType = $_.resourceType
ChangedBy = $_.changedBy
Client = $_.clientType
ChangedProperties = @($_.changes.PSObject.Properties.Name) -join '; '
SubscriptionId = $_.subscriptionId
ResourceId = $_.resourceId
}
} | Export-Csv -Path './resource-changes.csv' -NoTypeInformation -Encoding utf8
Write-Output "$($rows.Count) changes saved to resource-changes.csv."
}
} finally {
Disconnect-AzAccount | Out-Null
}The CSV holds each change's time, whether it created, updated or deleted the resource, who made it, the client they used and the names of the properties it changed. Change ago(7d) to ago(14d) for everything Resource Graph keeps, or add '| where changeType == "Delete"' before the order by line for deletions alone. Resource Graph paging needs id in the results, so keep it if you edit the query.
Option 2
Review changes in Change Analysis in the Azure portal
- Sign in to the Azure portal with an account that can read the subscriptions.
- Search for Change Analysis and open it.
- Set Subscription, Resource group and Time span, and use Change types to keep creations, updates or deletions.
- Select Add filter to narrow by resource type, resource name or who made the change, and use Group by to group the results, such as by Changed By.
Change Analysis suits a look at what changed around 1 incident. For a file to keep and compare each week, use PowerShell or Altivane.
Option 3 ยท Recommended for change reviews
Find recent resource changes with Altivane
- Open Altivane and choose the tenant.
- Run the Azure Resource Changes report.
- Open the Excel workbook and find Azure resource changes: every change Azure recorded, newest first, as Created, Updated or Deleted, with who made it and the client they used.
- Read What changed for each property a change touched, from the old value to the new one.
The report reads all the days Azure keeps, about 14, and names each subscription and resource type as the portal does. What changed spells out the first 5 properties of a change and then says how many more there were. The report needs a tenant signed in with a certificate and the Reader role for Altivane on the subscriptions.
Contact usCommon questions
Why does a new resource show no changed properties?
Azure records 0 changed properties for a creation, since every property is new, and for a deletion, since none remain. The record still says when it happened and who made it.
What do Unknown, Unspecified and System mean?
Unknown is a client Azure didn't recognise. Unspecified means the change carried no identity or client information. System is a background platform change that no person or app started directly.
How do I see changes older than 14 days?
Resource Graph keeps changes for 14 days. The activity log keeps operations for 90 days, with who ran each but not the properties changed. See how to export the activity log 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.