#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 ./Scripts/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-FzfMenu { param( [Parameter(Mandatory)] [string[]]$Items, [string]$Header = "Select one" ) $selected = $Items | fzf --header=$Header --bind=space:toggle 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 = Split-Path -Parent $PSScriptRoot # Build common parameter hashtable $commonParams = @{ TenantId = $TenantId AppId = $AppId Secret = $Secret Certificate = $Certificate AuthMode = $AuthMode RedirectUri = $RedirectUri SettingsFile = $SettingsFile } $menuItems = @( "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 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') switch($choiceNumber) { 1 { $script = "Start-HeadlessIntune.ps1"; $commonParams.Interactive = $true } 2 { $script = "Start-HeadlessIntune.ps1"; $commonParams.Interactive = $true } 3 { $script = "Scripts/Bulk-AppAssignment.ps1" } 4 { $script = "Scripts/Bulk-AssignmentManager.ps1" } 5 { $script = "Scripts/Backup-Restore-Assignments.ps1"; $commonParams.Mode = "Backup" } 6 { $script = "Scripts/Backup-Restore-Assignments.ps1"; $commonParams.Mode = "Restore" } 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"; $commonParams.WhatIf = $true } 12 { $script = "Scripts/Initialize-IntuneAuth.ps1" } default { continue } } # 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 } } $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($_) } } # Execute in same process so TUI flows naturally & $scriptPath @launchParams Write-Host "`nPress any key to return to the menu..." -ForegroundColor DarkGray $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") }