Skip to content

Commit f61e984

Browse files
Next batch
1 parent e4c9818 commit f61e984

11 files changed

+495
-4
lines changed

Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Push-CIPPDBCacheData.ps1

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,22 @@ function Push-CIPPDBCacheData {
126126
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "AuthenticationFlowsPolicy collection failed: $($_.Exception.Message)" -sev Error
127127
}
128128

129+
try { Set-CIPPDBCacheRiskyUsers -TenantFilter $TenantFilter } catch {
130+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "RiskyUsers collection failed: $($_.Exception.Message)" -sev Error
131+
}
132+
133+
try { Set-CIPPDBCacheRiskyServicePrincipals -TenantFilter $TenantFilter } catch {
134+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "RiskyServicePrincipals collection failed: $($_.Exception.Message)" -sev Error
135+
}
136+
137+
try { Set-CIPPDBCacheServicePrincipalRiskDetections -TenantFilter $TenantFilter } catch {
138+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "ServicePrincipalRiskDetections collection failed: $($_.Exception.Message)" -sev Error
139+
}
140+
141+
try { Set-CIPPDBCacheRiskDetections -TenantFilter $TenantFilter } catch {
142+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "RiskDetections collection failed: $($_.Exception.Message)" -sev Error
143+
}
144+
129145
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message 'Completed database cache collection for tenant' -sev Info
130146

131147
} catch {
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
function Set-CIPPDBCacheRiskDetections {
2+
<#
3+
.SYNOPSIS
4+
Caches risk detections from Identity Protection for a tenant
5+
6+
.PARAMETER TenantFilter
7+
The tenant to cache risk detections for
8+
#>
9+
[CmdletBinding()]
10+
param(
11+
[Parameter(Mandatory = $true)]
12+
[string]$TenantFilter
13+
)
14+
15+
try {
16+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message 'Caching risk detections from Identity Protection' -sev Info
17+
18+
# Requires P2 licensing
19+
$RiskDetections = New-GraphGetRequest -uri 'https://graph.microsoft.com/v1.0/identityProtection/riskDetections' -tenantid $TenantFilter
20+
21+
if ($RiskDetections) {
22+
Add-CIPPDbItem -TenantFilter $TenantFilter -Type 'RiskDetections' -Data $RiskDetections
23+
Add-CIPPDbItem -TenantFilter $TenantFilter -Type 'RiskDetections' -Data $RiskDetections -Count
24+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Cached $($RiskDetections.Count) risk detections successfully" -sev Info
25+
} else {
26+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message 'No risk detections found or Identity Protection not available' -sev Info
27+
}
28+
29+
} catch {
30+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter `
31+
-message "Failed to cache risk detections: $($_.Exception.Message)" `
32+
-sev Warning `
33+
-LogData (Get-CippException -Exception $_)
34+
}
35+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
function Set-CIPPDBCacheRiskyServicePrincipals {
2+
<#
3+
.SYNOPSIS
4+
Caches risky service principals from Identity Protection for a tenant
5+
6+
.PARAMETER TenantFilter
7+
The tenant to cache risky service principals for
8+
#>
9+
[CmdletBinding()]
10+
param(
11+
[Parameter(Mandatory = $true)]
12+
[string]$TenantFilter
13+
)
14+
15+
try {
16+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message 'Caching risky service principals from Identity Protection' -sev Info
17+
18+
# Requires Workload Identity Premium licensing
19+
$RiskyServicePrincipals = New-GraphGetRequest -uri 'https://graph.microsoft.com/v1.0/identityProtection/riskyServicePrincipals' -tenantid $TenantFilter
20+
21+
if ($RiskyServicePrincipals) {
22+
Add-CIPPDbItem -TenantFilter $TenantFilter -Type 'RiskyServicePrincipals' -Data $RiskyServicePrincipals
23+
Add-CIPPDbItem -TenantFilter $TenantFilter -Type 'RiskyServicePrincipals' -Data $RiskyServicePrincipals -Count
24+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Cached $($RiskyServicePrincipals.Count) risky service principals successfully" -sev Info
25+
} else {
26+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message 'No risky service principals found or Workload Identity Protection not available' -sev Info
27+
}
28+
29+
} catch {
30+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter `
31+
-message "Failed to cache risky service principals: $($_.Exception.Message)" `
32+
-sev Warning `
33+
-LogData (Get-CippException -Exception $_)
34+
}
35+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
function Set-CIPPDBCacheRiskyUsers {
2+
<#
3+
.SYNOPSIS
4+
Caches risky users from Identity Protection for a tenant
5+
6+
.PARAMETER TenantFilter
7+
The tenant to cache risky users for
8+
#>
9+
[CmdletBinding()]
10+
param(
11+
[Parameter(Mandatory = $true)]
12+
[string]$TenantFilter
13+
)
14+
15+
try {
16+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message 'Caching risky users from Identity Protection' -sev Info
17+
18+
# Requires P2 or Governance licensing
19+
$RiskyUsers = New-GraphGetRequest -uri 'https://graph.microsoft.com/v1.0/identityProtection/riskyUsers' -tenantid $TenantFilter
20+
21+
if ($RiskyUsers) {
22+
Add-CIPPDbItem -TenantFilter $TenantFilter -Type 'RiskyUsers' -Data $RiskyUsers
23+
Add-CIPPDbItem -TenantFilter $TenantFilter -Type 'RiskyUsers' -Data $RiskyUsers -Count
24+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Cached $($RiskyUsers.Count) risky users successfully" -sev Info
25+
} else {
26+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message 'No risky users found or Identity Protection not available' -sev Info
27+
}
28+
29+
} catch {
30+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter `
31+
-message "Failed to cache risky users: $($_.Exception.Message)" `
32+
-sev Warning `
33+
-LogData (Get-CippException -Exception $_)
34+
}
35+
}
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
function Set-CIPPDBCacheServicePrincipalRiskDetections {
2+
<#
3+
.SYNOPSIS
4+
Caches service principal risk detections from Identity Protection for a tenant
5+
6+
.PARAMETER TenantFilter
7+
The tenant to cache service principal risk detections for
8+
#>
9+
[CmdletBinding()]
10+
param(
11+
[Parameter(Mandatory = $true)]
12+
[string]$TenantFilter
13+
)
14+
15+
try {
16+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message 'Caching service principal risk detections from Identity Protection' -sev Info
17+
18+
# Requires Workload Identity Premium licensing
19+
$ServicePrincipalRiskDetections = New-GraphGetRequest -uri 'https://graph.microsoft.com/v1.0/identityProtection/servicePrincipalRiskDetections' -tenantid $TenantFilter
20+
21+
if ($ServicePrincipalRiskDetections) {
22+
Add-CIPPDbItem -TenantFilter $TenantFilter -Type 'ServicePrincipalRiskDetections' -Data $ServicePrincipalRiskDetections
23+
Add-CIPPDbItem -TenantFilter $TenantFilter -Type 'ServicePrincipalRiskDetections' -Data $ServicePrincipalRiskDetections -Count
24+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message "Cached $($ServicePrincipalRiskDetections.Count) service principal risk detections successfully" -sev Info
25+
} else {
26+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter -message 'No service principal risk detections found or Workload Identity Protection not available' -sev Info
27+
}
28+
29+
} catch {
30+
Write-LogMessage -API 'CIPPDBCache' -tenant $TenantFilter `
31+
-message "Failed to cache service principal risk detections: $($_.Exception.Message)" `
32+
-sev Warning `
33+
-LogData (Get-CippException -Exception $_)
34+
}
35+
}
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
function Invoke-CippTestZTNA21848 {
2+
param($Tenant)
3+
4+
$TestId = 'ZTNA21848'
5+
6+
try {
7+
# Get password protection settings from Settings cache
8+
$Settings = New-CIPPDbRequest -TenantFilter $Tenant -Type 'Settings'
9+
$PasswordProtectionSettings = $Settings | Where-Object { $_.templateId -eq '5cf42378-d67d-4f36-ba46-e8b86229381d' }
10+
11+
if (-not $PasswordProtectionSettings) {
12+
Add-CippTestResult -TenantFilter $Tenant -TestId $TestId -TestType 'Identity' -Status 'Investigate' -ResultMarkdown 'Password protection settings not found' -Risk 'Medium' -Name 'Add organizational terms to the banned password list' -UserImpact 'Low' -ImplementationEffort 'Low' -Category 'Credential management'
13+
return
14+
}
15+
16+
$EnableBannedPasswordCheck = ($PasswordProtectionSettings.values | Where-Object { $_.name -eq 'EnableBannedPasswordCheck' }).value
17+
$BannedPasswordList = ($PasswordProtectionSettings.values | Where-Object { $_.name -eq 'BannedPasswordList' }).value
18+
19+
if ([string]::IsNullOrEmpty($BannedPasswordList)) {
20+
$BannedPasswordList = $null
21+
}
22+
23+
$Passed = if ($EnableBannedPasswordCheck -eq $true -and $null -ne $BannedPasswordList) { 'Passed' } else { 'Failed' }
24+
25+
$PortalLink = 'https://entra.microsoft.com/#view/Microsoft_AAD_IAM/AuthenticationMethodsMenuBlade/~/PasswordProtection/fromNav/'
26+
27+
$Enforced = if ($EnableBannedPasswordCheck -eq $true) { 'Yes' } else { 'No' }
28+
29+
# Split on tab characters to handle tab-delimited banned password entries
30+
if ($BannedPasswordList) {
31+
$BannedPasswordArray = $BannedPasswordList -split '\t'
32+
} else {
33+
$BannedPasswordArray = @()
34+
}
35+
36+
# Show up to 10 banned passwords, summarize if more exist
37+
$MaxDisplay = 10
38+
if ($BannedPasswordArray.Count -gt $MaxDisplay) {
39+
$DisplayList = $BannedPasswordArray[0..($MaxDisplay-1)] + "...and $($BannedPasswordArray.Count - $MaxDisplay) more"
40+
} else {
41+
$DisplayList = $BannedPasswordArray
42+
}
43+
44+
if ($Passed -eq 'Passed') {
45+
$ResultMarkdown = "✅ Custom banned passwords are properly configured with organization-specific terms.`n`n"
46+
} else {
47+
$ResultMarkdown = "❌ Custom banned passwords are not enabled or lack organization-specific terms.`n`n"
48+
}
49+
50+
$ResultMarkdown += "## [Password protection settings]($PortalLink)`n`n"
51+
$ResultMarkdown += "| Enforce custom list | Custom banned password list | Number of terms |`n"
52+
$ResultMarkdown += "| :------------------ | :-------------------------- | :-------------- |`n"
53+
$ResultMarkdown += "| $Enforced | $($DisplayList -join ', ') | $($BannedPasswordArray.Count) |`n"
54+
55+
Add-CippTestResult -TenantFilter $Tenant -TestId $TestId -TestType 'Identity' -Status $Passed -ResultMarkdown $ResultMarkdown -Risk 'Medium' -Name 'Add organizational terms to the banned password list' -UserImpact 'Low' -ImplementationEffort 'Low' -Category 'Credential management'
56+
57+
} catch {
58+
$ErrorMessage = Get-CippException -Exception $_
59+
Write-LogMessage -API 'Tests' -tenant $Tenant -message "Failed to run test: $($ErrorMessage.NormalizedError)" -sev Error -LogData $ErrorMessage
60+
Add-CippTestResult -TenantFilter $Tenant -TestId $TestId -TestType 'Identity' -Status 'Failed' -ResultMarkdown "Error running test: $($ErrorMessage.NormalizedError)" -Risk 'Medium' -Name 'Add organizational terms to the banned password list' -UserImpact 'Low' -ImplementationEffort 'Low' -Category 'Credential management'
61+
}
62+
}

Modules/CIPPCore/Public/Tests/Invoke-CippTestZTNA21849.ps1

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,61 @@
11
function Invoke-CippTestZTNA21849 {
22
param($Tenant)
33

4+
$TestId = 'ZTNA21849'
5+
46
try {
5-
$groupSettings = New-CIPPDbRequest -TenantFilter $Tenant -Type 'Settings'
7+
# Get password rule settings from Settings cache
8+
$Settings = New-CIPPDbRequest -TenantFilter $Tenant -Type 'Settings'
9+
$PasswordRuleSettings = $Settings | Where-Object { $_.displayName -eq 'Password Rule Settings' }
10+
11+
$PortalLink = 'https://entra.microsoft.com/#view/Microsoft_AAD_IAM/AuthenticationMethodsMenuBlade/~/PasswordProtection/fromNav/'
12+
13+
if ($null -eq $PasswordRuleSettings) {
14+
# Default is 60 seconds
15+
$Passed = 'Passed'
16+
$ResultMarkdown = "✅ Smart Lockout duration is configured to 60 seconds or higher (default).`n`n"
17+
$ResultMarkdown += "## [Smart Lockout Settings]($PortalLink)`n`n"
18+
$ResultMarkdown += "| Setting | Value |`n"
19+
$ResultMarkdown += "| :---- | :---- |`n"
20+
$ResultMarkdown += "| Lockout Duration (seconds) | 60 (Default) |`n"
21+
} else {
22+
$LockoutDurationSetting = $PasswordRuleSettings.values | Where-Object { $_.name -eq 'LockoutDurationInSeconds' }
23+
24+
if ($null -eq $LockoutDurationSetting) {
25+
# Default is 60 seconds
26+
$Passed = 'Passed'
27+
$ResultMarkdown = "✅ Smart Lockout duration is configured to 60 seconds or higher (default).`n`n"
28+
$ResultMarkdown += "## [Smart Lockout Settings]($PortalLink)`n`n"
29+
$ResultMarkdown += "| Setting | Value |`n"
30+
$ResultMarkdown += "| :---- | :---- |`n"
31+
$ResultMarkdown += "| Lockout Duration (seconds) | 60 (Default) |`n"
32+
} else {
33+
$LockoutDuration = [int]$LockoutDurationSetting.value
34+
35+
if ($LockoutDuration -ge 60) {
36+
$Passed = 'Passed'
37+
$ResultMarkdown = "✅ Smart Lockout duration is configured to 60 seconds or higher.`n`n"
38+
} else {
39+
$Passed = 'Failed'
40+
$ResultMarkdown = "❌ Smart Lockout duration is configured below 60 seconds.`n`n"
41+
}
642

7-
if (-not $groupSettings) {
8-
Add-CippTestResult -TenantFilter $Tenant -TestId 'ZTNA21849' -TestType 'Identity' -Status 'Investigate' -ResultMarkdown 'Settings not found in database' -Risk 'Medium' -Name 'Smart lockout duration is set to a minimum of 60' -UserImpact 'Low' -ImplementationEffort 'Low' -Category 'Credential Management'
9-
return
43+
$ResultMarkdown += "## [Smart Lockout Settings]($PortalLink)`n`n"
44+
$ResultMarkdown += "| Setting | Value |`n"
45+
$ResultMarkdown += "| :---- | :---- |`n"
46+
$ResultMarkdown += "| Lockout Duration (seconds) | $LockoutDuration |`n"
47+
}
1048
}
1149

50+
Add-CippTestResult -TenantFilter $Tenant -TestId $TestId -TestType 'Identity' -Status $Passed -ResultMarkdown $ResultMarkdown -Risk 'Medium' -Name 'Smart lockout duration is set to a minimum of 60' -UserImpact 'Low' -ImplementationEffort 'Low' -Category 'Credential management'
51+
52+
} catch {
53+
$ErrorMessage = Get-CippException -Exception $_
54+
Write-LogMessage -API 'Tests' -tenant $Tenant -message "Failed to run test: $($ErrorMessage.NormalizedError)" -sev Error -LogData $ErrorMessage
55+
Add-CippTestResult -TenantFilter $Tenant -TestId $TestId -TestType 'Identity' -Status 'Failed' -ResultMarkdown "Error running test: $($ErrorMessage.NormalizedError)" -Risk 'Medium' -Name 'Smart lockout duration is set to a minimum of 60' -UserImpact 'Low' -ImplementationEffort 'Low' -Category 'Credential management'
56+
}
57+
}
58+
1259
$passwordRuleSettings = $groupSettings | Where-Object { $_.displayName -eq 'Password Rule Settings' }
1360

1461
$passed = 'Passed'
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
function Invoke-CippTestZTNA21850 {
2+
param($Tenant)
3+
4+
$TestId = 'ZTNA21850'
5+
6+
try {
7+
# Get password rule settings from Settings cache
8+
$Settings = New-CIPPDbRequest -TenantFilter $Tenant -Type 'Settings'
9+
$PasswordRuleSettings = $Settings | Where-Object { $_.displayName -eq 'Password Rule Settings' }
10+
11+
$PortalLink = 'https://entra.microsoft.com/#view/Microsoft_AAD_IAM/AuthenticationMethodsMenuBlade/~/PasswordProtection/fromNav/'
12+
13+
if ($null -eq $PasswordRuleSettings) {
14+
$Passed = 'Failed'
15+
$ResultMarkdown = "❌ Password rule settings template not found."
16+
} else {
17+
$LockoutThresholdSetting = $PasswordRuleSettings.values | Where-Object { $_.name -eq 'LockoutThreshold' }
18+
19+
if ($null -eq $LockoutThresholdSetting) {
20+
$Passed = 'Failed'
21+
$ResultMarkdown = "❌ Lockout threshold setting not found in [password rule settings]($PortalLink)."
22+
} else {
23+
$LockoutThreshold = [int]$LockoutThresholdSetting.value
24+
25+
if ($LockoutThreshold -le 10) {
26+
$Passed = 'Passed'
27+
$ResultMarkdown = "✅ Smart lockout threshold is set to 10 or below.`n`n"
28+
} else {
29+
$Passed = 'Failed'
30+
$ResultMarkdown = "❌ Smart lockout threshold is configured above 10.`n`n"
31+
}
32+
33+
$ResultMarkdown += "## [Smart lockout configuration]($PortalLink)`n`n"
34+
$ResultMarkdown += "| Setting | Value |`n"
35+
$ResultMarkdown += "| :---- | :---- |`n"
36+
$ResultMarkdown += "| Lockout threshold | $LockoutThreshold attempts |`n"
37+
}
38+
}
39+
40+
Add-CippTestResult -TenantFilter $Tenant -TestId $TestId -TestType 'Identity' -Status $Passed -ResultMarkdown $ResultMarkdown -Risk 'Medium' -Name 'Smart lockout threshold set to 10 or less' -UserImpact 'Low' -ImplementationEffort 'Low' -Category 'Credential management'
41+
42+
} catch {
43+
$ErrorMessage = Get-CippException -Exception $_
44+
Write-LogMessage -API 'Tests' -tenant $Tenant -message "Failed to run test: $($ErrorMessage.NormalizedError)" -sev Error -LogData $ErrorMessage
45+
Add-CippTestResult -TenantFilter $Tenant -TestId $TestId -TestType 'Identity' -Status 'Failed' -ResultMarkdown "Error running test: $($ErrorMessage.NormalizedError)" -Risk 'Medium' -Name 'Smart lockout threshold set to 10 or less' -UserImpact 'Low' -ImplementationEffort 'Low' -Category 'Credential management'
46+
}
47+
}

0 commit comments

Comments
 (0)