Skip to content

[pull] dev from KelvinTegelaar:dev#105

Open
pull[bot] wants to merge 368 commits into
isgq-github01:devfrom
KelvinTegelaar:dev
Open

[pull] dev from KelvinTegelaar:dev#105
pull[bot] wants to merge 368 commits into
isgq-github01:devfrom
KelvinTegelaar:dev

Conversation

@pull

@pull pull Bot commented Jun 16, 2026

Copy link
Copy Markdown

See Commits and Changes for more details.


Created by pull[bot] (v2.0.0-alpha.4)

Can you help keep this open source service alive? 💖 Please sponsor : )

pull Bot and others added 30 commits May 30, 2026 17:36
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
Updated to write to and read from cetralised CIPP database
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
Added license check for new Defender category

Signed-off-by: DamienMatthys <damien@pcunplug.com>
Cleaned up logging

Signed-off-by: DamienMatthys <damien@pcunplug.com>
[pull] dev from KelvinTegelaar:dev
[pull] dev from KelvinTegelaar:dev
KelvinTegelaar and others added 30 commits July 1, 2026 22:26
Resolves KelvinTegelaar/CIPP#6246

## Problem

Intune assignment resolves group and assignment-filter names with
PowerShell's `-like`
operator. `-like` treats `[ ]` as wildcard character-class syntax, so a
literal group
named `[WIN] Company Devices` never matches itself. Deploying an app (or
policy) to such
a group fails with `No matching groups resolved for assignment
request.`, even though the
group exists with that exact name. Bracket-prefixed naming schemes
(`[WIN]`, `[PROD]`,
`[Pilot]`, ...) are common, so this hits real tenants. Other wildcard
metacharacters in a
literal name (`?`, `*`) are affected the same way.

## Fix

Escape only the square brackets in the supplied name (`` `[ `` / `` `]
``) before the `-like`
match, so `[` and `]` are treated as literal characters instead of a
wildcard character-class.
`*` and `?` are left untouched, so the documented wildcard matching (the
assignment UI labels
say "Wildcards (*) are allowed") keeps working exactly as before. Only
the unintended
bracket-as-character-class behaviour is fixed.

The same root cause is present in every Intune assignment group-name
lookup, so all six
group-resolution sites are fixed together rather than only the one path
in the report:

| File | Group lookups fixed |
|---|---|
| `Set-CIPPAssignedApplication.ps1` | include, exclude |
| `Set-CIPPAssignedPolicy.ps1` | include, exclude |
| `Compare-CIPPIntuneAssignments.ps1` | include, exclude |

This covers app deployment (Standards "Deploy Application", the
Chrome-extension standard,
Office-app deploy, the assign-app endpoint), configuration-policy
assignment, and the
assignment drift/comparison reporting, all of which share the predicate.

Assignment-filter name matching (which also uses `-like`) is
deliberately left unchanged:
`Compare-CIPPIntuneAssignments` documents the filter name as supporting
wildcards, so
escaping it would remove a documented feature. Only group-name
resolution, which is matched
against exact names, is made literal here.

## Behaviour note

Wildcards `*` and `?` still work exactly as documented - only `[` and
`]` are escaped. So
`Sales*` keeps matching every Sales group, while a literal `[WIN]
Company Devices` now
resolves to itself instead of being read as the character-class `[WIN]`.

## Verification

Validated by inspection plus a standalone logic harness that reproduces
the resolution
predicate (old vs new) against a realistic group set including
bracketed, parenthesised and
near-collision names. The harness confirms: the bug pre-fix (bracketed
name resolves to
nothing), the fix post-fix (resolves to the correct group only), plain
names still resolve,
comma-separated multi-group input works, and no over-matching across
similar names.

## Related (separate issue)

`Get-CIPPAlertGroupMembershipChange` uses the same `-like` pattern when
matching audit-log
group names against the admin's monitored-group list. Bracketed
monitored group names would
silently never alert. It is intentionally left out of this PR and raised
separately, because
that path may be intended to support wildcard monitoring and the desired
behaviour is a
maintainer decision.
Return only 1 line instead of 5 per device. 
It's not much more readable. Each device that is added, also is written
to logdata making it a lot easier to find tenants devices were added to.
Existing tests hardcoded module paths that break whenever a
function moves between modules. Resolve the function under
test by filename under Modules/ instead, so tests keep
passing after file moves. Fixes the Intune/Alert/Standards
tests currently failing on dev.
Set-CIPPMailboxAccess, Invoke-ExecEditMailboxPermissions and
Invoke-ExecModifyMBPerms each duplicated the permission-level
to EXO cmdlet mapping. Route all three through the existing
Set-CIPPMailboxPermission helper (~230 fewer lines) and add
Pester coverage for the three refactored functions.

Intended behavior changes:
- ExecEditMailboxPermissions drops a redundant Graph id
  lookup; the UPN is passed straight to EXO as identity.
- SendOnBehalf now syncs the permission cache, matching
  FullAccess/SendAs.

Bulk processing in ExecModifyMBPerms is unchanged.
Pester coverage for Set-CIPPMailboxPermission,
Set-CIPPMailboxVacation and Remove-CIPPMailboxPermissions:
permission-level to EXO cmdlet mapping, cache sync,
Add/Remove actions and error paths. Tests dot-source the
function under test and stub CIPP helpers, per house style.
Invoke-CippTests.ps1 runs the Pester suite with optional -CI
(NUnit results) and -Coverage output; New-CippTest.ps1
scaffolds a runnable test skeleton for any function (helper
stubs, fake HTTP contexts, move-resilient path resolution)
to lower the barrier to adding backend tests. Ignore the
runner's result/coverage artifacts.
Split out of #2096 (1/4).

Several existing Pester tests (Intune reusable settings,
GlobalAdminAllowList alert, ReusableSettingsTemplate standard) hardcode
the module path of the function under test, so they broke when functions
moved between modules and currently fail on `dev`. This resolves the
function by filename under `Modules/` instead, making the tests
move-resilient.

Test-only change; all 36 tests in the touched files pass locally.
Split out of #2096 (2/4).

`Set-CIPPMailboxAccess`, `Invoke-ExecEditMailboxPermissions`, and
`Invoke-ExecModifyMBPerms` each duplicated the permission → EXO cmdlet
mapping. They now share the existing `Set-CIPPMailboxPermission` helper
(~230 fewer lines). Bulk processing in `ExecModifyMBPerms` is unchanged.
Includes Pester coverage for all three refactored functions (34 tests,
passing locally).

## Intended behavior changes

- `ExecEditMailboxPermissions` drops a redundant Graph `id` lookup — the
UPN is passed straight to EXO as the identity.
- `SendOnBehalf` now syncs the permission cache, matching
FullAccess/SendAs.
Split out of #2096 (3/4).

New Pester coverage for `Set-CIPPMailboxPermission`,
`Set-CIPPMailboxVacation`, and `Remove-CIPPMailboxPermissions`:
permission-level → EXO cmdlet mapping, cache sync, Add/Remove actions,
and error paths. Tests dot-source the function under test and stub CIPP
helpers, matching the existing test style.

Test-only change; 43 tests pass locally against current `dev`.
Split out of #2096 (4/4).

- `Tests/Invoke-CippTests.ps1` — runs the whole Pester suite, with
optional `-CI` (NUnit results file) and `-Coverage` output.
- `Tests/New-CippTest.ps1` — scaffolds a runnable test skeleton for any
function (helper stubs, fake HTTP contexts, move-resilient path
resolution by filename), lowering the barrier to adding backend tests.
- `.gitignore` — ignores the runner's `TestResults.xml` / `coverage.xml`
artifacts.

Tooling only — no runtime code touched.
Adds a read-only endpoint that surfaces the currently-active fired alert
items for a tenant, so the frontend can display live alert instances
(not just configured rules or snoozed items). Backs the new Alerts card
on the dashboard.
ExecModifyMBPerms executes EXO cmdlets itself via -AsCmdletObject,
which bypasses Set-CIPPMailboxPermission's execute-mode cache sync,
so every change through this endpoint left the cached permission
report stale until the next full sync. Track which operations
actually succeeded and sync each cacheable one.
Lets the frontend fetch a single user's mailbox access from the
cached report without downloading the whole tenant's data.
Cache rows are keyed by mailbox UPN, so syncing with the raw
request identifier missed the row whenever the caller passed a
Graph object id. The new User query filter also emptied the
mailbox-grouped report shape, which has no top-level User
property; it now only applies alongside ByUser=true.
## Summary

Companion to the CIPP frontend PR adding bulk mailbox-permission removal
and a per-user "Mailbox Access" card.

- **`Invoke-ExecModifyMBPerms`**: sync the reporting-DB cache
(`Sync-CIPPMailboxPermissionCache`) for every successful
FullAccess/SendAs/SendOnBehalf operation. The endpoint executes cmdlets
via `New-ExoBulkRequest`/`New-ExoRequest` built with
`Set-CIPPMailboxPermission -AsCmdletObject`, which returns before its
own execute-mode sync — so every change through this endpoint left the
cached permission report stale. The sync uses the Graph-resolved UPN
(cache rows are keyed by mailbox UPN), and failed operations are not
synced.
- **`Invoke-ListmailboxPermissions`**: optional `User` query filter on
the `UseReportDB` + `ByUser=true` path, so the frontend can fetch one
user's mailbox access without downloading the whole tenant report. The
filter is gated on `ByUser=true` because the mailbox-grouped shape has
no top-level `User` property.

## Tests

`Tests/Endpoint/Invoke-ExecModifyMBPerms.Tests.ps1`: 25 Pester tests
covering per-level cmdlet mapping, bulk/individual/fallback execution
paths, user lookup fallbacks, input shapes, guards, and the new
cache-sync behaviour (syncs on success with resolved UPN, skips failures
and non-cacheable levels). All passing.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
…che, tests and standards

This addressed authentication issues with GDAP and the Teams PowerShell module, not all uses of the module have been replaced but this covers most of them with the remaining to be ported at a later date allowing for the complete removal of the teams PowerShell module
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

10 participants