Skip to content

Add Microsoft 365 deployment toolkits and policy validation - #7

Merged
AKB (alankbui) merged 5 commits into
mainfrom
public-destination-files-20260925
Sep 25, 2026
Merged

AKB (alankbui) merged 5 commits into
mainfrom
public-destination-files-20260925

Conversation

@hiteshsai

@hiteshsai Hitesh Jonnalagadda (hiteshsai) commented Sep 25, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Add the Defender, Entra and Intune deployment toolkits alongside Purview, with configuration files, operator guides and deployment reports. Update Purview with offline deployment plans and read-only tenant configuration validation.

This is a source-snapshot import, not a transfer of the source repository's Git history. See each product README for supported operations and release limitations.

Review fixes

  • Correct Conditional Access role, guest and application targeting, the device-or-MFA alternative, and managed-control readback. New policies remain report-only by default. Guest MFA targets guests and external users across the tenant, not the workforce pilot group.
  • Preserve existing policies for manual migration review where scope or controls have changed. Do not silently adopt, overwrite or duplicate them.
  • Verify Intune policy settings, scheduled-action children and exact assignments on creation and reruns. Recognize the documented enrollment restriction shapes and report incomplete evidence accurately.
  • Bind Defender authentication to the requested operator and customer tenant, and give failed operations precedence over blocked report entries.

Validation

Executed locally under PowerShell 7:

Command Result
pwsh -NoProfile -File .\scripts\verify.ps1 66 scripts parsed; eight configuration files imported
pwsh -NoProfile -File .\scripts\Test-IdentityReviewFixes.ps1 196 assertions passed
pwsh -NoProfile -File .\scripts\Test-IntuneReviewFixes.ps1 87 scenarios passed
pwsh -NoProfile -File .\scripts\Test-DefenderConnectionGuards.ps1 16 scenarios passed

Regression tests use synthetic service responses, not tenant credentials or customer exports. Guest targeting, readback and Defender authentication failures were reproduced before their fixes. Scoped independent reviews supplement these checks; they are not a full migration audit.

GPT-5.4 performed the rubber-duck reviews. GPT-5.5 independently reviewed the guest-targeting and Defender authentication follow-ups. Those scoped reviews found no concrete blockers; they do not certify the full migration or replace maintainer review.

No live tenant deployment was performed for these fixes. Independent maintainer approval, effective permissions and approved pilot-tenant validation remain required. Tenant reports and other private evidence are not included.

Verified API and runtime clarifications

Some automated findings did not require code changes:

Existing phishing-resistant policy migration and unmanaged app-protection collision guards were retained. The single-platform enrollment restriction is a valid beta resource, not a misspelled legacy discriminator.

Merge plan

Preserve the review commits while this PR is open. After outstanding review is complete, use Squash and merge for one commit on main, with the PR title as its subject and a concise summary instead of the concatenated intermediate commit messages.

<!-- BEGIN pr-telemetry -->
assistance: agentic-cli
type: feature
agent-tool: copilot-cli
agent-model: gpt-6-astra
work-item: AB#n/a
<!-- END pr-telemetry -->

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
@hiteshsai
Hitesh Jonnalagadda (hiteshsai) requested review from a team and a lite review from Copilot September 25, 2026 17:20
@hiteshsai Hitesh Jonnalagadda (hiteshsai) added documentation Improvements or additions to documentation enhancement New feature or request agentic-cli Work primarily authored by a terminal AI agent docs Documentation changes labels Sep 25, 2026
@hiteshsai

Copy link
Copy Markdown
Contributor Author

@microsoft-github-policy-service agree company="Microsoft"

This comment was marked as outdated.

Prevent incomplete policy deployments from being reported as verified.
Correct Conditional Access targeting and the device-or-MFA alternative,
preserve manual migration for existing policies, and verify managed
settings and assignments before reporting success.

Keep tenant identity permissions least-privileged, make operation failures
visible in Defender summaries, and document the corrected behavior.
Add offline regression checks with synthetic Graph responses. These
checks do not replace approved pilot-tenant validation.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings September 25, 2026 18:33
@hiteshsai Hitesh Jonnalagadda (hiteshsai) changed the title Migrate Microsoft 365 best-practice deployment toolkit to open source Add Microsoft 365 deployment toolkits and policy validation Sep 25, 2026
@hiteshsai Hitesh Jonnalagadda (hiteshsai) added the feature New or expanded product functionality label Sep 25, 2026

This comment was marked as outdated.

Replace the pilot-group placeholder with the documented guest/external
user selector so workforce pilot members are not included by this policy.
Keep report-only defaults and require manual review of existing policies
instead of changing their scope or enforcement through adoption.

Reject unexpected guest exclusions during readback. Add regressions for
guest-only targeting, tenant-wide mode, legacy-policy preservation and
corrupt readback, and document the guest-wide scope explicitly.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

This comment was marked as outdated.

Target delegated customer sign-in explicitly instead of relying on a
home-tenant or cached Graph context. Reuse a session only after matching
the requested operator, delegated mode, scopes and live tenant identity.

Reject an unexpected account after sign-in and recheck it in preflight.
Keep existing permission and app-only restrictions. Add isolated connection
regressions and update the operator guidance.

Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Unresolved critical authentication and state-validation defects, plus moderate deployment-verification issues, block approval.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 10 High severity

Open (10)
Resolved since last review (2)
Previously missed (3)

In code that hasn't changed since last review

Medium severity Verify existing app configuration and assignments on reruns

Products/​Intune/​Modules/​Setup-AppDeployment.ps1:203

On every rerun, any toolkit-tagged officeSuiteApp is reported as AlreadyCompliant with Readback='Verified' without checking its managed fields or assignment. If an operator or another process changed the channel, products, or target after creation, the next run will silently accept the drift; perform the same exact readback on existing objects or report them as unverified/guided instead of claiming verification.

Medium severity Read back app-protection policies and assignments

Products/​Intune/​Modules/​Setup-AppProtectionPolicies.ps1:523

After creating and assigning each app-protection policy, this path only records the POSTs as successful and never reads back the policy settings, targeted apps, or exact assignment. A successful response can still leave a partial or incorrectly scoped policy, so the run can claim a completed deployment without the readback guarantee described by the toolkit and PR summary; add bounded readback (or report the result as unverified) before treating this operation as successful.

Low severity Align Defender release status across documentation

Products/​Defender/​README.md:14

This release status conflicts with the repository's product table, which still marks Defender as “Candidate; release authorization required” (README.md:14). Operators can therefore read this page as authorizing a release that the top-level documentation says is not yet authorized; use one consistent status and release boundary across both pages.

Removed initialization of the $result variable as an ordered hashtable. This is a validated issue and the suggestion resolves the issue.

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

@alankbui AKB (alankbui) left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some underlying issues remain, will add to the fix log for future WIP.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Unresolved critical and moderate review findings remain across the Defender, Entra, Intune, and Purview changes.

Get a fresh assessment by requesting another Copilot review.

Review effort: Lite
Findings: 13 High severity

Open (13)
Resolved since last review (3)
Previously missed (1)

In code that hasn't changed since last review

Medium severity Entra identity read requests an unnecessarily broad Graph scope

Products/​Entra/​Config/​EntraConfig.psd1:64

Entra's only tenant-identity Graph read selects id,verifiedDomains from /organization; this product does not use /subscribedSkus. Requesting delegated Organization.Read.All here therefore grants broader directory read than the operation needs, unlike the repository's User.Read identity contract (for example, Products/Defender/Config/DefenderConfig.psd1:211-215). Remove this delegated scope so the consent prompt remains least-privilege.

Comment on lines +372 to +380
finally {
if ($global:DefenderRunLog) {
$endTime = [datetime]::UtcNow
Save-DefenderRunLogJson -EndTime $endTime
Write-DefenderHtmlReport -Path $htmlPath -Entries (Get-DefenderRunLog) `
-RunId $runId -StartTime $startTime -EndTime $endTime `
-TenantId $TenantId -TenantAdminUpn $TenantAdminUpn `
-ScriptVersion $config.ProductVersion
Clear-DefenderRunLog
Comment on lines +185 to +192
$created = Invoke-WithTransientRetry -Description 'Create break-glass account' -Action {
Invoke-MgGraphRequest -Method POST -Uri "$v1/users" -Body $body -ContentType 'application/json'
}
$password = $null
$userIds.Add([string] $created.id)
Add-EntraRunLogEntry -Module $module -Action 'CreateBreakGlass' -BestPracticeKey $bestPracticeKey `
-Status 'Created' -Disposition 'Applicable' -Target $upn `
-Detail 'Created a cloud-only break-glass account. It has no admin role yet: assign it Global Administrator, reset its password in the portal, and store the credentials securely. The next run confirms the role; the account is excluded from every Conditional Access policy automatically.'
Comment on lines +75 to +80
$parsedNext = $null
if (-not [uri]::TryCreate($nextUri, [UriKind]::Absolute, [ref] $parsedNext) -or
$parsedNext.Scheme -ne 'https' -or
-not [string]::Equals(
$parsedNext.Host,
$base.Host,
Comment on lines +103 to +107
$parsedNext = $null
if (-not [uri]::TryCreate($nextUri, [UriKind]::Absolute, [ref] $parsedNext) -or
$parsedNext.Scheme -ne 'https' -or
-not [string]::Equals($parsedNext.Host, $base.Host, [StringComparison]::OrdinalIgnoreCase)) {
throw "Microsoft Graph returned a next link outside the approved Microsoft Graph host for $EvidenceTarget."
Comment on lines +406 to +410
$beta = $Config.Api.GraphBetaBaseUri
$pilotGroup = if (-not [string]::IsNullOrWhiteSpace([string] $Context.PilotGroupId)) { $Context.PilotGroupId } else { $PilotGroupId }
$assignmentTarget = $null
$assignmentDetail = $null
if ($Context.AssignmentScope -eq 'TenantWide') {
Comment on lines +146 to +153
$parsedNext = $null
if (-not [uri]::TryCreate($nextUri, [UriKind]::Absolute, [ref] $parsedNext) -or
$parsedNext.Scheme -ne 'https' -or
-not [string]::Equals(
$parsedNext.Host,
$base.Host,
[StringComparison]::OrdinalIgnoreCase
) -or
@alankbui
AKB (alankbui) merged commit 24ee35c into main Sep 25, 2026
2 checks passed
@Cj-Scott
Cj-Scott deleted the public-destination-files-20260925 branch September 28, 2026 19:29
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agentic-cli Work primarily authored by a terminal AI agent docs Documentation changes documentation Improvements or additions to documentation enhancement New feature or request feature New or expanded product functionality

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants