Skip to content

Feature/itglue#34

Merged
TecharyJames merged 70 commits intoTechary:masterfrom
TecharyJames:feature/itglue
Mar 18, 2026
Merged

Feature/itglue#34
TecharyJames merged 70 commits intoTechary:masterfrom
TecharyJames:feature/itglue

Conversation

@TecharyJames
Copy link
Copy Markdown
Member

No description provided.

James-Tarran and others added 30 commits February 23, 2026 09:04
…uate

as falsy and report the policy as disabled even when it was enabled but
misconfigured.
…ent remediation running against null state

- Replace unreliable .length checks with explicit $PolicyExists/$RuleExists flags using .Count and null guards
- Fix disable path treating absent policy as correctly configured, which silently skipped remediation and caused null vs false report mismatches
- Include address fields in correctness checks for all paths so stale
  email addresses are detected as drift
- Fix array comparison for email fields using -contains instead of -eq
- Null out address fields in disable remediation to clean up stale values
- Check and disable rule when state is disable, replacing hardcoded $true
- Fix $Policy undefined variable in alert block, should be $PolicyState
drift detection also compared address fields and rule state. This caused
perpetual drift reports for tenants with residual address values or an
active rule, since remediation considered the state correct and never
acted.

- Add address field Count checks to $StateIsCorrect for 'enable' (no mail) and 'disable' cases
- Add rule state check to $StateIsCorrect for both cases
- Include address fields in PolicyParams so they are explicitly cleared during remediation
- Remove the submission rule (rather than disable) when it should not be active, clearing SentTo in a single operation
- Normalise $CurrentValue.RuleState.State to 'Disabled' when no rule exists, preventing phantom drift after rule removal
treating null and [] as different values. Address fields in $ExpectedValue
were set to $null when no email is configured, but Exchange returns empty
arrays for these properties, causing perpetual drift on correctly
configured tenants. Changed to @() to match the actual Exchange return
type.
…hile

drift detection compared all fields. This caused perpetual drift reports
for states that remediation considered correct and would never act on.

Changes:
- Expanded $StateIsCorrect checks to include address array counts (.Count -eq 0) and rule state, fully matching drift detection fields
- Use Remove-ReportSubmissionRule to clear the rule in a single API call
- Wrap Exchange address collection properties with @() in $CurrentValue to normalise the Exchange MultiValuedProperty type for consistent JSON serialisation
- Fix $ExpectedValue address fields: inline `if { @() }` returns $null (empty arrays write nothing to the pipeline); use @(if { ... }) outer wrapping instead to correctly produce an empty array
- Fix $ExpectedValue.RuleState condition to include $state -eq 'disable', preventing an incorrect State='Enabled' expectation when email is configured but the standard is set to disable
- Normalise RuleState.State to 'Disabled' and SentTo to $null in $CurrentValue when no submission rule exists
Introduce ITGlue integration: add connection helpers, API request wrapper, mapping endpoints, and full sync implementation. Files added: Connect-ITGlueAPI (builds headers/base URL), Invoke-ITGlueRequest (JSON:API helper with pagination and rate-limit handling), Get-ITGlueMapping, Get-ITGlueFieldMapping, Set-ITGlueMapping, and Invoke-ITGlueExtensionSync (creates/updates flexible assets, contacts, configurations, and org quick-notes from CIPP M365 data). Update core entrypoints and helpers to handle ITGlue: Invoke-ExecExtensionMapping, Invoke-ExecExtensionSync, Invoke-ExecExtensionTest, Invoke-ExecExtensionsConfig, Push-CippExtensionData, and Register-CIPPExtensionScheduledTasks. Set-ITGlueMapping replaces mapping table entries; Invoke-ITGlueRequest unwraps JSON:API responses and supports POST/PATCH wrapping. Overall enables scheduling, testing, mapping, and execution of ITGlue syncs from the platform.
[pull] master from KelvinTegelaar:master
Add ITGlue extension support and sync
The ITGlue API requires 'label-name' instead of 'label' in the
contact-emails array. This was causing 422 errors with "can't be blank"
when creating contacts.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix ITGlue contact creation - use correct label-name field
- Fix license summary bug where $_ scope issue caused incorrect SKU lookups
- Replace plain text quick-notes with HTML formatting for better readability
- Add license table with headers instead of plain text list
- Add quick links to CIPP, M365 Admin, and Entra Admin portals
- Sort licenses alphabetically by SKU part number

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Improve ITGlue quick-notes formatting
- Replace Set-Location with proper module path resolution for ConversionTable.csv
- Add 100ms rate limiting between API calls to avoid hitting ITGlue limits on large tenants

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Add HTML comment markers to identify CIPP managed section
- Fetch existing quick-notes before updating
- If CIPP section exists, replace only that section
- If other content exists, append CIPP section with <hr/> separator
- If no content exists, add CIPP section without separator

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Fix ITGlue sync reliability issues
Replace HTML comment markers with a real <div class="cipp-managed"> wrapper because ITGlue's sanitizer strips HTML comments. Update detection and replacement logic to match the new div wrapper, fall back to legacy comment markers if present, and attempt to repair orphaned CIPP content by matching the section heading and the "(CIPP Managed)" timestamp. Also refine append/replace behavior and ensure the leading <hr/> is omitted when creating a new CIPP section in empty notes.
Fix ITGlue quick-notes duplicating CIPP section on every sync
Fix ITGlue quick-notes duplicating CIPP section on every sync
ITGlue strips both HTML comments and class attributes, so marker-based
approaches fail. Use greedy regex on the heading/timestamp content instead
to capture all duplicates in a single replacement.
Fix ITGlue quick-notes duplicating and format domains as list
TecharyJames and others added 28 commits March 13, 2026 14:13
Introduce a new cmdlet to manage the tenant default App Management Policy via Microsoft Graph. The script reads supplied settings (password/symmetric key addition flags and credential max lifetimes), converts day values to ISO 8601 durations, builds the desired application and service principal restrictions, compares them with the current policy, and optionally remediates via a PATCH, emits alerts, and reports results. Includes error handling and logging for Graph operations.
Add Invoke-CIPPStandardAppManagementPolicy cmdlet
Frontend may send setting values as objects like {label,value} or as plain values. Unwrap those inputs by preferring the .value property when present (using null-coalescing) for password/key lifetime fields and password restriction values, preserving existing checks for empty/"Select a value" entries and ISO duration conversion logic.
Unwrap frontend autoComplete values into plain strings and convert day-based lifetime inputs into ISO 8601 duration strings. Rework how desired credential restrictions are built: replace the previous generic defs/loop with explicit construction of desiredPasswordCredentials, mirror passwordAddition state for symmetricKeyAddition, and add entries for customPasswordAddition, passwordLifetime and symmetricKeyLifetime when provided. Also rename the UI label from "Custom Password Addition" to "Custom Password".
Handle autocomplete inputs and ISO durations
Ensure stable ordering of password/key credential arrays by sorting both desired and current application/servicePrincipal restrictions by restrictionType. Use the sorted arrays when building the desired state and when constructing CurrentValue so comparisons aren't affected by Graph API ordering. Replace multiple per-property JSON comparisons with a single whole-object JSON comparison for clarity and to avoid false diffs due to ordering.
Replace Sort-Object -Property with a script block ({ $_.restrictionType }) because the items are hashtables, not PSCustomObjects. This ensures desiredPasswordCredentials and desiredKeyCredentials are sorted correctly so their order matches Graph API responses.
Use script block in Sort-Object for hashtables
Add support for syncing M365 Conditional Access Policies into ITGlue flexible assets. This change adds CAPTypeId mapping and pulls ConditionalAccessPolicies from the extension cache, creates required flexible-asset fields, builds an HTML summary for each policy, and upserts flexible assets (create or PATCH). It also deletes orphaned assets no longer present in M365 and records logs/errors. Minor variable assignments and small sleep between requests included for rate control and stability.
Introduce full support for syncing Microsoft 365 Conditional Access Policies (CAPs) into ITGlue and refactor ITGlue sync logic for more efficient updates.

Changes:
- Added private helpers: Add-ITGlueFlexibleAssetFields (batch-add flexible asset fields), Format-ITGlueCAPValue (format newline lists), and Sync-ITGlueConditionalAccessPolicies (create/update/delete CAP flexible assets, HTML details, hash-based change detection, caching).
- Extended Get-ITGlueFieldMapping to include ConditionalAccessPolicies mapping key.
- Heavily refactored Invoke-ITGlueExtensionSync to:
  - Use a centralized asset cache table and hash-based detection to skip unchanged assets (users, devices, CAPs). Timestamps are excluded from hashes so only real content changes trigger updates.
  - Batch field additions via Add-ITGlueFlexibleAssetFields and auto-create a Conditional Access Policy flexible asset type if missing.
  - Support create/update/delete flows for users, devices, configurations and CAP flexible assets, with cache maintenance and improved logging/metrics (updated vs unchanged counts).
  - Improve HTML quick-notes replacement logic for organization overview.

Why: reduce unnecessary API calls and updates, add CAP syncing capability, and simplify management of flexible asset fields and change detection.
change stuff
@TecharyJames TecharyJames merged commit 5ca7e9f into Techary:master Mar 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants