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:
2026-06-14 15:24:42 +02:00
parent e333af978c
commit d3e0769799
30 changed files with 8711 additions and 175 deletions
+84 -6
View File
@@ -33,6 +33,14 @@ Does not delete the app registration in Entra ID.
.PARAMETER DeleteApp
Remove the app registration from the Entra tenant and clean up local credentials.
Requires the same Microsoft Graph permissions as initialization.
.PARAMETER RotateSecret
Create a new client secret for the existing app registration, remove the old
IntuneManagementSecret credential, and update local storage. Does not recreate
the app registration or re-grant admin consent.
.PARAMETER SecretExpiryYears
Lifetime of the created client secret in years (1-5). Default: 1.
#>
[CmdletBinding()]
param(
@@ -46,7 +54,12 @@ param(
[switch]$Delete,
[switch]$DeleteApp
[switch]$DeleteApp,
[switch]$RotateSecret,
[ValidateRange(1,5)]
[int]$SecretExpiryYears = 1
)
$ErrorActionPreference = "Stop"
@@ -145,6 +158,70 @@ if ($Delete)
}
#endregion
#region Rotate secret (no app recreation)
if ($RotateSecret)
{
$existingAppId = Get-AuthSetting -SubPath $TenantId -Key "GraphAzureAppId"
if (-not $existingAppId)
{
throw "No saved AppId found for tenant $TenantId. Run without -RotateSecret to set up first."
}
$requiredModulesRotate = @("Microsoft.Graph.Authentication", "Microsoft.Graph.Applications")
foreach ($mod in $requiredModulesRotate)
{
if (-not (Get-Module $mod -ListAvailable))
{
throw "Module '$mod' is not installed. Run: Install-Module Microsoft.Graph -Scope CurrentUser"
}
}
Import-Module Microsoft.Graph.Authentication -Force
Import-Module Microsoft.Graph.Applications -Force
Write-Host ""
Write-Host "Connecting to Microsoft Graph..." -ForegroundColor Cyan
Connect-MgGraph -Scopes "Application.ReadWrite.All" -NoWelcome
$appObj = Get-MgApplication -Filter "appId eq '$existingAppId'" -ErrorAction SilentlyContinue | Select-Object -First 1
if (-not $appObj)
{
throw "App registration $existingAppId not found in tenant $TenantId."
}
# Remove existing IntuneManagementSecret credentials
$oldCreds = $appObj.PasswordCredentials | Where-Object { $_.DisplayName -eq "IntuneManagementSecret" }
foreach ($cred in $oldCreds)
{
Write-Host "Removing old secret (KeyId: $($cred.KeyId))..." -ForegroundColor Yellow
Remove-MgApplicationPassword -ApplicationId $appObj.Id -KeyId $cred.KeyId
}
# Create new secret
Write-Host "Creating new client secret..." -ForegroundColor Cyan
$newCred = @{
displayName = "IntuneManagementSecret"
endDateTime = (Get-Date).AddYears($SecretExpiryYears)
}
$newSecret = Add-MgApplicationPassword -ApplicationId $appObj.Id -PasswordCredential $newCred
# Store new secret
if ($IsMacOS)
{
$null = security add-generic-password -a "IntuneManagement" -s "IntuneMgmt-$existingAppId" -w "$($newSecret.SecretText)" -U 2>$null
Write-Host "New secret stored in macOS Keychain." -ForegroundColor Green
}
else
{
Save-AuthSetting -SubPath $TenantId -Key "GraphAzureAppSecret" -Value $newSecret.SecretText
Write-Host "New secret stored in $SettingsFile." -ForegroundColor Green
}
Write-Host "Secret rotated. Expiry: $((Get-Date).AddYears($SecretExpiryYears).ToString('yyyy-MM-dd'))" -ForegroundColor Green
Disconnect-MgGraph | Out-Null
return
}
#endregion
#region Microsoft Graph modules
$requiredModules = @("Microsoft.Graph.Authentication", "Microsoft.Graph.Applications")
foreach ($mod in $requiredModules)
@@ -389,16 +466,17 @@ if ($sp)
Write-Host "Creating client secret..." -ForegroundColor Cyan
$passwordCred = @{
displayName = "IntuneManagementSecret"
endDateTime = (Get-Date).AddYears(1)
endDateTime = (Get-Date).AddYears($SecretExpiryYears)
}
$secret = Add-MgApplicationPassword -ApplicationId $app.Id -PasswordCredential $passwordCred
#endregion
#region Save settings
Write-Host "Saving settings to $SettingsFile ..." -ForegroundColor Cyan
Save-AuthSetting -SubPath $TenantId -Key "GraphAzureAppId" -Value $app.AppId
Save-AuthSetting -SubPath $TenantId -Key "GraphAzureAppLogin" -Value $true
Save-AuthSetting -Key "TenantId" -Value $TenantId
Save-AuthSetting -SubPath $TenantId -Key "GraphAzureAppId" -Value $app.AppId
Save-AuthSetting -SubPath $TenantId -Key "GraphAzureAppLogin" -Value $true
Save-AuthSetting -Key "TenantId" -Value $TenantId
Save-AuthSetting -SubPath "EndpointManager" -Key "EMAzureApp" -Value $app.AppId
if ($IsMacOS)
{
@@ -426,7 +504,7 @@ if ($IsMacOS)
}
else
{
Write-Host "Secret : $($secret.SecretText)"
Write-Host "Secret : <stored in $SettingsFile>"
}
Write-Host "=============================================================" -ForegroundColor Green