{"id":19454144,"url":"https://github.com/21bshwjt/microsoftgraph","last_synced_at":"2026-04-29T08:32:52.030Z","repository":{"id":211058176,"uuid":"728092475","full_name":"21bshwjt/MicrosoftGraph","owner":"21bshwjt","description":"Microsoft Graph API","archived":false,"fork":false,"pushed_at":"2025-01-29T06:00:28.000Z","size":291,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-01-29T06:31:14.029Z","etag":null,"topics":["azure","graphapi","oauth2","powershell","rest-api","serviceprincipal"],"latest_commit_sha":null,"homepage":"","language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/21bshwjt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-12-06T08:02:41.000Z","updated_at":"2025-01-29T06:00:32.000Z","dependencies_parsed_at":"2024-12-31T09:27:48.798Z","dependency_job_id":"16728b06-7564-4727-8d9c-df1852ba4042","html_url":"https://github.com/21bshwjt/MicrosoftGraph","commit_stats":null,"previous_names":["21bshwjt/microsoftgraph"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/21bshwjt%2FMicrosoftGraph","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/21bshwjt%2FMicrosoftGraph/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/21bshwjt%2FMicrosoftGraph/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/21bshwjt%2FMicrosoftGraph/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/21bshwjt","download_url":"https://codeload.github.com/21bshwjt/MicrosoftGraph/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":240645844,"owners_count":19834493,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["azure","graphapi","oauth2","powershell","rest-api","serviceprincipal"],"created_at":"2024-11-10T17:08:09.149Z","updated_at":"2026-04-29T08:32:52.022Z","avatar_url":"https://github.com/21bshwjt.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Microsoft Graph API\n[Microsoft Graph](https://developer.microsoft.com/en-us/graph/graph-explorer)  or  [https://aka.ms/ge](https://aka.ms/ge)  or  [https://ge.cmd.ms/](https://ge.cmd.ms/)\n\n### Graph Explorer\n\n```powershell\n# Default Query\nhttps://graph.microsoft.com/v1.0/me\n\n# Filtered Attributes\nhttps://graph.microsoft.com/v1.0/me?$select=id,userPrincipalName\n\n# User.Read.All - Permission is needed to run the below query\nhttps://graph.microsoft.com/v1.0/users?$select=id,userPrincipalName\n\n# Get Top three users\nhttps://graph.microsoft.com/v1.0/users?$top=3\u0026$select=id,userPrincipalName\n```\n\n### Retrieve users from the Microsoft Graph API using a User account (Tested with Global Admin)\n\n```powershell\n$url = \"https://graph.microsoft.com/v1.0/users\"\n$token = \"*************************************\"\n$header = @{Authorization = \"Bearer $token\"}\ninvoke-RestMethod -uri $url -Headers $header\n$result =invoke-RestMethod -uri $url -Headers $header\n$result.value\n$result.value | Measure-Object\n$result.value | Select-Object id,userPrincipalName\n```\n\n### Retrieve AAD users \u0026 Azure resources from the Microsoft Graph API using an Azure Service Principal\n\n\u003cimg src=\"https://github.com/21bshwjt/MicrosoftGraph/blob/main/Screenshots/perms.png?raw=true\" width=\"800\" height=\"320\"\u003e\n\n#### Above permissions are needed for that Application to work all the scripts mentioned here.\n- [**scope**](https://graph.microsoft.com/.default) uri is needed to query the AAD users \u0026 [**resource**](https://management.core.windows.net) uri is needed to query the AZ resources.\n- Authorization endpoint is not needed when \"**grant_type**\" is  \"**client_credentials**\". The token endpoint is only needed. **Token type: Access_Token**\n- Token Endpoint (V1) : [https://login.microsoftonline.com/\u003ctenant_Id\u003e/oauth2/token](https://login.microsoftonline.com/\u003ctenant_Id\u003e/oauth2/token) - Use that for Azure Resouces\n- Token Endpoint (V2) : [https://login.microsoftonline.com/\u003ctenant_Id\u003e/oauth2/v2.0/token](https://login.microsoftonline.com/\u003ctenant_Id\u003e/oauth2/v2.0/token) - Use that for Entra ID\n\n```powershell\n\u003c##\n.Description\nRetrieve users from the Microsoft Graph API using an Azure Service Principal\n\nSource: https://github.com/goodworkaround/bluescreen_scripts/blob/main/Working%20with%20the%20Microsoft%20Graph%20from%20PowerShell/get-access-token-manual.ps1\nhttps://github.com/goodworkaround/bluescreen_scripts/blob/main/Working%20with%20the%20Microsoft%20Graph%20from%20PowerShell/get-access-token-sdk.ps1\nhttps://github.com/BohrenAn/GitHub_PowerShellScripts/blob/main/AzureAD/CreateAADApp-MgGraph.ps1\n##\u003e\n\n# Define variables\n$tenantId = \"*********************\"\n$clientId = \"*********************\"\n$clientSecret = \"*****************\"\n\n# Define API endpoint and parameters\n$tokenEndpoint = \"https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token\"\n$tokenParams = @{\n    grant_type    = \"client_credentials\"\n    client_id     = $clientId\n    client_secret = $clientSecret\n    scope         = \"https://graph.microsoft.com/.default\"\n}\n\n# Get access token\n$accessToken = Invoke-RestMethod -Method Post -Uri $tokenEndpoint -Body $tokenParams\n\n# Output access token\n#Write-Output $accessToken.access_token\n\n$result = Invoke-RestMethod \"https://graph.microsoft.com/v1.0/users\" -Headers @{Authorization = \"Bearer $($accessToken.access_token)\"}\n$result.value | Measure-Object\n$result.value | Select-Object id,userPrincipalName\n```\n\n### Microsoft Azure REST API's using Client credential flow\n\n```powershell\n# Microsoft Azure REST API's using Client credential flow\nConnect-AzAccount -Identity\n$tenantid = Get-AzKeyVaultSecret -VaultName \"\u003cKeyVault\u003e\" -Name \"\u003ctenantId_Seceret\u003e\" -AsPlainText\n$openid = Invoke-RestMethod -Uri \"https://login.microsoftonline.com/$tenantid/.well-known/openid-configuration\"\n$tokenendpoint = $openid.token_endpoint\n\n$body = @{\n    grant_type    = \"client_credentials\"\n    client_id     = \"\u003cClient_Id\u003e\"\n    client_secret = \"\u003cClient_Secret\u003e\"\n    redirect_uri = \"https://localhost\"\n    resource = \"https://management.core.windows.net\"\n    tenant = \"\u003cDomainname.com\u003e\" # optional\n    \n}\n\n$token = Invoke-RestMethod -Uri $tokenendpoint -Body $body -Method Post\n$access_token = $token.access_token\n\n$url = \"https://management.azure.com/subscriptions/\u003cSubscription_id\u003e/resources?api-version=2021-04-01\"\n$az_resources = Invoke-RestMethod $url -Headers @{Authorization = \"Bearer $($access_token)\"} -Method Get\n```\n\n### Retrieve AAD Users from the Microsoft Graph PowerShell using System Assigned Managed Identity(MSI) \u0026 KeyVault\n\n```powershell\n#Script is tested from Azure Automation Account \u0026 Azure VM\n#Requires -Module @{ ModuleName = 'Az.Accounts'; ModuleVersion = '2.13.2' }\n#Requires -Module @{ ModuleName = 'Az.KeyVault'; ModuleVersion = '5.0.1' }\n#Requires -Module @{ ModuleName = 'Microsoft.Graph.Authentication'; ModuleVersion = '2.10.0' }\n#Requires -Module @{ ModuleName = 'Microsoft.Graph.Users'; ModuleVersion = '2.10.0' }\nConnect-AzAccount -Identity\n$ApplicationId = Get-AzKeyVaultSecret -VaultName \"\u003cYour_KeyVault\u003e\" -Name \"\u003cClientId_Secret\u003e\" -AsPlainText\n$SecuredPassword = Get-AzKeyVaultSecret -VaultName \"\u003cYour_KeyVault\u003e\" -Name \"\u003cClient_Secret\u003e\" -AsPlainText\n$tenantID = Get-AzKeyVaultSecret -VaultName \"\u003cYour_KeyVault\u003e\" -Name \"\u003cTenantID_Secret\u003e\" -AsPlainText\n\n$SecuredPasswordPassword = ConvertTo-SecureString -String $SecuredPassword -AsPlainText -Force\n$ClientSecretCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList `\n$ApplicationId, $SecuredPasswordPassword\nConnect-MgGraph -TenantId $tenantID -ClientSecretCredential $ClientSecretCredential -NoWelcome\nGet-MgUser | Select-Object DisplayName, Id, UserPrincipalName\n```\n\n### Graph SDK - Certificate based authentication using Service principle name\n\n```powershell\n# Permissions are needed as per the above screenshot. \n$client_id = \"*****************\"\n$tenant_id = \"********************\"\n$thumb_print = (Get-ChildItem \"Cert:\\LocalMachine\\my\" | Where-Object { $_.Subject -eq \"CN=*******\" }).Thumbprint\n\nConnect-MgGraph -ClientId $client_id -TenantId $tenant_id -CertificateThumbprint $thumb_print\n\n$result = Invoke-MgGraphRequest -Method GET -Uri \"https://graph.microsoft.com/v1.0/users\"\n$result.value\n$result.value | Select-Object id,displayName,userPrincipalName\n```\n\n### Create an Azure Application using Graph API\n\n```powershell\n# 'Application.ReadWrite.OwnedBy' - Permission is required\n$client_id = \"*****************\"\n$tenant_id = \"********************\"\n$thumb_print = (Get-ChildItem \"Cert:\\LocalMachine\\my\" | Where-Object { $_.Subject -eq \"CN=*******\" }).Thumbprint\nConnect-MgGraph -ClientId $client_id -TenantId $tenant_id -CertificateThumbprint $thumb_print\nNew-MgApplication -DisplayName \u003cMy_New_App1\u003e\n```\n\n### Get AAD Users from Azure Automation PowerShell RunBook\n```powershell\n# Get the Azure Automation connection object\n$connection = Get-AutomationConnection -Name \"\u003cAzure_SPI\u003e\"\n\n# Connect to Azure using the connection object\nTry {\n    Connect-MgGraph -ClientId $connection.ApplicationID `\n        -TenantId $connection.TenantID `\n        -CertificateThumbprint $connection.CertificateThumbprint\n}    \ncatch {\n    Write-Error -Message $_.Exception\n    throw $_.Exception\n}\n# Set the subscription context\nSet-AzContext -SubscriptionId \"\u003cSub_Id\u003e\" | Out-Null\nConnect-MgGraph -ClientId $client_id -TenantId $tenant_id -CertificateThumbprint $thumb_print -NoWelcome\n$result = Invoke-MgGraphRequest -Method GET -Uri \"https://graph.microsoft.com/v1.0/users\"\n#$result.value\n$result.value | Select-Object id,displayName,userPrincipalName\n```\n### Get Tenant Creation Date Using Postman\n- API : https://graph.microsoft.com/v1.0/organization\n- Access Token URL\n- Client ID\n- Client Secret\n- Scope : https://graph.microsoft.com/.default\n- Client Authentication:  Send as Basic Auth Header\n- Attribute : **createdDateTime**\n\n### Get Tenant Creation Date Using PowerShell\n\n```powershell\n# MSFT Graph API : https://learn.microsoft.com/en-us/graph/api/organization-list?view=graph-rest-1.0\u0026tabs=http\n# Define variables\n$tenantId = \"************************\"\n$clientId = \"************************\"\n$clientSecret = \"************************\"\n\n# Define API endpoint and parameters\n$tokenEndpoint = \"https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token\"\n$tokenParams = @{\n    grant_type    = \"client_credentials\"\n    client_id     = $clientId\n    client_secret = $clientSecret\n    scope         = \"https://graph.microsoft.com/.default\"\n}\n\n# Get access token\n$accessToken = Invoke-RestMethod -Method Post -Uri $tokenEndpoint -Body $tokenParams\n\n# Output access token\n#Write-Output $accessToken.access_token\n\n$result = Invoke-RestMethod \"https://graph.microsoft.com/v1.0/organization\" -Headers @{Authorization = \"Bearer $($accessToken.access_token)\" }\n\n[PSCustomObject]@{\n    TenantCreationDate         = $($result.value.createdDateTime)\n    CustomDomain               = $($result.value.verifiedDomains.Name)\n    onPremisesSyncEnabled      = $($result.value.onPremisesSyncEnabled)\n    onPremisesLastSyncDateTime = $($result.value.onPremisesLastSyncDateTime)  \n    countryCode                = $($result.value.countryLetterCode)\n}\n\n```\n\n#### Output\n\u003cimg src=\"https://github.com/21bshwjt/MicrosoftGraph/blob/main/Screenshots/customdomain.png?raw=true\" width=\"800\" height=\"125\"\u003e\n\n### Authentication using SPN \u0026 Certificate \n```powershell\nfunction New-JwtToken {\n    param (\n        [Parameter(Mandatory = $true)]\n        [System.Security.Cryptography.X509Certificates.X509Certificate2]$Certificate,\n        \n        [Parameter(Mandatory = $true)]\n        [string]$ClientId,\n        \n        [Parameter(Mandatory = $true)]\n        [string]$TenantId\n    )\n\n    $header = @{\n        alg = \"RS256\"\n        typ = \"JWT\"\n        x5t = [System.Convert]::ToBase64String($Certificate.GetCertHash())\n    }\n\n    $claims = @{\n        aud = \"https://login.microsoftonline.com/$TenantId/oauth2/v2.0/token\"\n        iss = $ClientId\n        sub = $ClientId\n        jti = [System.Guid]::NewGuid().ToString()\n        exp = [System.DateTimeOffset]::UtcNow.ToUnixTimeSeconds() + 3600\n        nbf = [System.DateTimeOffset]::UtcNow.ToUnixTimeSeconds()\n    }\n\n    $encodedHeader = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $header -Compress)))\n    $encodedClaims = [System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes((ConvertTo-Json $claims -Compress)))\n    $unsignedToken = \"$encodedHeader.$encodedClaims\"\n    \n    $rsaProvider = [System.Security.Cryptography.X509Certificates.RSACertificateExtensions]::GetRSAPrivateKey($Certificate)\n    $signatureBytes = $rsaProvider.SignData([System.Text.Encoding]::UTF8.GetBytes($unsignedToken), [System.Security.Cryptography.HashAlgorithmName]::SHA256, [System.Security.Cryptography.RSASignaturePadding]::Pkcs1)\n    $signature = [System.Convert]::ToBase64String($signatureBytes)\n    \n    return \"$unsignedToken.$signature\"\n}\n# Enter Your TenantID, ClientID \u0026 Thumbprint\n$tenantId = \"\"\n$clientId = \"\"\n$certificateThumbprint = \"\"\n\n# Define API endpoint and parameters\n$tokenEndpoint = \"https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token\"\n$tokenParams = @{\n    grant_type = \"client_credentials\"\n    client_id  = $clientId\n    scope      = \"https://graph.microsoft.com/.default\"\n}\n\n# Get the certificate\n$cert = Get-Item -Path \"Cert:\\LocalMachine\\My\\$certificateThumbprint\"\n\n# Get access token\n$tokenParams[\"client_assertion\"] = New-JwtToken -Certificate $cert -ClientId $clientId -TenantId $tenantId\n$tokenParams[\"client_assertion_type\"] = \"urn:ietf:params:oauth:client-assertion-type:jwt-bearer\"\n\n$accessToken = Invoke-RestMethod -Method Post -Uri $tokenEndpoint -Body $tokenParams\n\n# Output access token\nWrite-Output $accessToken.access_token\n\nInvoke-RestMethod \"https://graph.microsoft.com/v1.0/users\" -Headers @{Authorization = \"Bearer $($accessToken.access_token)\" }\n```\n### Multi-Tenant Organization (B2B)\n```powershell\n# 38. Multi Tenant Org. \u0026 B2B Partners\n#region Authentication \u0026 Authorization\n$Token = \"*******************\"\n#endregion\n\n#region Generic Variables\n$BaseApi = 'https://graph.microsoft.com'\n$ApiVersion = 'v1.0'\n$Endpoint = '/policies/crossTenantAccessPolicy/partners'\n\n$Uri = \"{0}/{1}{2}\" -f $BaseApi, $ApiVersion, $Endpoint\n\n$Headers = @{\n    'Authorization' = \"Bearer $Token\"\n    'Content-Type'  = 'application/json'\n}\n\n$RequestProperties = @{\n    Uri     = $Uri\n    Method  = 'GET'\n    Headers = $Headers\n}\n#endregion\n\n#region Get Partner Info\ntry {\n    $Get_Partners = Invoke-RestMethod @RequestProperties\n    $RawResults = $Get_Partners.value\n}\ncatch {\n    Write-Error \"Failed to retrieve B2B partner data: $_\"\n    return\n}\n\n# Flatten the results\n$HTMLResult = foreach ($partner in $RawResults) {\n    [PSCustomObject]@{\n        Partner_TenantId               = $partner.tenantId\n        IsServiceProvider              = $partner.isServiceProvider\n        IsInMultiTenantOrganization    = $partner.isInMultiTenantOrganization\n\n        # Consent\n        Consent_InboundAllowed         = $partner.automaticUserConsentSettings?.inboundAllowed\n        Consent_OutboundAllowed        = $partner.automaticUserConsentSettings?.outboundAllowed\n\n        # Inbound Trust\n        TrustMFA                       = $partner.inboundTrust?.isMfaAccepted\n        TrustCompliantDevice           = $partner.inboundTrust?.isCompliantDeviceAccepted\n        TrustHybridJoinedDevice        = $partner.inboundTrust?.isHybridAzureADJoinedDeviceAccepted\n\n        # B2B Inbound Collaboration\n        B2BInbound_AllowApps           = ($partner.b2bCollaborationInbound?.accessSettings?.application?.targets | ForEach-Object { $_.target }) -join ', '\n        B2BInbound_BlockApps           = ($partner.b2bCollaborationInbound?.accessSettings?.application?.exclusions | ForEach-Object { $_.target }) -join ', '\n\n        # B2B Outbound Collaboration\n        B2BOutbound_AllowApps          = ($partner.b2bCollaborationOutbound?.accessSettings?.application?.targets | ForEach-Object { $_.target }) -join ', '\n        B2BOutbound_BlockApps          = ($partner.b2bCollaborationOutbound?.accessSettings?.application?.exclusions | ForEach-Object { $_.target }) -join ', '\n\n        # Direct Connect\n        DirectConnect_Inbound_Enabled  = $partner.b2bDirectConnectInbound?.isEnabled\n        DirectConnect_Outbound_Enabled = $partner.b2bDirectConnectOutbound?.isEnabled\n\n\n    }\n}\n#endregion\n\n#region HTML \u0026 Excel Output\n$Ps1FileName = $($MyInvocation.MyCommand.Name)\n$DirName = ($Ps1FileName -split \"_\")[0]\n$HtmFileName = [System.IO.Path]::GetFileNameWithoutExtension($MyInvocation.MyCommand.Name)\n\n# Ensure output directory exists\n$OutputDir = \".\\Output\\$DirName\"\nif (!(Test-Path $OutputDir)) {\n    [void](New-Item -ItemType Directory -Path $OutputDir -Force)\n}\n\n# Set title from comment\n$FirstLine = Get-Content $MyInvocation.MyCommand.Path | Select-Object -First 1\n$Title = $FirstLine -replace '^#\\s*\\d+\\.\\s*', ''\n$date = (Get-Date).ToString('MM-dd-yyyy')\n$headertxt = \"\u003cH2\u003e\u003cCenter\u003e$Title | $date \u003c/Center\u003e\u003c/H2\u003e\"\n\n# Generate HTML Report\nNew-HTML -TitleText $Title {\n    New-HTMLContent -HeaderText \"\u003ccenter\u003e$headertxt\u003c/center\u003e\" {\n        New-HTMLTable -Title $Title -DataTable $HTMLResult -HideFooter -PagingOptions @(100, 200, 300) {\n        }\n    }\n} -FilePath \"$OutputDir\\$HtmFileName.htm\"\n\n# Export to Excel\nif ($HTMLResult) {\n    $HTMLResult | Export-Excel -Path \".\\Output\\Entra_Posture_Management.xlsx\" -WorksheetName $HtmFileName -AutoSize -TableStyle Medium21\n}\nelse {\n    Write-Host \"No data to export to Excel.\" -ForegroundColor Yellow\n}\n#endregion\n\n```\n### Email via Graph API - App Based Auth\n```powershell\n# Define your app details\n# Mail.Send under \"Application\" type is listed\n$tenantId = \"\" # Your Tenant ID\n$clientId = \"\" # Your Application ID\n$clientSecret = \"\" # App Secret\n$sender = \"\" # Sender Email\n$recipient = \"\" # Recipient Email\n\n# Get a token\n$body = @{\n    grant_type    = \"client_credentials\"\n    scope         = \"https://graph.microsoft.com/.default\"\n    client_id     = $clientId\n    client_secret = $clientSecret\n}\n\n$tokenResponse = Invoke-RestMethod -Method Post -Uri \"https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token\" -Body $body\n$accessToken = $tokenResponse.access_token\n\n# Step 1: Define table data\n$tableData = @(\n    @{ Name = \"Alice Smith\"; Department = \"IT\"; Status = \"Active\" },\n    @{ Name = \"Bob Johnson\"; Department = \"Finance\"; Status = \"Inactive\" },\n    @{ Name = \"Charlie Brown\"; Department = \"HR\"; Status = \"Active\" }\n)\n\n# Step 2: Generate HTML table rows\n$htmlRows = foreach ($row in $tableData) {\n    \"\u003ctr\u003e\u003ctd\u003e$($row.Name)\u003c/td\u003e\u003ctd\u003e$($row.Department)\u003c/td\u003e\u003ctd\u003e$($row.Status)\u003c/td\u003e\u003c/tr\u003e\"\n} -join \"`n\"\n\n# Step 3: Define the main email body with table rows injected\n$emailBody = @{\n    message         = @{\n        subject      = \"📧 Email via Graph API - App Based Auth\"\n        body         = @{\n            contentType = \"HTML\"\n            content     = @\"\n\u003chtml\u003e\n\u003chead\u003e\n  \u003cstyle\u003e\n    body { font-family: Segoe UI, sans-serif; background-color: #f9f9f9; padding: 20px; color: #333; }\n    .container { background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\n    h2 { color: #0078D4; }\n    table { width: 100%; border-collapse: collapse; margin-top: 20px; }\n    th, td { border: 1px solid #ddd; padding: 8px 12px; text-align: left; }\n    th { background-color: #0078D4; color: white; }\n    tr:nth-child(even) { background-color: #f2f2f2; }\n  \u003c/style\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  \u003cdiv class=\"container\"\u003e\n    \u003ch2\u003eHello,\u003c/h2\u003e\n    \u003cp\u003eThis message was sent using \u003cstrong\u003eMicrosoft Graph API\u003c/strong\u003e with \u003cem\u003eapp-only authentication\u003c/em\u003e.\u003c/p\u003e\n\n    \u003ctable\u003e\n      \u003ctr\u003e\n        \u003cth\u003eName\u003c/th\u003e\n        \u003cth\u003eDepartment\u003c/th\u003e\n        \u003cth\u003eStatus\u003c/th\u003e\n      \u003c/tr\u003e\n      $htmlRows\n    \u003c/table\u003e\n\n    \u003cp style=\"margin-top:20px;\"\u003eRegards,\u003cbr/\u003eGraph API Bot\u003c/p\u003e\n  \u003c/div\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n\"@\n        }\n        toRecipients = @(\n            @{\n                emailAddress = @{\n                    address = $recipient\n                }\n            }\n        )\n        from         = @{\n            emailAddress = @{\n                address = $sender\n            }\n        }\n    }\n    saveToSentItems = \"false\"\n} | ConvertTo-Json -Depth 10\n\n\n\n# Send the email\n$response = Invoke-RestMethod -Method POST `\n    -Uri \"https://graph.microsoft.com/v1.0/users/$sender/sendMail\" `\n    -Headers @{ Authorization = \"Bearer $accessToken\" } `\n    -Body $emailBody `\n    -ContentType \"application/json\"\n$response\nWrite-Host \"Email sent successfully.\" -ForegroundColor Green\n\n```\n### Email via Graph API - App Based Auth with Shared Mailbox\n```powershell\n# === CONFIGURE VARIABLES ===\n# Define your app and email details\n$tenantId     = \"\"   # Your tenant ID\n$clientId     = \"\"   # Your application (client) ID\n$clientSecret = \"\"   # Your client secret\n$sender       = \"\"  # The sender's email address (must be a mailbox your app can send as)\n\n# Define recipients\n$recipients = @(\"Email1\", \"Email2\")\n\n# === AUTHENTICATE TO GRAPH ===\n$tokenRequestBody = @{\n    grant_type    = \"client_credentials\"\n    scope         = \"https://graph.microsoft.com/.default\"\n    client_id     = $clientId\n    client_secret = $clientSecret\n}\n$tokenResponse = Invoke-RestMethod -Method Post -Uri \"https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token\" -Body $tokenRequestBody\n$accessToken = $tokenResponse.access_token\n\n# === BUILD HTML TABLE DATA ===\n$tableData = @(\n    @{ Name = \"Alice Smith\"; Department = \"IT\"; Status = \"Active\" },\n    @{ Name = \"Bob Johnson\"; Department = \"Finance\"; Status = \"Inactive\" },\n    @{ Name = \"Charlie Brown\"; Department = \"HR\"; Status = \"Active\" }\n)\n\n$htmlRows = foreach ($row in $tableData) {\n    \"\u003ctr\u003e\u003ctd\u003e$($row.Name)\u003c/td\u003e\u003ctd\u003e$($row.Department)\u003c/td\u003e\u003ctd\u003e$($row.Status)\u003c/td\u003e\u003c/tr\u003e\"\n} -join \"`n\"\n\n# === GENERATE HTML BODY ===\n$htmlBody = @\"\n\u003chtml\u003e\n\u003chead\u003e\n  \u003cstyle\u003e\n    body { font-family: Segoe UI, sans-serif; background-color: #f9f9f9; padding: 20px; color: #333; }\n    .container { background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 2px 4px rgba(0,0,0,0.1); }\n    h2 { color: #0078D4; }\n    table { width: 100%; border-collapse: collapse; margin-top: 20px; }\n    th, td { border: 1px solid #ddd; padding: 8px 12px; text-align: left; }\n    th { background-color: #0078D4; color: white; }\n    tr:nth-child(even) { background-color: #f2f2f2; }\n  \u003c/style\u003e\n\u003c/head\u003e\n\u003cbody\u003e\n  \u003cdiv class=\"container\"\u003e\n    \u003ch2\u003eHello,\u003c/h2\u003e\n    \u003cp\u003eThis email was sent via \u003cstrong\u003eMicrosoft Graph API\u003c/strong\u003e using \u003cem\u003eApp-only authentication\u003c/em\u003e.\u003c/p\u003e\n\n    \u003ctable\u003e\n      \u003ctr\u003e\u003cth\u003eName\u003c/th\u003e\u003cth\u003eDepartment\u003c/th\u003e\u003cth\u003eStatus\u003c/th\u003e\u003c/tr\u003e\n      $htmlRows\n    \u003c/table\u003e\n\n    \u003cp style=\"margin-top:20px;\"\u003eRegards,\u003cbr/\u003eGraph API Bot\u003c/p\u003e\n  \u003c/div\u003e\n\u003c/body\u003e\n\u003c/html\u003e\n\"@\n\n# === BUILD JSON PAYLOAD ===\n$toRecipientsJson = @(\n    foreach ($email in $recipients) {\n        @{\n            emailAddress = @{\n                address = $email\n            }\n        }\n    }\n)\n\n$emailPayload = @{\n    message = @{\n        subject = \"📧 Email from Graph API using App-only Auth\"\n        body = @{\n            contentType = \"HTML\"\n            content = $htmlBody\n        }\n        toRecipients = $toRecipientsJson\n    }\n    saveToSentItems = $false\n} | ConvertTo-Json -Depth 10\n\n# === SEND EMAIL VIA GRAPH API ===\n$response = Invoke-RestMethod -Method POST `\n    -Uri \"https://graph.microsoft.com/v1.0/users/$sender/sendMail\" `\n    -Headers @{ Authorization = \"Bearer $accessToken\" } `\n    -Body $emailPayload `\n    -ContentType \"application/json\"\n$response\n\nWrite-Host \"✅ Email sent successfully.\" -ForegroundColor Green\n\n```\n### Connect-MgGraph With App \u0026 Secret - SDK\n```powershell\n$ApplicationId = \"\"\n$TenantId = \"\"\n$ClientSecret = \"\"\n\n# Secure the Client Secret\n$ClientSecretSecure = $ClientSecret | ConvertTo-SecureString -AsPlainText -Force\n$Credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $ApplicationId, $ClientSecretSecure\n\n# Connect to Microsoft Graph\nConnect-MgGraph -TenantId $TenantId -Credential $Credential\n\n# Validate connection\nGet-MgContext\n```\n### Entra ID - Get Extension Attributes - SDK \n```powershell\n(Get-MgUser -UserId \"UPN\" -Property extension_46a8f918361f4d8fb5e505453a0e21a8_msDS_cloudExtensionAttribute1).AdditionalProperties\n\n# Get only top-level keys (property names)\n$user = Get-MgUser -UserId \"bshwjt@contoso.com\" -Property *\n$user.PSObject.Properties.Name\n```\n### Get onPremisesExtensionAttributes\n```powershell\nhttps://graph.microsoft.com/v1.0/users?$select=displayName,userPrincipalName,mail,jobTitle,department,accountEnabled,userType,createdDateTime,lastModifiedDateTime,telephoneNumber,physicalDeliveryOfficeName,city,state,country,companyName,employeeId,streetAddress,mobilePhone,preferredLanguage,onPremisesSyncEnabled,onPremisesDistinguishedName,onPremisesImmutableId,onPremisesExtensionAttributes\n```\n### Get Custom Attributes\n```powershell\n# Cmdlet: Get-MgDirectoryObjectAvailableExtensionProperty\n#region Authentication \u0026 Authorization\n. \".\\AuthN_AuthZ.ps1\"\n#endregion\n\n#region Generic Variables\n$BaseApi = 'https://graph.microsoft.com'\n$ApiVersion = 'v1.0'\n$Endpoint = \"/directoryObjects/microsoft.graph.getAvailableExtensionProperties\"\n\n$Uri = \"{0}/{1}{2}\" -f $BaseApi, $ApiVersion, $Endpoint\n\n$Headers = @{\n    'Authorization' = 'Bearer ' + $accessToken\n    'Content-Type'  = 'application/json'\n}\n\n# Body is required even if minimal\n$Body = @{\n    isSyncedFromOnPremises = $false  # Set to true if you only want synced extension properties\n} | ConvertTo-Json\n\n$RequestProperties = @{\n    Uri     = $Uri\n    Method  = 'POST'  # Must be POST\n    Headers = $Headers\n    Body    = $Body\n}\n#endregion\n\n#region Invoke-RestMethod\n$Response = Invoke-RestMethod @RequestProperties\n$Response.value.Name | Sort-Object | ForEach-Object {\n    Write-Host $_ -ForegroundColor Magenta\n}\n#endregion\n\n```\n### Evaluate Entra Conditional Access Policy\n```powershell\n# Permissions: Directory.Read.All \u0026 Policy.Read.All\n# KB: https://learn.microsoft.com/en-us/graph/api/conditionalaccessroot-evaluate?view=graph-rest-beta\n# Step 1: Get access token\n$tenantId = \"\"\n$clientId = \"\"\n$clientSecret = \"\"\n\n$userObjectId = \"b23b252e-0f36-4d56-9538-03fcd97e8805\"  # Replace with actual user object ID\n$appObjectId = \"00000003-0000-0000-c000-000000000000\"  # Replace with app's service principal ID (e.g., Graph)\n\n# ========== GET ACCESS TOKEN ==========\n$tokenResponse = Invoke-RestMethod -Method POST -Uri \"https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token\" -Body @{\n    grant_type    = \"client_credentials\"\n    client_id     = $clientId\n    client_secret = $clientSecret\n    scope         = \"https://graph.microsoft.com/.default\"\n}\n$accessToken = $tokenResponse.access_token\n\n# ========== BUILD EVALUATION REQUEST BODY ==========\n$body = @{\n    signInIdentity      = @{\n        \"@odata.type\" = \"#microsoft.graph.userSignIn\"\n        userId        = $userObjectId\n    }\n    signInContext       = @{\n        \"@odata.type\"       = \"#microsoft.graph.applicationContext\"\n        includeApplications = @($appObjectId)\n    }\n    signInConditions    = @{\n        clientAppType   = \"browser\"\n        ipAddress       = \"203.0.113.10\"\n        signInRiskLevel = \"low\"\n        userRiskLevel   = \"none\"\n        devicePlatform  = \"windows\"\n        country         = \"IN\"\n    }\n    appliedPoliciesOnly = $true\n} | ConvertTo-Json -Depth 6\n\n# ========== CALL THE EVALUATE API ==========\n$uri = \"https://graph.microsoft.com/beta/identity/conditionalAccess/evaluate\"\n$response = Invoke-RestMethod -Method POST -Uri $uri -Headers @{\n    Authorization  = \"Bearer $accessToken\"\n    \"Content-Type\" = \"application/json\"\n} -Body $body\n\n# ========== DISPLAY RESULTS ==========\nfunction Show-CAEvaluationResult {\n    param (\n        [Parameter(Mandatory)]\n        $Policy\n    )\n\n    Write-Host \"`n===================================\" -ForegroundColor Cyan\n    Write-Host \"Policy Name:      $($Policy.displayName)\"\n    Write-Host \"Policy Applies:   $($Policy.policyApplies)\"\n    Write-Host \"Analysis Reason:  $($Policy.analysisReasons)\"\n\n    Write-Host \"`n--- Conditions ---\" -ForegroundColor Yellow\n    $c = $Policy.conditions\n    if ($c) {\n        Write-Host \"User Risk Levels:        $($c.userRiskLevels -join ', ')\"\n        Write-Host \"Sign-in Risk Levels:     $($c.signInRiskLevels -join ', ')\"\n        Write-Host \"Client App Types:        $($c.clientAppTypes -join ', ')\"\n        if ($c.platforms) {\n            Write-Host \"Platforms:               $($c.platforms.includePlatforms -join ', ')\"\n        }\n        if ($c.locations) {\n            Write-Host \"Locations:               $($c.locations.includeLocations -join ', ')\"\n        }\n    }\n\n    Write-Host \"`n--- Grant Controls ---\" -ForegroundColor Yellow\n    $g = $Policy.grantControls\n    if ($g) {\n        Write-Host \"Operator:                $($g.operator)\"\n        Write-Host \"Built-in Controls:       $($g.builtInControls -join ', ')\"\n        Write-Host \"Custom Auth Factors:     $($g.customAuthenticationFactors -join ', ')\"\n        Write-Host \"Terms of Use:            $($g.termsOfUse -join ', ')\"\n        if ($g.authenticationStrength) {\n            Write-Host \"Authentication Strength: $($g.authenticationStrength.displayName)\"\n        }\n    }\n\n    Write-Host \"===================================\" -ForegroundColor Cyan\n}\n\n# ========== LOOP THROUGH EACH POLICY ==========\nforeach ($policy in $response.value) {\n    Show-CAEvaluationResult -Policy $policy\n}\n\n```\n### How to find Tenant ID\n```powershell\nInvoke-RestMethod -Uri \"https://odc.officeapps.live.com/odc/v2.1/federationprovider?domain=contoso.com\"\n```\n\n### User Password Reset\n```powershell\n\u003c# \nGraph API Version: v1.0\nPermissions: 'User Administrator' Role \u0026 'User.ReadWrite.All' (SPN Application permission with Admin Consent)\nNote: Not Delegated Permission\nAuthor: \nDate: 22-April-2026\n#\u003e\n\n\u003c#\nReset Password - Single User\n#\u003e\n#region Authentication \u0026 Authorization\n. \".\\AuthN_AuthZ.ps1\"\n#endregion\n\n$userId = \"user@test.onmicrosoft.com\"  # or use Object ID\n$newPassword = \"****\" # Hard coded the password \u0026 tested with 12 charector password\n\n$headers = @{\n    \"Authorization\" = \"Bearer $accessToken\"\n    \"Content-Type\"  = \"application/json\"\n}\n\n$body = @{\n    passwordProfile = @{\n        # Set it to $false if you don't want to force a password change at next logon.\n        forceChangePasswordNextSignIn = $true # or $false\n        password                      = $newPassword\n    }\n} | ConvertTo-Json -Depth 3\n\nInvoke-RestMethod -Method Patch `\n    -Uri \"https://graph.microsoft.com/v1.0/users/$userId\" `\n    -Headers $headers `\n    -Body $body\n```\n\n###  Revoke all active sessions\n```powershell\n###  Revoke all active sessions\n\u003c# \nAuthor: \nDescription: Revoke all active sessions for a single Entra ID user\n#\u003e\n\n#region Authentication\n. \".\\AuthN_AuthZ.ps1\"\n#endregion\n\n# Normalize access token (handle object vs string)\nif ($accessToken -is [System.Management.Automation.PSCustomObject]) {\n    $accessToken = $accessToken.access_token\n}\n\n# Validate Access Token\nif (-not $accessToken -or $accessToken.Split(\".\").Count -ne 3) {\n    throw \"Invalid or missing access token. Check AuthN_AuthZ.ps1\"\n}\n\n# Input\n$userId = \"biswajit@contoso.onmicrosoft.com\"\n\n# Headers\n$headers = @{\n    Authorization = \"Bearer $accessToken\"\n    \"Content-Type\" = \"application/json\"\n}\n\n# Validate user exists\ntry {\n    Invoke-RestMethod -Method GET `\n        -Uri \"https://graph.microsoft.com/v1.0/users/$userId\" `\n        -Headers $headers `\n        -ErrorAction Stop\n}\ncatch {\n    Write-Error \"User not found or not accessible: $userId\"\n    return\n}\n\n# Revoke sessions\ntry {\n    Invoke-RestMethod -Method POST `\n        -Uri \"https://graph.microsoft.com/v1.0/users/$userId/revokeSignInSessions\" `\n        -Headers $headers `\n        -ErrorAction Stop\n\n    Write-Host \"Active sessions revoked successfully for $userId\" -ForegroundColor Green\n}\ncatch {\n    Write-Warning (\"Failed to revoke sessions for {0}. Error: {1}\" -f $userId, $_.Exception.Message)\n\n    if ($_.ErrorDetails.Message) {\n        Write-Host \"Graph Error Details:\" -ForegroundColor Yellow\n        Write-Host $_.ErrorDetails.Message\n    }\n}\n\n```\n### Disable an user\n```powershell\n$Uri = \"https://graph.microsoft.com/v1.0/users/$UserId\"\n\n$Body = @{\n    accountEnabled = $false\n} | ConvertTo-Json\n\nWrite-Host \"Disabling user: $UserId\"\nWrite-Host $Uri\n\ntry {\n    Invoke-RestMethod `\n        -Method PATCH `\n        -Uri $Uri `\n        -Headers $Headers `\n        -Body $Body\n\n    Write-Host \"✅ User disabled successfully\"\n}\ncatch {\n    Write-Host \"❌ Failed to disable user\" -ForegroundColor Red\n    Write-Host $_\n}\n```\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F21bshwjt%2Fmicrosoftgraph","html_url":"https://awesome.ecosyste.ms/projects/github.com%2F21bshwjt%2Fmicrosoftgraph","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2F21bshwjt%2Fmicrosoftgraph/lists"}