release: v4.1.0 — restructure entry points, add CIS baselines, reporting tools and fzf hints
- Restructure launchers: Start-IntuneToolkit.ps1 moves to repo root; Start-HeadlessIntune.ps1 moves to Scripts/; TUI helper moves to Scripts/Private/ - Add AGENTS.md with project architecture, entry points, and security notes - Add CIS M365 baseline assets (CISM365-v7, M365-CIS-Rapid) and reporting scripts - Add Python reporting utilities (Export-SettingsReport, Export-AssignmentReport, Export-ObjectInventoryReport) and CA wizard helpers - Update Deploy-IntuneBaseline.ps1 with Merge conflict resolution, ReportPath, and optimized group loading - Update Initialize-IntuneAuth.ps1 with -RotateSecret and configurable secret expiry - Update Extensions for Settings Catalog definition auto-export - Update README with v4.1.0, new entry points and script catalog - Bump VERSION to 4.1.0 - Harden .gitignore against .DS_Store, __pycache__, .venv-pdf/, local exports, Settings.json and IntuneManagement.log
This commit is contained in:
@@ -0,0 +1,237 @@
|
||||
# CIS M365 v7.0.0 YAML Baseline Format
|
||||
|
||||
This document describes the YAML schema for `CISM365-v7.example.yaml`, which extends the existing `OpenIntuneBaseline.example.yaml` format to cover **tenant-level** M365 configuration.
|
||||
|
||||
## Why This Format?
|
||||
|
||||
The existing Intune baseline YAML works great for device policies. For CIS M365 compliance, you need the same declarative approach but for:
|
||||
- Entra ID settings (password policies, device quotas, consent)
|
||||
- Conditional Access policies
|
||||
- Defender for Office 365 policies
|
||||
- Exchange Online transport rules
|
||||
- SharePoint / OneDrive sharing
|
||||
- Microsoft Teams policies
|
||||
|
||||
This YAML keeps the **same root structure** as the Intune baseline so you can optionally include Intune policies in the same manifest, or keep them separate.
|
||||
|
||||
## Root Structure
|
||||
|
||||
```yaml
|
||||
baseline:
|
||||
name: string
|
||||
conflictResolution: Skip | Update | Error
|
||||
whatIf: false
|
||||
|
||||
tenantMutation:
|
||||
search: string # optional
|
||||
replace: string # optional
|
||||
prefix: string # optional (alternative to search/replace)
|
||||
|
||||
groups: [] # Cloud-only security groups (same as Intune baseline)
|
||||
policies: [] # Intune policies (optional, same schema as Intune baseline)
|
||||
tenantConfig: # NEW: M365 tenant-level configuration
|
||||
adminCenter: {}
|
||||
entraId: {}
|
||||
conditionalAccess: {}
|
||||
defender: {}
|
||||
exchange: {}
|
||||
sharePoint: {}
|
||||
teams: {}
|
||||
```
|
||||
|
||||
## tenantConfig Sections
|
||||
|
||||
### adminCenter
|
||||
|
||||
M365 Admin Center settings.
|
||||
|
||||
```yaml
|
||||
adminCenter:
|
||||
passwordExpiration: NeverExpire # NeverExpire | 90Days | 180Days
|
||||
idleSessionTimeoutHours: 3
|
||||
restrictUserOwnedApps: true
|
||||
formsPhishingProtection: true
|
||||
customerLockbox: true
|
||||
restrictThirdPartyStorage: true
|
||||
```
|
||||
|
||||
### entraId
|
||||
|
||||
Entra ID directory settings.
|
||||
|
||||
```yaml
|
||||
entraId:
|
||||
blockUserConsent: true
|
||||
blockTenantCreation: true
|
||||
restrictAdminCenterAccess: true
|
||||
disableLinkedIn: true
|
||||
maxDevicesPerUser: 5
|
||||
gaLocalAdminDisabled: true
|
||||
bannedPasswords:
|
||||
- "Contoso"
|
||||
- "Password"
|
||||
```
|
||||
|
||||
### conditionalAccess
|
||||
|
||||
The most powerful section. Supports **automatic CA policy creation** with:
|
||||
- **Global `reportOnly` switch** — all policies default to report-only
|
||||
- **Automatic break-glass exclusion** — specify one group, it's excluded from every policy
|
||||
- **Custom naming** via `tenantMutation`
|
||||
- **Role name resolution** — use friendly names like "Global Administrator", script maps to template IDs
|
||||
|
||||
```yaml
|
||||
conditionalAccess:
|
||||
reportOnly: true # Global switch
|
||||
breakGlassGroup: "CIS-BreakGlass" # Auto-excluded from all policies
|
||||
policies:
|
||||
- name: "Block-Legacy-Auth"
|
||||
cisControl: "5.2.2.3"
|
||||
description: "Block legacy authentication"
|
||||
state: enabledForReportingButNotEnforced
|
||||
conditions:
|
||||
applications:
|
||||
includeApplications: ["All"]
|
||||
users:
|
||||
includeUsers: ["All"]
|
||||
excludeGroups: ["CIS-Pilot-Users"]
|
||||
clientAppTypes: ["exchangeActiveSync", "other"]
|
||||
grantControls:
|
||||
builtInControls: ["block"]
|
||||
operator: "OR"
|
||||
```
|
||||
|
||||
**CA Policy Conditions Supported:**
|
||||
|
||||
| Condition | YAML Key | Example |
|
||||
|-----------|----------|---------|
|
||||
| Apps | `applications.includeApplications` | `["All"]` or `["Office365"]` |
|
||||
| User actions | `applications.includeUserActions` | `["urn:user:registersecurityinfo"]` |
|
||||
| Users | `users.includeUsers` | `["All"]` or specific UPNs |
|
||||
| Groups | `users.includeGroups` / `excludeGroups` | `["CIS-Pilot-Users"]` — resolved by displayName |
|
||||
| Roles | `users.includeRoles` / `excludeRoles` | `["Global Administrator"]` — friendly names mapped to template IDs |
|
||||
| Client apps | `clientAppTypes` | `["exchangeActiveSync", "other"]` |
|
||||
| Sign-in risk | `signInRiskLevels` | `["medium", "high"]` |
|
||||
| Locations | `locations.includeLocations` | `["AllTrusted"]` or `["All"]` |
|
||||
| Auth flows | `authenticationFlows.deviceCodeFlow` | `{ isEnabled: true }` |
|
||||
|
||||
**Grant Controls Supported:**
|
||||
|
||||
| Control | YAML Key |
|
||||
|---------|----------|
|
||||
| Block | `grantControls.builtInControls: ["block"]` |
|
||||
| Require MFA | `grantControls.builtInControls: ["mfa"]` |
|
||||
| Compliant device | `grantControls.builtInControls: ["compliantDevice", "domainJoinedDevice"]` |
|
||||
| Phishing-resistant MFA | `grantControls.builtInControls: ["authenticationStrength"]` + `grantControls.authenticationStrength.id` |
|
||||
|
||||
**Session Controls Supported:**
|
||||
|
||||
```yaml
|
||||
sessionControls:
|
||||
signInFrequency:
|
||||
value: 12
|
||||
type: hours
|
||||
isEnabled: true
|
||||
persistentBrowser:
|
||||
mode: never # never | always
|
||||
isEnabled: true
|
||||
```
|
||||
|
||||
### defender
|
||||
|
||||
Defender for Office 365 policies.
|
||||
|
||||
```yaml
|
||||
defender:
|
||||
safeLinks:
|
||||
- name: "SafeLinks-Default"
|
||||
cisControl: "2.1.1"
|
||||
enabled: true
|
||||
trackClicks: true
|
||||
allowClickThrough: false
|
||||
scanUrls: true
|
||||
enableForInternalSenders: true
|
||||
safeAttachments:
|
||||
- name: "SafeAttachments-Default"
|
||||
cisControl: "2.1.4"
|
||||
enabled: true
|
||||
action: Block
|
||||
quarantineMessages: true
|
||||
antiMalware:
|
||||
- name: "AntiMalware-Default"
|
||||
cisControl: "2.1.2"
|
||||
enabled: true
|
||||
enableInternalNotifications: true
|
||||
fileTypes: ["ace", "exe", "jar", "vbs"]
|
||||
```
|
||||
|
||||
### exchange
|
||||
|
||||
Exchange Online settings.
|
||||
|
||||
```yaml
|
||||
exchange:
|
||||
enableMailboxAuditOrgWide: true
|
||||
blockExternalForwarding: true
|
||||
enableExternalSenderBanner: true
|
||||
externalEmailWarningRule: true
|
||||
```
|
||||
|
||||
### sharePoint
|
||||
|
||||
SharePoint / OneDrive sharing settings.
|
||||
|
||||
```yaml
|
||||
sharePoint:
|
||||
adminUrl: "https://contoso-admin.sharepoint.com"
|
||||
defaultSharingLinkType: Direct
|
||||
sharePointExternalSharing: Disabled
|
||||
oneDriveExternalSharing: Disabled
|
||||
guestAccessExpirationDays: 30
|
||||
denyCustomScripts: true
|
||||
```
|
||||
|
||||
### teams
|
||||
|
||||
Microsoft Teams policies.
|
||||
|
||||
```yaml
|
||||
teams:
|
||||
allowAnonymousUsersToJoinMeeting: false
|
||||
allowAnonymousUsersToStartMeeting: false
|
||||
enableEmailIntegration: false
|
||||
allowFederatedUsers: false
|
||||
allowTeamsConsumer: false
|
||||
```
|
||||
|
||||
## Using the Draft PDF
|
||||
|
||||
Since CIS does not publish XLS for draft benchmarks:
|
||||
|
||||
1. Open the PDF and work through each section
|
||||
2. For **automated** controls, add them to the appropriate `tenantConfig` section with the `cisControl` field
|
||||
3. For **manual** controls, skip them or add a comment
|
||||
4. The `cisControl` field preserves traceability (e.g., `cisControl: "5.2.2.3"`)
|
||||
|
||||
## Deployment
|
||||
|
||||
```powershell
|
||||
# Assess (read-only)
|
||||
./Scripts/Deploy-CISM365Baseline.ps1 -BaselinePath ./Baselines/mytenant-cisv7.yaml
|
||||
|
||||
# Deploy (applies changes)
|
||||
./Scripts/Deploy-CISM365Baseline.ps1 -BaselinePath ./Baselines/mytenant-cisv7.yaml -Mode Deploy -Apply -Verbose
|
||||
|
||||
# Deploy only specific workloads
|
||||
./Scripts/Deploy-CISM365Baseline.ps1 -BaselinePath ./Baselines/mytenant-cisv7.yaml -Mode Deploy -Apply -Workloads ConditionalAccess,EntraID
|
||||
```
|
||||
|
||||
## Safety Defaults
|
||||
|
||||
| Feature | Default | Why |
|
||||
|---------|---------|-----|
|
||||
| `Mode` | `Assess` | Must explicitly opt in to changes |
|
||||
| `conditionalAccess.reportOnly` | `true` | All CA policies created in report-only mode |
|
||||
| `breakGlassGroup` | Auto-excluded | Prevents lockout |
|
||||
| `Apply` switch | Required for Deploy | Double-confirmation pattern |
|
||||
| `-WhatIf` | Supported | Native PowerShell WhatIf |
|
||||
Reference in New Issue
Block a user