From 0ddd21ab149c8b285e4ab98b6e7a167226f22f7b Mon Sep 17 00:00:00 2001 From: Tomas Kracmar Date: Tue, 14 Apr 2026 15:05:15 +0200 Subject: [PATCH] feat(launcher): add baseline deployer to unified menu - Adds 'Deploy baseline' and 'Deploy baseline (dry-run / WhatIf)' to Start-IntuneToolkit.ps1 - Ensures WhatIf flag is cleared between menu iterations --- CHANGELOG_macOS_IntuneToolkit.md | 11 ++ OPERATIONS_LOG.md | 36 ++++++ Scripts/Start-IntuneToolkit.ps1 | 181 +++++++++++++++++++++++++++++++ 3 files changed, 228 insertions(+) create mode 100644 Scripts/Start-IntuneToolkit.ps1 diff --git a/CHANGELOG_macOS_IntuneToolkit.md b/CHANGELOG_macOS_IntuneToolkit.md index ec6129c..1e651e4 100644 --- a/CHANGELOG_macOS_IntuneToolkit.md +++ b/CHANGELOG_macOS_IntuneToolkit.md @@ -70,3 +70,14 @@ ### Dependencies - `powershell-yaml` module (auto-install prompt if missing). + + +## 2026-04-13 — Unified Launcher: Baseline Deployer Integration + +### Modified +- **`Scripts/Start-IntuneToolkit.ps1`** + - Added menu entries for baseline deployment: + - `10. Deploy baseline` + - `11. Deploy baseline (dry-run / WhatIf)` + - Forwards `-WhatIf` switch correctly when dry-run option is selected. + - Ensures `WhatIf` flag is cleared between loop iterations to avoid leakage to other tools. diff --git a/OPERATIONS_LOG.md b/OPERATIONS_LOG.md index 67a53a8..3cd3606 100644 --- a/OPERATIONS_LOG.md +++ b/OPERATIONS_LOG.md @@ -109,3 +109,39 @@ Build a declarative Intune baseline deployment system (YAML manifest + deployer - `Baselines/OpenIntuneBaseline.example.yaml` - `Scripts/Deploy-IntuneBaseline.ps1` - `Scripts/ConvertTo-IntuneBaseline.ps1` + + +## Session: 2026-04-13 (continuation 2) + +### Task +Add the new `Deploy-IntuneBaseline.ps1` to the unified launcher menu, with separate dry-run and write entries. + +--- + +## Operations performed + +1. **ReadFile** + - Path: `/Users/avedelphina/Local/IntuneManagement/Scripts/Start-IntuneToolkit.ps1` + - Purpose: Inspect menu array, switch mapping, and parameter forwarding logic. + +2. **StrReplaceFile** + - Path: `/Users/avedelphina/Local/IntuneManagement/Scripts/Start-IntuneToolkit.ps1` + - Changes: + - Expanded `$menuItems` from 10→0 to 12→0, inserting `Deploy baseline (dry-run / WhatIf)` and `Deploy baseline`. + - Added `switch` cases for `10` and `11` mapping to `Scripts/Deploy-IntuneBaseline.ps1`. + - Added `$commonParams.Remove("WhatIf")` in the cleanup block to prevent flag leakage. + +3. **Shell** + - Command: Syntax validation on `Start-IntuneToolkit.ps1`. + - Result: Syntax OK. + +4. **WriteFile (append)** + - Path: `/Users/avedelphina/Local/IntuneManagement/CHANGELOG_macOS_IntuneToolkit.md` + - Added launcher integration changelog entry. + +5. **WriteFile (append)** + - Path: `/Users/avedelphina/Local/IntuneManagement/OPERATIONS_LOG.md` + - Added this operations entry. + +## Files modified in this session +- `Scripts/Start-IntuneToolkit.ps1` diff --git a/Scripts/Start-IntuneToolkit.ps1 b/Scripts/Start-IntuneToolkit.ps1 new file mode 100644 index 0000000..3076df9 --- /dev/null +++ b/Scripts/Start-IntuneToolkit.ps1 @@ -0,0 +1,181 @@ +#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 + + # Execute in same process so TUI flows naturally + & $scriptPath @commonParams + + Write-Host "`nPress any key to return to the menu..." -ForegroundColor DarkGray + $null = $Host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") +}