Skip to content

Commit

Permalink
Improved reporting for federated identities
Browse files Browse the repository at this point in the history
  • Loading branch information
merill committed Jul 18, 2024
1 parent 00baf70 commit 2e870cc
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 46 deletions.
46 changes: 2 additions & 44 deletions src/Export-MsIdAzureMfaReport.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -286,7 +286,7 @@ function Export-MsIdAzureMfaReport {
AddMfaProperties $user
UpdateProgress $currentCount $totalCount $user

if ($user.AuthenticationRequirement -eq "multiFactorAuthentication") {
if ($user.HasSignedInWithMfa) {
$user.MfaStatus = "MFA Capable + Signed in with MFA"
$user.MfaStatusIcon = ""
}
Expand Down Expand Up @@ -341,7 +341,7 @@ function Export-MsIdAzureMfaReport {
$user.IsMfaCapable = $isMfaRegistered
}

if ($user.AuthenticationRequirement -ne "multiFactorAuthentication") {
if (!$user.HasSignedInWithMfa) {
if ($user.IsMfaCapable) {
$user.MfaStatus = "MFA Capable"
$user.MfaStatusIcon = ""
Expand Down Expand Up @@ -392,48 +392,6 @@ function Export-MsIdAzureMfaReport {
Write-Progress -Activity "Getting authentication method" -Status "[$currentCount of $totalCount] Checking $userStatusDisplay. $percent% complete" -PercentComplete $percent
}

function WriteExportProgress(
# The current step of the overal generation
[ValidateSet("ServicePrincipal", "AppPerm", "DownloadDelegatePerm", "ProcessDelegatePerm", "GenerateExcel", "Complete")]
$MainStep,
$Status = "Processing...",
# The percentage of completion within the child step
$ChildPercent,
[switch]$ForceRefresh) {
$percent = 0
switch ($MainStep) {
"ServicePrincipal" {
$percent = GetNextPercent $ChildPercent 2 10
$activity = "Downloading service principals"
}
"AppPerm" {
$percent = GetNextPercent $ChildPercent 10 50
$activity = "Downloading application permissions"
}
"DownloadDelegatePerm" {
$percent = GetNextPercent $ChildPercent 50 75
$activity = "Downloading delegate permissions"
}
"ProcessDelegatePerm" {
$percent = GetNextPercent $ChildPercent 75 90
$activity = "Processing delegate permissions"
}
"GenerateExcel" {
$percent = GetNextPercent $ChildPercent 90 99
$activity = "Processing risk information"
}
"Complete" {
$percent = 100
$activity = "Complete"
}
}

if ($ForceRefresh.IsPresent) {
Start-Sleep -Milliseconds 250
}
Write-Progress -Id 0 -Activity $activity -PercentComplete $percent -Status $Status
}

function GetAuthMethodInfo($type) {
$methodInfo = $authMethods | Where-Object { $_.Type -eq $type }
if ($null -eq $methodInfo) {
Expand Down
29 changes: 27 additions & 2 deletions src/Get-MsIdAzureUsers.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ function Get-MsIdAzureUsers {
# Create an array of filter and join with 'and'
$filter = "$appFilter $statusFilter $dateFilter"
Write-Verbose "Graph filter: $filter"
$select = "userId,userPrincipalName,userDisplayName,appId,createdDateTime,authenticationRequirement"
$select = "userId,userPrincipalName,userDisplayName,appId,createdDateTime,authenticationRequirement,status"

Write-Progress -Activity "Querying sign-in logs..."

Expand All @@ -103,7 +103,7 @@ function Get-MsIdAzureUsers {
if ($Days) { $dayDiff = $Days }
else { $dayDiff = (Get-Date).Subtract($earliestDate).Days }
Write-Host "Getting sign-in logs for the last $dayDiff days (from $earliestDate to now)..." -ForegroundColor Green
$graphUri = "$graphBaseUri/beta/auditLogs/signIns?`$select=$select&`$filter=$filter"
$graphUri = "$graphBaseUri/beta/auditLogs/signIns?`$filter=$filter"

Write-Verbose "Getting sign-in logs $graphUri"
$resultsJson = Invoke-GraphRequest -Uri $graphUri -Method GET
Expand All @@ -120,6 +120,9 @@ function Get-MsIdAzureUsers {
# Check if user exists in the dictionary and create a new object if not
[string]$userId = $item.userId
$user = $azureUsers[$userId]

$hasSignedInWithMfa = GetHasSignedInWithMfa $item

if ($null -eq $user) {
$user = [pscustomobject]@{
UserId = $item.userId
Expand All @@ -128,6 +131,7 @@ function Get-MsIdAzureUsers {
AzureAppName = ""
AzureAppId = @($item.appId)
AuthenticationRequirement = $item.authenticationRequirement
HasSignedInWithMfa = $hasSignedInWithMfa
}
$azureUsers[$userId] = $user
}
Expand All @@ -137,6 +141,11 @@ function Get-MsIdAzureUsers {
$user.AzureAppId += $item.appId
}
# Flag as MFA if user signed in at least once
if(!$user.HasSignedInWithMfa -and $hasSignedInWithMfa){
$user.HasSignedInWithMfa = $hasSignedInWithMfa
}

# Set user auth requirement to MFA if MFA was enforced at least once
if ($user.AuthenticationRequirement -ne "multiFactorAuthentication" `
-and $item.authenticationRequirement -eq "multiFactorAuthentication") {
$user.AuthenticationRequirement = $item.authenticationRequirement
Expand Down Expand Up @@ -179,6 +188,22 @@ function Get-MsIdAzureUsers {
return $percent
}

function GetHasSignedInWithMfa($signInItem) {
$hasSignedInWithMfa = $false
# Check if MFA was enforced for this succesful sign in
if($signInItem.authenticationRequirement -eq 'multiFactorAuthentication'){
$hasSignedInWithMfa = $true
}
else { # authenticationRequirement was singleFactorAuthentication
# Could be a federated sign in where MFA claim was sent even though Entra didn't enforce MFA
$additionalDetails = Get-ObjectPropertyValue $signInItem.status -Property 'additionalDetails'
if($additionalDetails -eq 'MFA requirement satisfied by claim in the token'){
$hasSignedInWithMfa = $true
}
}
return $hasSignedInWithMfa
}

function GetEarliestDate($filter) {

$graphUri = "$graphBaseUri/beta/auditLogs/signIns?`$select=createdDateTime&`$filter=$filter&`$top=1&`$orderby=createdDateTime asc"
Expand Down

0 comments on commit 2e870cc

Please sign in to comment.