{"id":6122,"date":"2021-03-23T07:31:25","date_gmt":"2021-03-23T15:31:25","guid":{"rendered":"https:\/\/officedevblogs.wpengine.com\/?p=6122"},"modified":"2021-03-23T07:31:25","modified_gmt":"2021-03-23T15:31:25","slug":"microsoft-graph-mailbag-getting-started-with-the-microsoft-graph-powershell-sdk","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/microsoft-graph-mailbag-getting-started-with-the-microsoft-graph-powershell-sdk\/","title":{"rendered":"Microsoft Graph Mailbag &#8211; Getting Started with the Microsoft Graph PowerShell SDK"},"content":{"rendered":"<p>In this Microsoft Graph Mailbag blog post, we focus on using the Microsoft Graph API from a system administrator perspective, specifically getting started with the Microsoft Graph PowerShell SDK.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-6131\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image0-1-1024x469.jpg\" alt=\"\" width=\"664\" height=\"304\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image0-1-1024x469.jpg 1024w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image0-1-300x137.jpg 300w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image0-1-768x352.jpg 768w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image0-1-1536x704.jpg 1536w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image0-1.jpg 1676w\" sizes=\"(max-width: 664px) 100vw, 664px\" \/><\/p>\n<p>Please be sure to follow this blog series using <a href=\"https:\/\/aka.ms\/MSGraphMailbag\">https:\/\/aka.ms\/MSGraphMailbag<\/a> or with RSS using <a href=\"https:\/\/developer.microsoft.com\/graph\/blogs\/feed\/?tag=MSGraphMailbag\">https:\/\/developer.microsoft.com\/graph\/blogs\/feed\/?tag=MSGraphMailbag<\/a>.<\/p>\n<h4>Introduction<\/h4>\n<p>As a non-developer, seeing terms like &#8220;API&#8221;, &#8220;REST&#8221;, and &#8220;SDK&#8221; can be a bit intimidating. I want to assure you that knowledge of development and experience working with APIs isn&#8217;t necessary to enjoy the benefits of Microsoft Graph API. With a few new skills, we\u2019ll be building scripts calling Microsoft Graph in no time.<\/p>\n<p>I&#8217;ll be the first to admit I&#8217;m not a developer. As an Exchange engineer, developing applications wasn&#8217;t a core job function. I did realize however, that scripting was a skillset that would make my life easier. Our day-to-day workloads likely include repetitive tasks that many of us have learned to automate using a scripting language like PowerShell. If you\u2019ve already invested the time to learn PowerShell, I will show\u00a0 how to utilize existing skillsets to build useful tools and processes that include Microsoft Graph.<\/p>\n<h4>Background<\/h4>\n<p>A little background to get started with Microsoft Graph. It is a RESTful web API, so it uses web requests to submit calls to an endpoint. By providing a method (GET, POST, PATCH, PUT, DELETE) with the request, we can access and interact with data and resources within a Microsoft 365 tenant. We can make requests to the endpoints in two ways &#8211; using an SDK or a manual HTTP request. The Microsoft Graph PowerShell SDK allows you to issue PowerShell commandlets (also called cmdlets) like Get-MGUser to make calls. The manual method uses Invoke-RestMethod or Invoke-WebRequest to manually submit an HTTP request to the Microsoft Graph API. Whether using the PowerShell module or the Invoke-RestMethod\/Invoke-WebRequest cmdlets, we can use our PowerShell know-how to interact with the Microsoft Graph API.<\/p>\n<h4>Getting Started<\/h4>\n<p>Normally, we would run a PowerShell script using a user account (admin account or service account) as part of a scheduled task or even manually. Microsoft Graph authentication is different. Microsoft Graph requires an access token to be submitted with each HTTP request. This token is issued by the <a href=\"https:\/\/developer.microsoft.com\/en-us\/identity\">Microsoft identity platform<\/a> and contains information used to validate the requestor and the specific permission(s) they have within the API. Before our PowerShell script can get an access token, we need to <a href=\"https:\/\/docs.microsoft.com\/graph\/auth-register-app-v2\">register an application<\/a> through the Azure Portal. This app registration is where we get the required information to connect to Microsoft Graph: Application ID, Tenant ID, Client Secret, Redirect URI, and permissions. We assign or configure these through the application registration process.<\/p>\n<p>Covering the app registration process could be an entire blog post, so for our purposes, we\u2019ll assume we are using application permissions. This allows us to simplify the authentication process as there is no username\/password requirement and Microsoft Graph permissions are applied to the application itself. (If you are interested in hearing more about application vs delegated permissions, see the <a href=\"https:\/\/docs.microsoft.com\/graph\/auth\/auth-concepts#delegated-and-application-permissions\">Authentication and authorization basic for Microsoft Graph<\/a> documentation or please let us know using the #MSGraphMailbag hashtag on Twitter).<\/p>\n<p>For this example, we\u2019ll perform an <a href=\"https:\/\/docs.microsoft.com\/graph\/powershell\/app-only\">app-only authentication<\/a> using the Microsoft Graph PowerShell SDK and submit our application ID and certificate as credentials to receive the access token. The certificate is created locally and then uploaded to the app registration. It is used in place of the client secret as a more secure method of authentication.<\/p>\n<p>The PowerShell Graph SDK will handle authentication and manage the access tokens for us. This is nice because we don\u2019t need to build logic in our script to keep track of the access token or handle information like token expiration for long running sessions. We can call the \u2018Connect-MGGraph\u2019 cmdlet, pass in information from our app registration, and we\u2019re authenticated and ready to work with the Microsoft Graph API. The example below shows how to authenticate using app-only authentication and the PowerShell Graph SDK:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-large wp-image-6123\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image4-1024x143.png\" alt=\"\" width=\"1024\" height=\"143\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image4-1024x143.png 1024w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image4-300x42.png 300w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image4-768x107.png 768w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image4.png 1394w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>(text from image above)<\/p>\n<pre class=\"\">$appID = \u201cFrom App Registration\u201d\n$tenantId = \u201cFrom App Registration\u201d\n$authCertThumb = \u201cFrom App Registration\u201d\n#Connect to Microsoft Graph using Microsoft Graph PowerShell SDK\nConnect-MgGraph -ClientId $appID -TenantId $tenantID -CertificateThumbprint $authCertThumb<\/pre>\n<p>For more information, see <a href=\"https:\/\/docs.microsoft.com\/graph\/powershell\">Use app-only authentication with the Microsoft Graph PowerShell SDK<\/a>.<\/p>\n<h4>Querying Microsoft Graph data<\/h4>\n<p>Let\u2019s look at a simple query like getting a list of users in a tenant. With the Microsoft Graph PowerShell SDK, this is one cmdlet, and we\u2019ll save the results to a variable:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-6124\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image5.png\" alt=\"\" width=\"313\" height=\"47\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image5.png 313w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image5-300x45.png 300w\" sizes=\"(max-width: 313px) 100vw, 313px\" \/><\/p>\n<p>(text from image above)<\/p>\n<pre class=\"\">$Users = Get-MGUser<\/pre>\n<p>In this request, we are getting information from the \u2018\/users\u2019 endpoint in Microsoft Graph and saving that data in the $Users PowerShell variable. Notice that we don\u2019t have to submit any of required information for a HTTP request like we would be using the manual Invoke-RestMethod cmdlet. The SDK hides that manual layer and takes care of things such as the HTTP method, Uri, and the access token allowing us to interact with Microsoft Graph using PowerShell syntax.<\/p>\n<p>Let\u2019s look at the $Users variable:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-large wp-image-6125\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image6-1024x284.png\" alt=\"\" width=\"1024\" height=\"284\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image6-1024x284.png 1024w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image6-300x83.png 300w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image6-768x213.png 768w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image6.png 1045w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/p>\n<p>We now have a set of PowerShell Objects obtained from Microsoft Graph that we can start interacting with using PowerShell functionality.<\/p>\n<p><span style=\"text-decoration: underline\">Count:<\/span><\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-6126\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image7.png\" alt=\"\" width=\"152\" height=\"35\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image7.png 152w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image7-150x35.png 150w\" sizes=\"(max-width: 152px) 100vw, 152px\" \/><\/p>\n<p>(text from image above)<\/p>\n<pre class=\"\">$Users.Count<\/pre>\n<p><span style=\"text-decoration: underline\">Format-List:<\/span><\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-6127\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image8.png\" alt=\"\" width=\"432\" height=\"360\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image8.png 432w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image8-300x250.png 300w\" sizes=\"(max-width: 432px) 100vw, 432px\" \/><\/p>\n<p>(text from image above)<\/p>\n<pre class=\"\">$Users | Format-List displayName, userPrincipalName<\/pre>\n<p><span style=\"text-decoration: underline\">Loops:<\/span><\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-6128\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image9.png\" alt=\"\" width=\"437\" height=\"372\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image9.png 437w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image9-300x255.png 300w\" sizes=\"(max-width: 437px) 100vw, 437px\" \/><\/p>\n<p>(text from image above)<\/p>\n<pre class=\"\">Foreach($user in $Users)\n{\n\u00a0\u00a0\u00a0 If($null -ne $user.jobTitle)\n\u00a0\u00a0\u00a0 {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 Write-Host $user.displayName`n $user.jobTitle`n\n\u00a0\u00a0\u00a0 }\n}<\/pre>\n<p><span style=\"text-decoration: underline\">Filter results:<\/span><\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-6129\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image10.png\" alt=\"\" width=\"684\" height=\"316\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image10.png 684w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image10-300x139.png 300w\" sizes=\"(max-width: 684px) 100vw, 684px\" \/><\/p>\n<p>(text from image above)<\/p>\n<pre class=\"\">$Users | Where-Object {$_.jobTitle -like \u201c*manager\u201d} | Format-List displayName, jobTitle<\/pre>\n<h4>Modifying Microsoft Graph data<\/h4>\n<p>Querying Microsoft Graph API for data using PowerShell is great and can be useful. But, what if we want to interact with the data in Microsoft Graph rather than just read it?<\/p>\n<p><span style=\"font-size: 11.0pt;font-family: 'Calibri',sans-serif\">Extra Credit: Creating and editing data in Microsoft Graph requires us to submit information in JSON format as part of the body of a request. For those of you not familiar with JSON, it is a way to format and organize name\/value pairs similar to XML. It is a common method of interacting with web APIs. <\/span><\/p>\n<p><span style=\"font-size: 11.0pt;font-family: 'Calibri',sans-serif\">The good news is that the Microsoft Graph PowerShell SDK does the heavy lifting for us. The manual HTTP request would require us to build out the JSON data and submit it as part of the HTTP request. The PowerShell SDK still allows this using the \u2018-BodyParameter\u2019 parameter but simplifies the process by surfacing attribute parameters through the cmdlet. <\/span><\/p>\n<p>Let\u2019s look at a simple edit command to update the jobTitle of a specific user:<\/p>\n<p><img decoding=\"async\" class=\"aligncenter size-full wp-image-6130\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image11.png\" alt=\"\" width=\"621\" height=\"22\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image11.png 621w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2021\/03\/image11-300x11.png 300w\" sizes=\"(max-width: 621px) 100vw, 621px\" \/><\/p>\n<p>(text from image above)<\/p>\n<pre class=\"\">Update-MgUser -UserId <a href=\"mailto:AdeleV@M365x188429.OnMicrosoft.com\">AdeleV@M365x188429.OnMicrosoft.com<\/a> -JobTitle \u201cRegional Manager\u201d<\/pre>\n<p>We are making a request to the \u2018\/users\u2019 endpoint and specifying an individual user to edit. The cmdlet takes care of the HTTP method, the Uri, the access token, and in this case the body of the request that specifies the desired change. Microsoft Graph PowerShell SDK puts the request in a format that is familiar to PowerShell users allowing us to pass in parameters like \u2018-jobTitle\u2019 in place of JSON formatted data.<\/p>\n<h4>Conclusion<\/h4>\n<p>In this post, we covered what is needed to start working with Microsoft Graph using PowerShell and how to utilize our current PowerShell skills with the Microsoft Graph PowerShell SDK. \u00a0This allows us to directly interact with Microsoft Graph in a familiar way. We\u2019ve just scratched the surface.\u00a0 I plan on digging in deeper into the benefits and features of the Microsoft Graph PowerShell SDK in a future post. Until next time!<\/p>\n<p>&nbsp;<\/p>\n<p>Today\u2019s post was written by Matt Krause, Customer Engineer (CE) at Microsoft.\u00a0You can follow Matt on <a href=\"https:\/\/www.twitter.com\/mattckrause\">Twitter @mattckrause<\/a>. \u00a0Join us for our next post April 13th, 2021.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Learn how to start working with Microsoft Graph using PowerShell and how to utilize our current PowerShell skills with the Microsoft Graph PowerShell SDK.<\/p>\n","protected":false},"author":69075,"featured_media":25159,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[3],"tags":[17],"class_list":["post-6122","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microsoft-graph","tag-msgraphmailbag"],"acf":[],"blog_post_summary":"<p>Learn how to start working with Microsoft Graph using PowerShell and how to utilize our current PowerShell skills with the Microsoft Graph PowerShell SDK.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/6122","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/users\/69075"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/comments?post=6122"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/6122\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media\/25159"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/media?parent=6122"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/categories?post=6122"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/tags?post=6122"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}