How to Connect to Microsoft Graph PowerShell (Including GCC High)
If you’ve searched for “connect-mggraph,” you’re probably staring at a PowerShell prompt right now. You need to connect to Microsoft Graph to manage users, pull license reports, update groups, or automate something that the admin portal is too slow or too manual for.
Microsoft’s documentation gives you the cmdlet reference. What it doesn’t give you is a straight answer on which authentication method to use, which scopes you need, or how to make any of it work in GCC High. That’s what this guide is for.
Install the Module
Before you connect, you need the Microsoft Graph PowerShell SDK installed. If you’re not sure whether you have it:
Get-Module Microsoft.Graph.Authentication -ListAvailable If that returns nothing, install it:
Install-Module Microsoft.Graph -Scope CurrentUser This installs the full SDK — all sub-modules. It’s large. If you only need specific functionality, you can install individual sub-modules instead (e.g., Install-Module Microsoft.Graph.Users). The Microsoft.Graph.Authentication module, which contains Connect-MgGraph, is always required.
Version matters. If you have an older version installed and things aren’t working, update first:
Update-Module Microsoft.Graph The Microsoft.Graph.Beta module is separate and optional. You only need it if you’re working with preview APIs. Don’t install it unless you have a specific reason.
Interactive Authentication (The Quick Way)
This is what you use when you’re sitting at your desk running commands manually:
Connect-MgGraph -Scopes "User.Read.All","Group.Read.All" A browser window opens. You sign in with your admin account. You consent to the scopes. You’re connected.
What are scopes? Scopes define what your session is allowed to do. Think of them as permissions for this specific connection. Some common ones:
| Task | Scopes You Need |
|---|---|
| Read user profiles | User.Read.All |
| Manage users (create, update, delete) | User.ReadWrite.All |
| Read groups | Group.Read.All |
| Manage groups | Group.ReadWrite.All |
| Read directory info | Directory.Read.All |
| Manage devices | Device.ReadWrite.All |
| Read audit logs | AuditLog.Read.All |
| Manage Conditional Access | Policy.ReadWrite.ConditionalAccess |
| Full admin (use sparingly) | Directory.ReadWrite.All |
You can specify multiple scopes separated by commas. If you realize mid-session that you need additional scopes, just run Connect-MgGraph again with the new scopes — it’ll prompt you to consent to the additional permissions without disconnecting your existing session.
If you’re a Global Admin, the consent prompt is straightforward. If you’re not, your admin may need to grant admin consent for the scopes you’re requesting. This is configured per-app in the Entra admin center under Enterprise applications > Microsoft Graph Command Line Tools > Permissions.
To verify what you’re connected as and which scopes are active:
Get-MgContext This shows your account, tenant ID, scopes, and authentication type. Run this after connecting to confirm you’re where you think you are.
Certificate-Based Authentication (For Automation)
Interactive auth doesn’t work for scheduled tasks, Azure Automation runbooks, or any scenario where nobody is sitting at a browser to sign in. For that, you need an app registration with a certificate.
Step 1: Create an App Registration
In the Entra admin center (or Azure portal):
- Go to Identity > Applications > App registrations > New registration
- Name it something descriptive (e.g., “Graph PowerShell Automation - User Reports”)
- Set supported account types to Single tenant
- Click Register
- Note the Application (client) ID and Directory (tenant) ID — you need both
Step 2: Add API Permissions
In the app registration:
- Go to API permissions > Add a permission > Microsoft Graph > Application permissions
- Add the permissions your script needs (e.g.,
User.Read.All,Group.Read.All) - Click Grant admin consent — application permissions always require admin consent
Important distinction: When you connect interactively, you use delegated permissions — actions are performed as you, limited by your own access. When you connect with a certificate, you use application permissions — the app acts as itself with whatever permissions you granted it. Application permissions tend to be broader, so only grant what the script actually needs.
Step 3: Create and Upload a Certificate
Generate a self-signed certificate:
$cert = New-SelfSignedCertificate -Subject "CN=GraphAutomation" `
-CertStoreLocation "Cert:CurrentUserMy" `
-KeyExportPolicy Exportable `
-KeySpec Signature `
-KeyLength 2048 `
-NotAfter (Get-Date).AddYears(2)
Export-Certificate -Cert $cert -FilePath ".GraphAutomation.cer" Upload the .cer file to your app registration under Certificates & secrets > Certificates > Upload certificate.
Step 4: Connect
Connect-MgGraph -ClientId "your-app-id" `
-TenantId "your-tenant-id" `
-CertificateThumbprint $cert.Thumbprint No browser prompt. No interactive sign-in. The certificate authenticates the app directly.
For Azure Automation runbooks, store the certificate in the Automation Account’s certificate store and reference the thumbprint in your runbook. For scheduled tasks on a server, the certificate needs to be in the local machine’s certificate store.
Client Secret Authentication (Not Recommended)
You can also authenticate with a client secret instead of a certificate:
$clientSecret = ConvertTo-SecureString "your-secret-value" -AsPlainText -Force
$credential = New-Object System.Management.Automation.PSCredential("your-app-id", $clientSecret)
Connect-MgGraph -ClientSecretCredential $credential -TenantId "your-tenant-id" This works, but certificates are strictly better for security. Secrets are strings that can be leaked in logs, scripts, or source control. Certificates are cryptographic — the private key never leaves the machine. If you’re in a compliance environment (CMMC, FedRAMP, SOC 2), use certificates.
Managed Identity Authentication (Azure Only)
If your script runs in Azure (Automation Account, Azure Function, Azure VM), managed identities are the cleanest option — no certificates or secrets to manage at all:
Connect-MgGraph -Identity That’s it. Azure handles the authentication transparently. The managed identity needs the appropriate Graph API permissions assigned via PowerShell or the Azure CLI — you can’t assign them through the portal for managed identities:
# Assign Graph permissions to a managed identity
$managedIdentityId = "your-managed-identity-object-id"
$graphAppId = "00000003-0000-0000-c000-000000000000"
$graphSP = Get-MgServicePrincipal -Filter "appId eq '$graphAppId'"
$permission = $graphSP.AppRoles | Where-Object { $_.Value -eq "User.Read.All" }
New-MgServicePrincipalAppRoleAssignment -ServicePrincipalId $managedIdentityId `
-PrincipalId $managedIdentityId `
-ResourceId $graphSP.Id `
-AppRoleId $permission.Id If You’re in GCC High
Everything above works in GCC High with one critical addition: you must specify the environment.
Interactive in GCC High
Connect-MgGraph -Environment USGov -Scopes "User.Read.All" Without -Environment USGov, the module tries to authenticate against the commercial endpoint (login.microsoftonline.com). Your GCC High credentials won’t work there. You’ll get an error that looks like an auth failure when it’s really just pointing at the wrong cloud.
Certificate-Based in GCC High
Connect-MgGraph -ClientId "your-app-id" `
-TenantId "your-tenant-id" `
-CertificateThumbprint "your-thumbprint" `
-Environment USGov Managed Identity in GCC High
Connect-MgGraph -Identity -Environment USGov What -Environment USGov Actually Changes
When you set the environment to USGov, the SDK switches all its endpoints:
| Commercial | GCC High (USGov) | |
|---|---|---|
| Authentication | login.microsoftonline.com | login.microsoftonline.us |
| Graph API | graph.microsoft.com | graph.microsoft.us |
| Portal | entra.microsoft.com | entra.microsoft.us |
This matters beyond just connecting. If your script constructs any URLs manually — for example, building a direct link to a user’s profile or a sign-in log — those URLs need to use the .us domain in GCC High. The SDK handles the API calls automatically, but anything you build yourself needs to match.
App Registrations in GCC High
When you create the app registration for certificate-based auth, you create it in the Azure Government portal (portal.azure.us), not the commercial portal. The app registration process is identical, but the endpoints it generates will use the government cloud. If you accidentally create the app in the commercial portal, authentication will fail — the app exists in a different cloud than your tenant.
GCC High-Specific Gotchas
The -Environment values aren’t obvious. Here’s the full list:
| Cloud | -Environment Value |
|---|---|
| Commercial | Global (default) |
| GCC | Global (same as commercial for Graph) |
| GCC High | USGov |
| DoD | USGovDoD |
| China (21Vianet) | China |
GCC uses the same Graph endpoint as commercial — only the tenant-level configurations differ. GCC High and DoD use completely separate endpoints. This confuses people because the naming isn’t consistent with other Microsoft PowerShell modules.
Some Graph API features ship to commercial before GCC High. If a cmdlet works in your test tenant (commercial) but fails in GCC High, check the Microsoft 365 roadmap for government cloud availability. The error message usually won’t tell you the feature isn’t available yet — it’ll give you a generic permissions or “resource not found” error.
Beta module endpoints also differ. If you’re using Microsoft.Graph.Beta, the environment flag works the same way, but be aware that beta APIs in GCC High have even larger availability gaps than the v1.0 APIs.
Common Errors and Fixes
“Insufficient privileges to complete the operation”
You have the scopes, but your account doesn’t have the Entra role to consent. A Global Admin needs to consent to the scopes first, or you need to use an app registration with pre-consented application permissions.
“AADSTS700016: Application with identifier ‘xxx’ was not found”
Your app registration doesn’t exist in the tenant you’re connecting to. In GCC High, this almost always means you created the app in the commercial portal instead of the government portal. Verify the app exists at portal.azure.us.
“Connect-MgGraph: The term ‘Connect-MgGraph’ is not recognized”
The module isn’t installed or isn’t imported. Run Install-Module Microsoft.Graph.Authentication -Scope CurrentUser and try again. If it’s installed but not recognized, check for PowerShell version conflicts — the Graph SDK requires PowerShell 5.1 or later (7.x recommended).
“The remote server returned an error: (403) Forbidden”
You’re connected but the specific operation requires a scope or role you don’t have. Run Get-MgContext to see your current scopes. If the scope is there, the issue is likely an Entra role limitation — some operations require Directory roles regardless of Graph scopes.
“Unable to resolve host ‘graph.microsoft.us’”
Network issue. Your machine can’t reach the GCC High Graph endpoint. Check your firewall rules, DNS resolution, and proxy settings. Government endpoints use different IP ranges than commercial — your network team may need to allowlist them.
Disconnecting
When you’re done:
Disconnect-MgGraph This clears your session tokens. If you’re running automated scripts, disconnect at the end to avoid leaving authenticated sessions open.
Which Method Should You Use?
| Scenario | Method | Why |
|---|---|---|
| Ad-hoc admin tasks at your desk | Interactive (-Scopes) | Simple, uses your identity |
| Scheduled scripts on a server | Certificate-based | No secrets to leak, no human needed |
| Azure Automation / Functions | Managed Identity | Zero credential management |
| Quick one-off in a pinch | Client secret | Works but replace with cert ASAP |
If you’re in GCC High, add -Environment USGov to every single one of these. Consider setting it as a default in your PowerShell profile so you never forget:
# Add to your PowerShell profile ($PROFILE)
$PSDefaultParameterValues['Connect-MgGraph:Environment'] = 'USGov' Now every Connect-MgGraph call in that shell session will default to GCC High without you having to specify it.
Verifying Your Tenant’s Cloud Environment
Not sure if your organization is in Commercial, GCC, or GCC High? Use our free Azure Tenant ID Lookup tool — it’s the only tool that identifies which Microsoft cloud environment a tenant belongs to. Enter your domain or tenant ID and you’ll see immediately whether you need the -Environment USGov flag.
Need help connecting Microsoft Graph to GCC High, building automation scripts for your government tenant, or migrating to GCC High in the first place? That’s what we do. Whether it’s GCC High migration, PowerShell automation, or managing the whole stack, we work in government cloud environments every day.