Public/NA.ConnectGraph.ps1
|
<#
.SYNOPSIS Connect to Microsoft Graph using application credentials. .DESCRIPTION Reuses an existing Microsoft Graph session when possible, otherwise performs a client credentials flow and connects with Connect-MgGraph -AccessToken. Can optionally install Microsoft.Graph if missing. .EXAMPLE Test-MgGraphConnection -TenantId $tenantId -ClientId $clientId -ClientSecret $clientSecret -LogLocation "C:\Logs\graph.log" .PARAMETER TenantId Azure AD tenant ID (GUID or verified domain). .PARAMETER ClientId Application (client) ID used for client-credential auth. .PARAMETER ClientSecret Client secret associated with the application. .PARAMETER LogLocation Path to a log file; used only when Write-Log is available. .PARAMETER AutoInstall Install Microsoft.Graph automatically if missing. .PARAMETER ShowInformations When set, writes additional diagnostic info (never logs secrets). .NOTES Author: Giovanni Solone #> function Test-MgGraphConnection { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$TenantId, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$ClientId, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [string]$ClientSecret, [string]$LogLocation, [bool]$AutoInstall = $false, [bool]$ShowInformations = $false ) $status = [pscustomobject]@{ Success = $false Message = $null } # Ensure Microsoft.Graph is available $graphModule = Get-Module -ListAvailable -Name Microsoft.Graph | Select-Object -First 1 if (-not $graphModule) { if ($AutoInstall) { Write-NALog "Microsoft.Graph not found. Installing (CurrentUser scope)..." -Level INFO -LogLocation $LogLocation try { Install-Module -Name Microsoft.Graph -Scope CurrentUser -Force -AllowClobber -ErrorAction Stop $graphModule = Get-Module -ListAvailable -Name Microsoft.Graph | Select-Object -First 1 } catch { $status.Message = "Failed to install Microsoft.Graph: $($_.Exception.Message)" Write-NALog $status.Message -Level ERROR -LogLocation $LogLocation return $status.Success } } else { $status.Message = "Microsoft.Graph module is not available. Install it or use -AutoInstall." Write-NALog $status.Message -Level ERROR -LogLocation $LogLocation return $status.Success } } if (-not (Get-Module -Name Microsoft.Graph)) { try { Import-Module Microsoft.Graph -ErrorAction Stop } catch { $status.Message = "Failed to import Microsoft.Graph: $($_.Exception.Message)" Write-NALog $status.Message -Level ERROR -LogLocation $LogLocation return $status.Success } } try { Get-MgUser -Top 1 -ErrorAction Stop $status.Success = $true } catch { $Scope = "https://graph.microsoft.com/.default" $TokenEndpoint = "https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token" $body = @{ client_id = $ClientId scope = $Scope client_secret = $ClientSecret grant_type = "client_credentials" } $tokenResponse = $null try { $tokenResponse = Invoke-RestMethod -Method Post -Uri $TokenEndpoint -Body $body -ErrorAction Stop } catch { $status.Message = "Failed to obtain access token: $($_.Exception.Message)" Write-NALog $status.Message -Level ERROR -LogLocation $LogLocation return $status.Success } if (-not $tokenResponse.access_token) { $status.Message = "Token response did not include access_token." Write-NALog $status.Message -Level ERROR -LogLocation $LogLocation return $status.Success } if ($ShowInformations) { $sanitizedSecret = ConvertTo-MaskedSecret -Secret $ClientSecret Write-NALog "TenantId: $TenantId" -Level DEBUG -LogLocation $LogLocation Write-NALog "ClientId: $ClientId" -Level DEBUG -LogLocation $LogLocation Write-NALog "ClientSecret (masked): $sanitizedSecret" -Level DEBUG -LogLocation $LogLocation Write-NALog "Token endpoint: $TokenEndpoint" -Level DEBUG -LogLocation $LogLocation } $accessToken = $tokenResponse.access_token | ConvertTo-SecureString -AsPlainText -Force try { Connect-MgGraph -AccessToken $accessToken -ErrorAction Stop $status.Success = $true $status.Message = "Connected to Microsoft Graph with application credentials." Write-NALog $status.Message -Level INFO -LogLocation $LogLocation } catch { $status.Message = "Cannot connect to Microsoft Graph: $($_.Exception.Message)" Write-NALog "Connect-MgGraph exception: $($_.Exception.ToString())" -Level ERROR -LogLocation $LogLocation Write-NALog $status.Message -Level ERROR -LogLocation $LogLocation } } return $status.Success } Set-Alias -Name CheckMGGraphConnection -Value Test-MgGraphConnection -Description "Connect to Microsoft Graph (function)" |