From c72aef965248e74133d84bd50099ac6f0c944179 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 20 Jun 2025 13:18:00 -0400 Subject: [PATCH 01/26] Update CIPP-Permissions.json --- CIPP-Permissions.json | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CIPP-Permissions.json b/CIPP-Permissions.json index 96368090acd7..95c4e7dea816 100644 --- a/CIPP-Permissions.json +++ b/CIPP-Permissions.json @@ -225,6 +225,11 @@ "Name": "Organization.ReadWrite.All", "Description": "Allows the app to read and write the organization and related resources, on your behalf. Related resources include things like subscribed skus and tenant branding information." }, + { + "Id": "346c19ff-3fb2-4e81-87a0-bac9e33990c1", + "Name": "OrgSettings-Forms.ReadWrite.All", + "Description": "Allows the app to read and write organization-wide Microsoft Forms settings on your behalf." + }, { "Id": "e67e6727-c080-415e-b521-e3f35d5248e9", "Name": "PeopleSettings.ReadWrite.All", @@ -577,6 +582,11 @@ "Name": "Organization.ReadWrite.All", "Description": "Allows the app to read and write the organization and related resources, without a signed-in user. Related resources include things like subscribed skus and tenant branding information." }, + { + "Id": "2cb92fee-97a3-4034-8702-24a6f5d0d1e9", + "Name": "OrgSettings-Forms.ReadWrite.All", + "Description": "Allows the app to read and write organization-wide Microsoft Forms settings, without a signed-in user." + }, { "Id": "b6890674-9dd5-4e42-bb15-5af07f541ae1", "Name": "PeopleSettings.ReadWrite.All", @@ -637,6 +647,11 @@ "Name": "ReportSettings.ReadWrite.All", "Description": "Allows the app to read and update all admin report settings, such as whether to display concealed information in reports, without a signed-in user." }, + { + "Id": "025d3225-3f02-4882-b4c0-cd5b541a4e80", + "Name": "RoleManagement.ReadWrite.Exchange", + "Description": "Allows the app to read and manage the role-based access control (RBAC) settings for your organization's Exchange Online service, without a signed-in user. This includes reading, creating, updating, and deleting Exchange management role definitions, role groups, role group membership, role assignments, management scopes, and role assignment policies." + }, { "Id": "04c55753-2244-4c25-87fc-704ab82a4f69", "Name": "SecurityAnalyzedMessage.ReadWrite.All", From 8e4a8a37af2134a54d8a8abf8c49f8a73559ee76 Mon Sep 17 00:00:00 2001 From: ngms-psh Date: Sat, 21 Jun 2025 14:43:06 +0200 Subject: [PATCH 02/26] Create SP if missing to remediate correctly --- ...e-CIPPStandardRestrictThirdPartyStorageServices.ps1 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRestrictThirdPartyStorageServices.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRestrictThirdPartyStorageServices.ps1 index d523b3d83174..161c13bc6813 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRestrictThirdPartyStorageServices.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRestrictThirdPartyStorageServices.ps1 @@ -52,6 +52,16 @@ function Invoke-CIPPStandardRestrictThirdPartyStorageServices { } else { # Disable the service principal to restrict third-party storage services try { + # Create the service principal if it does not exist + if ($null -eq $CurrentState){ + $CreateBody = @{ + appId = $AppId + } | ConvertTo-Json -Depth 10 -Compress + + $CreateUri = "https://graph.microsoft.com/beta/servicePrincipals" + $null = New-GraphPOSTRequest -uri $CreateUri -tenantid $Tenant -Body $CreateBody + } + $DisableBody = @{ accountEnabled = $false } | ConvertTo-Json -Depth 10 -Compress From cddca7d843f782632e1709c0d36d0270c9286f12 Mon Sep 17 00:00:00 2001 From: Zac Richards <107489668+Zacgoose@users.noreply.github.com> Date: Mon, 23 Jun 2025 08:40:21 +0800 Subject: [PATCH 03/26] Fix this dammed alert --- .../CIPPCore/Public/Alerts/Get-CIPPAlertHuntressRogueApps.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertHuntressRogueApps.ps1 b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertHuntressRogueApps.ps1 index a949986da6a3..8531738f452b 100644 --- a/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertHuntressRogueApps.ps1 +++ b/Modules/CIPPCore/Public/Alerts/Get-CIPPAlertHuntressRogueApps.ps1 @@ -13,7 +13,7 @@ function Get-CIPPAlertHuntressRogueApps { Param ( [Parameter(Mandatory = $false)] [Alias('input')] - [bool]$InputValue = $false, + $InputValue, $TenantFilter ) @@ -22,7 +22,7 @@ function Get-CIPPAlertHuntressRogueApps { $RogueAppFilter = $RogueApps.appId -join "','" $ServicePrincipals = New-GraphGetRequest -uri "https://graph.microsoft.com/beta/servicePrincipals?`$filter=appId in ('$RogueAppFilter')" -tenantid $TenantFilter # If IgnoreDisabledApps is true, filter out disabled service principals - if ($InputValue) { + if ($InputValue -eq $true) { $ServicePrincipals = $ServicePrincipals | Where-Object { $_.accountEnabled -eq $true } } From daf1a228717be24e95368654c5ac53a43f11b48c Mon Sep 17 00:00:00 2001 From: John Duprey Date: Mon, 23 Jun 2025 14:01:04 -0400 Subject: [PATCH 04/26] add accept header --- Modules/CIPPCore/Public/GraphHelper/New-TeamsAPIGetRequest.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/GraphHelper/New-TeamsAPIGetRequest.ps1 b/Modules/CIPPCore/Public/GraphHelper/New-TeamsAPIGetRequest.ps1 index 31f1c662b994..8d3e99ce8892 100644 --- a/Modules/CIPPCore/Public/GraphHelper/New-TeamsAPIGetRequest.ps1 +++ b/Modules/CIPPCore/Public/GraphHelper/New-TeamsAPIGetRequest.ps1 @@ -17,7 +17,7 @@ function New-TeamsAPIGetRequest($Uri, $tenantID, $Method = 'GET', $Resource = '4 'x-ms-correlation-id' = [guid]::NewGuid() 'X-Requested-With' = 'XMLHttpRequest' 'x-ms-tnm-applicationid' = '045268c0-445e-4ac1-9157-d58f67b167d9' - + 'Accept' = 'application/json' } $Data if ($noPagination) { $nextURL = $null } else { $nextURL = $data.NextLink } From 58ee300612ee1084eb4055cc188c60a613e31554 Mon Sep 17 00:00:00 2001 From: BNWEIN Date: Tue, 24 Jun 2025 17:10:50 +0100 Subject: [PATCH 05/26] Update Invoke-ListGroups.ps1 to include 'onPremisesSyncEnabled' in the SelectString for group queries --- .../Identity/Administration/Groups/Invoke-ListGroups.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroups.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroups.ps1 index 6b5117824ec7..2450c678abf8 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroups.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroups.ps1 @@ -20,7 +20,7 @@ function Invoke-ListGroups { $BulkRequestArrayList = [System.Collections.Generic.List[object]]::new() if ($Request.Query.GroupID) { - $SelectString = 'id,createdDateTime,displayName,description,mail,mailEnabled,mailNickname,resourceProvisioningOptions,securityEnabled,visibility,organizationId,onPremisesSamAccountName,membershipRule,groupTypes,userPrincipalName' + $SelectString = 'id,createdDateTime,displayName,description,mail,mailEnabled,mailNickname,resourceProvisioningOptions,securityEnabled,visibility,organizationId,onPremisesSamAccountName,membershipRule,groupTypes,userPrincipalName,onPremisesSyncEnabled' $BulkRequestArrayList.add(@{ id = 1 method = 'GET' From 0d111e8ba040d87285168e15108d0753769b33f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Tue, 24 Jun 2025 19:33:43 +0200 Subject: [PATCH 06/26] throw it --- Modules/CIPPCore/Public/Set-CIPPGroupAuthentication.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Set-CIPPGroupAuthentication.ps1 b/Modules/CIPPCore/Public/Set-CIPPGroupAuthentication.ps1 index 230afb2e3604..1bf763480b2d 100644 --- a/Modules/CIPPCore/Public/Set-CIPPGroupAuthentication.ps1 +++ b/Modules/CIPPCore/Public/Set-CIPPGroupAuthentication.ps1 @@ -15,7 +15,7 @@ function Set-CIPPGroupAuthentication( New-ExoRequest -tenantid $TenantFilter -cmdlet 'Set-UnifiedGroup' -cmdParams @{Identity = $Id; RequireSenderAuthenticationEnabled = $OnlyAllowInternal } } elseif ($GroupType -eq 'Security') { Write-LogMessage -headers $Headers -API $APIName -tenant $TenantFilter -message 'This setting cannot be set on a security group.' -Sev 'Error' - return "$GroupType's group cannot have this setting changed" + throw "$GroupType's group cannot have this setting changed" } $Message = "Successfully set $GroupType group $Id to allow messages from people $messageSuffix" @@ -25,6 +25,6 @@ function Set-CIPPGroupAuthentication( $ErrorMessage = Get-CippException -Exception $_ $Message = "Failed to set Delivery Management: $($ErrorMessage.NormalizedError)" Write-LogMessage -headers $Headers -API $APIName -tenant $TenantFilter -message $Message -Sev 'Error' -LogData $ErrorMessage - return $Message + throw $Message } } From 19a7060a9ef4233b69dc4e832bb6997a981b2023 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Tue, 24 Jun 2025 20:03:19 +0200 Subject: [PATCH 07/26] only set the sendCopies and allowExternal when explicitly sent from the frontend --- .../Groups/Invoke-EditGroup.ps1 | 76 ++++++++++++------- 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 index 86f1abdd4922..76b9d5b82330 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 @@ -55,7 +55,7 @@ function Invoke-EditGroup { Write-Host "body: $($PatchObj | ConvertTo-Json -Depth 10 -Compress)" -ForegroundColor Yellow if ($UserObj.membershipRules) { $PatchObj | Add-Member -MemberType NoteProperty -Name 'membershipRule' -Value $UserObj.membershipRules -Force } try { - $patch = New-GraphPOSTRequest -type PATCH -uri "https://graph.microsoft.com/beta/groups/$($GroupId)" -tenantid $UserObj.tenantFilter -body ($PatchObj | ConvertTo-Json -Depth 10 -Compress) + $null = New-GraphPOSTRequest -type PATCH -uri "https://graph.microsoft.com/beta/groups/$($GroupId)" -tenantid $UserObj.tenantFilter -body ($PatchObj | ConvertTo-Json -Depth 10 -Compress) $Results.Add("Success - Edited group properties for $($GroupName) group. It might take some time to reflect the changes.") Write-LogMessage -headers $Headers -API $APIName -tenant $UserObj.tenantFilter -message "Edited group properties for $($GroupName) group" -Sev 'Info' } catch { @@ -134,7 +134,7 @@ function Invoke-EditGroup { }) } else { Write-LogMessage -API $APIName -tenant $TenantId -headers $Headers -message 'You cannot add a Contact to a Security Group or a M365 Group' -Sev 'Error' - $null = $Results.Add('Error - You cannot add a contact to a Security Group or a M365 Group') + $Results.Add('Error - You cannot add a contact to a Security Group or a M365 Group') } } catch { Write-Warning "Error in AddContacts: $($_.Exception.Message)" @@ -162,7 +162,7 @@ function Invoke-EditGroup { }) } else { Write-LogMessage -API $APIName-tenant $TenantId -headers $Headers -message 'You cannot remove a contact from a Security Group' -Sev 'Error' - $null = $Results.Add('You cannot remove a contact from a Security Group') + $Results.Add('You cannot remove a contact from a Security Group') } } } @@ -260,7 +260,7 @@ function Invoke-EditGroup { if ($GroupType -in @( 'Distribution List', 'Mail-Enabled Security') -and ($AddOwners -or $RemoveOwners)) { $CurrentOwners = New-ExoRequest -tenantid $TenantId -cmdlet 'Get-DistributionGroup' -cmdParams @{ Identity = $GroupId } -UseSystemMailbox $true | Select-Object -ExpandProperty ManagedBy - $NewManagedBy = [system.collections.generic.list[string]]::new() + $NewManagedBy = [System.Collections.Generic.List[string]]::new() foreach ($CurrentOwner in $CurrentOwners) { if ($RemoveOwners -and $RemoveOwners.addedFields.id -contains $CurrentOwner) { $OwnerToRemove = $RemoveOwners | Where-Object { $_.addedFields.id -eq $CurrentOwner } @@ -330,7 +330,7 @@ function Invoke-EditGroup { foreach ($ExoError in $LastError.error) { $Sev = 'Error' $Results.Add("Error - $ExoError") - Write-LogMessage -headers $Headers -API $APIName -tenant $TenantId -message $Message -Sev $Sev + Write-LogMessage -headers $Headers -API $APIName -tenant $TenantId -message $ExoError -Sev $Sev } foreach ($ExoLog in $ExoLogs) { @@ -344,39 +344,63 @@ function Invoke-EditGroup { } } - if ($UserObj.allowExternal -eq $true -and $GroupType -ne 'Security') { + # Only process allowExternal if it was explicitly sent + if ($null -ne $UserObj.allowExternal -and $GroupType -ne 'Security') { try { Set-CIPPGroupAuthentication -ID $UserObj.mail -OnlyAllowInternal (!$UserObj.allowExternal) -GroupType $GroupType -tenantFilter $TenantId -APIName $APIName -Headers $Headers - $body = $Results.Add("Allowed external senders to send to $($UserObj.mail).") + if ($UserObj.allowExternal -eq $true) { + $Results.Add("Allowed external senders to send to $($UserObj.mail).") + } else { + $Results.Add("Blocked external senders from sending to $($UserObj.mail).") + } } catch { - $body = $Results.Add("Failed to allow external senders to send to $($UserObj.mail).") - Write-LogMessage -headers $Headers -API $APIName -tenant $TenantId -message "Failed to allow external senders for $($UserObj.mail). Error:$($_.Exception.Message)" -Sev 'Error' + $action = if ($UserObj.allowExternal -eq $true) { 'allow' } else { 'block' } + $Results.Add("Failed to $action external senders for $($UserObj.mail).") } - } - if ($UserObj.sendCopies -eq $true) { + # Only process sendCopies if it was explicitly sent + if ($null -ne $UserObj.sendCopies) { try { - $Params = @{ Identity = $GroupId; subscriptionEnabled = $true; AutoSubscribeNewMembers = $true } - New-ExoRequest -tenantid $TenantId -cmdlet 'Set-UnifiedGroup' -cmdParams $Params -useSystemMailbox $true + if ($UserObj.sendCopies -eq $true) { + $Params = @{ Identity = $GroupId; subscriptionEnabled = $true; AutoSubscribeNewMembers = $true } + New-ExoRequest -tenantid $TenantId -cmdlet 'Set-UnifiedGroup' -cmdParams $Params -useSystemMailbox $true - $MemberParams = @{ Identity = $GroupId; LinkType = 'members' } - $Members = New-ExoRequest -tenantid $TenantId -cmdlet 'Get-UnifiedGroupLinks' -cmdParams $MemberParams + $MemberParams = @{ Identity = $GroupId; LinkType = 'members' } + $Members = New-ExoRequest -tenantid $TenantId -cmdlet 'Get-UnifiedGroupLinks' -cmdParams $MemberParams - $MemberSmtpAddresses = $Members | ForEach-Object { $_.PrimarySmtpAddress } + $MemberSmtpAddresses = $Members | ForEach-Object { $_.PrimarySmtpAddress } - if ($MemberSmtpAddresses) { - $subscriberParams = @{ Identity = $GroupId; LinkType = 'subscribers'; Links = @($MemberSmtpAddresses | Where-Object { $_ }) } - New-ExoRequest -tenantid $TenantId -cmdlet 'Add-UnifiedGroupLinks' -cmdParams $subscriberParams -Anchor $UserObj.mail - } + if ($MemberSmtpAddresses) { + $subscriberParams = @{ Identity = $GroupId; LinkType = 'subscribers'; Links = @($MemberSmtpAddresses | Where-Object { $_ }) } - $body = $Results.Add("Send Copies of team emails and events to team members inboxes for $($UserObj.mail) enabled.") - Write-LogMessage -headers $Headers -API $APIName -tenant $TenantId -message "Send Copies of team emails and events to team members inboxes for $($UserObj.mail) enabled." -Sev 'Info' + try { + New-ExoRequest -tenantid $TenantId -cmdlet 'Add-UnifiedGroupLinks' -cmdParams $subscriberParams -Anchor $UserObj.mail + } catch { + Write-Warning "Error and fuckery in SendCopies: Add-UnifiedGroupLinks $($_.Exception.Message) - $($_.InvocationInfo.ScriptLineNumber)" + } + + } + + $Results.Add("Send Copies of team emails and events to team members inboxes for $($UserObj.mail) enabled.") + Write-LogMessage -headers $Headers -API $APIName -tenant $TenantId -message "Send Copies of team emails and events to team members inboxes for $($UserObj.mail) enabled." -Sev 'Info' + } else { + # Disable send copies. Has to be done in 2 calls, otherwise it fails saying AutoSubscribeNewMembers cannot be true when subscriptionEnabled is false. + # Why this happens and can't be done in one call, only Bill Gates and the mystical gods of Exchange knows. + $Params = @{ Identity = $GroupId; AutoSubscribeNewMembers = $false } + $null = New-ExoRequest -tenantid $TenantId -cmdlet 'Set-UnifiedGroup' -cmdParams $Params -useSystemMailbox $true + $Params = @{ Identity = $GroupId; subscriptionEnabled = $false } + $null = New-ExoRequest -tenantid $TenantId -cmdlet 'Set-UnifiedGroup' -cmdParams $Params -useSystemMailbox $true + + $Results.Add("Send Copies of team emails and events to team members inboxes for $($UserObj.mail) disabled.") + Write-LogMessage -headers $Headers -API $APIName -tenant $TenantId -message "Send Copies of team emails and events to team members inboxes for $($UserObj.mail) disabled." -Sev 'Info' + } } catch { - Write-Warning "Error in SendCopies: $($_.Exception.Message) - $($_.InvocationInfo.ScriptLineNumber)" - Write-Warning ($_.InvocationInfo.PositionMessage) - $body = $Results.Add("Failed to Send Copies of team emails and events to team members inboxes for $($UserObj.mail).") - Write-LogMessage -headers $Headers -API $APIName -tenant $TenantId -message "Failed to Send Copies of team emails and events to team members inboxes for $($UserObj.mail). Error:$($_.Exception.Message)" -Sev 'Error' + $ErrorMessage = Get-CippException -Exception $_ + Write-Warning "Error in SendCopies: $($ErrorMessage.NormalizedError) - $($_.InvocationInfo.ScriptLineNumber)" + $action = if ($UserObj.sendCopies -eq $true) { 'enable' } else { 'disable' } + $Results.Add("Failed to $action Send Copies of team emails and events to team members inboxes for $($UserObj.mail).") + Write-LogMessage -headers $Headers -API $APIName -tenant $TenantId -message "Failed to $action Send Copies of team emails and events to team members inboxes for $($UserObj.mail). Error:$($ErrorMessage.NormalizedError)" -Sev 'Error' -LogData $ErrorMessage } } From 05fb79281ca063a16b2d83858b61382ca76d7851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Tue, 24 Jun 2025 20:12:12 +0200 Subject: [PATCH 08/26] Apparently PrimarySmtpAddress can be null? --- .../Identity/Administration/Groups/Invoke-EditGroup.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 index 76b9d5b82330..e1207f7a2f07 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 @@ -369,7 +369,7 @@ function Invoke-EditGroup { $MemberParams = @{ Identity = $GroupId; LinkType = 'members' } $Members = New-ExoRequest -tenantid $TenantId -cmdlet 'Get-UnifiedGroupLinks' -cmdParams $MemberParams - $MemberSmtpAddresses = $Members | ForEach-Object { $_.PrimarySmtpAddress } + $MemberSmtpAddresses = $Members | ForEach-Object { $_.ExternalDirectoryObjectId } if ($MemberSmtpAddresses) { $subscriberParams = @{ Identity = $GroupId; LinkType = 'subscribers'; Links = @($MemberSmtpAddresses | Where-Object { $_ }) } From bff6b9851f25f5eda04dff72ac5bd20b7ae697a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Tue, 24 Jun 2025 20:43:46 +0200 Subject: [PATCH 09/26] Fix allowExternal and sendCopies and add select for more SPEEEEEEEED rename param --- .../Groups/Invoke-EditGroup.ps1 | 14 ++++--- .../Groups/Invoke-ListGroups.ps1 | 39 +++++++++---------- 2 files changed, 27 insertions(+), 26 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 index e1207f7a2f07..34ec25c7abdc 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-EditGroup.ps1 @@ -347,7 +347,8 @@ function Invoke-EditGroup { # Only process allowExternal if it was explicitly sent if ($null -ne $UserObj.allowExternal -and $GroupType -ne 'Security') { try { - Set-CIPPGroupAuthentication -ID $UserObj.mail -OnlyAllowInternal (!$UserObj.allowExternal) -GroupType $GroupType -tenantFilter $TenantId -APIName $APIName -Headers $Headers + $OnlyAllowInternal = $UserObj.allowExternal -eq $true ? $false : $true + Set-CIPPGroupAuthentication -ID $UserObj.mail -OnlyAllowInternal $OnlyAllowInternal -GroupType $GroupType -tenantFilter $TenantId -APIName $APIName -Headers $Headers if ($UserObj.allowExternal -eq $true) { $Results.Add("Allowed external senders to send to $($UserObj.mail).") } else { @@ -369,15 +370,16 @@ function Invoke-EditGroup { $MemberParams = @{ Identity = $GroupId; LinkType = 'members' } $Members = New-ExoRequest -tenantid $TenantId -cmdlet 'Get-UnifiedGroupLinks' -cmdParams $MemberParams - $MemberSmtpAddresses = $Members | ForEach-Object { $_.ExternalDirectoryObjectId } - - if ($MemberSmtpAddresses) { - $subscriberParams = @{ Identity = $GroupId; LinkType = 'subscribers'; Links = @($MemberSmtpAddresses | Where-Object { $_ }) } + $MembershipIds = $Members | ForEach-Object { $_.ExternalDirectoryObjectId } + if ($MembershipIds) { + $subscriberParams = @{ Identity = $GroupId; LinkType = 'subscribers'; Links = @($MembershipIds | Where-Object { $_ }) } try { New-ExoRequest -tenantid $TenantId -cmdlet 'Add-UnifiedGroupLinks' -cmdParams $subscriberParams -Anchor $UserObj.mail } catch { - Write-Warning "Error and fuckery in SendCopies: Add-UnifiedGroupLinks $($_.Exception.Message) - $($_.InvocationInfo.ScriptLineNumber)" + $ErrorMessage = Get-CippException -Exception $_ + Write-Warning "Error in SendCopies: Add-UnifiedGroupLinks $($ErrorMessage.NormalizedError) - $($_.InvocationInfo.ScriptLineNumber)" + throw "Error in SendCopies: Add-UnifiedGroupLinks $($ErrorMessage.NormalizedError)" } } diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroups.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroups.ps1 index 6b5117824ec7..c0a3d0e87f7c 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroups.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Groups/Invoke-ListGroups.ps1 @@ -14,38 +14,42 @@ function Invoke-ListGroups { $Headers = $Request.Headers Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - $TenantFilter = $Request.Query.TenantFilter + $TenantFilter = $Request.Query.tenantFilter + $GroupID = $Request.Query.groupID + $GroupType = $Request.Query.groupType + $Members = $Request.Query.members + $Owners = $Request.Query.owners $SelectString = 'id,createdDateTime,displayName,description,mail,mailEnabled,mailNickname,resourceProvisioningOptions,securityEnabled,visibility,organizationId,onPremisesSamAccountName,membershipRule,groupTypes,onPremisesSyncEnabled,resourceProvisioningOptions,userPrincipalName&$expand=members($select=userPrincipalName)' $BulkRequestArrayList = [System.Collections.Generic.List[object]]::new() - if ($Request.Query.GroupID) { + if ($GroupID) { $SelectString = 'id,createdDateTime,displayName,description,mail,mailEnabled,mailNickname,resourceProvisioningOptions,securityEnabled,visibility,organizationId,onPremisesSamAccountName,membershipRule,groupTypes,userPrincipalName' $BulkRequestArrayList.add(@{ id = 1 method = 'GET' - url = "groups/$($Request.Query.GroupID)?`$select=$SelectString" + url = "groups/$($GroupID)?`$select=$SelectString" }) } - if ($Request.Query.members) { + if ($Members) { $SelectString = 'id,userPrincipalName,displayName,hideFromOutlookClients,hideFromAddressLists,mail,mailEnabled,mailNickname,resourceProvisioningOptions,securityEnabled,visibility,organizationId,onPremisesSamAccountName,membershipRule' $BulkRequestArrayList.add(@{ id = 2 method = 'GET' - url = "groups/$($Request.Query.GroupID)/members?`$top=999&select=$SelectString" + url = "groups/$($GroupID)/members?`$top=999&select=$SelectString" }) } - if ($Request.Query.owners) { - if ($Request.Query.groupType -ne 'Distribution List' -and $Request.Query.groupType -ne 'Mail-Enabled Security') { + if ($Owners) { + if ($GroupType -ne 'Distribution List' -and $GroupType -ne 'Mail-Enabled Security') { $SelectString = 'id,userPrincipalName,displayName,hideFromOutlookClients,hideFromAddressLists,mail,mailEnabled,mailNickname,resourceProvisioningOptions,securityEnabled,visibility,organizationId,onPremisesSamAccountName,membershipRule' $BulkRequestArrayList.add(@{ id = 3 method = 'GET' - url = "groups/$($Request.Query.GroupID)/owners?`$top=999&select=$SelectString" + url = "groups/$($GroupID)/owners?`$top=999&select=$SelectString" }) } else { - $OwnerIds = New-ExoRequest -cmdlet 'Get-DistributionGroup' -tenantid $TenantFilter -cmdParams @{Identity = $Request.Query.GroupID } -useSystemMailbox $true | Select-Object -ExpandProperty ManagedBy + $OwnerIds = New-ExoRequest -cmdlet 'Get-DistributionGroup' -tenantid $TenantFilter -cmdParams @{Identity = $GroupID } -Select 'ManagedBy' -useSystemMailbox $true | Select-Object -ExpandProperty ManagedBy $BulkRequestArrayList.add(@{ id = 3 @@ -61,23 +65,18 @@ function Invoke-ListGroups { } } - if ($Request.Query.groupType -eq 'Distribution List' -or $Request.Query.groupType -eq 'Mail-Enabled Security') { + if ($GroupType -eq 'Distribution List' -or $GroupType -eq 'Mail-Enabled Security') { # get the outside the organization RequireSenderAuthenticationEnabled setting - $OnlyAllowInternal = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Get-DistributionGroup' -cmdParams @{Identity = $Request.Query.GroupID } -useSystemMailbox $true | Select-Object -ExpandProperty RequireSenderAuthenticationEnabled + $OnlyAllowInternal = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Get-DistributionGroup' -cmdParams @{Identity = $GroupID } -Select 'RequireSenderAuthenticationEnabled' -useSystemMailbox $true | Select-Object -ExpandProperty RequireSenderAuthenticationEnabled } elseif ($GroupType -eq 'Microsoft 365') { - $OnlyAllowInternal = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Get-UnifiedGroup' -cmdParams @{Identity = $Request.Query.GroupID } -useSystemMailbox $true | Select-Object -ExpandProperty RequireSenderAuthenticationEnabled + $UnifiedGroup = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Get-UnifiedGroup' -cmdParams @{Identity = $GroupID } -Select 'RequireSenderAuthenticationEnabled,subscriptionEnabled,AutoSubscribeNewMembers' -useSystemMailbox $true + $OnlyAllowInternal = $UnifiedGroup.RequireSenderAuthenticationEnabled } else { $OnlyAllowInternal = $null } - if ($Request.Query.groupType -eq 'Microsoft 365') { - $UnifiedGroup = New-ExoRequest -tenantid $TenantFilter -cmdlet 'Get-UnifiedGroup' -cmdParams @{Identity = $Request.Query.GroupID } -useSystemMailbox $true | Select-Object -Property subscriptionEnabled, AutoSubscribeNewMembers - - if ($UnifiedGroup.subscriptionEnabled -eq $true -and $UnifiedGroup.AutoSubscribeNewMembers -eq $true) { - $SendCopies = $true - } else { - $SendCopies = $false - } + if ($GroupType -eq 'Microsoft 365') { + if ($UnifiedGroup.subscriptionEnabled -eq $true -and $UnifiedGroup.AutoSubscribeNewMembers -eq $true) { $SendCopies = $true } else { $SendCopies = $false } } else { $SendCopies = $null } From a15c8293ac7330cd7681117207e022864ffff667 Mon Sep 17 00:00:00 2001 From: John Martin <50556267+StoricU@users.noreply.github.com> Date: Wed, 25 Jun 2025 10:18:10 +0200 Subject: [PATCH 10/26] Update Invoke-CIPPStandardSendReceiveLimitTenant.ps1 Fix handling of send/receive limits: support 'Unlimited' values and use correct "MB" string format for Set-MailboxPlan. Added byte-based comparison for accurate checks. --- .../Invoke-CIPPStandardSendReceiveLimitTenant.ps1 | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSendReceiveLimitTenant.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSendReceiveLimitTenant.ps1 index e9e3daa4a36b..333788bf51e0 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSendReceiveLimitTenant.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardSendReceiveLimitTenant.ps1 @@ -43,8 +43,10 @@ function Invoke-CIPPStandardSendReceiveLimitTenant { } $AllMailBoxPlans = New-ExoRequest -tenantid $Tenant -cmdlet 'Get-MailboxPlan' | Select-Object DisplayName, MaxSendSize, MaxReceiveSize, GUID - $MaxSendSize = $Settings.SendLimit * 1MB - $MaxReceiveSize = $Settings.ReceiveLimit * 1MB + $MaxSendSize = "$($Settings.SendLimit)MB" + $MaxReceiveSize = "$($Settings.ReceiveLimit)MB" + $MaxSendSizeBytes = $Settings.SendLimit * 1MB + $MaxReceiveSizeBytes = $Settings.ReceiveLimit * 1MB $NotSetCorrectly = foreach ($MailboxPlan in $AllMailBoxPlans) { if ($MailboxPlan.MaxSendSize -eq 'Unlimited') { @@ -59,7 +61,7 @@ function Invoke-CIPPStandardSendReceiveLimitTenant { $PlanMaxReceiveSize = [int64]($MailboxPlan.MaxReceiveSize -replace '.*\(([\d,]+).*', '$1' -replace ',', '') } - if ($PlanMaxSendSize -ne $MaxSendSize -or $PlanMaxReceiveSize -ne $MaxReceiveSize) { + if ($PlanMaxSendSize -ne $MaxSendSizeBytes -or $PlanMaxReceiveSize -ne $MaxReceiveSizeBytes) { $MailboxPlan } } From c3d65eb4a4d61bfce140316e65509270506ee7d6 Mon Sep 17 00:00:00 2001 From: ngms-psh Date: Wed, 25 Jun 2025 14:00:44 +0200 Subject: [PATCH 11/26] Add 'Prefer' header to make request upsert method --- ...CIPPStandardRestrictThirdPartyStorageServices.ps1 | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRestrictThirdPartyStorageServices.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRestrictThirdPartyStorageServices.ps1 index 161c13bc6813..9ee55cba203d 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRestrictThirdPartyStorageServices.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardRestrictThirdPartyStorageServices.ps1 @@ -52,16 +52,6 @@ function Invoke-CIPPStandardRestrictThirdPartyStorageServices { } else { # Disable the service principal to restrict third-party storage services try { - # Create the service principal if it does not exist - if ($null -eq $CurrentState){ - $CreateBody = @{ - appId = $AppId - } | ConvertTo-Json -Depth 10 -Compress - - $CreateUri = "https://graph.microsoft.com/beta/servicePrincipals" - $null = New-GraphPOSTRequest -uri $CreateUri -tenantid $Tenant -Body $CreateBody - } - $DisableBody = @{ accountEnabled = $false } | ConvertTo-Json -Depth 10 -Compress @@ -69,7 +59,7 @@ function Invoke-CIPPStandardRestrictThirdPartyStorageServices { # Normal /servicePrincipal/AppId does not find the service principal, so gotta use the Upsert method. Also handles if the service principal does not exist nicely. # https://learn.microsoft.com/en-us/graph/api/serviceprincipal-upsert?view=graph-rest-beta&tabs=http $UpdateUri = "https://graph.microsoft.com/beta/servicePrincipals(appId='$AppId')" - $null = New-GraphPostRequest -Uri $UpdateUri -Body $DisableBody -TenantID $Tenant -Type PATCH + $null = New-GraphPostRequest -Uri $UpdateUri -Body $DisableBody -TenantID $Tenant -Type PATCH -AddedHeaders @{'Prefer' = 'create-if-missing'} # Refresh the current state after disabling $CurrentState = New-GraphGetRequest -Uri $Uri -tenantid $Tenant | Select-Object displayName, accountEnabled, appId From 14b60a5e73491ef7f963672c60e16734d81fced0 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Wed, 25 Jun 2025 09:56:16 -0400 Subject: [PATCH 12/26] skip top level null in locationinfo --- Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 b/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 index 0e4d23694b98..8dd288691767 100644 --- a/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPCAPolicy.ps1 @@ -117,9 +117,9 @@ function New-CIPPCAPolicy { } } - #for each of the locations, check if they exist, if not create them. These are in $jsonobj.LocationInfo $LocationLookupTable = foreach ($locations in $jsonobj.LocationInfo) { + if (!$locations) { continue } foreach ($location in $locations) { if (!$location.displayName) { continue } $CheckExististing = New-GraphGETRequest -uri 'https://graph.microsoft.com/beta/identity/conditionalAccess/namedLocations' -tenantid $TenantFilter -asApp $true @@ -233,7 +233,7 @@ function New-CIPPCAPolicy { $CheckExististing = New-GraphGETRequest -uri 'https://graph.microsoft.com/beta/identity/conditionalAccess/policies' -tenantid $TenantFilter -asApp $true | Where-Object -Property displayName -EQ $displayname if ($CheckExististing) { if ($Overwrite -ne $true) { - Throw "Conditional Access Policy with Display Name $($Displayname) Already exists" + throw "Conditional Access Policy with Display Name $($Displayname) Already exists" return $false } else { Write-Information "overwriting $($CheckExististing.id)" From 3968a301e83e8a22bc796ba742a3e8d06cf694c9 Mon Sep 17 00:00:00 2001 From: RunningFreak <156828136+OwenIbarra@users.noreply.github.com> Date: Wed, 25 Jun 2025 13:22:36 -0400 Subject: [PATCH 13/26] Update New-CippAuditLogSearch.ps1 Filterss -> Filters --- Modules/CIPPCore/Public/AuditLogs/New-CippAuditLogSearch.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/AuditLogs/New-CippAuditLogSearch.ps1 b/Modules/CIPPCore/Public/AuditLogs/New-CippAuditLogSearch.ps1 index 2bb80d31427f..a840dac13486 100644 --- a/Modules/CIPPCore/Public/AuditLogs/New-CippAuditLogSearch.ps1 +++ b/Modules/CIPPCore/Public/AuditLogs/New-CippAuditLogSearch.ps1 @@ -147,7 +147,7 @@ function New-CippAuditLogSearch { if ($IPAddressFilters) { $SearchParams.ipAddressFilters = @($IPAddressFilters) } - if ($ObjectIdFilterss) { + if ($ObjectIdFilters) { $SearchParams.objectIdFilters = @($ObjectIdFilters) } if ($AdministrativeUnitFilters) { From ebfdec574b91a47d52e218084175922357abfeeb Mon Sep 17 00:00:00 2001 From: RunningFreak <156828136+OwenIbarra@users.noreply.github.com> Date: Wed, 25 Jun 2025 13:47:41 -0400 Subject: [PATCH 14/26] Create test --- .github/workflows/test | 1 + 1 file changed, 1 insertion(+) create mode 100644 .github/workflows/test diff --git a/.github/workflows/test b/.github/workflows/test new file mode 100644 index 000000000000..9daeafb9864c --- /dev/null +++ b/.github/workflows/test @@ -0,0 +1 @@ +test From 04d73399aebbc67a53268e4cecf40b98cc206e92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Wed, 25 Jun 2025 23:03:57 +0200 Subject: [PATCH 15/26] fix casing issue --- .../Users/Invoke-ExecOneDriveShortCut.ps1 | 8 +++++++- Modules/CIPPCore/Public/New-CIPPOneDriveShortCut.ps1 | 12 ++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOneDriveShortCut.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOneDriveShortCut.ps1 index 5bf461f6a0d5..4ca493e65db2 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOneDriveShortCut.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOneDriveShortCut.ps1 @@ -14,8 +14,14 @@ Function Invoke-ExecOneDriveShortCut { $Headers = $Request.Headers Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' + # Interact with the body of the request + $TenantFilter = $Request.Body.tenantFilter + $Username = $Request.Body.username + $UserId = $Request.Body.userid + $URL = $Request.Body.siteUrl.value + Try { - $Result = New-CIPPOneDriveShortCut -username $Request.Body.username -userid $Request.Body.userid -TenantFilter $Request.Body.tenantFilter -URL $Request.Body.siteUrl.value -Headers $Request.Headers + $Result = New-CIPPOneDriveShortCut -Username $Username -UserId $UserId -TenantFilter $TenantFilter -URL $URL -Headers $Headers $StatusCode = [HttpStatusCode]::OK } catch { $Result = $_.Exception.Message diff --git a/Modules/CIPPCore/Public/New-CIPPOneDriveShortCut.ps1 b/Modules/CIPPCore/Public/New-CIPPOneDriveShortCut.ps1 index 29764fc40e34..d1d5ce8db072 100644 --- a/Modules/CIPPCore/Public/New-CIPPOneDriveShortCut.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPOneDriveShortCut.ps1 @@ -12,11 +12,11 @@ function New-CIPPOneDriveShortCut { Write-Host "Received $Username and $UserId. We're using $URL and $TenantFilter" try { $SiteInfo = New-GraphGetRequest -uri 'https://graph.microsoft.com/beta/sites/' -tenantid $TenantFilter -asapp $true | Where-Object -Property weburl -EQ $URL - $ListItemUniqueId = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/sites/$($siteInfo.id)/drive?`$select=SharepointIds" -tenantid $TenantFilter -asapp $true).SharePointIds + $ListItemUniqueId = (New-GraphGetRequest -uri "https://graph.microsoft.com/beta/sites/$($SiteInfo.id)/drive?`$select=SharepointIds" -tenantid $TenantFilter -asapp $true).SharePointIds $body = [PSCustomObject]@{ name = 'Documents' remoteItem = @{ - SharepointIds = @{ + sharepointIds = @{ listId = $($ListItemUniqueId.listid) listItemUniqueId = 'root' siteId = $($ListItemUniqueId.siteId) @@ -26,12 +26,12 @@ function New-CIPPOneDriveShortCut { } '@microsoft.graph.conflictBehavior' = 'rename' } | ConvertTo-Json -Depth 10 - New-GraphPOSTRequest -method POST "https://graph.microsoft.com/beta/users/$username/drive/root/children" -body $body -tenantid $TenantFilter -asapp $true - Write-LogMessage -API $APIName -headers $Headers -message "Created OneDrive shortcut called $($SiteInfo.displayName) for $($username)" -Sev 'info' - return "Successfully created OneDrive Shortcut for $username called $($SiteInfo.displayName) " + New-GraphPOSTRequest -method POST "https://graph.microsoft.com/beta/users/$Username/drive/root/children" -body $Body -tenantid $TenantFilter -asapp $true + Write-LogMessage -API $APIName -headers $Headers -message "Created OneDrive shortcut called $($SiteInfo.displayName) for $($Username)" -Sev 'info' + return "Successfully created OneDrive Shortcut for $Username called $($SiteInfo.displayName) " } catch { $ErrorMessage = Get-CippException -Exception $_ - $Result = "Could not add Onedrive shortcut to $username : $($ErrorMessage.NormalizedError)" + $Result = "Could not add Onedrive shortcut to $Username : $($ErrorMessage.NormalizedError)" Write-LogMessage -headers $Headers -API $APIName -message $Result -Sev 'Error' -LogData $ErrorMessage throw $Result } From c16993d76ce26753aef33e8e8925fad1d8cb75a5 Mon Sep 17 00:00:00 2001 From: Zac Richards <107489668+Zacgoose@users.noreply.github.com> Date: Thu, 26 Jun 2025 09:11:10 +0800 Subject: [PATCH 16/26] Remove extra periods... --- .../Email-Exchange/Administration/Invoke-AddSharedMailbox.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-AddSharedMailbox.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-AddSharedMailbox.ps1 index 797025084402..4ad094971c5d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-AddSharedMailbox.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-AddSharedMailbox.ps1 @@ -29,7 +29,7 @@ Function Invoke-AddSharedMailbox { Shared = $true } $AddSharedRequest = New-ExoRequest -tenantid $Tenant -cmdlet 'New-Mailbox' -cmdParams $BodyToShip - $Body = $Results.Add("Successfully created shared mailbox: $Email.") + $Body = $Results.Add("Successfully created shared mailbox: $Email") Write-LogMessage -Headers $Headers -API $APIName -tenant $Tenant -message "Created shared mailbox $($MailboxObject.displayName) with email $Email" -Sev 'Info' # Block sign-in for the mailbox @@ -38,7 +38,7 @@ Function Invoke-AddSharedMailbox { $Body = $Results.Add("Blocked sign-in for shared mailbox $Email") } catch { $ErrorMessage = Get-CippException -Exception $_ - $Message = "Failed to block sign-in for shared mailbox $Email. Error: $($ErrorMessage.NormalizedError)" + $Message = "Failed to block sign-in for shared mailbox $Email Error: $($ErrorMessage.NormalizedError)" Write-LogMessage -Headers $Headers -API $APIName -tenant $Tenant -message $Message -Sev 'Error' -LogData $ErrorMessage $Body = $Results.Add($Message) } From d0be894df3c358dd942c1ca182b848615c2e9adb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Thu, 26 Jun 2025 19:38:51 +0200 Subject: [PATCH 17/26] award for dumbest bug goes to --- .../Email-Exchange/Administration/Invoke-ExecSetOoO.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecSetOoO.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecSetOoO.ps1 index 1bd62dac8eb9..c262bfb5ce5d 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecSetOoO.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Email-Exchange/Administration/Invoke-ExecSetOoO.ps1 @@ -30,8 +30,8 @@ Function Invoke-ExecSetOoO { # User action uses input, edit exchange uses InternalMessage and ExternalMessage # User action disable OoO doesn't send any input if ($Request.Body.input) { - $InternalMessage = $Request.Body.input - $ExternalMessage = $Request.Body.input + $SplatParams.InternalMessage = $Request.Body.input + $SplatParams.ExternalMessage = $Request.Body.input } else { $InternalMessage = $Request.Body.InternalMessage $ExternalMessage = $Request.Body.ExternalMessage From 72fe3190653eb19fce4513536064484f1e07741f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kristian=20Kj=C3=A6rg=C3=A5rd?= Date: Thu, 26 Jun 2025 21:35:56 +0200 Subject: [PATCH 18/26] Enhance domain analysis script with structured region comments. - Add new terms to cspell configuration. - Always ask EXO for MSCNAMERecords selector values --- .../Push-DomainAnalyserDomain.ps1 | 52 +++++++++---------- cspell.json | 2 + 2 files changed, 27 insertions(+), 27 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Domain Analyser/Push-DomainAnalyserDomain.ps1 b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Domain Analyser/Push-DomainAnalyserDomain.ps1 index 168342bd7701..08cf028b8704 100644 --- a/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Domain Analyser/Push-DomainAnalyserDomain.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/Activity Triggers/Domain Analyser/Push-DomainAnalyserDomain.ps1 @@ -83,7 +83,7 @@ function Push-DomainAnalyserDomain { # Setup Score Explanation $ScoreExplanation = [System.Collections.Generic.List[string]]::new() - # Check MX Record + #Region MX Check $MXRecord = Read-MXRecord -Domain $Domain -ErrorAction Stop $Result.ExpectedSPFRecord = $MXRecord.ExpectedInclude @@ -106,8 +106,9 @@ function Push-DomainAnalyserDomain { } else { $Result.MailProvider = $MXRecord.MailProvider.Name } + #EndRegion MX Check - # Get SPF Record + #Region SPF Check try { $SPFRecord = Read-SpfRecord -Domain $Domain -ErrorAction Stop if ($SPFRecord.RecordCount -gt 0) { @@ -126,12 +127,11 @@ function Push-DomainAnalyserDomain { Write-LogMessage -API 'DomainAnalyser' -tenant $DomainObject.TenantId -message $Message -LogData (Get-CippException -Exception $_) -sev Error } - # Check SPF Record - $Result.SPFPassAll = $false # Check warning + fail counts to ensure all tests pass #$SPFWarnCount = $SPFRecord.ValidationWarns | Measure-Object | Select-Object -ExpandProperty Count $SPFFailCount = $SPFRecord.ValidationFails | Measure-Object | Select-Object -ExpandProperty Count + $Result.SPFPassAll = $false if ($SPFFailCount -eq 0) { $ScoreDomain += $Scores.SPFCorrectAll @@ -139,8 +139,9 @@ function Push-DomainAnalyserDomain { } else { $ScoreExplanation.Add('SPF record did not pass validation') | Out-Null } + #EndRegion SPF Check - # Get DMARC Record + #Region DMARC Check try { $DMARCPolicy = Read-DmarcPolicy -Domain $Domain -ErrorAction Stop @@ -188,8 +189,9 @@ function Push-DomainAnalyserDomain { Write-LogMessage -API 'DomainAnalyser' -tenant $DomainObject.TenantId -message $Message -LogData (Get-CippException -Exception $_) -sev Error #return $Message } + #EndRegion DMARC Check - # DNS Sec Check + #Region DNS Sec Check try { $DNSSECResult = Test-DNSSEC -Domain $Domain -ErrorAction Stop $DNSSECFailCount = $DNSSECResult.ValidationFails | Measure-Object | Select-Object -ExpandProperty Count @@ -206,8 +208,9 @@ function Push-DomainAnalyserDomain { Write-LogMessage -API 'DomainAnalyser' -tenant $DomainObject.TenantId -message $Message -LogData (Get-CippException -Exception $_) -sev Error #return $Message } + #EndRegion DNS Sec Check - # DKIM Check + #Region DKIM Check try { $DkimParams = @{ Domain = $Domain @@ -241,7 +244,9 @@ function Push-DomainAnalyserDomain { Write-LogMessage -API 'DomainAnalyser' -tenant $DomainObject.TenantId -message $Message -LogData (Get-CippException -Exception $_) -sev Error #return $Message } + #EndRegion DKIM Check + #Region MSCNAME DKIM Records # Get Microsoft DKIM CNAME selector Records # Ugly, but i needed to create a scope/loop i could break out of without breaking the rest of the function foreach ($d in $Domain) { @@ -250,7 +255,7 @@ function Push-DomainAnalyserDomain { if ($Result.DKIMEnabled -eq $true) { continue } - # Test if its a onmicrosft.com domain, skip domain if it is + # Test if its a onmicrosoft.com domain, skip domain if it is if ($Domain -match 'onmicrosoft.com') { continue } @@ -264,28 +269,21 @@ function Push-DomainAnalyserDomain { } } + # Get the DKIM record from EXO. This is the only way to get the correct values for the MSCNAME records since the new format was introduced in May 2025. + $DKIM = (New-ExoRequest -tenantid $Tenant.Tenant -cmdlet 'Get-DkimSigningConfig' -Select 'Domain,Selector1CNAME,Selector2CNAME') | Where-Object { $_.Domain -eq $Domain } - # Compute the DKIM CNAME records from $Tenant.InitialDomainName according to this logic: https://learn.microsoft.com/en-us/defender-office-365/email-authentication-dkim-configure#syntax-for-dkim-cname-records - # Test if it has a - in the domain name - if ($Domain -like '*-*') { - Write-Information 'Domain has a - in it. Got to query EXO for the right values' - $DKIM = (New-ExoRequest -tenantid $Tenant.Tenant -cmdlet 'Get-DkimSigningConfig') | Where-Object { $_.Domain -eq $Domain } | Select-Object Domain, Selector1CNAME, Selector2CNAME - - # If no DKIM signing record is found, create a new disabled one - if ($null -eq $DKIM) { - Write-Information 'No DKIM record found in EXO - Creating new signing' - $NewDKIMSigningRequest = New-ExoRequest -tenantid $Tenant.Tenant -cmdlet 'New-DkimSigningConfig' -cmdParams @{ KeySize = 2048; DomainName = $Domain; Enabled = $false } - $Selector1Value = $NewDKIMSigningRequest.Selector1CNAME - $Selector2Value = $NewDKIMSigningRequest.Selector2CNAME - } else { - $Selector1Value = $DKIM.Selector1CNAME - $Selector2Value = $DKIM.Selector2CNAME - } + # If no DKIM signing record is found, create a new disabled one + if ($null -eq $DKIM) { + Write-Information 'No DKIM record found in EXO - Creating new signing' + $NewDKIMSigningRequest = New-ExoRequest -tenantid $Tenant.Tenant -cmdlet 'New-DkimSigningConfig' -cmdParams @{ KeySize = 2048; DomainName = $Domain; Enabled = $false } + $Selector1Value = $NewDKIMSigningRequest.Selector1CNAME + $Selector2Value = $NewDKIMSigningRequest.Selector2CNAME } else { - $Selector1Value = "selector1-$($Domain -replace '\.', '-' )._domainkey.$($Tenant.InitialDomainName)" - $Selector2Value = "selector2-$($Domain -replace '\.', '-' )._domainkey.$($Tenant.InitialDomainName)" + $Selector1Value = $DKIM.Selector1CNAME + $Selector2Value = $DKIM.Selector2CNAME } + # Create the MSCNAME object $MSCNAMERecords = [PSCustomObject]@{ Domain = $Domain @@ -304,7 +302,7 @@ function Push-DomainAnalyserDomain { Write-LogMessage -API 'DomainAnalyser' -tenant $DomainObject.TenantId -message "MS CNAME DKIM error: $($ErrorMessage.NormalizedError)" -LogData $ErrorMessage -sev Error } } - + #EndRegion MSCNAME DKIM Records # Final Score $Result.Score = $ScoreDomain $Result.ScorePercentage = [int](($Result.Score / $Result.MaximumScore) * 100) diff --git a/cspell.json b/cspell.json index e4ec9aadb5ed..b931fc283665 100644 --- a/cspell.json +++ b/cspell.json @@ -14,6 +14,7 @@ "Connectwise", "CPIM", "Datto", + "Dmarc", "DMARC", "endswith", "entra", @@ -25,6 +26,7 @@ "Intune", "locationcipp", "MAPI", + "MSCNAME", "Multitenant", "OBEE", "passwordless", From aa681fd5716b2803559badd4a806385a8859b393 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 26 Jun 2025 16:37:37 -0400 Subject: [PATCH 19/26] casing --- .../Identity/Administration/Users/Invoke-ExecOffboardUser.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOffboardUser.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOffboardUser.ps1 index cfff9d58c240..970d02136dfd 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOffboardUser.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-ExecOffboardUser.ps1 @@ -1,6 +1,6 @@ using namespace System.Net -Function Invoke-ExecOffboardUser { +function Invoke-ExecOffboardUser { <# .FUNCTIONALITY Entrypoint @@ -30,7 +30,7 @@ Function Invoke-ExecOffboardUser { options = $Request.Body RunScheduled = $true } - ScheduledTime = $Request.Body.scheduled.date + ScheduledTime = $Request.Body.Scheduled.date PostExecution = @{ Webhook = [bool]$Request.Body.PostExecution.webhook Email = [bool]$Request.Body.PostExecution.email From e5770affb5e0972fb2d5a6eec6ae2b92893c183a Mon Sep 17 00:00:00 2001 From: John Duprey Date: Thu, 26 Jun 2025 17:07:45 -0400 Subject: [PATCH 20/26] Delete .github/workflows/test --- .github/workflows/test | 1 - 1 file changed, 1 deletion(-) delete mode 100644 .github/workflows/test diff --git a/.github/workflows/test b/.github/workflows/test deleted file mode 100644 index 9daeafb9864c..000000000000 --- a/.github/workflows/test +++ /dev/null @@ -1 +0,0 @@ -test From ce2a7842b94399d9cdff0c76c4ae3c32bdf7c61f Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 27 Jun 2025 10:16:06 -0400 Subject: [PATCH 21/26] remove where object --- .../Scheduler/Invoke-ListScheduledItems.ps1 | 32 +++++++++++-------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-ListScheduledItems.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-ListScheduledItems.ps1 index ceadb14858a8..4361e6d64ee6 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-ListScheduledItems.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/CIPP/Scheduler/Invoke-ListScheduledItems.ps1 @@ -14,23 +14,29 @@ function Invoke-ListScheduledItems { $Headers = $Request.Headers Write-LogMessage -headers $Headers -API $APIName -message 'Accessed this API' -Sev 'Debug' - - # Interact with query parameters or the body of the request. - $ShowHidden = $Request.Query.ShowHidden ?? $Request.Body.ShowHidden - $Name = $Request.Query.Name ?? $Request.Body.Name - $Type = $Request.Query.Type ?? $Request.Body.Type - $ScheduledItemFilter = [System.Collections.Generic.List[string]]::new() $ScheduledItemFilter.Add("PartitionKey eq 'ScheduledTask'") - if ($ShowHidden -eq $true) { - $ScheduledItemFilter.Add('Hidden eq true') + $Id = $Request.Query.Id ?? $Request.Body.Id + if ($Id) { + # Interact with query parameters. + $ScheduledItemFilter.Add("RowKey eq '$($Id)'") } else { - $ScheduledItemFilter.Add('Hidden eq false') - } + # Interact with query parameters or the body of the request. + $ShowHidden = $Request.Query.ShowHidden ?? $Request.Body.ShowHidden + $Name = $Request.Query.Name ?? $Request.Body.Name + $Type = $Request.Query.Type ?? $Request.Body.Type + + if ($ShowHidden -eq $true) { + $ScheduledItemFilter.Add('Hidden eq true') + } else { + $ScheduledItemFilter.Add('Hidden eq false') + } + + if ($Name) { + $ScheduledItemFilter.Add("Name eq '$($Name)'") + } - if ($Name) { - $ScheduledItemFilter.Add("Name eq '$($Name)'") } $Filter = $ScheduledItemFilter -join ' and ' @@ -42,7 +48,7 @@ function Invoke-ListScheduledItems { } else { $HiddenTasks = $true } - $Tasks = Get-CIPPAzDataTableEntity @Table -Filter $Filter | Where-Object { $_.Hidden -ne $HiddenTasks } + $Tasks = Get-CIPPAzDataTableEntity @Table -Filter $Filter if ($Type) { $Tasks = $Tasks | Where-Object { $_.command -eq $Type } } From 90f00c75b33778929f45277a40cdc2c6c100fc1e Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 27 Jun 2025 10:16:19 -0400 Subject: [PATCH 22/26] remove extra slash --- .../HTTP Functions/Tenant/Conditional/Invoke-EditCAPolicy.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-EditCAPolicy.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-EditCAPolicy.ps1 index eb3324e2ab75..755914af4aaf 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-EditCAPolicy.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Conditional/Invoke-EditCAPolicy.ps1 @@ -32,7 +32,7 @@ Function Invoke-EditCAPolicy { $properties["displayName"] = $DisplayName } - $Request = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta//identity/conditionalAccess/policies/$($ID)" -tenantid $TenantFilter -type PATCH -body ($properties | ConvertTo-Json) -asapp $true + $Request = New-GraphPOSTRequest -uri "https://graph.microsoft.com/beta/identity/conditionalAccess/policies/$($ID)" -tenantid $TenantFilter -type PATCH -body ($properties | ConvertTo-Json) -asapp $true $Result = "Successfully updated CA policy $($ID)" if ($State) { $Result += " state to $($State)" } From 3eddb4c907af4bf120a5938c41015ce0473b0251 Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 27 Jun 2025 10:34:32 -0400 Subject: [PATCH 23/26] fix phishing protection url --- .../Tenant/Standards/Invoke-AddStandardsTemplate.ps1 | 9 +++++++++ .../Standards/Invoke-CIPPStandardPhishProtection.ps1 | 6 +++++- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsTemplate.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsTemplate.ps1 index c41da1262f37..b22a4b1687e0 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsTemplate.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Tenant/Standards/Invoke-AddStandardsTemplate.ps1 @@ -30,6 +30,15 @@ function Invoke-AddStandardsTemplate { PartitionKey = 'StandardsTemplateV2' GUID = "$GUID" } + + $AddObject = @{ + PartitionKey = 'InstanceProperties' + RowKey = 'CIPPURL' + Value = [string]([System.Uri]$Headers.'x-ms-original-url').Host + } + $ConfigTable = Get-CIPPTable -tablename 'Config' + Add-AzDataTableEntity @ConfigTable -Entity $AddObject -Force + Write-LogMessage -headers $Request.Headers -API $APINAME -message "Standards Template $($Request.body.templateName) with GUID $GUID added/edited." -Sev 'Info' $body = [pscustomobject]@{'Results' = 'Successfully added template'; Metadata = @{id = $GUID } } diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishProtection.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishProtection.ps1 index 5469ef708182..123f0d7eb73d 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishProtection.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishProtection.ps1 @@ -35,6 +35,10 @@ function Invoke-CIPPStandardPhishProtection { $TenantId = Get-Tenants | Where-Object -Property defaultDomainName -EQ $tenant + $Table = Get-CIPPTable -TableName Config + $CippConfig = (Get-CIPPAzDataTableEntity @Table) + $CIPPUrl = ($CippConfig | Where-Object { $_.RowKey -eq 'CIPPURL' }).Value + try { $currentBody = (New-GraphGetRequest -Uri "https://graph.microsoft.com/beta/organization/$($TenantId.customerId)/branding/localizations/0/customCSS" -tenantid $tenant) } catch { @@ -42,7 +46,7 @@ function Invoke-CIPPStandardPhishProtection { } $CSS = @" .ext-sign-in-box { - background-image: url(https://clone.cipp.app/api/PublicPhishingCheck?Tenantid=$($tenant)&URL=$($Settings.URL)); + background-image: url(https://clone.cipp.app/api/PublicPhishingCheck?Tenantid=$($tenant)&URL=https://$($CIPPUrl)); } "@ if ($Settings.remediate -eq $true) { From aee9e9941aafaed916c88abf14ed1149ad60e860 Mon Sep 17 00:00:00 2001 From: rvdwegen Date: Fri, 27 Jun 2025 17:03:06 +0200 Subject: [PATCH 24/26] Cleanup broken CSS --- .../Standards/Invoke-CIPPStandardPhishProtection.ps1 | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishProtection.ps1 b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishProtection.ps1 index 123f0d7eb73d..c74ea30aa0e8 100644 --- a/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishProtection.ps1 +++ b/Modules/CIPPCore/Public/Standards/Invoke-CIPPStandardPhishProtection.ps1 @@ -51,6 +51,17 @@ function Invoke-CIPPStandardPhishProtection { "@ if ($Settings.remediate -eq $true) { + $malformedCSSPattern = '\.ext-sign-in-box\s*\{\s*background-image:\s*url\(https://clone\.cipp\.app/api/PublicPhishingCheck\?Tenantid=[^&]*&URL=\);\s*\}' + if ($currentBody -match $malformedCSSPattern) { + if ($Settings.remediate -eq $true) { + Write-LogMessage -API 'Standards' -tenant $tenant -message 'Attempting to fix malformed PhishProtection CSS by removing the problematic pattern' -sev Info + # Remove the malformed CSS pattern + $currentBody = $currentBody -replace $malformedCSSPattern, '' + # Clean up any duplicate .ext-sign-in-box entries + #$currentBody = $currentBody -replace '\.ext-sign-in-box\s*\{[^}]*\}\s*\.ext-sign-in-box', '.ext-sign-in-box' + } + } + try { if (!$currentBody) { $AddedHeaders = @{'Accept-Language' = 0 } From 702c74da509bc0de4428249c6449f6995201311a Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 27 Jun 2025 11:13:40 -0400 Subject: [PATCH 25/26] fix casing for set-cippuserlicense --- .../Identity/Administration/Users/Invoke-AddUserBulk.ps1 | 2 +- .../Identity/Administration/Users/Invoke-EditUser.ps1 | 2 +- Modules/CIPPCore/Public/New-CIPPUserTask.ps1 | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUserBulk.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUserBulk.ps1 index 3bb2c6b06a53..a7240624c9c1 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUserBulk.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-AddUserBulk.ps1 @@ -131,7 +131,7 @@ function Invoke-AddUserBulk { if ($AssignedLicenses) { $GuidPattern = '([a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12})' $LicenseSkus = $AssignedLicenses.value ?? $AssignedLicenses | Where-Object { $_ -match $GuidPattern } - Set-CIPPUserLicense -User $BulkResult.id -AddLicenses $LicenseSkus -TenantFilter $TenantFilter + Set-CIPPUserLicense -UserId $BulkResult.id -AddLicenses $LicenseSkus -TenantFilter $TenantFilter } $Results.Add(@{ resultText = $Message.resultText diff --git a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-EditUser.ps1 b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-EditUser.ps1 index d40f20130797..5b985cf0817e 100644 --- a/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-EditUser.ps1 +++ b/Modules/CIPPCore/Public/Entrypoints/HTTP Functions/Identity/Administration/Users/Invoke-EditUser.ps1 @@ -98,7 +98,7 @@ function Invoke-EditUser { value = 'Set-CIPPUserLicense' } Parameters = [pscustomobject]@{ - userId = $UserObj.id + UserId = $UserObj.id APIName = 'Sherweb License Assignment' AddLicenses = $licenses } diff --git a/Modules/CIPPCore/Public/New-CIPPUserTask.ps1 b/Modules/CIPPCore/Public/New-CIPPUserTask.ps1 index 3c228ef1006b..97c14c02d6e6 100644 --- a/Modules/CIPPCore/Public/New-CIPPUserTask.ps1 +++ b/Modules/CIPPCore/Public/New-CIPPUserTask.ps1 @@ -30,7 +30,7 @@ function New-CIPPUserTask { value = 'Set-CIPPUserLicense' } Parameters = [pscustomobject]@{ - userId = $UserObj.id + UserId = $UserObj.id APIName = 'Sherweb License Assignment' AddLicenses = $licenses } From 17c489eddd5f3f0981a2b7dcd9d4aaf20f67af7c Mon Sep 17 00:00:00 2001 From: John Duprey Date: Fri, 27 Jun 2025 11:16:59 -0400 Subject: [PATCH 26/26] up version --- version_latest.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/version_latest.txt b/version_latest.txt index 8104cabd36fb..0e79152459e0 100644 --- a/version_latest.txt +++ b/version_latest.txt @@ -1 +1 @@ -8.1.0 +8.1.1