Skip to content

Instantly share code, notes, and snippets.

@ranieuwe
Created February 13, 2026 06:26
Show Gist options
  • Select an option

  • Save ranieuwe/168b50874cdff814fc78c20ba0246b9d to your computer and use it in GitHub Desktop.

Select an option

Save ranieuwe/168b50874cdff814fc78c20ba0246b9d to your computer and use it in GitHub Desktop.
PowerShell script to retrieve Azure Activity Logs (tenant/directory level) without LAW export
#Requires -Modules Az.Accounts
<#
.SYNOPSIS
Retrieves Azure Activity Logs from subscriptions or tenant level.
.DESCRIPTION
Fetches Azure Activity Logs from the Azure Management API. Useful when you cannot
export to Log Analytics Workspace (LAW). Can query subscription-level or tenant-level
(directory) logs.
.PARAMETER DaysBack
Number of days to look back for activity logs. Default is 1.
.PARAMETER OperationFilter
Optional operation name to filter results. Use $null for all operations.
.PARAMETER TenantLevel
Query tenant/directory level logs. Requires elevated permissions (Global Admin with
"Access management for Azure resources" enabled).
.PARAMETER SubscriptionId
Specific subscription to query. Defaults to current context subscription.
.EXAMPLE
.\get-directory-logs.ps1
# Gets subscription-level activity logs for current subscription
.EXAMPLE
.\get-directory-logs.ps1 -DaysBack 7 -OperationFilter $null
# Gets all activity logs from last 7 days
.EXAMPLE
.\get-directory-logs.ps1 -TenantLevel -OperationFilter 'Microsoft.Authorization/elevateAccess/action'
# Gets tenant-level elevateAccess events (requires elevated permissions)
#>
[CmdletBinding()]
param(
[Parameter()]
[int]$DaysBack = 1,
[Parameter()]
[string]$OperationFilter,
[Parameter()]
[switch]$TenantLevel,
[Parameter()]
[string]$SubscriptionId
)
# Calculate start date for query
$startDate = (Get-Date).AddDays(-$DaysBack).ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")
# Get Azure context and validate connection
$currentContext = Get-AzContext
if (-not $currentContext) {
Write-Error "Not connected to Azure. Run Connect-AzAccount first."
return
}
Write-Verbose "Connected to tenant: $($currentContext.Tenant.Id)"
Write-Verbose "Fetching activity logs from: $startDate"
# Get access token using modern method
try {
$tokenResponse = Get-AzAccessToken -ResourceUrl "https://management.azure.com"
# Handle SecureString token (Az.Accounts 5.x+)
if ($tokenResponse.Token -is [System.Security.SecureString]) {
$accessToken = $tokenResponse.Token | ConvertFrom-SecureString -AsPlainText
} else {
$accessToken = $tokenResponse.Token
}
}
catch {
Write-Error "Failed to acquire access token: $_"
return
}
# Build URI for Activity Log API
if ($TenantLevel) {
# Tenant/directory level - requires elevated permissions
$baseUri = "https://management.azure.com/providers/microsoft.insights/eventtypes/management/values"
Write-Host "Querying tenant-level activity logs (requires elevated directory permissions)" -ForegroundColor Yellow
} else {
# Subscription level
$subId = if ($SubscriptionId) { $SubscriptionId } else { $currentContext.Subscription.Id }
if (-not $subId) {
Write-Error "No subscription in context. Use -SubscriptionId or select a subscription with Set-AzContext."
return
}
$baseUri = "https://management.azure.com/subscriptions/$subId/providers/microsoft.insights/eventtypes/management/values"
Write-Host "Querying subscription: $subId" -ForegroundColor Cyan
}
$apiVersion = "2015-04-01"
$filter = "eventTimestamp ge '$startDate'"
$select = "eventName,id,resourceGroupName,resourceProviderName,operationName,status,eventTimestamp,correlationId,submissionTimestamp,level,caller,claims"
$uri = "$baseUri`?api-version=$apiVersion&`$filter=$filter&`$select=$select"
# Invoke REST API
$requestParams = @{
Uri = $uri
Headers = @{
Authorization = "Bearer $accessToken"
'Content-Type' = 'application/json'
}
Method = 'GET'
}
try {
$response = Invoke-RestMethod @requestParams
}
catch {
Write-Error "API call failed: $_"
return
}
# Process and output results
$results = @()
foreach ($item in $response.value) {
$operationName = $item.operationName.value
# Apply filter if specified
if ($OperationFilter -and $operationName -ne $OperationFilter) {
continue
}
$results += [PSCustomObject]@{
EventTimestamp = $item.eventTimestamp
OperationName = $operationName
Status = $item.status.value
Level = $item.level
Caller = $item.caller
ResourceGroupName = $item.resourceGroupName
ResourceProviderName = $item.resourceProviderName.value
CorrelationId = $item.correlationId
SubmissionTimestamp = $item.submissionTimestamp
EventName = $item.eventName.value
Id = $item.id
}
}
Write-Host "Found $($results.Count) matching events" -ForegroundColor Cyan
# Output results (can be piped to Export-Csv, Format-Table, etc.)
$results
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment