Public/Connect-TenantToolbox.ps1
|
function Connect-TenantToolbox { <# .SYNOPSIS Signs in to Microsoft Graph once and sets the shared log path. .DESCRIPTION Central auth entry point for all TenantToolbox cmdlets. After calling it, all cmdlets reuse the same Graph session. Optionally sets a log path where state-changing actions (ACTION) are recorded. .PARAMETER Scopes Graph permissions. The default covers the current cmdlets. .PARAMETER LogPath Path to a log file. If omitted, logging goes to the console only. .PARAMETER UseDeviceCode More robust in embedded terminals (VS Code): no hidden WAM window, instead a code to enter at microsoft.com/devicelogin. .PARAMETER UseBrowser Regular OAuth sign-in in the default browser (with SSO) instead of the WAM popup. .PARAMETER ClientId App (client) id for unattended certificate authentication (app-only). .PARAMETER TenantId Tenant id for certificate authentication. .PARAMETER CertificateThumbprint Thumbprint of a certificate in the user's cert store. Together with -ClientId and -TenantId this signs in app-only (no interaction) - ideal for scheduled/unattended runs. .EXAMPLE Connect-TenantToolbox -LogPath .\tenanttoolbox.log .EXAMPLE Connect-TenantToolbox -UseDeviceCode .EXAMPLE Connect-TenantToolbox -ClientId <appid> -TenantId <tenantid> -CertificateThumbprint <thumb> #> [CmdletBinding(DefaultParameterSetName = 'Interactive')] param( [Parameter(ParameterSetName = 'Interactive')] [string[]]$Scopes = @( 'User.ReadWrite.All', 'Group.ReadWrite.All', 'AuditLog.Read.All', 'Directory.Read.All', 'Policy.Read.All', 'Application.Read.All', 'UserAuthenticationMethod.Read.All', 'RoleManagement.Read.Directory', 'DeviceManagementManagedDevices.ReadWrite.All', 'DeviceManagementApps.Read.All', 'MailboxSettings.Read', 'IdentityRiskyUser.Read.All', 'ServiceHealth.Read.All', 'ServiceMessage.Read.All', 'BitlockerKey.Read.All', 'DeviceManagementServiceConfig.Read.All', 'MailboxSettings.ReadWrite', 'DelegatedPermissionGrant.ReadWrite.All' ), [string]$LogPath, [Parameter(ParameterSetName = 'Interactive')] [switch]$UseDeviceCode, [Parameter(ParameterSetName = 'Interactive')] [switch]$UseBrowser, [Parameter(Mandatory, ParameterSetName = 'Certificate')] [string]$ClientId, [Parameter(Mandatory, ParameterSetName = 'Certificate')] [string]$TenantId, [Parameter(Mandatory, ParameterSetName = 'Certificate')] [string]$CertificateThumbprint ) if (-not (Get-Module -ListAvailable -Name Microsoft.Graph.Authentication)) { throw "Microsoft Graph SDK is missing. Please run once: Install-Module Microsoft.Graph -Scope CurrentUser" } if ($LogPath) { $script:TTLogPath = $LogPath if (-not (Test-Path $LogPath)) { New-Item -ItemType File -Path $LogPath -Force | Out-Null } } # Disable WAM -> classic browser OAuth flow (with SSO). # The parameter name differs by SDK version -> detect automatically. if ($UseBrowser) { $opt = Get-Command Set-MgGraphOption -ErrorAction SilentlyContinue if ($opt) { try { if ($opt.Parameters.ContainsKey('DisableLoginByWAM')) { Set-MgGraphOption -DisableLoginByWAM $true } elseif ($opt.Parameters.ContainsKey('EnableLoginByWAM')) { Set-MgGraphOption -EnableLoginByWAM $false } else { Write-Warning "This SDK version offers no WAM switch. Consider -UseDeviceCode." } } catch { Write-Warning "Could not disable WAM: $_" } } } try { if ($PSCmdlet.ParameterSetName -eq 'Certificate') { Connect-MgGraph -ClientId $ClientId -TenantId $TenantId -CertificateThumbprint $CertificateThumbprint -ErrorAction Stop | Out-Null } elseif ($UseDeviceCode) { Connect-MgGraph -Scopes $Scopes -UseDeviceCode -ErrorAction Stop | Out-Null } else { Connect-MgGraph -Scopes $Scopes -ErrorAction Stop | Out-Null } } catch { $script:TTConnected = $false Write-TTLog -Level ERROR -Message "Sign-in failed: $_" Write-Host "Sign-in failed: $($_.Exception.Message)" -ForegroundColor Red Write-Host "Tip: in the VS Code terminal WAM often gets in the way - use: Connect-TenantToolbox -UseDeviceCode" -ForegroundColor Yellow return } # Only report as connected if a context really exists. $ctx = Get-MgContext $identity = if ($ctx.Account) { $ctx.Account } elseif ($ctx.AppName) { "$($ctx.AppName) (app-only)" } else { $null } if (-not $ctx -or -not $identity) { $script:TTConnected = $false Write-Host "No valid session obtained. Use: Connect-TenantToolbox -UseDeviceCode" -ForegroundColor Yellow return } $script:TTConnected = $true Write-TTLog -Level INFO -Message "Connected to tenant '$($ctx.TenantId)' as '$identity'." Write-Host "TenantToolbox connected: $identity ($($ctx.TenantId))" -ForegroundColor Green } |