From 249b67a3ede8fbf04bfa4a17bb31716003c63c3b Mon Sep 17 00:00:00 2001 From: angry-bender Date: Fri, 22 Mar 2024 16:26:50 +1030 Subject: [PATCH 1/2] Update Get-AzureADGraphLogs.ps1 Added same logic as Get-AzureADLogs --- Scripts/Get-AzureADGraphLogs.ps1 | 116 +++++++++++++++++++++---------- 1 file changed, 81 insertions(+), 35 deletions(-) diff --git a/Scripts/Get-AzureADGraphLogs.ps1 b/Scripts/Get-AzureADGraphLogs.ps1 index 53b37dd..177b02d 100644 --- a/Scripts/Get-AzureADGraphLogs.ps1 +++ b/Scripts/Get-AzureADGraphLogs.ps1 @@ -47,11 +47,12 @@ function Get-ADSignInLogsGraph { [CmdletBinding()] param( [string]$startDate, - [string]$endDate, + [string]$endDate, [string]$OutputDir, [string]$UserIds, [string]$Encoding = "UTF8", - [switch]$Application + [switch]$Application, + [string]$Interval ) if (!($Application.IsPresent)) { @@ -70,13 +71,20 @@ function Get-ADSignInLogsGraph { $Encoding = "UTF8" } + + if ($Interval -eq "") { + $Interval = 1440 + Write-LogFile -Message "[INFO] Setting the Interval to the default value of 1440" + } + write-logFile -Message "[INFO] Running Get-ADSignInLogsGraph" -Color "Green" - if ($outputDir -eq "" ){ - $outputDir = "Output\AzureAD" - if (!(test-path $outputDir)) { - write-logFile -Message "[INFO] Creating the following directory: $outputDir" - New-Item -ItemType Directory -Force -Name $outputDir | Out-Null + $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 } } @@ -89,43 +97,81 @@ function Get-ADSignInLogsGraph { write-Error "[Error] Custom directory invalid: $OutputDir exiting script" -ErrorAction Stop write-LogFile -Message "[Error] Custom directory invalid: $OutputDir exiting script" } + } + if ($UserIds){ + Write-LogFile -Message "[INFO] UserID's eq $($UserIds)" + } + + StartDateAz + EndDate + + $date = Get-Date -Format 'yyyyMMddHHmmss' $filePath = Join-Path -Path $outputDir -ChildPath "$($date)-SignInLogsGraph.json" - if ($Before -and $After) { - write-logFile -Message "[WARNING] Please provide only one of either a start date or end date" -Color "Red" + [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 } - - $filter = "" - if ($endDate) { - $filter = "createdDateTime lt $endDate" - } - if ($startDate) { - $filter = "createdDateTime gt $startDate" - } - if ($UserIds) { - if ($filter) { - $filter = " and $filter" + while ($currentStart -lt $script:EndDate) { + $currentEnd = $currentStart.AddMinutes($Interval) + if ($UserIds){ + Write-LogFile -Message "[DEBUG] Start Of Day" + 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-MgBetaAuditLogSignIn -ExpandProperty * -All -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-MgBetaAuditLogSignIn -ExpandProperty * -All -Filter "UserPrincipalName eq '$($Userids)' and createdDateTime lt $($currentEnd.ToString("yyyy-MM-dd")) and createdDateTime gt $($currentStart.ToString("yyyy-MM-dd"))" + } } - Get-MgBetaAuditLogSignIn -ExpandProperty * -All -Filter "userPrincipalName eq '$UserIds' $filter" | Select-Object AppDisplayName,AppId,AppTokenProtectionStatus,AppliedConditionalAccessPolicies,ConditionsNotSatisfied,ConditionsSatisfied,AppliedConditionalAccessPoliciesDisplayName,EnforcedGrantControls,EnforcedSessionControls,AppliedConditionalAccessPoliciesId,AppliedConditionalAccessPoliciesResult,AppliedConditionalAccessPolicies2,AppliedEventListeners,AuthenticationAppDeviceDetails,AppVersion,ClientApp,DeviceId,OperatingSystem,AuthenticationAppPolicyEvaluationDetails,AdminConfiguration,AuthenticationEvaluation,AuthenticationAppPolicyEvaluationDetailsPolicyName,AuthenticationAppPolicyEvaluationDetailsStatus,AuthenticationContextClassReferences,AuthenticationDetails,AuthenticationMethodsUsed,AuthenticationProcessingDetails,AuthenticationProtocol,AuthenticationRequirement,AuthenticationRequirementPolicies,Detail,RequirementProvider,AutonomousSystemNumber,AzureResourceId,ClientAppUsed,ClientCredentialType,ConditionalAccessStatus,CorrelationId,@{N='CreatedDateTime';E={$_.CreatedDateTime.ToString()}},CrossTenantAccessType,DeviceDetail,Browser,DeviceDetailDeviceId,DisplayName,IsCompliant,IsManaged,DeviceDetailOperatingSystem,TrustType,FederatedCredentialId,FlaggedForReview,HomeTenantId,HomeTenantName,IPAddress,IPAddressFromResourceProvider,Id,IncomingTokenType,IsInteractive,IsTenantRestricted,Location,City,CountryOrRegion,State,ManagedServiceIdentity,AssociatedResourceId,FederatedTokenId,FederatedTokenIssuer,MsiType,MfaDetail,AuthDetail,AuthMethod,NetworkLocationDetails,OriginalRequestId,OriginalTransferMethod,PrivateLinkDetails,PolicyId,PolicyName,PolicyTenantId,PrivateLinkDetailsResourceId,ProcessingTimeInMilliseconds,ResourceDisplayName,ResourceId,ResourceServicePrincipalId,ResourceTenantId,RiskDetail,RiskEventTypesV2,RiskLevelAggregated,RiskLevelDuringSignIn,RiskState,ServicePrincipalCredentialKeyId,ServicePrincipalCredentialThumbprint,ServicePrincipalId,ServicePrincipalName,SessionLifetimePolicies,SignInEventTypes,SignInIdentifier,SignInIdentifierType,SignInTokenProtectionStatus,Status,StatusAdditionalDetails,TokenIssuerName,TokenIssuerType,UniqueTokenIdentifier,UserAgent,UserDisplayName,UserId,UserPrincipalName,UserType,AdditionalProperties | - ForEach-Object { - $_ | ConvertTo-Json -Depth 100 - } | - Out-File -FilePath $filePath -Encoding UTF8 - } - else { - Get-MgBetaAuditLogSignIn -ExpandProperty * -All -Filter $filter | Select-Object AppDisplayName,AppId,AppTokenProtectionStatus,AppliedConditionalAccessPolicies,ConditionsNotSatisfied,ConditionsSatisfied,AppliedConditionalAccessPoliciesDisplayName,EnforcedGrantControls,EnforcedSessionControls,AppliedConditionalAccessPoliciesId,AppliedConditionalAccessPoliciesResult,AppliedConditionalAccessPolicies2,AppliedEventListeners,AuthenticationAppDeviceDetails,AppVersion,ClientApp,DeviceId,OperatingSystem,AuthenticationAppPolicyEvaluationDetails,AdminConfiguration,AuthenticationEvaluation,AuthenticationAppPolicyEvaluationDetailsPolicyName,AuthenticationAppPolicyEvaluationDetailsStatus,AuthenticationContextClassReferences,AuthenticationDetails,AuthenticationMethodsUsed,AuthenticationProcessingDetails,AuthenticationProtocol,AuthenticationRequirement,AuthenticationRequirementPolicies,Detail,RequirementProvider,AutonomousSystemNumber,AzureResourceId,ClientAppUsed,ClientCredentialType,ConditionalAccessStatus,CorrelationId,@{N='CreatedDateTime';E={$_.CreatedDateTime.ToString()}},CrossTenantAccessType,DeviceDetail,Browser,DeviceDetailDeviceId,DisplayName,IsCompliant,IsManaged,DeviceDetailOperatingSystem,TrustType,FederatedCredentialId,FlaggedForReview,HomeTenantId,HomeTenantName,IPAddress,IPAddressFromResourceProvider,Id,IncomingTokenType,IsInteractive,IsTenantRestricted,Location,City,CountryOrRegion,State,ManagedServiceIdentity,AssociatedResourceId,FederatedTokenId,FederatedTokenIssuer,MsiType,MfaDetail,AuthDetail,AuthMethod,NetworkLocationDetails,OriginalRequestId,OriginalTransferMethod,PrivateLinkDetails,PolicyId,PolicyName,PolicyTenantId,PrivateLinkDetailsResourceId,ProcessingTimeInMilliseconds,ResourceDisplayName,ResourceId,ResourceServicePrincipalId,ResourceTenantId,RiskDetail,RiskEventTypesV2,RiskLevelAggregated,RiskLevelDuringSignIn,RiskState,ServicePrincipalCredentialKeyId,ServicePrincipalCredentialThumbprint,ServicePrincipalId,ServicePrincipalName,SessionLifetimePolicies,SignInEventTypes,SignInIdentifier,SignInIdentifierType,SignInTokenProtectionStatus,Status,StatusAdditionalDetails,TokenIssuerName,TokenIssuerType,UniqueTokenIdentifier,UserAgent,UserDisplayName,UserId,UserPrincipalName,UserType,AdditionalProperties | - ForEach-Object { - $_ | ConvertTo-Json -Depth 100 - } | - Out-File -FilePath $filePath -Encoding UTF8 - } + else { + try{ + [Array]$results = Get-MgBetaAuditLogSignIn -ExpandProperty * -All -Filter "createdDateTime lt $($currentEnd.ToString("yyyy-MM-dd")) and createdDateTime gt $($currentStart.ToString("yyyy-MM-dd"))" + } + catch{ + Start-Sleep -Seconds 20 + [Array]$results = Get-MgBetaAuditLogSignIn -ExpandProperty * -All -Filter "createdDateTime lt $($currentEnd.ToString("yyyy-MM-dd")) and createdDateTime gt $($currentStart.ToString("yyyy-MM-dd"))" + } + } + 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!" + } + else { + $currentCount = $results.Count + if ($currentDay -ne 0){ + $currentTotal = $currentCount + $results.Count + } + else { + $currentTotal = $currentCount + } + + 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" + + $filePath = "$OutputDir\SignInLogsGraph-$($CurrentStart.ToString("yyyyMMdd"))-$($CurrentEnd.ToString("yyyyMMdd")).json" + $results | Select-Object AppDisplayName,AppId,AppTokenProtectionStatus,AppliedConditionalAccessPolicies,ConditionsNotSatisfied,ConditionsSatisfied,AppliedConditionalAccessPoliciesDisplayName,EnforcedGrantControls,EnforcedSessionControls,AppliedConditionalAccessPoliciesId,AppliedConditionalAccessPoliciesResult,AppliedConditionalAccessPolicies2,AppliedEventListeners,AuthenticationAppDeviceDetails,AppVersion,ClientApp,DeviceId,OperatingSystem,AuthenticationAppPolicyEvaluationDetails,AdminConfiguration,AuthenticationEvaluation,AuthenticationAppPolicyEvaluationDetailsPolicyName,AuthenticationAppPolicyEvaluationDetailsStatus,AuthenticationContextClassReferences,AuthenticationDetails,AuthenticationMethodsUsed,AuthenticationProcessingDetails,AuthenticationProtocol,AuthenticationRequirement,AuthenticationRequirementPolicies,Detail,RequirementProvider,AutonomousSystemNumber,AzureResourceId,ClientAppUsed,ClientCredentialType,ConditionalAccessStatus,CorrelationId,@{N='CreatedDateTime';E={$_.CreatedDateTime.ToString()}},CrossTenantAccessType,DeviceDetail,Browser,DeviceDetailDeviceId,DisplayName,IsCompliant,IsManaged,DeviceDetailOperatingSystem,TrustType,FederatedCredentialId,FlaggedForReview,HomeTenantId,HomeTenantName,IPAddress,IPAddressFromResourceProvider,Id,IncomingTokenType,IsInteractive,IsTenantRestricted,Location,City,CountryOrRegion,State,ManagedServiceIdentity,AssociatedResourceId,FederatedTokenId,FederatedTokenIssuer,MsiType,MfaDetail,AuthDetail,AuthMethod,NetworkLocationDetails,OriginalRequestId,OriginalTransferMethod,PrivateLinkDetails,PolicyId,PolicyName,PolicyTenantId,PrivateLinkDetailsResourceId,ProcessingTimeInMilliseconds,ResourceDisplayName,ResourceId,ResourceServicePrincipalId,ResourceTenantId,RiskDetail,RiskEventTypesV2,RiskLevelAggregated,RiskLevelDuringSignIn,RiskState,ServicePrincipalCredentialKeyId,ServicePrincipalCredentialThumbprint,ServicePrincipalId,ServicePrincipalName,SessionLifetimePolicies,SignInEventTypes,SignInIdentifier,SignInIdentifierType,SignInTokenProtectionStatus,Status,StatusAdditionalDetails,TokenIssuerName,TokenIssuerType,UniqueTokenIdentifier,UserAgent,UserDisplayName,UserId,UserPrincipalName,UserType,AdditionalProperties | + ForEach-Object { + $_ | ConvertTo-Json -Depth 100 + } | Out-File -FilePath $filePath -Encoding $Encoding - write-logFile -Message "[INFO] Sign-in logs written to $filePath" -Color "Green" + Write-LogFile -Message "[INFO] Successfully retrieved $($currentCount) records out of total $($currentTotal) for the current time range." + } + Write-LogFile -Message "[DEBUG] End Of Day" + [Array]$results = @() + $CurrentStart = $CurrentEnd + $currentDay++ + } + Write-LogFile -Message "[INFO] Acquisition complete, check the $($OutputDir) directory for your files.." -Color "Green" } function Get-ADAuditLogsGraph { @@ -256,4 +302,4 @@ function Get-ADAuditLogsGraph { write-logFile -Message "[INFO] Audit logs written to $filePath" -Color "Green" } - \ No newline at end of file + From 4ec2e8cc205e5d45ce9d141d3017d232ad30fcaa Mon Sep 17 00:00:00 2001 From: angry-bender Date: Fri, 22 Mar 2024 16:41:28 +1030 Subject: [PATCH 2/2] Update Get-AzureADGraphLogs.ps1 Removed Debug entries --- Scripts/Get-AzureADGraphLogs.ps1 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Scripts/Get-AzureADGraphLogs.ps1 b/Scripts/Get-AzureADGraphLogs.ps1 index 177b02d..78305ec 100644 --- a/Scripts/Get-AzureADGraphLogs.ps1 +++ b/Scripts/Get-AzureADGraphLogs.ps1 @@ -52,7 +52,7 @@ function Get-ADSignInLogsGraph { [string]$UserIds, [string]$Encoding = "UTF8", [switch]$Application, - [string]$Interval + [string]$Interval ) if (!($Application.IsPresent)) { @@ -125,7 +125,6 @@ function Get-ADSignInLogsGraph { while ($currentStart -lt $script:EndDate) { $currentEnd = $currentStart.AddMinutes($Interval) if ($UserIds){ - Write-LogFile -Message "[DEBUG] Start Of Day" 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-MgBetaAuditLogSignIn -ExpandProperty * -All -Filter "UserPrincipalName eq '$($Userids)' and createdDateTime lt $($currentEnd.ToString("yyyy-MM-dd")) and createdDateTime gt $($currentStart.ToString("yyyy-MM-dd"))" @@ -166,7 +165,6 @@ function Get-ADSignInLogsGraph { Write-LogFile -Message "[INFO] Successfully retrieved $($currentCount) records out of total $($currentTotal) for the current time range." } - Write-LogFile -Message "[DEBUG] End Of Day" [Array]$results = @() $CurrentStart = $CurrentEnd $currentDay++