All scripts
Azure AI 843

Azure Activity Log Change Report

Pulls recent Azure Activity Log entries for a subscription and highlights write, delete, and action operations, so you can see what changed without digging through the portal one resource group at a time.

Get-AzureActivityLogReport.ps1
<#
.SYNOPSIS
    Reports on recent Azure Activity Log events across a subscription.

.DESCRIPTION
    Pulls Activity Log entries for a chosen time window and highlights write, delete,
    and action operations so you can see what changed in a subscription without digging
    through the portal one resource group at a time. Useful for a quick daily or weekly
    check on who changed what.

.AUTHOR
    Shehryar Hassan

.EXAMPLE
    .\Get-AzureActivityLogReport.ps1 -DaysBack 7 -ExportPath C:\Reports\activity-log.csv

    Reports on the last 7 days of activity across the currently connected subscription
    and writes the results to a CSV file.
#>

[CmdletBinding()]
param(
    [Parameter(Mandatory = $false)]
    [int]$DaysBack = 7,

    [Parameter(Mandatory = $false)]
    [string]$SubscriptionId,

    [Parameter(Mandatory = $false)]
    [string]$ExportPath
)

if (-not (Get-AzContext)) {
    Write-Host "No active Azure session found, connecting now." -ForegroundColor Yellow
    Connect-AzAccount | Out-Null
}

if ($SubscriptionId) {
    Set-AzContext -SubscriptionId $SubscriptionId | Out-Null
}

$startTime = (Get-Date).AddDays(-1 * $DaysBack)
$endTime = Get-Date

Write-Host "Pulling activity log from $startTime to $endTime..." -ForegroundColor Cyan

$events = Get-AzActivityLog -StartTime $startTime -EndTime $endTime

$results = foreach ($logEvent in $events) {
    [PSCustomObject]@{
        Timestamp     = $logEvent.EventTimestamp
        Caller        = $logEvent.Caller
        OperationName = $logEvent.OperationName.LocalizedValue
        ResourceGroup = $logEvent.ResourceGroupName
        ResourceId    = $logEvent.ResourceId
        Status        = $logEvent.Status.LocalizedValue
        Level         = $logEvent.Level
    }
}

$writeAndDeleteEvents = $results | Where-Object {
    $_.OperationName -match "Write|Delete|Action"
}

Write-Host "Found $($results.Count) total events, $($writeAndDeleteEvents.Count) were write, delete, or action operations." -ForegroundColor Green

if ($ExportPath) {
    $results | Export-Csv -Path $ExportPath -NoTypeInformation
    Write-Host "Full report exported to $ExportPath" -ForegroundColor Green
} else {
    $writeAndDeleteEvents | Sort-Object Timestamp -Descending | Format-Table -AutoSize
}

Read it before you run it, and test in a safe tenant first.