feat(toolkit): complete macOS Intune Toolkit v1
Core enhancements: - Expanded default export/import scope to ~45 object types including DeviceManagementIntents - Added -AllPages pagination support across Graph queries for large tenants - Invoke-GraphRequest now throws on 4xx/5xx instead of silently returning null - Added macOS Keychain fallback for secret retrieval in headless auth flow - Added NameSearchPattern/NameReplacePattern mutation support through export/import forms New toolkit scripts: - Bulk-AppAssignment.ps1: bulk-assign apps to groups/All Users/All Devices - Bulk-AssignmentManager.ps1: add/remove assignments for any policy type with correct @odata.type - Backup-Restore-Assignments.ps1: JSON backup with cross-tenant group resolution - Export-AssignmentsToCsv.ps1: CSV/Markdown documentation output - Bulk-RenamePolicies.ps1: regex search/replace and prefix mutations - Bulk-DeviceOperations.ps1: delete/retire/wipe/lock/sync with -WhatIf safeguards - Start-IntuneManagementTui.ps1: interactive terminal UI for headless operations - Create-IntuneManagementApp.ps1: helper for app registration setup Updated existing scripts: - Export-Policies.ps1 / Import-Policies.ps1: wired mutation params through - Start-HeadlessIntune.ps1: integrated TUI and new parameter forwarding
This commit is contained in:
@@ -1069,11 +1069,11 @@ function Connect-MSALUser
|
||||
{
|
||||
$headlessAuthMode = ?? $global:HeadlessAuthMode "AppOnly"
|
||||
|
||||
if($headlessAuthMode -eq "Browser")
|
||||
if($headlessAuthMode -eq "Browser" -or $headlessAuthMode -eq "DeviceCode")
|
||||
{
|
||||
if(-not $global:AzureAppId -or -not $global:TenantId)
|
||||
{
|
||||
Write-Log "Azure AppId and Tenant Id must be specified for browser auth" 3
|
||||
Write-Log "Azure AppId and Tenant Id must be specified for $headlessAuthMode auth" 3
|
||||
return
|
||||
}
|
||||
|
||||
@@ -1315,8 +1315,74 @@ function Connect-MSALUser
|
||||
Write-LogError "Failed to perform silent login" $_.Exception
|
||||
}
|
||||
|
||||
if($global:hideUI -eq $true -and $global:HeadlessAuthMode -eq "DeviceCode" -and ((-not $authResult -and $Silent -ne $true) -or $prompConsent))
|
||||
{
|
||||
#########################################################################################################
|
||||
### Device Code Login
|
||||
#########################################################################################################
|
||||
Write-Log "Initiate device code logon"
|
||||
|
||||
if($useDefaultPermissions -eq $false)
|
||||
{
|
||||
[string[]]$Scopes = Get-MSALRequiredScopes
|
||||
}
|
||||
|
||||
Write-Log "Scopes: $(($Scopes -join ","))"
|
||||
|
||||
$msalDllPath = Join-Path (Split-Path -Parent $PSScriptRoot) "Bin/Microsoft.Identity.Client.dll"
|
||||
$consoleDllPath = [System.Console].Assembly.Location
|
||||
if (-not ("DeviceCodeHelper" -as [type]))
|
||||
{
|
||||
Add-Type -Path $msalDllPath -ErrorAction SilentlyContinue
|
||||
Add-Type -TypeDefinition @"
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Identity.Client;
|
||||
|
||||
public static class DeviceCodeHelper
|
||||
{
|
||||
public static Task ShowDeviceCode(DeviceCodeResult result)
|
||||
{
|
||||
Console.WriteLine("");
|
||||
Console.WriteLine("To sign in, use a web browser to open the page " + result.VerificationUrl + " and enter the code " + result.UserCode + " to authenticate.");
|
||||
Console.WriteLine("");
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
}
|
||||
"@ -ReferencedAssemblies @($msalDllPath, $consoleDllPath)
|
||||
}
|
||||
|
||||
$method = [DeviceCodeHelper].GetMethod("ShowDeviceCode")
|
||||
$delegateType = [System.Func[Microsoft.Identity.Client.DeviceCodeResult, System.Threading.Tasks.Task]]
|
||||
$callback = [System.Delegate]::CreateDelegate($delegateType, $method)
|
||||
$aquireTokenObj = $global:MSALApp.AcquireTokenWithDeviceCode($Scopes, $callback)
|
||||
|
||||
if ($tenantId)
|
||||
{
|
||||
Write-Log "Tenant id: $tenantId"
|
||||
[void]$aquireTokenObj.WithAuthority("https://$((Get-MSALAppAuthority))/$tenantId/")
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Log "Authority: $($global:MSALApp.Authority)"
|
||||
[void]$aquireTokenObj.WithAuthority($global:MSALApp.Authority)
|
||||
}
|
||||
|
||||
if($script:authenticationFailure.Claims)
|
||||
{
|
||||
Write-Log "Login claims: $($script:authenticationFailure.Claims))"
|
||||
[void]$AquireTokenObj.WithClaims($script:authenticationFailure.Claims)
|
||||
}
|
||||
|
||||
$authResult = Get-MsalAuthenticationToken $aquireTokenObj
|
||||
if($authResult)
|
||||
{
|
||||
Write-Log "$($authResult.Account.UserName) authenticated successfully (Device Code). CorrelationId: $($authResult.CorrelationId)"
|
||||
}
|
||||
}
|
||||
|
||||
# Interactive login is only allowed once the app has started. Skip if silent login failed during startup
|
||||
if($global:MainAppStarted -and ((-not $authResult -and $Silent -ne $true) -or $prompConsent))
|
||||
if($global:MainAppStarted -and $global:HeadlessAuthMode -ne "DeviceCode" -and ((-not $authResult -and $Silent -ne $true) -or $prompConsent))
|
||||
{
|
||||
#########################################################################################################
|
||||
### Interactive Login
|
||||
|
||||
Reference in New Issue
Block a user