Skip to content

Commit 187b2e1

Browse files
Merge branch 'dev' of https://github.com/KelvinTegelaar/CIPP-API into dev
2 parents 9ac40f3 + 0808ea4 commit 187b2e1

2 files changed

Lines changed: 52 additions & 20 deletions

File tree

Modules/CIPPCore/Public/Alerts/Get-CIPPAlertMFAAdmins.ps1

Lines changed: 48 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,63 @@ function Get-CIPPAlertMFAAdmins {
1818
}
1919
}
2020
if (!$DuoActive) {
21-
$Users = New-GraphGETRequest -uri "https://graph.microsoft.com/beta/reports/authenticationMethods/userRegistrationDetails?`$top=999&filter=IsAdmin eq true and isMfaRegistered eq false and userType eq 'member'&`$select=id,userDisplayName,userPrincipalName,lastUpdatedDateTime,isMfaRegistered,IsAdmin" -tenantid $($TenantFilter) -AsApp $true |
22-
Where-Object { $_.userDisplayName -ne 'On-Premises Directory Synchronization Service Account' }
21+
$MFAReport = try { Get-CIPPMFAStateReport -TenantFilter $TenantFilter } catch { $null }
22+
$IncludeDisabled = [System.Convert]::ToBoolean($InputValue)
2323

24-
# Filter out JIT admins if any users were found
25-
if ($Users) {
24+
# Check 1: Admins with no MFA registered — prefer cache, fall back to live Graph
25+
$Users = if ($MFAReport) {
26+
$MFAReport | Where-Object { $_.IsAdmin -eq $true -and $_.MFARegistration -eq $false -and ($IncludeDisabled -or $_.AccountEnabled -eq $true) }
27+
} else {
28+
New-GraphGETRequest -uri "https://graph.microsoft.com/beta/reports/authenticationMethods/userRegistrationDetails?`$top=999&filter=IsAdmin eq true and isMfaRegistered eq false and userType eq 'member'&`$select=id,userDisplayName,userPrincipalName,lastUpdatedDateTime,isMfaRegistered,IsAdmin" -tenantid $($TenantFilter) -AsApp $true |
29+
Where-Object { $_.userDisplayName -ne 'On-Premises Directory Synchronization Service Account' } |
30+
Select-Object @{n = 'ID'; e = { $_.id } }, @{n = 'UPN'; e = { $_.userPrincipalName } }, @{n = 'DisplayName'; e = { $_.userDisplayName } }
31+
}
32+
33+
# Check 2: Admins with MFA registered but no enforcement.
34+
# I hate how this ended up looking, but I couldn't think of a better way to do it ¯\_(ツ)_/¯
35+
$UnenforcedAdmins = $MFAReport | Where-Object {
36+
$_.IsAdmin -eq $true -and
37+
$_.MFARegistration -eq $true -and
38+
($IncludeDisabled -or $_.AccountEnabled -eq $true) -and
39+
$_.PerUser -notin @('Enforced', 'Enabled') -and
40+
$null -ne $_.CoveredBySD -and
41+
$_.CoveredBySD -ne $true -and
42+
$_.CoveredByCA -notlike 'Enforced*'
43+
}
44+
45+
# Filter out JIT admins
46+
if ($Users -or $UnenforcedAdmins) {
2647
$Schema = Get-CIPPSchemaExtensions | Where-Object { $_.id -match '_cippUser' } | Select-Object -First 1
2748
$JITAdmins = New-GraphGETRequest -uri "https://graph.microsoft.com/beta/users?`$select=id,$($Schema.id)&`$filter=$($Schema.id)/jitAdminEnabled eq true" -tenantid $TenantFilter -ComplexFilter
2849
$JITAdminIds = $JITAdmins.id
29-
$Users = $Users | Where-Object { $_.id -notin $JITAdminIds }
50+
$Users = $Users | Where-Object { $_.ID -notin $JITAdminIds }
51+
$UnenforcedAdmins = $UnenforcedAdmins | Where-Object { $_.ID -notin $JITAdminIds }
52+
}
53+
54+
$AlertData = [System.Collections.Generic.List[PSCustomObject]]::new()
55+
56+
foreach ($user in $Users) {
57+
$AlertData.Add([PSCustomObject]@{
58+
Message = "Admin user $($user.DisplayName) ($($user.UPN)) does not have MFA registered."
59+
UserPrincipalName = $user.UPN
60+
DisplayName = $user.DisplayName
61+
Id = $user.ID
62+
Tenant = $TenantFilter
63+
})
3064
}
3165

32-
if ($Users.UserPrincipalName) {
33-
$AlertData = foreach ($user in $Users) {
34-
[PSCustomObject]@{
35-
Message = "Admin user $($user.userDisplayName) ($($user.userPrincipalName)) does not have MFA registered."
36-
UserPrincipalName = $user.userPrincipalName
37-
DisplayName = $user.userDisplayName
38-
Id = $user.id
39-
LastUpdated = $user.lastUpdatedDateTime
66+
foreach ($user in $UnenforcedAdmins) {
67+
$AlertData.Add([PSCustomObject]@{
68+
Message = "Admin user $($user.DisplayName) ($($user.UPN)) has MFA registered but no enforcement method (Per-User MFA, Security Defaults, or Conditional Access) is active."
69+
UserPrincipalName = $user.UPN
70+
DisplayName = $user.DisplayName
71+
Id = $user.ID
4072
Tenant = $TenantFilter
41-
}
42-
}
73+
})
74+
}
4375

76+
if ($AlertData.Count -gt 0) {
4477
Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $AlertData
45-
4678
}
4779
} else {
4880
Write-LogMessage -message 'Potentially using Duo for MFA, could not check MFA status for Admins with 100% accuracy' -API 'MFA Alerts - Informational' -tenant $TenantFilter -sev Info

Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardAddDKIM.ps1

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -108,15 +108,15 @@ function Invoke-CIPPStandardAddDKIM {
108108
}
109109

110110
# List of domains for each way to enable DKIM
111-
$NewDomains = [string[]]@($AllDomains | Where-Object { $DKIM.Domain -notcontains $_ })
112-
$SetDomains = [string[]]@($DKIM | Where-Object { $AllDomains -contains $_.Domain -and $_.Enabled -eq $false })
111+
$NewDomains = $AllDomains | Where-Object { $DKIM.Domain -notcontains $_ }
112+
$SetDomains = $DKIM | Where-Object { $AllDomains -contains $_.Domain -and $_.Enabled -eq $false }
113113

114114
$MissingDKIM = [System.Collections.Generic.List[string]]::new()
115115
if ($null -ne $NewDomains) {
116-
$MissingDKIM.AddRange($NewDomains)
116+
$MissingDKIM.AddRange(@($NewDomains))
117117
}
118118
if ($null -ne $SetDomains) {
119-
$MissingDKIM.AddRange($SetDomains.Domain)
119+
$MissingDKIM.AddRange(@($SetDomains.Domain))
120120
}
121121

122122
$CurrentValue = if ($MissingDKIM.Count -eq 0) { [PSCustomObject]@{'state' = 'Configured correctly' } } else { [PSCustomObject]@{'MissingDKIM' = $MissingDKIM } }

0 commit comments

Comments
 (0)