Practical PowerShell scripts and tools for IT pros & sysadmins. Free, open-source, and battle-tested.
Open-source tools built for real-world IT administration. Expand any card to view the script directly.
DelegateListLink attribute directly from the domain controller — no iteration required.
(Get-MailboxPermission "SharedMailbox" -ReadFromDomainController)[0].DelegateListLink
#Above will give Output as only the accounts which are automapped
$clientID = ""
$Tenantid = ""
$clientsecret = ""
#Convert Secret to secure string
$clientsecretpass = ConvertTo-SecureString -String $clientsecret -AsPlainText -Force
#Create a credential object
$clientSecretCred = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $clientID, $clientsecretpass
#Connect to Microsoft Graph
connect-MgGraph -TenantId $Tenantid -ClientSecretCredential $clientSecretCred
#Modify the values for the following variables to configure the audit log search.
$timestamp = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
$logFile = "c:\Temp\AuditLogSearchLog_$timestamp.txt"
$outputFile = "c:\Temp\AuditLogRecords_$timestamp.csv"
[DateTime]$start = [DateTime]::UtcNow.AddDays(-1)
[DateTime]$end = [DateTime]::UtcNow
#$record = "ExchangeAdmin"
#$Operations = "Remove-DistributionGroup"
#$FreeText = "PSDL1"
$resultSize = 5000
$intervalMinutes = 60
#Start script
[DateTime]$currentStart = $start
[DateTime]$currentEnd = $end
Function Write-LogFile ([String]$Message)
{
$final = [DateTime]::Now.ToUniversalTime().ToString("s") + ":" + $Message
$final | Out-File $logFile -Append
}
Write-LogFile "BEGIN: Retrieving audit records between $($start) and $($end), RecordType=$record, PageSize=$resultSize."
Write-Host "Retrieving audit records for the date range between $($start) and $($end), RecordType=$record, ResultsSize=$resultSize"
$totalCount = 0
while ($true)
{
$currentEnd = $currentStart.AddMinutes($intervalMinutes)
if ($currentEnd -gt $end)
{
$currentEnd = $end
}
if ($currentStart -eq $currentEnd)
{
break
}
$sessionID = [Guid]::NewGuid().ToString() + "_" + "ExtractLogs" + (Get-Date).ToString("yyyyMMddHHmmssfff")
Write-LogFile "INFO: Retrieving audit records for activities performed between $($currentStart) and $($currentEnd)"
Write-Host "Retrieving audit records for activities performed between $($currentStart) and $($currentEnd)"
$currentCount = 0
$sw = [Diagnostics.StopWatch]::StartNew()
do
{
$results = Search-UnifiedAuditLog -StartDate $currentStart -EndDate $currentEnd -RecordType $record -SessionId $sessionID -Operations $Operations -FreeText $FreeText -SessionCommand ReturnLargeSet -ResultSize $resultSize
if (($results | Measure-Object).Count -ne 0)
{
$results | export-csv -Path $outputFile -Append -NoTypeInformation
$currentTotal = $results[0].ResultCount
$totalCount += $results.Count
$currentCount += $results.Count
Write-LogFile "INFO: Retrieved $($currentCount) audit records out of the total $($currentTotal)"
if ($currentTotal -eq $results[$results.Count - 1].ResultIndex)
{
$message = "INFO: Successfully retrieved $($currentTotal) audit records for the current time range. Moving on!"
Write-LogFile $message
Write-Host "Successfully retrieved $($currentTotal) audit records for the current time range. Moving on to the next interval." -foregroundColor Yellow
""
break
}
}
}
while (($results | Measure-Object).Count -ne 0)
$currentStart = $currentEnd
}
Write-LogFile "END: Retrieving audit records between $($start) and $($end), RecordType=$record, PageSize=$resultSize, total count: $totalCount."
Write-Host "Script complete! Finished retrieving audit records for the date range between $($start) and $($end). Total count: $totalCount" -foregroundColor Green
ehlo.co.in is a home for open-source scripts and automation tools focused on Microsoft 365, Exchange Online, and enterprise IT administration.
Every script here solves a real problem, is free to use, and is published with clear documentation. The goal: save fellow admins hours of troubleshooting.
Found a bug, have a suggestion, or want to contribute? Reach out directly.