Files
Scripting/Powershell/PowerShell-collection/Office365/Invoke-GetAzureADAuditSignInLogs.ps1
DistractADD cfddd4fad2 Added Files
2021-07-06 13:16:46 +10:00

247 lines
7.6 KiB
PowerShell

<#
.SYNOPSIS
Get the AzureAD Audit Sign-In Logs
.DESCRIPTION
Get the AzureAD Audit Sign-In Logs and create several CSV files
.PARAMETER Days
Days to search
.EXAMPLE
PS C:\> .\Invoke-GetAzureADAuditSignInLogs.ps1
Get the AzureAD Audit Sign-In Logs for the last 24 hours
.EXAMPLE
PS C:\> .\Invoke-GetAzureADAuditSignInLogs.ps1 -Days 10
Get the AzureAD Audit Sign-In Logs for the last 10 days
.LINK
Get-AzureADAuditSignInLogs
.NOTES
Initial Beta Version
#>
[CmdletBinding(ConfirmImpact = 'None')]
param
(
[Parameter(ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[ValidateNotNull()]
[ValidateNotNullOrEmpty()]
[Alias('DaysToSearch')]
[int]
$Days = 1
)
begin
{
#region
if ($Days -lt 1)
{
Write-Error -Exception 'Value to low' -Message 'The given Days Value is below 1' -Category InvalidArgument -TargetObject $Days -RecommendedAction 'Select between 1 and 30' -ErrorAction Stop
Exit 1
}
if ($Days -gt 30)
{
Write-Error -Exception 'Value to high' -Message 'The given Days Value is above 30' -Category InvalidArgument -TargetObject $Days -RecommendedAction 'Select between 1 and 30' -ErrorAction Stop
Exit 1
}
#endregion
# You might want to tweak this a bit!
$null = (Disconnect-AzureAD -Confirm:$false -ErrorAction SilentlyContinue)
$null = (Remove-Module -Name AzureAD -Force -ErrorAction SilentlyContinue)
$null = (Import-Module -Name AzureADPreview -Force -ErrorAction SilentlyContinue)
$null = (Connect-AzureAD)
# Garbage Collection
[GC]::Collect()
# Cleanup
$filterAll = $null
$AzureAdSignInAll = $null
$AzureAdSignInFail = $null
$AzureAdSignInGood = $null
$AzureAdSignInAllCAfail = $null
$AzureAdSignInFailCAfail = $null
$AzureAdSignInGoodCAfail = $null
# Define some defaults
$StartDateRaw = ((Get-Date).addDays(-$Days))
$StartDate = ('{0}-{1}-{2}' -f $StartDateRaw.Year, $StartDateRaw.Month, $StartDateRaw.Day)
$StartDateRaw = $null
$EndDateRaw = (Get-Date)
$EndDate = ('{0}-{1}-{2}' -f $EndDateRaw.Year, $EndDateRaw.Month, $EndDateRaw.Day)
$EndDateRaw = $null
}
process
{
try
{
# Filtering
$filterAll = ('createdDateTime ge {0} and createdDateTime le {1}' -f $StartDate, $EndDate)
# Get the Logs
$AzureAdSignInAll = (Get-AzureADAuditSignInLogs -Filter $filterAll)
# Rest is done with filtering
$AzureAdSignInFail = ($AzureAdSignInAll | Where-Object -FilterScript {
$_.status.errorCode -ne 0
})
$AzureAdSignInGood = ($AzureAdSignInAll | Where-Object -FilterScript {
$_.status.errorCode -eq 0
})
#region StructureData
$AzureAdSignInGood = ($AzureAdSignInGood | Select-Object -Property CreatedDateTime, UserPrincipalName, RiskState, AppId, ClientAppUsed, IpAddress, @{
N = 'City'
E = {
$_.Location.City
}
}, @{
N = 'CountryOrRegion'
E = {
$_.Location.CountryOrRegion
}
}, @{
N = 'FailureReason'
E = {
$_.Status.FailureReason
}
}, ConditionalAccessStatus)
$AzureAdSignInAll = ($AzureAdSignInAll | Select-Object -Property CreatedDateTime, UserPrincipalName, RiskState, AppId, ClientAppUsed, IpAddress, @{
N = 'City'
E = {
$_.Location.City
}
}, @{
N = 'CountryOrRegion'
E = {
$_.Location.CountryOrRegion
}
}, @{
N = 'FailureReason'
E = {
$_.Status.FailureReason
}
}, ConditionalAccessStatus)
$AzureAdSignInFail = ($AzureAdSignInFail | Select-Object -Property CreatedDateTime, UserPrincipalName, RiskState, AppId, ClientAppUsed, IpAddress, @{
N = 'City'
E = {
$_.Location.City
}
}, @{
N = 'CountryOrRegion'
E = {
$_.Location.CountryOrRegion
}
}, @{
N = 'FailureReason'
E = {
$_.Status.FailureReason
}
}, ConditionalAccessStatus)
#endregion StructureData
#region ConditionalAccessFilter
# BUG: Does not work as expected
$AzureAdSignInAllCAfail = ($AzureAdSignInAll | Where-Object -FilterScript {
(($_.ConditionalAccessStatus -ne 'success') -and ($_.ConditionalAccessStatus -ne 'notApplied'))
})
$AzureAdSignInFailCAfail = ($AzureAdSignInFail | Where-Object -FilterScript {
(($_.ConditionalAccessStatus -ne 'success') -and ($_.ConditionalAccessStatus -ne 'notApplied'))
})
$AzureAdSignInGoodCAfail = ($AzureAdSignInGood | Where-Object -FilterScript {
(($_.ConditionalAccessStatus -ne 'success') -and ($_.ConditionalAccessStatus -ne 'notApplied'))
})
#endregion ConditionalAccessFilter
$TimeStamp = Get-Date -Format yyyyMMdd_HHmmss
# TODO: Make it a parameter
$ExportPath = ('C:\scripts\PowerShell\exports\AzureADSignInAudit')
if (-not (Test-Path -Path $ExportPath))
{
$null = (New-Item -Path $ExportPath -ItemType Directory -Force)
}
#region Export
$null = ($AzureAdSignInAll | Export-Csv -Path ($ExportPath + '\AllSignInAuditLogs_' + $TimeStamp + '.csv') -NoTypeInformation -Force -Encoding UTF8)
$null = ($AzureAdSignInFail | Export-Csv -Path ($ExportPath + '\FailSignInAuditLogs_' + $TimeStamp + '.csv') -NoTypeInformation -Force -Encoding UTF8)
$null = ($AzureAdSignInGood | Export-Csv -Path ($ExportPath + '\GoodSignInAuditLogs_' + $TimeStamp + '.csv') -NoTypeInformation -Force -Encoding UTF8)
if ($AzureAdSignInAllCAfail)
{
$null = ($AzureAdSignInAllCAfail | Export-Csv -Path ($ExportPath + '\AllSignInAuditLogs_CAFAIL_' + $TimeStamp + '.csv') -NoTypeInformation -Force -Encoding UTF8)
}
if ($AzureAdSignInFailCAfail)
{
$null = ($AzureAdSignInFailCAfail | Export-Csv -Path ($ExportPath + '\FailSignInAuditLogs_CAFAIL_' + $TimeStamp + '.csv') -NoTypeInformation -Force -Encoding UTF8)
}
if ($AzureAdSignInGoodCAfail)
{
$null = ($AzureAdSignInGoodCAfail | Export-Csv -Path ($ExportPath + '\GoodSignInAuditLogs_CAFAIL_' + $TimeStamp + '.csv') -NoTypeInformation -Force -Encoding UTF8)
}
#endregion Export
}
catch
{
#region ErrorHandler
# get error record
[Management.Automation.ErrorRecord]$e = $_
# retrieve information about runtime error
$info = [PSCustomObject]@{
Exception = $e.Exception.Message
Reason = $e.CategoryInfo.Reason
Target = $e.CategoryInfo.TargetName
Script = $e.InvocationInfo.ScriptName
Line = $e.InvocationInfo.ScriptLineNumber
Column = $e.InvocationInfo.OffsetInLine
}
# output information. Post-process collected info, and log info (optional)
$info | Out-String | Write-Verbose
$paramWriteError = @{
Message = $e.Exception.Message
ErrorAction = 'Stop'
Exception = $e.Exception
TargetObject = $e.CategoryInfo.TargetName
}
Write-Error @paramWriteError
# Only here to catch a global ErrorAction overwrite
exit 1
#endregion ErrorHandler
}
finally
{
# Cleanup
$filterAll = $null
$AzureAdSignInAll = $null
$AzureAdSignInFail = $null
$AzureAdSignInGood = $null
$AzureAdSignInAllCAfail = $null
$AzureAdSignInFailCAfail = $null
$AzureAdSignInGoodCAfail = $null
# Garbage Collection
[GC]::Collect()
}
}