Skip to content

Commit b370415

Browse files
authored
Merge pull request #310 from KelvinTegelaar/dev
[pull] dev from KelvinTegelaar:dev
2 parents 5617557 + b1a7451 commit b370415

File tree

4 files changed

+196
-2
lines changed

4 files changed

+196
-2
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
function Get-CIPPAlertLowDomainScore {
2+
<#
3+
.FUNCTIONALITY
4+
Entrypoint
5+
#>
6+
[CmdletBinding()]
7+
Param (
8+
[Parameter(Mandatory)]
9+
$TenantFilter,
10+
[Alias('input')]
11+
[ValidateRange(0, 100)]
12+
[int]$InputValue = 70
13+
)
14+
15+
$DomainData = Get-CIPPDomainAnalyser -TenantFilter $TenantFilter
16+
$LowScoreDomains = $DomainData | Where-Object {
17+
$_.ScorePercentage -lt $InputValue -and $_.ScorePercentage -ne ''
18+
} | ForEach-Object {
19+
"$($_.Domain): Domain security score is $($_.ScorePercentage)%, which is below the threshold of $InputValue%. Issues: $($_.ScoreExplanation)"
20+
}
21+
22+
if ($LowScoreDomains) {
23+
Write-AlertTrace -cmdletName $MyInvocation.MyCommand -tenantFilter $TenantFilter -data $LowScoreDomains
24+
}
25+
}
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
Function Invoke-ExecBulkLicense {
2+
<#
3+
.FUNCTIONALITY
4+
Entrypoint
5+
.ROLE
6+
Identity.User.ReadWrite
7+
#>
8+
[CmdletBinding()]
9+
param (
10+
$Request,
11+
$TriggerMetadata
12+
)
13+
14+
$APIName = $TriggerMetadata.FunctionName
15+
$Results = [System.Collections.Generic.List[string]]::new()
16+
$StatusCode = [HttpStatusCode]::OK
17+
18+
try {
19+
$UserRequests = $Request.Body
20+
$TenantGroups = $UserRequests | Group-Object -Property tenantFilter
21+
22+
foreach ($TenantGroup in $TenantGroups) {
23+
$TenantFilter = $TenantGroup.Name
24+
$TenantRequests = $TenantGroup.Group
25+
$AllUsers = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/users?&`$select=id,userPrincipalName,assignedLicenses" -tenantid $TenantFilter
26+
$UserLookup = @{}
27+
foreach ($User in $AllUsers) {
28+
$UserLookup[$User.id] = $User
29+
}
30+
31+
# Process each user request
32+
foreach ($UserRequest in $TenantRequests) {
33+
try {
34+
$UserId = $UserRequest.userIds
35+
$User = $UserLookup[$UserId]
36+
$UserPrincipalName = $User.userPrincipalName
37+
$LicenseOperation = $UserRequest.LicenseOperation
38+
$RemoveAllLicenses = [bool]$UserRequest.RemoveAllLicenses
39+
$Licenses = $UserRequest.Licenses | ForEach-Object { $_.value }
40+
# Handle license operations
41+
if ($LicenseOperation -eq 'Add' -or $LicenseOperation -eq 'Replace') {
42+
$AddLicenses = $Licenses
43+
}
44+
45+
if ($LicenseOperation -eq 'Remove' -and $RemoveAllLicenses) {
46+
$RemoveLicenses = $User.assignedLicenses.skuId
47+
} elseif ($LicenseOperation -eq 'Remove') {
48+
$RemoveLicenses = $Licenses
49+
} elseif ($LicenseOperation -eq 'Replace') {
50+
$RemoveReplace = $User.assignedLicenses.skuId
51+
if ($RemoveReplace) { Set-CIPPUserLicense -UserId $UserId -TenantFilter $TenantFilter -RemoveLicenses $RemoveReplace }
52+
} elseif ($RemoveAllLicenses) {
53+
$RemoveLicenses = $User.assignedLicenses.skuId
54+
}
55+
#todo: Actually build bulk support into set-cippuserlicense.
56+
$TaskResults = Set-CIPPUserLicense -UserId $UserId -TenantFilter $TenantFilter -AddLicenses $AddLicenses -RemoveLicenses $RemoveLicenses
57+
58+
$Results.Add($TaskResults)
59+
Write-LogMessage -API $APIName -tenant $TenantFilter -message "Successfully processed licenses for user $UserPrincipalName" -Sev 'Info'
60+
} catch {
61+
$ErrorMessage = Get-CippException -Exception $_
62+
$Results.Add("Failed to process licenses for user $($UserRequest.userIds). Error: $($ErrorMessage.NormalizedError)")
63+
Write-LogMessage -API $APIName -tenant $TenantFilter -message "Failed to process licenses for user $($UserRequest.userIds). Error: $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage
64+
}
65+
}
66+
}
67+
68+
$Body = @{
69+
Results = @($Results)
70+
}
71+
} catch {
72+
$ErrorMessage = Get-CippException -Exception $_
73+
$StatusCode = [HttpStatusCode]::BadRequest
74+
$Body = @{
75+
Results = @("Failed to process bulk license operation: $($ErrorMessage.NormalizedError)")
76+
}
77+
Write-LogMessage -API $APIName -message "Failed to process bulk license operation: $($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage
78+
}
79+
80+
# Return response
81+
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
82+
StatusCode = $StatusCode
83+
Body = $Body
84+
})
85+
}

Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,14 @@ function New-CIPPCAPolicy {
134134
if ($location.countriesAndRegions) { $location.countriesAndRegions = @($location.countriesAndRegions) }
135135
$Body = ConvertTo-Json -InputObject $Location
136136
$GraphRequest = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/beta/identity/conditionalAccess/namedLocations' -body $body -Type POST -tenantid $tenantfilter -asApp $true
137+
$retryCount = 0
138+
do {
139+
Write-Host "Checking for location $($GraphRequest.id) attempt $retryCount. $TenantFilter"
140+
$LocationRequest = New-GraphGETRequest -uri 'https://graph.microsoft.com/beta/identity/conditionalAccess/namedLocations' -tenantid $tenantfilter -asApp $true | Where-Object -Property id -EQ $GraphRequest.id
141+
Write-Host "LocationRequest: $($LocationRequest.id)"
142+
Start-Sleep -Seconds 2
143+
$retryCount++
144+
} while ((!$LocationRequest -or !$LocationRequest.id) -and ($retryCount -lt 5))
137145
Write-LogMessage -Headers $User -API $APINAME -message "Created new Named Location: $($location.displayName)" -Sev 'Info'
138146
[pscustomobject]@{
139147
id = $GraphRequest.id
@@ -236,8 +244,7 @@ function New-CIPPCAPolicy {
236244
} else {
237245
Write-Information 'Creating'
238246
if ($JSONobj.GrantControls.authenticationStrength.policyType -or $JSONObj.$jsonobj.LocationInfo) {
239-
#quick fix for if the policy isn't available
240-
Start-Sleep 1
247+
Start-Sleep 3
241248
}
242249
$null = New-GraphPOSTRequest -uri 'https://graph.microsoft.com/beta/identity/conditionalAccess/policies' -tenantid $tenantfilter -type POST -body $RawJSON -asApp $true
243250
Write-LogMessage -Headers $User -API $APINAME -tenant $($Tenant) -message "Added Conditional Access Policy $($JSONObj.Displayname)" -Sev 'Info'
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
function Invoke-CIPPStandardTeamsMeetingVerification {
2+
<#
3+
.FUNCTIONALITY
4+
Internal
5+
.COMPONENT
6+
(APIName) TeamsMeetingVerification
7+
.SYNOPSIS
8+
(Label) Meeting Verification (ReCaptcha) for Teams
9+
.DESCRIPTION
10+
(Helptext) Configures the CAPTCHA verification for external users joining Teams meetings. This helps prevent unauthorized AI notetakers and bots from joining meetings.
11+
(DocsDescription) Configures the CAPTCHA verification for external users joining Teams meetings. This helps prevent unauthorized AI notetakers and bots from joining meetings. When enabled, external users from untrusted organizations or anonymous users will need to complete a CAPTCHA verification before joining meetings.
12+
.NOTES
13+
CAT
14+
Teams Standards
15+
TAG
16+
ADDEDCOMPONENT
17+
{"type":"autoComplete","required":true,"multiple":false,"creatable":false,"name":"standards.TeamsMeetingVerification.CaptchaVerificationForMeetingJoin","label":"CAPTCHA verification for meeting join","options":[{"label":"Not Required","value":"NotRequired"},{"label":"Anonymous Users and Untrusted Organizations","value":"AnonymousUsersAndUntrustedOrganizations"}]}
18+
IMPACT
19+
Low Impact
20+
ADDEDDATE
21+
2025-06-14
22+
POWERSHELLEQUIVALENT
23+
Set-CsTeamsMeetingPolicy -Identity Global -CaptchaVerificationForMeetingJoin AnonymousUsersAndUntrustedOrganizations
24+
RECOMMENDEDBY
25+
"Microsoft"
26+
UPDATECOMMENTBLOCK
27+
Run the Tools\Update-StandardsComments.ps1 script to update this comment block
28+
.LINK
29+
https://docs.cipp.app/user-documentation/tenant/standards/list-standards
30+
.LINK
31+
https://learn.microsoft.com/en-us/microsoftteams/join-verification-check
32+
#>
33+
##$Rerun -Type Standard -Tenant $Tenant -Settings $Settings 'TeamsMeetingVerification'
34+
35+
param($Tenant, $Settings)
36+
$CurrentState = New-TeamsRequest -TenantFilter $Tenant -Cmdlet 'Get-CsTeamsMeetingPolicy' -CmdParams @{Identity = 'Global' } | Select-Object CaptchaVerificationForMeetingJoin
37+
$CaptchaVerificationForMeetingJoin = $Settings.CaptchaVerificationForMeetingJoin.value ?? $Settings.CaptchaVerificationForMeetingJoin
38+
$StateIsCorrect = ($CurrentState.CaptchaVerificationForMeetingJoin -eq $CaptchaVerificationForMeetingJoin)
39+
40+
if ($Settings.remediate -eq $true) {
41+
if ($StateIsCorrect -eq $true) {
42+
Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Teams Meeting Verification Policy already set.' -sev Info
43+
} else {
44+
$cmdParams = @{
45+
Identity = 'Global'
46+
CaptchaVerificationForMeetingJoin = $CaptchaVerificationForMeetingJoin
47+
}
48+
49+
try {
50+
New-TeamsRequest -TenantFilter $Tenant -Cmdlet 'Set-CsTeamsMeetingPolicy' -CmdParams $cmdParams
51+
Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Updated Teams Meeting Verification Policy' -sev Info
52+
} catch {
53+
$ErrorMessage = Get-CippException -Exception $_
54+
Write-LogMessage -API 'Standards' -tenant $Tenant -message "Failed to set Teams Meeting Verification Policy. Error: $($ErrorMessage.NormalizedError)" -sev Error -LogData $ErrorMessage
55+
}
56+
}
57+
}
58+
59+
if ($Settings.alert -eq $true) {
60+
if ($StateIsCorrect -eq $true) {
61+
Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Teams Meeting Verification Policy is set correctly.' -sev Info
62+
} else {
63+
Write-StandardsAlert -message 'Teams Meeting Verification Policy is not set correctly.' -object $CurrentState -tenant $Tenant -standardName 'TeamsMeetingVerification' -standardId $Settings.standardId
64+
Write-LogMessage -API 'Standards' -tenant $Tenant -message 'Teams Meeting Verification Policy is not set correctly.' -sev Info
65+
}
66+
}
67+
68+
if ($Settings.report -eq $true) {
69+
if ($StateIsCorrect) {
70+
$FieldValue = $true
71+
} else {
72+
$FieldValue = $CurrentState
73+
}
74+
Set-CIPPStandardsCompareField -FieldName 'standards.TeamsMeetingVerification' -FieldValue $FieldValue -Tenant $Tenant
75+
Add-CIPPBPAField -FieldName 'TeamsMeetingVerification' -FieldValue $StateIsCorrect -StoreAs bool -Tenant $Tenant
76+
}
77+
}

0 commit comments

Comments
 (0)