source/Private/GraphHelpers.ps1
|
function Invoke-RJMgGraphCommand { [CmdletBinding()] param( [Parameter(Mandatory = $true, Position = 0)] [ScriptBlock]$ScriptBlock ) try { if (-not $PSDefaultParameterValues.ContainsKey("*Mg*:ErrorAction")) { $PSDefaultParameterValues.Add('*Mg*:ErrorAction', 'Stop') } if (-not $PSDefaultParameterValues.ContainsKey("*Mg*:ErrorVariable")) { $PSDefaultParameterValues.Add('*Mg*:ErrorVariable', 'RJMSGraphError') } & $ScriptBlock } catch { $errorInfo = @{ StatusCode = $null StatusText = $null ErrorCode = $null Message = $null } $text = $RJMSGraphError[0].Message if ($text -match 'Status:\s*(\d{3})\s*\(([^)]+)\)') { $errorInfo.StatusCode = [int]$matches[1] $errorInfo.StatusText = $matches[2] } if ($text -match 'ErrorCode:\s*(\S+)') { $errorInfo.ErrorCode = $matches[1] } if ($text -match 'Message:\s*(.+)') { $errorInfo.Message = $matches[1] } else { $errorInfo.Message = $text } if ($errorInfo.StatusCode -eq 404) { Write-Verbose "Resource not found (404)" return $null } Write-Verbose ("Full error details:`n" + ($RJMSGraphError[0].ErrorRecord | Format-List -Force | Out-String)) # Use the original error record to preserve full context $PSCmdlet.ThrowTerminatingError($RJMSGraphError[0].ErrorRecord) } } function Invoke-GraphLogin { [CmdletBinding()] param() # Check whether already connected to Microsoft Graph $context = Invoke-RJMgGraphCommand { Get-MgContext } if ($context -and $context.Scopes) { $hasRequiredScopes = $true foreach ($scope in $RequiredGraphScopes) { if ($scope -notin $context.Scopes) { $hasRequiredScopes = $false break } } if ($hasRequiredScopes) { Write-Verbose "Already connected to Microsoft Graph with required scopes" Write-Verbose "Connected as: $($context.Account) to tenant: $($context.TenantId)" return $context } else { Write-Warning "Connected to Microsoft Graph but missing required scopes. Reconnecting..." Disconnect-MgGraph -ErrorAction SilentlyContinue } } # Connect to Microsoft Graph with required scopes Write-Information "Connecting to Microsoft Graph with required scopes..." Connect-MgGraph -Scopes $RequiredGraphScopes -NoWelcome # Verify connection # Get the current context to check if connected $context = Invoke-RJMgGraphCommand { Get-MgContext } if (-not $context) { throw "Failed to establish Microsoft Graph connection" } Write-Verbose "Successfully connected to Microsoft Graph" Write-Verbose "Connected as: $($context.Account) to tenant: $($context.TenantId)" return $context } function Get-TenantInfo { [CmdletBinding()] param() Write-Verbose "Retrieving current tenant information" $mgContext = Get-MgContext if (-not $mgContext) { throw "Not connected to Microsoft Graph. Please run Connect-MgGraph first." } $tenantId = $mgContext.TenantId # Get tenant display name from Microsoft Graph Write-Verbose "Getting tenant display name from Microsoft Graph" $displayName = "Unknown" $organization = Invoke-RJMgGraphCommand { Get-MgOrganization -Property Id, DisplayName } if ($organization) { $displayName = $organization.DisplayName #Always contains a single organization } else { throw "Failed to retrieve tenant display name from Microsoft Graph" } # Create simplified tenant info object $tenantInfo = [PSCustomObject]@{ TenantId = $tenantId DisplayName = $displayName } Write-Verbose "Current tenant: $($tenantInfo.DisplayName) ($($tenantInfo.TenantId))" return $tenantInfo } |