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,562 @@
|
||||
#requires -Version 5.1
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Unified launcher for the macOS Intune Toolkit.
|
||||
.DESCRIPTION
|
||||
Presents a single terminal UI to choose from all available
|
||||
headless Intune management tools. Passes through common auth parameters.
|
||||
Press Esc to go back to the menu from any selection.
|
||||
.EXAMPLE
|
||||
./Start-IntuneToolkit.ps1 -TenantId "contoso.onmicrosoft.com"
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[string]$TenantId,
|
||||
|
||||
[string]$AppId,
|
||||
|
||||
[string]$Secret,
|
||||
|
||||
[string]$Certificate,
|
||||
|
||||
[ValidateSet("AppOnly","Browser","DeviceCode")]
|
||||
[string]$AuthMode = "AppOnly",
|
||||
|
||||
[string]$RedirectUri,
|
||||
|
||||
[string]$SettingsFile
|
||||
)
|
||||
|
||||
$ErrorActionPreference = "Stop"
|
||||
|
||||
#region Helper functions
|
||||
function Test-FzfAvailable
|
||||
{
|
||||
return [bool](Get-Command fzf -ErrorAction SilentlyContinue)
|
||||
}
|
||||
|
||||
function Show-FzfHint
|
||||
{
|
||||
if(Test-FzfAvailable) { return }
|
||||
Write-Host "`n[fzf not found]" -ForegroundColor Yellow -NoNewline
|
||||
Write-Host " Install fzf for the best interactive menu experience.`n" -ForegroundColor DarkGray
|
||||
if($IsMacOS)
|
||||
{
|
||||
Write-Host " macOS: brew install fzf" -ForegroundColor DarkGray
|
||||
}
|
||||
elseif($IsLinux)
|
||||
{
|
||||
Write-Host " Debian/Ubuntu: sudo apt install fzf" -ForegroundColor DarkGray
|
||||
Write-Host " Fedora: sudo dnf install fzf" -ForegroundColor DarkGray
|
||||
Write-Host " Arch: sudo pacman -S fzf" -ForegroundColor DarkGray
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host " Windows: winget install junegunn.fzf" -ForegroundColor DarkGray
|
||||
Write-Host " choco install fzf" -ForegroundColor DarkGray
|
||||
}
|
||||
Write-Host " (Falling back to numbered menus for now.)`n" -ForegroundColor DarkGray
|
||||
}
|
||||
|
||||
function Show-FzfMenu
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string[]]$Items,
|
||||
[string]$Header = "Select one"
|
||||
)
|
||||
$selected = $Items | fzf --header=$Header
|
||||
if(-not $selected) { return $null }
|
||||
return $selected
|
||||
}
|
||||
|
||||
function Show-NumberedMenu
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string[]]$Items,
|
||||
[string]$Header = "Select one"
|
||||
)
|
||||
Write-Host "`n$Header" -ForegroundColor Cyan
|
||||
for($i=0; $i -lt $Items.Count; $i++)
|
||||
{
|
||||
Write-Host " $($i+1). $($Items[$i])"
|
||||
}
|
||||
$choice = Read-Host "Enter a number (0 to exit)"
|
||||
if($choice -eq "0") { return "EXIT" }
|
||||
$index = [int]$choice - 1
|
||||
if($index -ge 0 -and $index -lt $Items.Count)
|
||||
{
|
||||
return $Items[$index]
|
||||
}
|
||||
return $null
|
||||
}
|
||||
|
||||
function Select-MenuItem
|
||||
{
|
||||
param(
|
||||
[Parameter(Mandatory)]
|
||||
[string[]]$Items,
|
||||
[string]$Header = "Select one"
|
||||
)
|
||||
if(Test-FzfAvailable)
|
||||
{
|
||||
return Show-FzfMenu -Items $Items -Header $Header
|
||||
}
|
||||
return Show-NumberedMenu -Items $Items -Header $Header
|
||||
}
|
||||
#endregion
|
||||
|
||||
$projectRoot = $PSScriptRoot
|
||||
|
||||
#region Tenant selection
|
||||
function Get-DefaultSettingsPath
|
||||
{
|
||||
if($IsWindows -or $env:OS -eq "Windows_NT")
|
||||
{
|
||||
if($env:LOCALAPPDATA) { return (Join-Path $env:LOCALAPPDATA "macOS_IntuneManagement\Settings.json") }
|
||||
return (Join-Path $env:USERPROFILE "AppData\Local\macOS_IntuneManagement\Settings.json")
|
||||
}
|
||||
if($IsMacOS) { return (Join-Path $HOME "Library/Application Support/macOS_IntuneManagement/Settings.json") }
|
||||
return (Join-Path $HOME ".local/share/macOS_IntuneManagement/Settings.json")
|
||||
}
|
||||
|
||||
function Get-SavedTenants
|
||||
{
|
||||
param([string]$SettingsPath)
|
||||
if(-not (Test-Path $SettingsPath)) { return @() }
|
||||
try
|
||||
{
|
||||
$raw = Get-Content $SettingsPath -Raw -ErrorAction Stop | ConvertFrom-Json -AsHashtable -ErrorAction Stop
|
||||
$tenants = @()
|
||||
foreach($key in $raw.Keys)
|
||||
{
|
||||
if($key -match '^[0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12}$')
|
||||
{
|
||||
$name = $null
|
||||
if($raw[$key] -is [hashtable] -and $raw[$key].ContainsKey('TenantName'))
|
||||
{
|
||||
$name = $raw[$key]['TenantName']
|
||||
}
|
||||
elseif($raw[$key] -is [psobject] -and $raw[$key].PSObject.Properties['TenantName'])
|
||||
{
|
||||
$name = $raw[$key].TenantName
|
||||
}
|
||||
$display = if($name) { "$name ($key)" } else { $key }
|
||||
$tenants += [PSCustomObject]@{ TenantId = $key; TenantName = $name; Display = $display }
|
||||
}
|
||||
}
|
||||
return $tenants | Sort-Object Display
|
||||
}
|
||||
catch
|
||||
{
|
||||
return @()
|
||||
}
|
||||
}
|
||||
|
||||
function Update-TenantNameCache
|
||||
{
|
||||
param([string]$SettingsPath, [string]$TenantId, [string]$TenantName)
|
||||
if(-not (Test-Path $SettingsPath)) { return }
|
||||
try
|
||||
{
|
||||
$raw = Get-Content $SettingsPath -Raw -ErrorAction Stop | ConvertFrom-Json -AsHashtable -ErrorAction Stop
|
||||
if($raw[$TenantId] -is [hashtable])
|
||||
{
|
||||
$raw[$TenantId]['TenantName'] = $TenantName
|
||||
}
|
||||
else
|
||||
{
|
||||
$raw[$TenantId] = @{ TenantName = $TenantName }
|
||||
}
|
||||
$raw | ConvertTo-Json -Depth 10 | Set-Content -Path $SettingsPath -Force
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
function Resolve-TenantName
|
||||
{
|
||||
param([string]$TenantId, [string]$SettingsPath)
|
||||
$settingsObj = $null
|
||||
try
|
||||
{
|
||||
$settingsObj = Get-Content $SettingsPath -Raw -ErrorAction Stop | ConvertFrom-Json -AsHashtable -ErrorAction Stop
|
||||
}
|
||||
catch { return $null }
|
||||
|
||||
$tenantNode = $settingsObj[$TenantId]
|
||||
if(-not $tenantNode) { return $null }
|
||||
|
||||
$appId = $tenantNode['GraphAzureAppId']
|
||||
if(-not $appId) { return $null }
|
||||
|
||||
$secret = $tenantNode['GraphAzureAppSecret']
|
||||
$cert = $tenantNode['GraphAzureAppCert']
|
||||
|
||||
if(-not $secret -and $IsMacOS)
|
||||
{
|
||||
try
|
||||
{
|
||||
$keychainSecret = security find-generic-password -a "IntuneManagement" -s "IntuneMgmt-$AppId" -w 2>$null
|
||||
if($keychainSecret) { $secret = $keychainSecret }
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
$runtimeModule = Join-Path $projectRoot "Runtime/IntuneManagement.Runtime.psd1"
|
||||
if(-not (Test-Path $runtimeModule)) { return $null }
|
||||
|
||||
$invokeParams = @{
|
||||
Silent = $true
|
||||
JSonSettings = $true
|
||||
JSonFile = $SettingsPath
|
||||
TenantId = $TenantId
|
||||
AppId = $appId
|
||||
AuthMode = "AppOnly"
|
||||
}
|
||||
if($secret) { $invokeParams.Secret = $secret }
|
||||
elseif($cert) { $invokeParams.Certificate = $cert }
|
||||
|
||||
try
|
||||
{
|
||||
Import-Module $runtimeModule -Force | Out-Null
|
||||
Initialize-IntuneManagementRuntime -View "IntuneGraphAPI" @invokeParams | Out-Null
|
||||
if(Get-Command Invoke-GraphRequest -ErrorAction SilentlyContinue)
|
||||
{
|
||||
$org = Invoke-GraphRequest "/organization" -ErrorAction Stop
|
||||
if($org.value -and $org.value[0].displayName)
|
||||
{
|
||||
return $org.value[0].displayName
|
||||
}
|
||||
}
|
||||
}
|
||||
catch { }
|
||||
return $null
|
||||
}
|
||||
|
||||
$settingsPath = $SettingsFile
|
||||
if(-not $settingsPath) { $settingsPath = Get-DefaultSettingsPath }
|
||||
|
||||
if(-not $TenantId)
|
||||
{
|
||||
$tenants = Get-SavedTenants -SettingsPath $settingsPath
|
||||
$tenantOptions = @()
|
||||
foreach($t in $tenants)
|
||||
{
|
||||
$tenantOptions += $t.Display
|
||||
}
|
||||
$tenantOptions += "[+ Onboard new tenant]"
|
||||
$tenantOptions += "[Exit]"
|
||||
|
||||
$selectedTenantDisplay = Select-MenuItem -Items $tenantOptions -Header "Select a tenant"
|
||||
if(-not $selectedTenantDisplay -or $selectedTenantDisplay -eq "[Exit]")
|
||||
{
|
||||
exit 0
|
||||
}
|
||||
elseif($selectedTenantDisplay -eq "[+ Onboard new tenant]")
|
||||
{
|
||||
$TenantId = Read-Host "Enter the new Tenant ID (GUID)"
|
||||
if(-not $TenantId)
|
||||
{
|
||||
Write-Host "No tenant ID provided. Exiting." -ForegroundColor Yellow
|
||||
exit 0
|
||||
}
|
||||
$initPath = Join-Path $projectRoot "Scripts/Initialize-IntuneAuth.ps1"
|
||||
& $initPath -TenantId $TenantId
|
||||
Write-Host "`nOnboarding complete. Restarting launcher..." -ForegroundColor Green
|
||||
Start-Sleep -Seconds 1
|
||||
$restartParams = @{}
|
||||
if($SettingsFile) { $restartParams.SettingsFile = $SettingsFile }
|
||||
& $PSCommandPath @restartParams
|
||||
exit 0
|
||||
}
|
||||
else
|
||||
{
|
||||
$TenantId = $selectedTenantDisplay -replace '.*\(([0-9a-fA-F]{8}-([0-9a-fA-F]{4}-){3}[0-9a-fA-F]{12})\)$', '$1'
|
||||
if(-not $TenantId)
|
||||
{
|
||||
$TenantId = $selectedTenantDisplay
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$currentTenant = (Get-SavedTenants -SettingsPath $settingsPath) | Where-Object { $_.TenantId -eq $TenantId } | Select-Object -First 1
|
||||
if(-not $currentTenant -or -not $currentTenant.TenantName)
|
||||
{
|
||||
Write-Host "`nResolving tenant name..." -ForegroundColor Cyan
|
||||
$resolvedName = Resolve-TenantName -TenantId $TenantId -SettingsPath $settingsPath
|
||||
if($resolvedName)
|
||||
{
|
||||
Update-TenantNameCache -SettingsPath $settingsPath -TenantId $TenantId -TenantName $resolvedName
|
||||
Write-Host "Cached tenant name: $resolvedName" -ForegroundColor Green
|
||||
$currentTenant = [PSCustomObject]@{ TenantId = $TenantId; TenantName = $resolvedName; Display = "$resolvedName ($TenantId)" }
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
Show-FzfHint
|
||||
|
||||
# Build common parameter hashtable
|
||||
$commonParams = @{
|
||||
TenantId = $TenantId
|
||||
AppId = $AppId
|
||||
Secret = $Secret
|
||||
Certificate = $Certificate
|
||||
AuthMode = $AuthMode
|
||||
RedirectUri = $RedirectUri
|
||||
SettingsFile = $SettingsFile
|
||||
}
|
||||
|
||||
$menuItems = @(
|
||||
"18. Rotate app secret"
|
||||
"17. Deploy CIS M365 baseline"
|
||||
"16. Generate reports"
|
||||
"15. Delete tenant auth and app registration"
|
||||
"14. Delete local tenant auth only"
|
||||
"13. Refresh tenant names"
|
||||
"12. Initialize auth (one-time setup)"
|
||||
"11. Deploy baseline (dry-run / WhatIf)"
|
||||
"10. Deploy baseline"
|
||||
"9. Bulk device operations"
|
||||
"8. Bulk rename policies"
|
||||
"7. Export assignments to CSV/Markdown"
|
||||
"6. Restore assignments"
|
||||
"5. Backup assignments"
|
||||
"4. Bulk assignment manager (policies)"
|
||||
"3. Bulk app assignment"
|
||||
"2. Import policies"
|
||||
"1. Export policies"
|
||||
"0. Exit"
|
||||
)
|
||||
|
||||
while($true)
|
||||
{
|
||||
Clear-Host
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
Write-Host " macOS Intune Toolkit" -ForegroundColor Cyan
|
||||
Write-Host "========================================" -ForegroundColor Cyan
|
||||
if($currentTenant -and $currentTenant.TenantName)
|
||||
{
|
||||
Write-Host " Tenant: $($currentTenant.TenantName) ($TenantId)" -ForegroundColor Green
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host " Tenant: $TenantId" -ForegroundColor Green
|
||||
}
|
||||
Write-Host " Press Esc to go back, Space to select" -ForegroundColor DarkGray
|
||||
|
||||
$selection = Select-MenuItem -Items $menuItems -Header "Select a tool to launch"
|
||||
if(-not $selection)
|
||||
{
|
||||
continue
|
||||
}
|
||||
if($selection -eq "EXIT" -or $selection -like "*0. Exit*")
|
||||
{
|
||||
Write-Host "`nExiting. Goodbye!" -ForegroundColor Yellow
|
||||
exit 0
|
||||
}
|
||||
|
||||
$choiceNumber = [int]($selection -replace "^(\d+)\..*$", '$1')
|
||||
|
||||
$script = $null
|
||||
switch($choiceNumber)
|
||||
{
|
||||
1 { $script = "Scripts/Start-HeadlessIntune.ps1" }
|
||||
2 { $script = "Scripts/Start-HeadlessIntune.ps1" }
|
||||
3 { $script = "Scripts/Bulk-AppAssignment.ps1" }
|
||||
4 { $script = "Scripts/Bulk-AssignmentManager.ps1" }
|
||||
5 { $script = "Scripts/Backup-Restore-Assignments.ps1" }
|
||||
6 { $script = "Scripts/Backup-Restore-Assignments.ps1" }
|
||||
7 { $script = "Scripts/Export-AssignmentsToCsv.ps1" }
|
||||
8 { $script = "Scripts/Bulk-RenamePolicies.ps1" }
|
||||
9 { $script = "Scripts/Bulk-DeviceOperations.ps1" }
|
||||
10 { $script = "Scripts/Deploy-IntuneBaseline.ps1" }
|
||||
11 { $script = "Scripts/Deploy-IntuneBaseline.ps1" }
|
||||
12 { $script = "Scripts/Initialize-IntuneAuth.ps1" }
|
||||
14 { $script = "Scripts/Initialize-IntuneAuth.ps1" }
|
||||
15 { $script = "Scripts/Initialize-IntuneAuth.ps1" }
|
||||
18 { $script = "Scripts/Initialize-IntuneAuth.ps1" }
|
||||
default { }
|
||||
}
|
||||
|
||||
# Clear any mode-specific params from previous loop iteration
|
||||
$commonParams.Remove("Interactive")
|
||||
$commonParams.Remove("Mode")
|
||||
$commonParams.Remove("WhatIf")
|
||||
|
||||
switch($choiceNumber)
|
||||
{
|
||||
1 { $commonParams.Interactive = $true }
|
||||
2 { $commonParams.Interactive = $true }
|
||||
5 { $commonParams.Mode = "Backup" }
|
||||
6 { $commonParams.Mode = "Restore" }
|
||||
11 { $commonParams.WhatIf = $true }
|
||||
}
|
||||
|
||||
if($choiceNumber -eq 13)
|
||||
{
|
||||
Write-Host "`nRefreshing tenant names..." -ForegroundColor Cyan
|
||||
$tenantsToRefresh = Get-SavedTenants -SettingsPath $settingsPath
|
||||
$refreshed = 0
|
||||
$failed = 0
|
||||
foreach($t in $tenantsToRefresh)
|
||||
{
|
||||
Write-Host " Resolving $($t.TenantId) ..." -ForegroundColor DarkGray -NoNewline
|
||||
$name = Resolve-TenantName -TenantId $t.TenantId -SettingsPath $settingsPath
|
||||
if($name)
|
||||
{
|
||||
Update-TenantNameCache -SettingsPath $settingsPath -TenantId $t.TenantId -TenantName $name
|
||||
Write-Host " -> $name" -ForegroundColor Green
|
||||
$refreshed++
|
||||
if($t.TenantId -eq $TenantId)
|
||||
{
|
||||
$currentTenant = [PSCustomObject]@{ TenantId = $TenantId; TenantName = $name; Display = "$name ($TenantId)" }
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Host " -> FAILED" -ForegroundColor Red
|
||||
$failed++
|
||||
}
|
||||
}
|
||||
Write-Host "`nRefresh complete. Success: $refreshed, Failed: $failed" -ForegroundColor Cyan
|
||||
Write-Host "`nPress any key to return to the menu..." -ForegroundColor DarkGray
|
||||
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
||||
continue
|
||||
}
|
||||
|
||||
if($choiceNumber -eq 16)
|
||||
{
|
||||
$reportTypes = @("Settings","Assignments","ObjectInventory","All")
|
||||
$reportType = Select-MenuItem -Items $reportTypes -Header "Select report type"
|
||||
if(-not $reportType) { continue }
|
||||
|
||||
$dataSource = Select-MenuItem -Items @("Use existing backup","Pull fresh data from tenant") -Header "Data source"
|
||||
if(-not $dataSource) { continue }
|
||||
|
||||
$backupRoot = $null
|
||||
$exportPath = $null
|
||||
if($dataSource -like "*fresh*")
|
||||
{
|
||||
$exportPath = Read-Host "Export path (where to save fresh data)"
|
||||
if([string]::IsNullOrWhiteSpace($exportPath)) { Write-Host "Required." -ForegroundColor Red; continue }
|
||||
$backupRoot = $exportPath
|
||||
}
|
||||
else
|
||||
{
|
||||
$backupRoot = Read-Host "Backup root path"
|
||||
if([string]::IsNullOrWhiteSpace($backupRoot)) { Write-Host "Required." -ForegroundColor Red; continue }
|
||||
if(-not (Test-Path $backupRoot)) { Write-Host "Path not found: $backupRoot" -ForegroundColor Red; continue }
|
||||
}
|
||||
|
||||
$outputDir = Read-Host "Output directory for reports"
|
||||
if([string]::IsNullOrWhiteSpace($outputDir)) { Write-Host "Required." -ForegroundColor Red; continue }
|
||||
|
||||
$includeAssignments = $false
|
||||
if($reportType -in @("Settings","All"))
|
||||
{
|
||||
$ans = Read-Host "Include assignment columns in settings report? [y/N]"
|
||||
$includeAssignments = $ans -like 'y*'
|
||||
}
|
||||
|
||||
$headlessScript = Join-Path $projectRoot "Scripts/Start-HeadlessIntune.ps1"
|
||||
|
||||
if($dataSource -like "*fresh*")
|
||||
{
|
||||
Write-Host "`nExporting policies from tenant $TenantId ..." -ForegroundColor Cyan
|
||||
$exportParams = @{ Action = "Export"; TenantId = $TenantId; ExportPath = $exportPath; IncludeAssignments = $true; AuthMode = $AuthMode }
|
||||
if($AppId) { $exportParams.AppId = $AppId }
|
||||
if($Secret) { $exportParams.Secret = $Secret }
|
||||
elseif($Certificate) { $exportParams.Certificate = $Certificate }
|
||||
if($SettingsFile) { $exportParams.SettingsFile = $SettingsFile }
|
||||
& $headlessScript @exportParams
|
||||
}
|
||||
|
||||
$genParams = @{ Action = "GenerateReports"; ReportType = $reportType; BackupRoot = $backupRoot; OutputDir = $outputDir }
|
||||
if($includeAssignments) { $genParams.IncludeAssignmentsInSettings = $true }
|
||||
& $headlessScript @genParams
|
||||
Write-Host "`nPress any key to return to the menu..." -ForegroundColor DarkGray
|
||||
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
||||
continue
|
||||
}
|
||||
|
||||
if($choiceNumber -eq 17)
|
||||
{
|
||||
$defaultBaseline = Join-Path $projectRoot "Baselines/CISM365-v7-Generated.yaml"
|
||||
$baselinePath = Read-Host "Baseline YAML path (default: $defaultBaseline)"
|
||||
if([string]::IsNullOrWhiteSpace($baselinePath)) { $baselinePath = $defaultBaseline }
|
||||
if(-not (Test-Path $baselinePath)) { Write-Host "Not found: $baselinePath" -ForegroundColor Red; continue }
|
||||
|
||||
$cisMode = Select-MenuItem -Items @("Assess","Deploy") -Header "Select mode"
|
||||
if(-not $cisMode) { continue }
|
||||
|
||||
$apply = $false
|
||||
if($cisMode -eq "Deploy")
|
||||
{
|
||||
$ans = Read-Host "Apply changes? [y/N]"
|
||||
$apply = $ans -like 'y*'
|
||||
}
|
||||
|
||||
$allWorkloads = @("EntraID","ConditionalAccess","Exchange","SharePoint","Teams","PowerBI","Defender","Purview")
|
||||
$workloadStr = Read-Host "Workloads (comma-separated, or Enter for all)"
|
||||
$workloads = if([string]::IsNullOrWhiteSpace($workloadStr)) { $allWorkloads } else { $workloadStr -split ',' | ForEach-Object { $_.Trim() } | Where-Object { $_ } }
|
||||
|
||||
$cisScript = Join-Path $projectRoot "Scripts/Deploy-CISM365Baseline.ps1"
|
||||
$cisParams = @{ BaselinePath = $baselinePath; TenantId = $TenantId; Mode = $cisMode; AuthMode = $AuthMode; Workloads = $workloads }
|
||||
if($apply) { $cisParams.Apply = $true }
|
||||
if($AppId) { $cisParams.AppId = $AppId }
|
||||
if($Secret) { $cisParams.Secret = $Secret }
|
||||
elseif($Certificate) { $cisParams.Certificate = $Certificate }
|
||||
& $cisScript @cisParams
|
||||
Write-Host "`nPress any key to return to the menu..." -ForegroundColor DarkGray
|
||||
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
||||
continue
|
||||
}
|
||||
|
||||
if(-not $script)
|
||||
{
|
||||
continue
|
||||
}
|
||||
|
||||
$scriptPath = Join-Path $projectRoot $script
|
||||
if(-not (Test-Path $scriptPath))
|
||||
{
|
||||
throw "Script not found: $scriptPath"
|
||||
}
|
||||
|
||||
Write-Host "`nLaunching $script ...`n" -ForegroundColor Green
|
||||
|
||||
# Clone params and sanitize for scripts that don't accept the full auth set
|
||||
$launchParams = $commonParams.Clone()
|
||||
if($script -eq "Scripts/Initialize-IntuneAuth.ps1")
|
||||
{
|
||||
@("AppId","Secret","Certificate","AuthMode","RedirectUri","Interactive","Mode","WhatIf") | ForEach-Object { $launchParams.Remove($_) }
|
||||
}
|
||||
|
||||
if($choiceNumber -eq 14)
|
||||
{
|
||||
$launchParams.Delete = $true
|
||||
}
|
||||
|
||||
if($choiceNumber -eq 15)
|
||||
{
|
||||
$launchParams.DeleteApp = $true
|
||||
}
|
||||
|
||||
if($choiceNumber -eq 18)
|
||||
{
|
||||
$launchParams.RotateSecret = $true
|
||||
}
|
||||
|
||||
# Execute in same process so TUI flows naturally
|
||||
& $scriptPath @launchParams
|
||||
|
||||
if($choiceNumber -eq 14 -or $choiceNumber -eq 15)
|
||||
{
|
||||
Write-Host "`nTenant auth deleted. Exiting." -ForegroundColor Yellow
|
||||
exit 0
|
||||
}
|
||||
|
||||
Write-Host "`nPress any key to return to the menu..." -ForegroundColor DarkGray
|
||||
$null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")
|
||||
}
|
||||
Reference in New Issue
Block a user