Private/Connect-Intune.ps1
|
<#
.SYNOPSIS Connects to Microsoft Graph/Intune .DESCRIPTION Authenticates with Microsoft Graph using App Registration credentials .PARAMETER Config Configuration object containing App Registration details .OUTPUTS Boolean indicating success #> function Connect-Intune { [CmdletBinding()] param( [Parameter(Mandatory=$true)] [PSCustomObject]$Config ) try { if (-not (Get-Module -ListAvailable -Name 'Microsoft.Graph.Authentication')) { throw "Microsoft.Graph.Authentication is required for Intune. Install: Install-Module -Name Microsoft.Graph.Authentication, Microsoft.Graph.DeviceManagement -Scope CurrentUser" } # Check if we're already connected and working $ctx = $null if (Get-Command -Name 'Get-MgContext' -ErrorAction SilentlyContinue) { $ctx = Get-MgContext -ErrorAction SilentlyContinue } # If already connected and context is valid, skip module loading if ($ctx -and $ctx.TenantId) { Write-Verbose "Already connected to Microsoft Graph (tenant: $($ctx.TenantId))" return $true } # Check if module is already loaded and working $loadedAuth = Get-Module -Name 'Microsoft.Graph.Authentication' -ErrorAction SilentlyContinue $moduleWorking = $false if ($loadedAuth) { # Test if the module is functional by checking for Connect-MgGraph command if (Get-Command -Name 'Connect-MgGraph' -ErrorAction SilentlyContinue) { $moduleWorking = $true } } # Only reload if module is not loaded or not working if (-not $moduleWorking) { # Disconnect from Graph if already connected to release resources if (Get-Command -Name 'Disconnect-MgGraph' -ErrorAction SilentlyContinue) { try { $oldCtx = Get-MgContext -ErrorAction SilentlyContinue if ($oldCtx) { Disconnect-MgGraph -ErrorAction SilentlyContinue | Out-Null Start-Sleep -Milliseconds 300 } } catch { Write-Verbose "Disconnect-MgGraph failed (ignored): $_" } } # Remove all Graph modules to avoid assembly conflicts $graphModules = @('Microsoft.Graph.Authentication', 'Microsoft.Graph.DeviceManagement', 'Microsoft.Graph') foreach ($modName in $graphModules) { $mod = Get-Module -Name $modName -ErrorAction SilentlyContinue if ($mod) { try { Remove-Module -Name $modName -Force -ErrorAction SilentlyContinue } catch { Write-Verbose "Could not remove module $modName : $_" } } } # Wait longer to allow assembly unloading Start-Sleep -Milliseconds 500 # Import with error handling for assembly conflicts try { Import-Module Microsoft.Graph.Authentication -Force -ErrorAction Stop -Scope Global } catch { # If import fails due to assembly conflict, try to use the already loaded version $errorMsg = $_.Exception.Message if ($errorMsg -like "*Assembly with same name is already loaded*" -or $errorMsg -like "*already loaded*") { Write-Verbose "Microsoft.Graph.Authentication assembly already loaded, attempting to use existing version" # Try to get the module again - it might be available despite the error $loadedAuth = Get-Module -Name 'Microsoft.Graph.Authentication' -ErrorAction SilentlyContinue if (-not $loadedAuth -or -not (Get-Command -Name 'Connect-MgGraph' -ErrorAction SilentlyContinue)) { throw "Could not load Microsoft.Graph.Authentication. Assembly conflict detected. Please restart PowerShell session." } } else { throw } } if (Get-Module -ListAvailable -Name 'Microsoft.Graph.DeviceManagement') { Import-Module Microsoft.Graph.DeviceManagement -Force -ErrorAction SilentlyContinue -Scope Global } } # Get credentials from config $clientId = $Config.AppRegistration.ClientId $clientSecret = $Config.AppRegistration.ClientSecret $tenantId = $Config.AppRegistration.TenantId if ([string]::IsNullOrEmpty($clientId) -or [string]::IsNullOrEmpty($clientSecret) -or [string]::IsNullOrEmpty($tenantId)) { throw "App Registration credentials are incomplete. Please configure ClientId, ClientSecret, and TenantId in config.json" } # Create secure string for client secret (required for Connect-MgGraph; not persisted) $secureSecret = ConvertTo-SecureString -String $clientSecret -AsPlainText -Force $credential = New-Object System.Management.Automation.PSCredential($clientId, $secureSecret) Connect-MgGraph -TenantId $tenantId -ClientSecretCredential $credential -NoWelcome -ErrorAction Stop $ctx = Get-MgContext -ErrorAction SilentlyContinue if (-not $ctx -or -not $ctx.TenantId) { throw "Connect-MgGraph completed but no context. Check credentials and permissions." } Write-Verbose "Connected to Microsoft Graph (tenant: $($ctx.TenantId))" return $true } catch { Write-Error "Failed to connect to Intune: $_" return $false } } |