OfficeDev / O365-InvestigationTooling

MIT License
574 stars 361 forks source link

InactiveUsersLast90Days.ps1: Doesn't exclude failed logins #5

Open TotallyInformation opened 8 years ago

TotallyInformation commented 8 years ago

Hi, thanks for this script. Unfortunately it isn't excluding failed logins in the $loggedOnUsers list.

That would mean that users who had only failed to login would be counted as having used the system.

It might also make things quicker if the list were limited to unique entries?

It also fails badly for larger tenancies since 5,000 entries is nowhere near enough to cover 90d of use. We really need to have paging built in so that we can recover all entries. Or at least a pointer in the script to direct people to some example paging code.

Here is some example code extracted from another similar script of mine looking for password resets:

# Search for password use (-RecordType AzureActiveDirectoryAccountLogon, -Operations PasswordLogonInitialAuthUsingPassword)
$enddate = get-date

For ( $i = 1; $i -le $days; $i++ ) {
    $startdate = $enddate.AddDays( -1 )

    Write-Output ("Search Day Now-{1} {2}-{3}: {0} min" -f [math]::Round((New-TimeSpan -Start $strt).TotalMinutes,4), $i, $startdate, $enddate )

    $o = Search-UnifiedAuditLog -StartDate $startdate -EndDate $enddate `
                                -Operations PasswordLogonInitialAuthUsingPassword -ResultSize 5000 |
            Select CreationDate, UserIds, AuditData.ResultStatus, AuditData.Client, AuditData.Application

    $out += $o
    $enddate = $enddate.AddDays( -1 )

}
Write-Output ("Found {1} Entries: {0} min" -f (New-TimeSpan -Start $strt).TotalMinutes, $out.Count )
TotallyInformation commented 8 years ago

Actually, it is worse than I thought. With our ~8k users, it appears that even a 24hr period generates >5,000 records. Since a 5k record query seems to take around 2 minutes, the script will take at least 30 minutes, maybe more to run.

TotallyInformation commented 8 years ago

I have reworked the script. The reworked script uses -SessionCommand ReturnLargeSet to return "all" log entries. Except that it doesn't! It returns 50k which is the maximum possible and that still isnt' enough to cover our 8k users for 90d of activity. The reworked script takes around 20 minutes to run.

So the script so far, even with my changes, is still unreliable I'm afraid and if you used it to try and audit unused accounts, you would certainly get false positives on any decent sized and active tenancy.

The next step will be to wrap the loop in a second loop that breaks down the total number of days into chunks so that >50k results can be returned.

This is a LOT more complicated than it should be. The combined audit log has far too many entries for it to be realistically workable as it stands.