{"id":2113,"date":"2018-11-17T11:00:22","date_gmt":"2018-11-17T11:00:22","guid":{"rendered":"https:\/\/developer.microsoft.com\/en-us\/office\/blogs\/?p=2113"},"modified":"2018-11-17T11:00:22","modified_gmt":"2018-11-17T11:00:22","slug":"30daysmsgraph-day-17-use-case-assign-license","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/30daysmsgraph-day-17-use-case-assign-license\/","title":{"rendered":"30DaysMSGraph \u2013 Day 17 &#8211; Use Case: Assign an Office 365 license"},"content":{"rendered":"<p><a href=\"https:\/\/aka.ms\/30DaysMSGraph\">List of all posts in the #30DaysMSGraph series<\/a><\/p>\n<p>In <a href=\"https:\/\/developer.microsoft.com\/en-us\/graph\/blogs\/30daysmsgraph-day-16-use-case-create-user-in-azure-ad\">Day 16<\/a> we extended the base .Net Core console application to create a user by calling Azure AD.\u00a0 Today we&#8217;ll extend the base console application to assign a user license in Office 365.\u00a0 Note that it is not required to perform each of the daily Use Case samples in order to continue to the next.\u00a0 Starting with the base console application from Day 15 will be sufficient if building from scratch, or as always, you can clone the completed version in the provided repo at bottom of this post.<\/p>\n<p><img decoding=\"async\" class=\"aligncenter wp-image-2141\" src=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2018\/11\/30DaysMSGraph_Day17_Source-1024x683.jpg\" alt=\"\" width=\"800\" height=\"533\" srcset=\"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2018\/11\/30DaysMSGraph_Day17_Source-1024x683.jpg 1024w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2018\/11\/30DaysMSGraph_Day17_Source-300x200.jpg 300w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2018\/11\/30DaysMSGraph_Day17_Source-768x512.jpg 768w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2018\/11\/30DaysMSGraph_Day17_Source-1536x1024.jpg 1536w, https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-content\/uploads\/sites\/73\/2018\/11\/30DaysMSGraph_Day17_Source-2048x1365.jpg 2048w\" sizes=\"(max-width: 800px) 100vw, 800px\" \/><\/p>\n<p>You can assign licenses to an Office 365 user by calling the \/Users\/&lt;id&gt;\/assignLicense endpoint as detailed in the Microsoft Graph <a href=\"https:\/\/developer.microsoft.com\/en-us\/graph\/docs\/api-reference\/v1.0\/api\/user_assignlicense\">documentation<\/a>.\u00a0 Not only can you assign licenses but you can also remove licenses as well as enable or disable specific plans within a license.\u00a0 In this post and associated code sample we are only covering the assign license aspect.<\/p>\n<h3>Permissions required<\/h3>\n<p>The <strong>User.ReadWrite.All<\/strong> or <strong>Directory.ReadWrite.All<\/strong> permission is required to assign or remove a license.\u00a0 Before we can assign or remove a license though we must know which licenses are available within the tenant.\u00a0 Available licenses (also called subscribed SKUs) is available through the \/subscriberSkus endpoint (<a href=\"https:\/\/developer.microsoft.com\/en-us\/graph\/docs\/api-reference\/v1.0\/api\/subscribedsku_list\">documentation<\/a>) and requires <strong>Directory.Read.All<\/strong> or <strong>Directory.ReadWrite.All<\/strong> permissions.\u00a0 In order to simplify overall necessary permissions we will assign and consent the <strong>Directory.ReadWrite.All<\/strong> permissions for today.<\/p>\n<p>Since you didn&#8217;t assign this permission in a previous day ensure that you assign them now to your Azure AD application.\u00a0 Navigate to the <a href=\"http:\/\/aka.ms\/appregistrationspreview\">Preview App Registrations<\/a> experience in the Azure AD portal and assign the application permission for <strong>Directory.ReadWrite.All<\/strong> under Microsoft Graph API.<\/p>\n<h3>Get user<\/h3>\n<p>The first step in assigning a license is getting a reference to a user within the tenant.\u00a0 For today&#8217;s solution we&#8217;ll use the Microsoft Graph SDK and look up a user by their UPN.<\/p>\n<pre style=\"padding-left: 30px\">public async <em>Task<\/em>&lt;<em>User<\/em>&gt; GetUser(string UPN)\n{\n\u00a0\u00a0\u00a0 var user = await _graphClient.Users[UPN].Request().GetAsync();\n\u00a0\u00a0\u00a0 return user;\n}<\/pre>\n<h3>List licenses (subscription SKUs)<\/h3>\n<p>The second step is getting a reference to a license (subscription SKU) within the tenant.\u00a0 If you know the exact internal name of the SKU you could perform a query but many times the internal name (ex. &#8220;ENTERPRISEPREMIUM&#8221; is not the same as the display name (ex. &#8220;Office 365 Enterprise E5&#8221;).\u00a0 As such we&#8217;ll query for all SKUs and then select the first result from the collection that comes back.<\/p>\n<pre style=\"padding-left: 30px\">public async <em>Task<\/em>&lt;<em>SubscribedSku<\/em>&gt; GetLicense()\n{\n\u00a0\u00a0\u00a0 var skuResult = await _graphClient.SubscribedSkus.Request().GetAsync();\n\u00a0\u00a0\u00a0 return skuResult[0];\n}<\/pre>\n<h3>Assign license<\/h3>\n<p>The last step is building a request containing the licenses to add and the licenses to remove.\u00a0 In this case we pass in the userId and skuId from the previous calls above.<\/p>\n<pre style=\"padding-left: 30px\">public async <em>Task<\/em> AddLicense(string userId, <em>Guid<\/em>? skuId)\n{\n\u00a0\u00a0\u00a0 var licensesToAdd = new <em>List<\/em>&lt;<em>AssignedLicense<\/em>&gt;();\n\u00a0\u00a0\u00a0 var licensesToRemove = new <em>List<\/em>&lt;<em>Guid<\/em>&gt;();\n\n \u00a0\u00a0 var license = new <em>AssignedLicense<\/em>()\n\u00a0\u00a0\u00a0 {\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 SkuId = skuId,\n\u00a0\u00a0\u00a0 };\n\n\u00a0\u00a0\u00a0 licensesToAdd.Add(license);\n\n\u00a0\u00a0\u00a0 await _graphClient.Users[userId].AssignLicense(licensesToAdd, licensesToRemove).Request().PostAsync();\n}<\/pre>\n<p>&nbsp;<\/p>\n<h2>Try It Out<\/h2>\n<p>Navigate to the\u00a0<a href=\"https:\/\/github.com\/microsoftgraph\/dotnetcore-console-sample\">dotnetcore-console-sample<\/a> repo.\u00a0 Do one (or both) of the following:<\/p>\n<p><a href=\"https:\/\/github.com\/microsoftgraph\/30DaysMSGraph-TryItOut\/blob\/master\/Day17-AssignLicense.md\">Day 17 repo link<\/a><\/p>\n<ol>\n<li>Clone the repo and configure the project in the Day 17 sub-folder.<\/li>\n<li>Follow the instructions in <a href=\"https:\/\/github.com\/microsoftgraph\/dotnetcore-console-sample\/tree\/master\/day17-assign-license\">Day 17 sub-folder<\/a> to build the project from scratch yourself.<\/li>\n<\/ol>\n<p>If you run into any issues while building or configuring the project please create a new Issue on the repo.<\/p>\n<p>&nbsp;<\/p>\n<p>Join us tomorrow as we update a user mailbox using Microsoft Graph requests in <a href=\"https:\/\/developer.microsoft.com\/en-us\/graph\/blogs\/30daysmsgraph-day-18-use-case-update-user-mailbox-settings\/\">Day 18<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In Day 16 we extended the base .Net Core console application to create a user by calling Azure AD.\u00a0 Today we&#8217;ll extend the base console application to assign a user license in Office 365.<\/p>\n","protected":false},"author":73055,"featured_media":25159,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[3,11],"tags":[84],"class_list":["post-2113","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-microsoft-graph","category-office-add-ins","tag-30daysmsgraph"],"acf":[],"blog_post_summary":"<p>In Day 16 we extended the base .Net Core console application to create a user by calling Azure AD.\u00a0 Today we&#8217;ll extend the base console application to assign a user license in Office 365.<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/2113","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\/73055"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/comments?post=2113"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/posts\/2113\/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=2113"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/categories?post=2113"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/microsoft365dev\/wp-json\/wp\/v2\/tags?post=2113"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}