diff --git a/Scripts/Get-AzureADLogs.ps1 b/Scripts/Get-AzureADLogs.ps1 index 37890a2..06841ba 100644 --- a/Scripts/Get-AzureADLogs.ps1 +++ b/Scripts/Get-AzureADLogs.ps1 @@ -1,291 +1,368 @@ # This contains functions for getting Azure AD logging function Get-ADSignInLogs { -<# - .SYNOPSIS - Get sign-in logs. - - .DESCRIPTION - The Get-ADSignInLogs cmdlet collects the contents of the Azure Active Directory sign-in logs. - The output will be written to: Output\AzureAD\SignInLogs.json - - .PARAMETER startDate - The startDate parameter specifies the date from which all logs need to be collected. - - .PARAMETER endDate - The Before parameter specifies the date endDate which all logs need to be collected. - - .PARAMETER OutputDir - OutputDir is the parameter specifying the output directory. - Default: Output\AzureAD - - .PARAMETER Encoding - Encoding is the parameter specifying the encoding of the JSON output file. - Default: UTF8 - - .PARAMETER MergeOutput - MergeOutput is the parameter specifying if you wish to merge outputs to a single file - Default: No - - .PARAMETER UserIds - UserIds is the UserIds parameter filtering the log entries by the account of the user who performed the actions. - - .EXAMPLE - Get-ADSignInLogs - Get all sign-in logs. - - .EXAMPLE - Get-ADAuditLogs -UserIds Test@invictus-ir.com - Get sign-in logs for the user Test@invictus-ir.com. - - .EXAMPLE - Get-ADSignInLogs -endDate 2023-04-12 - Get sign-in logs before 2023-04-12. - - .EXAMPLE - Get-ADSignInLogs -startDate 2023-04-12 - Get sign-in logs after 2023-04-12. -#> - [CmdletBinding()] - param( - [string]$startDate, - [string]$endDate, - [string]$outputDir, - [string]$UserIds, - [switch]$MergeOutput, - [string]$Encoding, - [string]$Interval - ) - - try { - import-module AzureADPreview -force -ErrorAction stop - $areYouConnected = Get-AzureADAuditSignInLogs -ErrorAction stop - } - catch { - Write-logFile -Message "[WARNING] You must call Connect-Azure or install AzureADPreview before running this script" -Color "Red" - break - } - - Write-logFile -Message "[INFO] Running Get-AADSignInLogs" -Color "Green" - - StartDateAz - EndDate - - if ($Interval -eq "") { - $Interval = 1440 - Write-LogFile -Message "[INFO] Setting the Interval to the default value of 1440" - } - - if ($Encoding -eq "" ){ - $Encoding = "UTF8" - } - - $date = [datetime]::Now.ToString('yyyyMMddHHmmss') - if ($OutputDir -eq "" ){ - $OutputDir = "Output\AzureAD\$date" - if (!(test-path $OutputDir)) { - write-logFile -Message "[INFO] Creating the following directory: $OutputDir" - New-Item -ItemType Directory -Force -Name $OutputDir | Out-Null - } - } - - if ($UserIds){ - Write-LogFile -Message "[INFO] UserID's eq $($UserIds)" - } - - - $filePath = "$OutputDir\SignInLogs.json" + <# + .SYNOPSIS + Get sign-in logs. + + .DESCRIPTION + The Get-ADSignInLogs cmdlet collects the contents of the Azure Active Directory sign-in logs. + The output will be written to: Output\AzureAD\SignInLogs.json + + .PARAMETER startDate + The startDate parameter specifies the date from which all logs need to be collected. + + .PARAMETER endDate + The Before parameter specifies the date endDate which all logs need to be collected. + + .PARAMETER OutputDir + OutputDir is the parameter specifying the output directory. + Default: Output\AzureAD + + .PARAMETER Encoding + Encoding is the parameter specifying the encoding of the JSON output file. + Default: UTF8 + + .PARAMETER MergeOutput + MergeOutput is the parameter specifying if you wish to merge outputs to a single file + Default: No + + .PARAMETER UserIds + UserIds is the UserIds parameter filtering the log entries by the account of the user who performed the actions. - [DateTime]$currentStart = $script:StartDate - [DateTime]$currentEnd = $script:EndDate - [DateTime]$lastLog = $script:EndDate - $currentDay = 0 - - Write-LogFile -Message "[INFO] Extracting all available Directory Sign-in Logs between $($currentStart.ToUniversalTime().ToString("yyyy-MM-dd")) and $($currentEnd.ToUniversalTime().ToString("yyyy-MM-dd"))" -Color "Green" - if($currentStart -gt $script:EndDate){ - Write-LogFile -Message "[ERROR] $($currentStart.ToString("yyyy-MM-dd")) is greather than $($script:EndDate.ToString("yyyy-MM-dd")) - are you sure you put in the correct year? Exiting!" -Color "Red" - return - } - - while ($currentStart -lt $script:EndDate) { - $currentEnd = $currentStart.AddMinutes($Interval) - if ($UserIds){ - Write-LogFile -Message "[INFO] Collecting Directory Sign-in logs between $($currentStart.ToUniversalTime().ToString("yyyy-MM-dd")) and $($currentEnd.ToUniversalTime().ToString("yyyy-MM-dd"))." - try{ - [Array]$results = Get-AzureADAuditSignInLogs -All $true -Filter "UserPrincipalName eq '$($Userids)' and createdDateTime lt $($currentEnd.ToString("yyyy-MM-dd")) and createdDateTime gt $($currentStart.ToString("yyyy-MM-dd"))" - } - catch{ - Start-Sleep -Seconds 20 - [Array]$results = Get-AzureADAuditSignInLogs -All $true -Filter "UserPrincipalName eq '$($Userids)' and createdDateTime lt $($currentEnd.ToString("yyyy-MM-dd")) and createdDateTime gt $($currentStart.ToString("yyyy-MM-dd"))" - } + .EXAMPLE + Get-ADSignInLogs + Get all sign-in logs. + + .EXAMPLE + Get-ADAuditLogs -UserIds Test@invictus-ir.com + Get sign-in logs for the user Test@invictus-ir.com. + + .EXAMPLE + Get-ADSignInLogs -endDate 2023-04-12 + Get sign-in logs before 2023-04-12. + + .EXAMPLE + Get-ADSignInLogs -startDate 2023-04-12 + Get sign-in logs after 2023-04-12. + #> + [CmdletBinding()] + param( + [string]$startDate, + [string]$endDate, + [string]$outputDir, + [string]$UserIds, + [switch]$MergeOutput, + [string]$Encoding, + [string]$Interval + ) + + try { + import-module AzureADPreview -force -ErrorAction stop + $areYouConnected = Get-AzureADAuditSignInLogs -ErrorAction stop } - else { - try{ - [Array]$results = Get-AzureADAuditSignInLogs -All $true -Filter "createdDateTime lt $($currentEnd.ToString("yyyy-MM-dd")) and createdDateTime gt $($currentStart.ToString("yyyy-MM-dd"))" - } - catch{ - Start-Sleep -Seconds 20 - [Array]$results = Get-AzureADAuditSignInLogs -All $true -Filter "createdDateTime lt $($currentEnd.ToString("yyyy-MM-dd")) and createdDateTime gt $($currentStart.ToString("yyyy-MM-dd"))" + catch { + Write-logFile -Message "[WARNING] You must call Connect-Azure or install AzureADPreview before running this script" -Color "Red" + break + } + + Write-logFile -Message "[INFO] Running Get-AADSignInLogs" -Color "Green" + + StartDateAz + EndDate + + if ($Interval -eq "") { + $Interval = 1440 + Write-LogFile -Message "[INFO] Setting the Interval to the default value of 1440" + } + + if ($Encoding -eq "" ){ + $Encoding = "UTF8" + } + + $date = [datetime]::Now.ToString('yyyyMMddHHmmss') + if ($OutputDir -eq "" ){ + $OutputDir = "Output\AzureAD\$date" + if (!(test-path $OutputDir)) { + write-logFile -Message "[INFO] Creating the following directory: $OutputDir" + New-Item -ItemType Directory -Force -Name $OutputDir | Out-Null } } - if ($null -eq $results -or $results.Count -eq 0) { - Write-LogFile -Message "[WARNING] Empty data set returned between $($currentStart.ToUniversalTime().ToString("yyyy-MM-dd")) and $($currentEnd.ToUniversalTime().ToString("yyyy-MM-dd")). Moving On!" + + if ($UserIds){ + Write-LogFile -Message "[INFO] UserID's eq $($UserIds)" } - else { - $currentCount = $results.Count - if ($currentDay -ne 0){ - $currentTotal = $currentCount + $results.Count + + + $filePath = "$OutputDir\SignInLogs.json" + + [DateTime]$currentStart = $script:StartDate + [DateTime]$currentEnd = $script:EndDate + [DateTime]$lastLog = $script:EndDate + $currentDay = 0 + + Write-LogFile -Message "[INFO] Extracting all available Directory Sign-in Logs between $($currentStart.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) and $($currentEnd.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"))" -Color "Green" + if($currentStart -gt $script:EndDate){ + Write-LogFile -Message "[ERROR] $($currentStart.ToString("yyyy-MM-ddTHH:mm:ssZ")) is greather than $($script:EndDate.ToString("yyyy-MM-ddTHH:mm:ssZ")) - are you sure you put in the correct year? Exiting!" -Color "Red" + return + } + + while ($currentStart -lt $script:EndDate) { + $currentEnd = $currentStart.AddMinutes($Interval) + if ($UserIds){ + Write-LogFile -Message "[INFO] Collecting Directory Sign-in logs between $($currentStart.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) and $($currentEnd.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"))." + try{ + [Array]$results = Get-AzureADAuditSignInLogs -All $true -Filter "UserPrincipalName eq '$($Userids)' and createdDateTime lt $($currentEnd.ToString("yyyy-MM-ddTHH:mm:ssZ")) and createdDateTime gt $($currentStart.ToString("yyyy-MM-ddTHH:mm:ssZ"))" + } + catch{ + Start-Sleep -Seconds 20 + [Array]$results = Get-AzureADAuditSignInLogs -All $true -Filter "UserPrincipalName eq '$($Userids)' and createdDateTime lt $($currentEnd.ToString("yyyy-MM-ddTHH:mm:ssZ")) and createdDateTime gt $($currentStart.ToString("yyyy-MM-ddTHH:mm:ssZ"))" + } } else { - $currentTotal = $currentCount + try{ + [Array]$results = Get-AzureADAuditSignInLogs -All $true -Filter "createdDateTime lt $($currentEnd.ToString("yyyy-MM-ddTHH:mm:ssZ")) and createdDateTime gt $($currentStart.ToString("yyyy-MM-ddTHH:mm:ssZ"))" + } + catch{ + Start-Sleep -Seconds 20 + [Array]$results = Get-AzureADAuditSignInLogs -All $true -Filter "createdDateTime lt $($currentEnd.ToString("yyyy-MM-ddTHH:mm:ssZ")) and createdDateTime gt $($currentStart.ToString("yyyy-MM-ddTHH:mm:ssZ"))" + } } - - Write-LogFile -Message "[INFO] Found $currentCount Directory Sign-in Logs between $($currentStart.ToUniversalTime().ToString("yyyy-MM-dd")) and $($currentEnd.ToUniversalTime().ToString("yyyy-MM-dd"))" -Color "Green" + if ($null -eq $results -or $results.Count -eq 0) { + Write-LogFile -Message "[WARNING] Empty data set returned between $($currentStart.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) and $($currentEnd.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")). Moving On!" + } + else { + $currentCount = $results.Count + if ($currentDay -ne 0){ + $currentTotal = $currentCount + $results.Count + } + else { + $currentTotal = $currentCount + } - $filePath = "$OutputDir\SignInLogs-$($CurrentStart.ToString("yyyyMMdd"))-$($CurrentEnd.ToString("yyyyMMdd")).json" - $results | ConvertTo-Json -Depth 100 | Out-File -Append $filePath -Encoding $Encoding - - Write-LogFile -Message "[INFO] Successfully retrieved $($currentCount) records out of total $($currentTotal) for the current time range." - } - [Array]$results = @() - $CurrentStart = $CurrentEnd - $currentDay++ - } + Write-LogFile -Message "[INFO] Found $currentCount Directory Sign-in Logs between $($currentStart.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) and $($currentEnd.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"))" -Color "Green" + + $filePath = "$OutputDir\SignInLogs-$($CurrentStart.ToString("yyyyMMdd"))-$($CurrentEnd.ToString("yyyyMMdd")).json" + $results | ConvertTo-Json -Depth 100 | Out-File -Append $filePath -Encoding $Encoding - if ($MergeOutput.IsPresent) - { - Write-LogFile -Message "[INFO] Merging output files into one file" - $outputDirMerged = "$OutputDir\Merged\" - If (!(test-path $outputDirMerged)) { - Write-LogFile -Message "[INFO] Creating the following directory: $outputDirMerged" - New-Item -ItemType Directory -Force -Path $outputDirMerged | Out-Null - } - - $allJsonObjects = @() - - Get-ChildItem $OutputDir -Filter *.json | ForEach-Object { - $content = Get-Content -Path $_.FullName -Raw - $jsonObjects = $content | ConvertFrom-Json - $allJsonObjects += $jsonObjects + Write-LogFile -Message "[INFO] Successfully retrieved $($currentCount) records out of total $($currentTotal) for the current time range." + } + [Array]$results = @() + $CurrentStart = $CurrentEnd + $currentDay++ } + + if ($MergeOutput.IsPresent) + { + Write-LogFile -Message "[INFO] Merging output files into one file" + $outputDirMerged = "$OutputDir\Merged\" + If (!(test-path $outputDirMerged)) { + Write-LogFile -Message "[INFO] Creating the following directory: $outputDirMerged" + New-Item -ItemType Directory -Force -Path $outputDirMerged | Out-Null + } - $allJsonObjects | ConvertTo-Json -Depth 100 | Set-Content "$outputDirMerged\SignInLogs-Combined.json" - } + $allJsonObjects = @() - Write-LogFile -Message "[INFO] Acquisition complete, check the $($OutputDir) directory for your files.." -Color "Green" -} - -function Get-ADAuditLogs { -<# - .SYNOPSIS - Get directory audit logs. - - .DESCRIPTION - The Get-ADAuditLogs cmdlet collects the contents of the Azure Active Directory Audit logs. - The output will be written to: "Output\AzureAD\Auditlogs.json - - .PARAMETER startDate - The startDate parameter specifies the date from which all logs need to be collected. - - .PARAMETER endDate - The endDate parameter specifies the date before which all logs need to be collected. - - .PARAMETER OutputDir - outputDir is the parameter specifying the output directory. - Default: Output\AzureAD - - .PARAMETER Encoding - Encoding is the parameter specifying the encoding of the JSON output file. - Default: UTF8 - - .PARAMETER UserIds - UserIds is the UserIds parameter filtering the log entries by the account of the user who performed the actions. - - .EXAMPLE - Get-ADAuditLogs - Get directory audit logs. - - .EXAMPLE - Get-ADAuditLogs -UserIds Test@invictus-ir.com - Get directory audit logs for the user Test@invictus-ir.com. - - .EXAMPLE - Get-ADAuditLogs -endDate 2023-04-12 - Get directory audit logs before 2023-04-12. - - .EXAMPLE - Get-ADAuditLogs -startDate 2023-04-12 - Get directory audit logs after 2023-04-12. -#> - [CmdletBinding()] - param( - [string]$startDate, - [string]$endDate, - [string]$OutputDir, - [string]$UserIds, - [string]$Encoding - ) - - try { - $areYouConnected = Get-AzureADAuditDirectoryLogs -ErrorAction stop - } - catch { - Write-logFile -Message "[WARNING] You must call Connect-Azure or install AzureADPreview before running this script" -Color "Red" - break - } - - if ($Encoding -eq "" ){ - $Encoding = "UTF8" - } - - Write-logFile -Message "[INFO] Running Get-ADAuditLogs" -Color "Green" - - $date = [datetime]::Now.ToString('yyyyMMddHHmmss') - if ($OutputDir -eq "" ){ - $OutputDir = "Output\AzureAD" - if (!(test-path $OutputDir)) { - New-Item -ItemType Directory -Force -Name $OutputDir | Out-Null - write-logFile -Message "[INFO] Creating the following directory: $OutputDir" + Get-ChildItem $OutputDir -Filter *.json | ForEach-Object { + $content = Get-Content -Path $_.FullName -Raw + $jsonObjects = $content | ConvertFrom-Json + $allJsonObjects += $jsonObjects + } + + $allJsonObjects | ConvertTo-Json -Depth 100 | Set-Content "$outputDirMerged\SignInLogs-Combined.json" } + + Write-LogFile -Message "[INFO] Acquisition complete, check the $($OutputDir) directory for your files.." -Color "Green" } - - else { - if (Test-Path -Path $OutputDir) { - write-LogFile -Message "[INFO] Custom directory set to: $OutputDir" + + function Get-ADAuditLogs { + <# + .SYNOPSIS + Get directory audit logs. + + .DESCRIPTION + The Get-ADAuditLogs cmdlet collects the contents of the Azure Active Directory Audit logs. + The output will be written to: "Output\AzureAD\Auditlogs.json + + .PARAMETER startDate + The startDate parameter specifies the date from which all logs need to be collected. + + .PARAMETER endDate + The endDate parameter specifies the date before which all logs need to be collected. + + .PARAMETER OutputDir + outputDir is the parameter specifying the output directory. + Default: Output\AzureAD + + .PARAMETER Encoding + Encoding is the parameter specifying the encoding of the JSON output file. + Default: UTF8 + + .PARAMETER UserIds + UserIds is the UserIds parameter filtering the log entries by the account of the user who performed the actions. + + .EXAMPLE + Get-ADAuditLogs + Get directory audit logs. + + .EXAMPLE + Get-ADAuditLogs -UserIds Test@invictus-ir.com + Get directory audit logs for the user Test@invictus-ir.com. + + .EXAMPLE + Get-ADAuditLogs -endDate 2024-04-12T01:00:00Z + Get directory audit logs before 2023-04-12 at 01:00. + + .EXAMPLE + Get-ADAuditLogs -startDate 2024-04-12T01:00:00Z + Get directory audit logs after 2023-04-12 at 01:00. + + .EXAMPLE + Get-ADAuditLogs -startDate 2024-04-12T01:00:00Z -endDate 2024-04-12T02:00:00Z + Get directory audit logs after 2023-04-12 between 01:00 and 02:00 + #> + [CmdletBinding()] + param( + [string]$startDate, + [string]$endDate, + [string]$outputDir, + [string]$UserIds, + [switch]$MergeOutput, + [string]$Encoding, + [string]$Interval + ) + + try { + $areYouConnected = Get-AzureADAuditDirectoryLogs -ErrorAction stop } + catch { + Write-logFile -Message "[WARNING] You must call Connect-Azure or install AzureADPreview before running this script" -Color "Red" + break + } + + if ($Encoding -eq "" ){ + $Encoding = "UTF8" + } + + Write-logFile -Message "[INFO] Running Get-ADAuditLogs" -Color "Green" + + StartDateAz + EndDate + if ($Interval -eq "") { + $Interval = 720 + Write-LogFile -Message "[INFO] Setting the Interval to the default value of 720 (Larger values may result in out of memory errors)" + } + + + $date = [datetime]::Now.ToString('yyyyMMddHHmmss') + if ($OutputDir -eq "" ){ + $OutputDir = "Output\AzureAD\$date" + if (!(test-path $OutputDir)) { + write-logFile -Message "[INFO] Creating the following directory: $OutputDir" + New-Item -ItemType Directory -Force -Name $OutputDir | Out-Null + } + } else { - write-Error "[Error] Custom directory invalid: $OutputDir exiting script" -ErrorAction Stop - write-LogFile -Message "[Error] Custom directory invalid: $OutputDir exiting script" + if (Test-Path -Path $OutputDir) { + write-LogFile -Message "[INFO] Custom directory set to: $OutputDir" + } + + else { + write-Error "[Error] Custom directory invalid: $OutputDir exiting script" -ErrorAction Stop + write-LogFile -Message "[Error] Custom directory invalid: $OutputDir exiting script" + } } - } - - $filePath = "$OutputDir\$($date)-Auditlogs.json" - Write-logFile -Message "[INFO] Collecting the Directory Audit Logs" - - if ($endDate -and $After) { - write-logFile -Message "[WARNING] Please provide only one of either a start date or end date" -Color "Red" - return - } - - $filter = "" - if ($endDate) { - $filter = "activityDateTime lt $endDate" - } - if ($startDate) { - $filter = "activityDateTime gt $startDate" - } - - if ($UserIds) { - if ($filter) { - $filter = " and $filter" + + + if ($UserIds){ + Write-LogFile -Message "[INFO] UserID's eq $($UserIds)" } - $results = Get-AzureADAuditDirectoryLogs -All $true -Filter "initiatedBy/user/userPrincipalName eq '$Userids' $filter" - $results | ConvertTo-Json -Depth 100 | Out-File -Append $filePath -Encoding $Encoding - } - else { - $results = Get-AzureADAuditDirectoryLogs -All $true -Filter $filter - $results | ConvertTo-Json -Depth 100 | Out-File -Append $filePath -Encoding $Encoding + + + $filePath = "$OutputDir\$($date)-Auditlogs.json" + + [DateTime]$currentStart = $script:StartDate + [DateTime]$currentEnd = $script:EndDate + [DateTime]$lastLog = $script:EndDate + $currentDay = 0 + + Write-LogFile -Message "[INFO] Extracting all available Directory Audit Logs between $($currentStart.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) and $($currentEnd.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"))" -Color "Green" + if($currentStart -gt $script:EndDate){ + Write-LogFile -Message "[ERROR] $($currentStart.ToString("yyyy-MM-ddTHH:mm:ssZ")) is greather than $($script:EndDate.ToString("yyyy-MM-ddTHH:mm:ssZ")) - are you sure you put in the correct year? Exiting!" -Color "Red" + return + } + + while ($currentStart -lt $script:EndDate) { + $currentEnd = $currentStart.AddMinutes($Interval) + Start-Sleep -Seconds 5 + if ($UserIds){ + Write-LogFile -Message "[INFO] Collecting Directory Audit logs between $($currentStart.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) and $($currentEnd.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"))." + try{ + [Array]$results = Get-AzureADAuditDirectoryLogs -All $true -Filter "initiatedBy/user/userPrincipalName eq '$Userids' and activityDateTime gt $($currentStart.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) and activityDateTime lt $($currentEnd.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"))" | Select-Object Id,Category,CorrelationId,Result,ResultReason,ActivityDisplayName,@{N='ActivityDateTime';E={$_.ActivityDateTime.ToString()}},LoggedByService,OperationType,InitiatedBy,TargetResources,AdditionalDetails + } + catch{ + Write-LogFile -Message "[WARNING] Failed to acquire logs $($currentStart.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) and $($currentEnd.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")). Retrying after sleep " -Color "Yellow" + Start-Sleep -Seconds 30 + Write-LogFile -Message "[INFO] Collecting Directory Audit logs between $($currentStart.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) and $($currentEnd.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"))." + [Array]$results = Get-AzureADAuditDirectoryLogs -All $true -Filter "initiatedBy/user/userPrincipalName eq '$Userids' and activityDateTime gt $($currentStart.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) and activityDateTime lt $($currentEnd.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"))" | Select-Object Id,Category,CorrelationId,Result,ResultReason,ActivityDisplayName,@{N='ActivityDateTime';E={$_.ActivityDateTime.ToString()}},LoggedByService,OperationType,InitiatedBy,TargetResources,AdditionalDetails + } + } + else { + Write-LogFile -Message "[INFO] Collecting Directory Audit logs between $($currentStart.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) and $($currentEnd.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"))." + try{ + [Array]$results = Get-AzureADAuditDirectoryLogs -All $true -Filter "activityDateTime gt $($currentStart.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) and activityDateTime lt $($currentEnd.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"))" | Select-Object Id,Category,CorrelationId,Result,ResultReason,ActivityDisplayName,@{N='ActivityDateTime';E={$_.ActivityDateTime.ToString()}},LoggedByService,OperationType,InitiatedBy,TargetResources,AdditionalDetails + } + catch{ + Write-LogFile -Message "[WARNING] Failed to acquire logs $($currentStart.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) and $($currentEnd.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")). Retrying after sleep " -Color "Yellow" + Start-Sleep -Seconds 30 + Write-LogFile -Message "[INFO] Collecting Directory Audit logs between $($currentStart.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) and $($currentEnd.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"))." + [Array]$results = Get-AzureADAuditDirectoryLogs -All $true -Filter "activityDateTime gt $($currentStart.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) and activityDateTime lt $($currentEnd.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"))" | Select-Object Id,Category,CorrelationId,Result,ResultReason,ActivityDisplayName,@{N='ActivityDateTime';E={$_.ActivityDateTime.ToString()}},LoggedByService,OperationType,InitiatedBy,TargetResources,AdditionalDetails + } + } + if ($null -eq $results -or $results.Count -eq 0) { + Write-LogFile -Message "[WARNING] Empty data set returned between $($currentStart.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) and $($currentEnd.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")). Moving On!" -Color "Yellow" + } + else { + $currentCount = $results.Count + if ($currentDay -ne 0){ + $currentTotal = $currentCount + $results.Count + } + else { + $currentTotal = $currentCount + } + + Write-LogFile -Message "[INFO] Found $currentCount Directory Audit Logs between $($currentStart.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ")) and $($currentEnd.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ssZ"))" -Color "Green" + + $filePath = "$OutputDir\AuditLogs-$($CurrentStart.ToString("yyyyMMddHHmmss"))-$($CurrentEnd.ToString("yyyyMMddHHmmss")).json" + $results | ConvertTo-Json -Depth 100 | Out-File -Append $filePath -Encoding $Encoding + + Write-LogFile -Message "[INFO] Successfully retrieved $($currentCount) records out of total $($currentTotal) for the current time range." + } + [Array]$results = @() + $CurrentStart = $CurrentEnd + $currentDay++ + } + + if ($MergeOutput.IsPresent) + { + Write-LogFile -Message "[INFO] Merging output files into one file" + $outputDirMerged = "$OutputDir\Merged\" + If (!(test-path $outputDirMerged)) { + Write-LogFile -Message "[INFO] Creating the following directory: $outputDirMerged" + New-Item -ItemType Directory -Force -Path $outputDirMerged | Out-Null + } + + $allJsonObjects = @() + + Get-ChildItem $OutputDir -Filter *.json | ForEach-Object { + $content = Get-Content -Path $_.FullName -Raw + $jsonObjects = $content | ConvertFrom-Json + $allJsonObjects += $jsonObjects + } + + $allJsonObjects | ConvertTo-Json -Depth 100 | Set-Content "$outputDirMerged\AuditLogs-Combined.json" + } + + Write-LogFile -Message "[INFO] Acquisition complete, check the $($OutputDir) directory for your files.." -Color "Green" } - Write-logFile -Message "[INFO] Directory audit logs written to $filePath" -Color "Green" -}