How to use the Microsoft Graph PowerShell SDK

The Microsoft Graph PowerShell SDK

Today I want to talk about how to use the Microsoft Graph PowerShell SDK. By now, you may know that you can use PowerShell to connect to Microsoft Graph for managing many aspects of Azure AD, Intune and other Azure services. You may not know how to get started. Don’t worry! I didn’t either. We can go through this together and then we can start to learn more about using PowerShell to connect to MS Graph.

I like the idea of this for several reasons. First, Microsoft plans to deprecate older methods of access. So if you have been using the Azure AD PowerShell module, it will be going away. Maintaining access is obviously important. Second, it starts to open up a wider world of access as you now can reach more through a single API and with a single PowerShell module. Finally, long term it should allow for more automation and better tools for managing specific aspects of what is increasingly becoming a cloud oriented environment. Lets check it out and see what we can make happen.

DISCLAIMER

Please understand that the content herein is for informational purposes only. This existence and contents shall not create an obligation, liability or suggest a consultancy relationship. In further, such shall be considered as is without any express or implied warranties including, but not limited to express and implied warranties of merchantability, fitness for a particular purpose and non-infringement. There is no commitment about the content within the services that the specific functions of the services or its reliability, applicability or ability to meet your needs, whether unique or standard. Please be sure to test this process fully before deploying in ANY production capacity, and ensure you understand that you are doing so at your own risk.

Table Of Contents

Install MS Graph PowerShell Module
Configure App Registration in Azure AD
Build Sample PowerShell Script
Update Existing PowerShell Script
Conclusion

Thoughts before we Start

You can find Microsoft’s official documentation on this process HERE. However, we will also cover the entire in this post. One thing to note is that Microsoft has set this up (at least in the tutorial) as being more of an ‘ad-hoc’ type process where you get connected and then run your queries in PowerShell. This is certainly fine, but in the long term, it will take more consideration to your processes if you plan to use this in automation or scheduled tasks. It can be very powerful (nearly everything is reachable through Graph), but that also means it can be difficult to use. Stick in there, and follow along as we learn the nuances together.

Free Azure Tenant Access

The first place we will be starting with PowerShell for MS Graph, will be in Azure AD. If you just want to follow along and figure out the basics, check out signing up for a free Developer Account with Microsoft. This will give you access to a Sandbox environment for 90 days, fully licensed with users, sample data and access to all things Azure. Just keep in mind that after the 90 days is over, the entire environment is deleted. So be sure to export those JSON files and anything you configure if you want to be able to recreate it quickly.

Install the Microsoft Graph PowerShell SDK

To start off, we will be installing the Microsoft Graph PowerShell SDK. This is a straightforward installation, but it needs to happen before you attempt to run anything connecting to MS Graph. Also this is a longer installation compared to most PowerShell modules, so grab a cup of coffee after you run this one.

To Install, run these two lines in a PowerShell window. (This is running for the current user, so no Admin permissions are required). NOTE: Microsoft recommends running this in PowerShell 7. I do as well, and everything I am running in this post is in PowerShell 7. You can get it HERE.

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Install-Module Microsoft.Graph -Scope CurrentUser

Once this completes, you are ready to get started with the MS Graph PowerShell SDK.

Configure App Registration in Azure AD

  1. To get started, log on to portal.azure.com. In the Search bar type “App registrations” and hit enter. Click the icon when it comes up in search.
azure ad app registrations for Microsoft Graph PowerShell
  1. Once on the App registrations page, choose “+ New Registration” to create our app registration. Give the app a name, and Hit Register.
naming our new app registration for Microsoft Graph PowerShell
  1. Now on the overview page for your app, you will want to grab a few things to start. If you haven’t started a new PowerShell file in VS Code yet, now is a good time to do so. Create two variables and call them $client & $tenant (or something similar).
Overview Page for App Registration for Microsoft Graph PowerShell
Overview Page for App Registration

Copy the Application (Client) ID and Directory (Tenant) ID from the App Registration Overview page, into those variables.

powershell script so far
Our PowerShell Script so far

Add Permissions and Grant Consent

  1. Next navigate to the API permissions. For this test, we are going to query for the details of a specific user. For this, we will need the User.Read.All permissions from Microsoft Graph. So click ‘Add a Permission’, and choose Microsoft Graph (Large across the top). From there select Delegated Permissions, and search for User.Read.All. Do the same for Application Permissions. Check the box, and hit ‘Add Permissions’.
adding api permissions in Azure app registration for Microsoft Graph PowerShell
  1. You’ll notice that there is a message about giving consent on behalf of the organization. Only Global Administrators can perform this function, and it is required for you to be able to use the app this way. Ours is a test tenant, and so hit the Grant Consent button, and confirm you are sure you want to grant consent. It should then look like this.
Microsoft Graph PowerShell application permissions

Create a Self-Signed Certificate

For this next step we will need to create a Self-Signed certificate. Microsoft recommends NOT using a Self-signed certificate for production use, and to use it for development only. If you were trying to implement something in a production environment, you’ll want to look into using PKI or something along those lines. Technically, you will only need the certificate with app-auth type scripting as you can use the web sign in process for Delegated scripting. In this case, we will make a certificate to make it easier and prepare for automation later.

  1. Use this script below to create a Self-Signed Certificate:
$cert = New-SelfSignedCertificate -Subject "CN=PowerShell App-Only Auth" -CertStoreLocation `
  "Cert:\CurrentUser\My" -KeyExportPolicy Exportable -KeySpec Signature -KeyLength 2048 `
  -KeyAlgorithm RSA -HashAlgorithm SHA256
Export-Certificate -Cert $cert -FilePath "C:\Temp\PowerShellAppOnly.cer"
Export the self-signed certificate
  1. Now, we want to upload the Certificate to out app registration in Azure. Click on the Certificates and Secrets tab, choose Certificates, and hit Upload. Navigate to C:\Temp\ to get the certificate we created. Give it a description and hit OK to upload.
upload certificate for authentication for Microsoft Graph PowerShell
  1. Next, we will need to update out script. Next you need to add a line to include the certificate thumbprint we just created. You can get the thumbprint from the manifest. It will be labeled “customKeyIdentifier“.
manifest for the Microsoft Graph PowerShell app registration
  1. Out new line of code will look like this:
$Certificate = Get-ChildItem Cert:\CurrentUser\My\{thumbprint}
  1. And now our script looks like this:
Script details for authentication
  1. And if we hit Play on our script to run it, we get greeted with the “Welcome to Microsoft Graph!”. Now we know we are connected.

Build a Sample Script

Now that we are connected, lets run some tests. Since I created a Dev instance for this, we should have out 25 sample users included. If not, then you will want to add at least one single user to know for sure that you are pulling back the correct information. Try this to see what comes back.

#Details to get you connected to Azure Tenant
$client = 'ba2cd202-0aac-4385-a7c1-29ce37b16f12'
$tenant = '6d6501e8-d240-497a-bd5b-b441929aac20'
$Certificate = Get-ChildItem Cert:\CurrentUser\My\512AB3B8F5127336AD34E46F8C6C963CD7801FE5
Connect-Graph -TenantId $tenant -AppId $client -Certificate $Certificate

#test our script to see what comes back
Get-MgUser

Upon running this in my Dev tenant, I get this information below.

test output for our Microsoft Graph PowerShell query

As long as you get something back (assuming you have at least one user) you have successfully connected!

Congrats!

Modify an Old Script to use Graph

You may or may not be familiar with one of the original scripts on my blog. In this one, I import a CSV file, and add those users to an Azure AD group. Lets modify that one to use Graph.

  1. First I need to change the permissions of the app registrations. In the API permissions, lets add Group.ReadWrite.All & GroupMember.ReadWrite.All under the Application permissions. You will need to Grant consent to the new permissions for this to work.
add new API permissions to test new script
  1. Next make sure you have a group you can add users to. Whether you create one or grab existing one doesn’t matter, just make sure that it isn’t going to impact anything, as this should be for testing only. I created a group called “PowerShell Group” to make this work.
create a group for testing our new script
  1. Now, you can either create your own CSV to import users, or you can go to the Users section in Portal.azure.com and hit the Download Users button to get a list of everyone. Then we will delete all but 5 that we want to add to our group.
download a sample group of users
  1. Next lets prepare our CSV. If you downloaded a list, you’ll notice it contains every column that the user has. For our script, all we need is the userPrincipalName column. You can delete the rest as it will speed up the import. With my 5 users, it will look like this:
CSV list for userPrincipalName import
  1. If you didn’t already do so, rename the CSV file to AddToGroup.csv (or anything you want, just make a note of the name and change it in the script). Same that CSV file in the C:\Temp directory (or update the script to match your location).
  2. Finally, copy the script here, change your Details to match what we have above, and the be prepared to watch the magic happen.
PowerShell Script

Graph-AddUsersToAzureADGroup.ps1 · SeeSmitty/Powershell (github.com)

#Details to get you connected to Azure Tenant
$client = 'ba2cd202-0aac-4385-a7c1-29ce37b16f12'
$tenant = '6d6501e8-d240-497a-bd5b-b441929aac20'
$Certificate = Get-ChildItem Cert:\CurrentUser\My\512AB3B8F5127336AD34E46F8C6C963CD7801FE5
Connect-Graph -TenantId $tenant -AppId $client -Certificate $Certificate


#import a CSv with the list of users to be added to the group
$users = Import-Csv "C:\temp\AddToGroup.csv"
#Name of the group being added
$group = "PowerShell Group"


#Get the ObjectID for the group in question
$GroupObjectID = Get-MgGroup -Search "DisplayName:$group" -ConsistencyLevel eventual | select-object Id,DisplayName

#Loop to confirm everyone in the list is added to the group
ForEach ($u in $users) {
    $members = Get-MgGroupMember -GroupId $GroupObjectID.Id
    $u2 = Get-MgUser -UserId $u.userPrincipalName | select Id

    #Check if user is a member; add if they are not
    If ($u2.Id -in $members.id) {
        Write-Host $u.userPrincipalName" is already in the group" -ForegroundColor Blue
    }Else{
        New-MgGroupMember -GroupId $GroupObjectID.Id -DirectoryObjectId $u2.Id
        Write-Host $u.userPrincipalName" has been added to the group" -ForegroundColor Green

    }
}

Disconnect-Graph

Your final output should look something like this:

powershell graph output for script

And if you check the group, in Azure you will now see new members in that group.

members now in group via powershell graph

Important Note:

If you get any errors about ‘insufficient permissions‘ AND you confirmed you have the API permissions configured the way I do in this post, then it could be a result of you having chosen ‘Delegated’ permissions instead of ‘Application’. Be sure to check your API permissions and confirm you have set these as ‘Application’ permissions. The application permissions are really intended more for automation or passive execution, avoid the use of Delegated permissions unless you plan to run it manually and sign in each time.

Conclusion

I hope you found this to be informative. I personally am curious to learn more about what is possible with MS Graph via PowerShell. I know many other people have begun to do some great things with it, and I hope to explore it more in depth over time. The goal is to grow into some of the Azure Automation opportunities and find ways to make my job easier! I plan to expand this into the MEMCM realm and find ways to automate more in that arena as well. So stick around as we work together to learn MS Graph in PowerShell. Also don’t worry, I deleted this app registration before I posted anything, so the values are as good as meaningless.

I’m open to feedback, and look forward to hearing what you think about this post. As always, hit me up on Twitter @SeeSmittyIT to let me know what you thought of this post. Thanks for reading!

Smitty

Curtis Smith works in IT with a primary focus on Mobile Device Management, M365 Apps, and Azure AD. He has certifications from CompTIA and Microsoft, and writes as a hobby.

View all posts by Smitty →