v4.0.1: per-user app naming, auth deletion, TUI onboarding flow, PIM docs

This commit is contained in:
2026-04-16 15:40:33 +02:00
parent 1ff059342f
commit 70679cba48
4 changed files with 200 additions and 25 deletions

View File

@@ -17,7 +17,7 @@ The Microsoft Entra tenant ID (GUID). If omitted, the script reads from
existing settings or prompts interactively.
.PARAMETER DisplayName
The display name for the app registration. Default: IntuneManagement-Headless.
The display name for the app registration. Default: IntuneManagement-<current user name>.
.PARAMETER SettingsFile
Path to the JSON settings file. If omitted, defaults to the macOS_IntuneManagement
@@ -25,16 +25,28 @@ settings folder (~/Library/Application Support/macOS_IntuneManagement/Settings.j
.PARAMETER Force
Recreate the app registration and secret even if existing credentials are found.
.PARAMETER Delete
Remove the saved tenant credentials from the local settings file (and macOS Keychain if applicable).
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.
#>
[CmdletBinding()]
param(
[string]$TenantId,
[string]$DisplayName = "IntuneManagement-Headless",
[string]$DisplayName = "IntuneManagement-$([Environment]::UserName)",
[string]$SettingsFile,
[switch]$Force
[switch]$Force,
[switch]$Delete,
[switch]$DeleteApp
)
$ErrorActionPreference = "Stop"
@@ -67,6 +79,45 @@ function Get-AuthSetting
param($Key, [string]$SubPath = "", $DefaultValue = $null)
Get-Setting -SubPath $SubPath -Key $Key -DefaultValue $DefaultValue
}
function Remove-LocalAuthSettings
{
param([string]$TenantId, [string]$AppId)
if ($global:JsonSettingsObj)
{
if ($global:JsonSettingsObj.ContainsKey($TenantId))
{
$global:JsonSettingsObj.Remove($TenantId) | Out-Null
Write-Host "Removed tenant settings for $TenantId from $SettingsFile" -ForegroundColor Green
}
if ($global:JsonSettingsObj["TenantId"] -eq $TenantId)
{
$global:JsonSettingsObj.Remove("TenantId") | Out-Null
Write-Host "Removed default TenantId from $SettingsFile" -ForegroundColor Green
}
$global:JsonSettingsObj | ConvertTo-Json -Depth 30 | Out-File -LiteralPath $global:JSonSettingFile -Force -Encoding utf8
}
if ($AppId)
{
if ($IsMacOS)
{
$null = security delete-generic-password -a "IntuneManagement" -s "IntuneMgmt-$AppId" 2>$null
Write-Host "Removed client secret for AppId $AppId from macOS Keychain" -ForegroundColor Green
}
else
{
Write-Host "Client secret was stored in $SettingsFile and has been removed along with the tenant node." -ForegroundColor Green
}
}
else
{
Write-Warning "No saved credentials found for tenant $TenantId."
}
}
#endregion
#region Determine TenantId
@@ -85,6 +136,96 @@ if (-not $TenantId)
}
#endregion
#region Delete saved credentials
if ($Delete)
{
$appIdToClean = Get-AuthSetting -SubPath $TenantId -Key "GraphAzureAppId"
Remove-LocalAuthSettings -TenantId $TenantId -AppId $appIdToClean
return
}
#endregion
#region Microsoft Graph modules
$requiredModules = @("Microsoft.Graph.Authentication", "Microsoft.Graph.Applications")
foreach ($mod in $requiredModules)
{
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
#endregion
#region Connect to Graph
Write-Host ""
Write-Host "Connecting to Microsoft Graph..." -ForegroundColor Cyan
Write-Host "A browser window will open for authentication." -ForegroundColor Cyan
Connect-MgGraph -Scopes "Application.ReadWrite.All", "AppRoleAssignment.ReadWrite.All", "Organization.Read.All" -NoWelcome
#endregion
#region Resolve authenticated user for app naming
if (-not $PSBoundParameters.ContainsKey('DisplayName'))
{
try
{
$ctx = Get-MgContext -ErrorAction Stop
if ($ctx -and $ctx.Account)
{
$DisplayName = "IntuneManagement-$($ctx.Account)"
Write-Host "Using app display name: $DisplayName" -ForegroundColor DarkGray
}
}
catch { }
}
#endregion
#region Cache tenant name
try
{
$org = Get-MgOrganization -ErrorAction Stop
if ($org -and $org.DisplayName)
{
Save-AuthSetting -SubPath $TenantId -Key "TenantName" -Value $org.DisplayName
Write-Host "Cached tenant name: $($org.DisplayName)" -ForegroundColor Green
}
}
catch
{
Write-Warning "Failed to cache tenant name: $($_.Exception.Message)"
}
#endregion
#region Delete app registration and local credentials
if ($DeleteApp)
{
$appIdToClean = Get-AuthSetting -SubPath $TenantId -Key "GraphAzureAppId"
if ($appIdToClean)
{
$appToDelete = Get-MgApplication -Filter "appId eq '$appIdToClean'" -ErrorAction SilentlyContinue | Select-Object -First 1
if ($appToDelete)
{
Remove-MgApplication -ApplicationId $appToDelete.Id
Write-Host "Deleted app registration $($appToDelete.DisplayName) ($appIdToClean) from tenant $TenantId" -ForegroundColor Green
}
else
{
Write-Warning "App registration $appIdToClean not found in tenant $TenantId."
}
}
else
{
Write-Warning "No AppId found in local settings for tenant $TenantId."
}
Remove-LocalAuthSettings -TenantId $TenantId -AppId $appIdToClean
Disconnect-MgGraph | Out-Null
return
}
#endregion
#region Check for existing credentials
$existingAppId = Get-AuthSetting -SubPath $TenantId -Key "GraphAzureAppId"
if ($existingAppId -and -not $Force)
@@ -116,27 +257,6 @@ if ($existingAppId -and -not $Force)
}
#endregion
#region Microsoft Graph modules
$requiredModules = @("Microsoft.Graph.Authentication", "Microsoft.Graph.Applications")
foreach ($mod in $requiredModules)
{
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
#endregion
#region Connect to Graph
Write-Host ""
Write-Host "Connecting to Microsoft Graph..." -ForegroundColor Cyan
Write-Host "A browser window will open for authentication." -ForegroundColor Cyan
Connect-MgGraph -Scopes "Application.ReadWrite.All", "AppRoleAssignment.ReadWrite.All" -NoWelcome
#endregion
#region App registration
$graphSp = Get-MgServicePrincipal -Filter "appId eq '00000003-0000-0000-c000-000000000000'"
if (-not $graphSp)

View File

@@ -261,6 +261,12 @@ 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
& $PSCommandPath
exit 0
}
else
{
@@ -300,6 +306,8 @@ $commonParams = @{
}
$menuItems = @(
"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)"
@@ -360,6 +368,8 @@ while($true)
11 { $script = "Scripts/Deploy-IntuneBaseline.ps1"; $commonParams.WhatIf = $true }
12 { $script = "Scripts/Initialize-IntuneAuth.ps1" }
13 { $script = $null }
14 { $script = "Scripts/Initialize-IntuneAuth.ps1" }
15 { $script = "Scripts/Initialize-IntuneAuth.ps1" }
default { continue }
}
@@ -424,9 +434,25 @@ while($true)
@("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
}
# 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")
}