[CmdletBinding()] param( [ValidateSet("Export","Import","DeployCISBaseline","GenerateReports")] [string]$Action, [string]$BaselinePath, [ValidateSet("Assess","Deploy")] [string]$Mode = "Assess", [string[]]$Workloads, [switch]$Apply, [string]$TenantId, [string]$AppId, [string]$Secret, [string]$Certificate, [ValidateSet("AppOnly","Browser","DeviceCode")] [string]$AuthMode = "AppOnly", [string]$RedirectUri, [string]$SettingsFile, [string]$BatchFile, [string]$NameFilter = "", [string]$NameSearchPattern = "", [string]$NameReplacePattern = "", [string[]]$ObjectTypes, [string]$ExportPath, [string]$ImportPath, [ValidateSet("alwaysImport","skipIfExist","replace","replace_with_assignments","update")] [string]$ImportType = "alwaysImport", [switch]$IncludeAssignments, [switch]$AddCompanyName, [switch]$IncludeScopeTags, [switch]$ReplaceDependencyIds, [switch]$Interactive, # GenerateReports params [ValidateSet("Settings","Assignments","ObjectInventory","All")] [string]$ReportType = "All", [string]$BackupRoot, [string]$OutputDir, [string]$DataSource, [switch]$IncludeAssignmentsInSettings ) $modulePath = Join-Path (Split-Path -Parent $PSScriptRoot) "Headless/IntuneManagement.Headless.psd1" Import-Module $modulePath -Force if($Interactive -and -not $Action) { Write-Host "Interactive mode will prompt for the action and other settings." -ForegroundColor Cyan } elseif(-not $Action) { throw "Action is required. Use -Interactive to select it in a terminal UI." } if($Interactive) { $tuiScript = Join-Path (Split-Path -Parent $PSScriptRoot) "Scripts/Private/Start-IntuneManagementTui.ps1" if(Test-Path $tuiScript) { $tuiResult = & $tuiScript if(-not $tuiResult) { Write-Host "No selection made. Exiting." -ForegroundColor Yellow; exit 0 } foreach($prop in $tuiResult.PSObject.Properties) { if($null -ne $prop.Value -and $prop.Name -ne "Action") { Set-Variable -Name $prop.Name -Value $prop.Value } elseif($prop.Name -eq "Action") { $Action = $prop.Value } } } else { throw "TUI script not found: $tuiScript" } } if($Action -eq "GenerateReports") { if([string]::IsNullOrWhiteSpace($OutputDir)) { throw "OutputDir is required for GenerateReports." } if($DataSource -like "*fresh*") { if([string]::IsNullOrWhiteSpace($TenantId)) { throw "TenantId is required when pulling fresh data." } $freshDest = if(-not [string]::IsNullOrWhiteSpace($ExportPath)) { $ExportPath } else { $BackupRoot } if([string]::IsNullOrWhiteSpace($freshDest)) { throw "ExportPath or BackupRoot required for fresh data pull." } Write-Host "Pulling fresh data from tenant $TenantId ..." -ForegroundColor Cyan $freshParams = @{ Action = "Export"; TenantId = $TenantId; ExportPath = $freshDest; IncludeAssignments = $true; AuthMode = $AuthMode } if($AppId) { $freshParams.AppId = $AppId } if($Secret) { $freshParams.Secret = $Secret } elseif($Certificate) { $freshParams.Certificate = $Certificate } if($SettingsFile) { $freshParams.SettingsFile = $SettingsFile } Invoke-IntunePolicyAction @freshParams $BackupRoot = $freshDest } # Validate inputs if([string]::IsNullOrWhiteSpace($BackupRoot)) { throw "BackupRoot is required for GenerateReports." } if(-not (Test-Path $BackupRoot)) { throw "BackupRoot not found: $BackupRoot" } $python = Get-Command python3 -ErrorAction SilentlyContinue if(-not $python) { $python = Get-Command python -ErrorAction SilentlyContinue } if(-not $python) { throw "python3 not found. Install Python 3 to use GenerateReports." } $pythonExe = $python.Source $scriptsDir = Split-Path -Parent $PSScriptRoot if(-not (Test-Path (Join-Path $scriptsDir "Scripts/Export-SettingsReport.py"))) { $scriptsDir = $PSScriptRoot } New-Item -ItemType Directory -Path $OutputDir -Force | Out-Null function Invoke-Report { param([string]$Script, [string[]]$ScriptArgs) $fullScript = Join-Path $scriptsDir "Scripts/$Script" if(-not (Test-Path $fullScript)) { Write-Warning "Report script not found: $fullScript"; return } Write-Host "Running $Script ..." -ForegroundColor Cyan & $pythonExe $fullScript @ScriptArgs } if($ReportType -in @("Settings","All")) { $settingsArgs = @("--root", $BackupRoot, "--output", (Join-Path $OutputDir "settings-report.csv")) if($IncludeAssignmentsInSettings) { $settingsArgs += "--include-assignments" } Invoke-Report -Script "Export-SettingsReport.py" -ScriptArgs $settingsArgs } if($ReportType -in @("Assignments","All")) { Invoke-Report -Script "Export-AssignmentReport.py" -ScriptArgs @( "--root", $BackupRoot, "--output", (Join-Path $OutputDir "assignment-report.csv") ) } if($ReportType -in @("ObjectInventory","All")) { Invoke-Report -Script "Export-ObjectInventoryReport.py" -ScriptArgs @( "--root", $BackupRoot, "--output", (Join-Path $OutputDir "object-inventory.csv") ) } Write-Host "`nReports written to: $OutputDir" -ForegroundColor Green return } if($Action -eq "DeployCISBaseline") { $deployScript = Join-Path (Split-Path -Parent $PSScriptRoot) "Scripts/Deploy-CISM365Baseline.ps1" if(-not (Test-Path $deployScript)) { throw "CIS baseline deployment script not found: $deployScript" } $deployParams = @{ BaselinePath = $BaselinePath TenantId = $TenantId Mode = $Mode AuthMode = $AuthMode } if($Apply) { $deployParams.Apply = $true } if($PSBoundParameters.ContainsKey("Workloads") -or $Workloads) { $deployParams.Workloads = $Workloads } if($Secret) { $deployParams.Secret = $Secret } elseif($Certificate) { $deployParams.Certificate = $Certificate } if($AppId) { $deployParams.AppId = $AppId } if($RedirectUri) { $deployParams.RedirectUri = $RedirectUri } & $deployScript @deployParams return } if([string]::IsNullOrWhiteSpace($TenantId)) { throw "TenantId is required for Action '$Action'." } $invokeParams = @{ Action = $Action TenantId = $TenantId AppId = $AppId AuthMode = $AuthMode SettingsFile = $SettingsFile BatchFile = $BatchFile NameFilter = $NameFilter NameSearchPattern = $NameSearchPattern NameReplacePattern = $NameReplacePattern ExportPath = $ExportPath ImportPath = $ImportPath ImportType = $ImportType IncludeAssignments = $IncludeAssignments AddCompanyName = $AddCompanyName IncludeScopeTags = $IncludeScopeTags ReplaceDependencyIds = $ReplaceDependencyIds } if($Interactive -and $Action) { $invokeParams.Action = $Action } if($PSBoundParameters.ContainsKey("ObjectTypes") -or $ObjectTypes) { $invokeParams.ObjectTypes = $ObjectTypes } if($Secret) { $invokeParams.Secret = $Secret } elseif($Certificate) { $invokeParams.Certificate = $Certificate } if($RedirectUri) { $invokeParams.RedirectUri = $RedirectUri } Invoke-IntunePolicyAction @invokeParams