internal/functions/Import-AzureAuthenticationLogs.ps1
Function Import-AzureAuthenticationLogs { <# .SYNOPSIS Takes in a set of azure Authentication logs and combines them into a unified output .DESCRIPTION Takes in a set of azure Authentication logs and combines them into a unified output .PARAMETER JsonConvertedLogs Logs that are converted .EXAMPLE Import-AzureAuthenticationLogs Imports Azure Auth logs .NOTES General notes #> Param([array]$JsonConvertedLogs) # Null out the output object $Listoutput = $null $baseproperties = $null $i = 0 # Create the output list array $ListOutput = New-Object System.Collections.ArrayList $baseproperties = New-Object System.Collections.ArrayList # Process each entry in the array foreach ($entry in $JsonConvertedLogs) { if ([bool]($i % 25)) { } Else { Write-Progress -Activity "Converting Json Entries" -CurrentOperation ("Entry " + $i) -PercentComplete (($i / $JsonConvertedLogs.count) * 100) -Status ("Processing") } # null out a temp object and create it as a new custom ps object $processedentry = $null $processedentry = New-Object -TypeName PSobject # Look at each member of the entry ... we want to process each in turn and add them to a new object foreach ($member in ($entry | get-member -MemberType NoteProperty)) { # Identity unique properties and add to property list of base object if not present if ($baseproperties -contains $member.name) { } else { $baseproperties.add($member.name) | Out-Null } # Switch statement to deal with known "special" properties switch ($member.name) { # Extended properties can contain additional values so we need to expand those ExtendedProperties { # Null check if ($null -eq $entry.ExtendedProperties) { } else { # expand out each entry and add it to the base properties and to the property of our exported object Foreach ($Object in $entry.ExtendedProperties) { # Identity unique properties and add to property list of base object if not present if ($baseproperties -contains $object.name) { } else { $baseproperties.add($object.name) | out-null } # For some entries a property can appear in ExtendedProperties and as a normal property # We need to deal with this situation try { # Now add the entry from extendedproperties to the overall properties list $processedentry | Add-Member -MemberType NoteProperty -Name $object.name -Value $object.value -ErrorAction SilentlyContinue } catch { if ((($error[0].FullyQualifiedErrorId).split(",")[0]) -eq "MemberAlreadyExists") { } } } # Convert our extended properties into a string and add that just for fidelity # null the output string [string]$epstring = $null # Convert into a string that is , separated but with : separating name and value foreach ($ep in $entry.extendedproperties) { [string]$epstring += $ep.name + ":" + $ep.v + "," } # We also still want to add extendedproperties in as is just for fidelity $processedentry | Add-Member -MemberType NoteProperty -Name ExtendedProperties -Value ($epstring.TrimEnd(",")) } } # Need to convert this from a system object into a string # This is an initial pass at this might be a better way to do it Actor { if ($null -eq $entry.actor) { } else { # null the output string [string]$actorstring = $null # Convert into a string that is , separated but with : separating ID and type foreach ($actor in $entry.actor) { [string]$actorstring += $actor.id + ":" + $actor.type + "," } # Add the string to the output $processedentry | Add-Member -MemberType NoteProperty -Name "Actor" -Value ($actorstring.TrimEnd(",")) } } Target { if ($null -eq $entry.target) { } else { # null the output string [string]$targetstring = $null # Convert into a string that is , separated but with : separating ID and type foreach ($target in $entry.target) { [string]$targetstring += $target.id + ":" + $target.type + "," } # Add the string to the output $processedentry | Add-Member -MemberType NoteProperty -Name "Target" -Value ($targetstring.TrimEnd(",")) } } Creationtime { $processedentry | Add-Member -MemberType NoteProperty -Name CreationTime -value (get-date $entry.Creationtime -format g) } Default { # For some entries a property can appear in ExtendedProperties and as a normal property # We need to deal with this situation try { # Now add the entry from extendedproperties to the overall properties list $processedentry | Add-Member -MemberType NoteProperty -Name $member.name -Value $entry.($member.name) -ErrorAction SilentlyContinue } catch { if ((($error[0].FullyQualifiedErrorId).split(",")[0]) -eq "MemberAlreadyExists") { } } } } } # Increment our counter $i++ # Add to output object $Listoutput.add($processedentry) | Out-Null } Write-Progress -Completed -Activity "Converting Json Entries" -Status " " # Build a base object using all unique property names $baseobject = $null $baseobject = New-Object -TypeName PSobject foreach ($propertyname in $baseproperties) { switch ($propertyname) { CreationTime { $baseobject | Add-Member -MemberType NoteProperty -Name $propertyname -Value (get-date 01/01/1900 -format g) } Default { $baseobject | Add-Member -MemberType NoteProperty -Name $propertyname -Value "Base" } } } # Add that object to the output $Listoutput.add($baseobject) | Out-Null # Base object HAS to be the first entry in the output so that when it is written to CSV it includes all properties [array]$sortedoutput = $Listoutput | Sort-Object -Property creationtime $sortedoutput = $sortedoutput | Where-Object { $_.ClientIP -ne 'Base' } # Build an ordered array to use to order the output columns # Key columns that we want ordered at the beginning of the output [array]$baseorder = "CreationTime", "UserId", "Workload", "ClientIP", "CountryName", "City", "UserAgent", "Operation" foreach ($columnheader in $baseorder) { # If the column header exists as one of our base properties then add to to columnorder array and remove from baseproperties list if ($baseproperties -contains $columnheader) { [array]$columnorder += $columnheader $baseproperties.remove($columnheader) } else { } } # Add all of the remaining base properties to the sort order array [array]$columnorder += $baseproperties $sortedoutput = $sortedoutput | Select-Object $columnorder # write-host $baseproperties return $sortedoutput } |