@@ -260,47 +260,96 @@ The purpose of this script is to remove unnecessary direct licenses from users w
260
260
261
261
262
262
``` powershell
263
- Import-Module Microsoft.Graph
263
+ # Import the Microsoft.Graph.Users and Microsoft.Graph.Groups modules
264
+ Import-Module Microsoft.Graph.Users -Force
265
+ Import-Module Microsoft.Graph.Authentication -Force
266
+ Import-Module Microsoft.Graph.Users.Actions -Force
267
+ Import-Module Microsoft.Graph.Groups -Force
264
268
265
- # Connect to the Microsoft Graph
266
- Connect-MgGraph
269
+ Clear-Host
267
270
268
- # Get the group to be processed
269
- $groupId = "48ca647b-7e4d-41e5-aa66-40cab1e19101"
270
-
271
- # Get the license to be removed - Office 365 E3
272
- $skuId = "contoso:ENTERPRISEPACK"
273
-
274
- # Minimum set of service plans we know are inherited by this group
275
- $expectedDisabledPlans = @("Exchange Online", "SharePoint Online", "Lync Online")
276
-
277
- # Get the users in the group
278
- $users = Get-MgUser -GroupObjectId $groupId
279
-
280
- # For each user, get the license for the specified SKU
281
- foreach ($user in $users) {
282
- $license = GetUserLicense $user $skuId
283
-
284
- # If the user has the license assigned directly, continue to the next user
285
- if (UserHasLicenseAssignedDirectly $user $skuId) {
286
- continue
287
- }
288
-
289
- # If the user is inheriting the license from the specified group, continue to the next user
290
- if (UserHasLicenseAssignedFromThisGroup $user $skuId $groupId) {
291
- continue
292
- }
271
+ if ($null -eq (Get-MgContext)) {
272
+ Connect-MgGraph -Scopes "Directory.Read.All, User.Read.All, Group.Read.All, Organization.Read.All" -NoWelcome
273
+ }
293
274
294
- # Get the list of disabled service plans for the SKU
295
- $disabledPlans = GetDisabledPlansForSKU $skuId $expectedDisabledPlans
275
+ # Get all groups with licenses assigned
276
+ $groupsWithLicenses = Get-MgGroup -All -Property AssignedLicenses, DisplayName, Id | Where-Object { $_.assignedlicenses } | Select-Object DisplayName, Id -ExpandProperty AssignedLicenses | Select-Object DisplayName, Id, SkuId
296
277
297
- # Get the list of unexpected enabled plans for the user
298
- $extraPlans = GetUnexpectedEnabledPlansForUser $user $skuId $expectedDisabledPlans
278
+ $output = @()
299
279
300
- # If there are any unexpected enabled plans, print them to the console
301
- if ($extraPlans.Count -gt 0) {
302
- Write-Warning "The user $user has the following unexpected enabled plans for the $skuId SKU: $extraPlans"
280
+ # Check if there is any group that has licenses assigned or not
281
+ if ($null -ne $groupsWithLicenses) {
282
+ # Loop through each group
283
+ foreach ($group in $groupsWithLicenses) {
284
+ # Get the group's licenses
285
+ $groupLicenses = $group.SkuId
286
+
287
+ # Get the group's members
288
+ $groupMembers = Get-MgGroupMember -GroupId $group.Id -All
289
+
290
+ # Check if the group member list is empty or not
291
+ if ($groupMembers) {
292
+ # Loop through each member
293
+ foreach ($member in $groupMembers) {
294
+ # Check if the member is a user
295
+ if ($member.AdditionalProperties.'@odata.type' -eq '#microsoft.graph.user') {
296
+ # Get the user's direct licenses
297
+ Write-Host "Fetching license details for $($member.AdditionalProperties.displayName)" -ForegroundColor Yellow
298
+
299
+ # Get User With Directly Assigned Licenses Only
300
+ $user = Get-MgUser -UserId $member.Id -Property AssignedLicenses, LicenseAssignmentStates, DisplayName | Select-Object DisplayName, AssignedLicenses -ExpandProperty LicenseAssignmentStates | Select-Object DisplayName, AssignedByGroup, State, Error, SkuId | Where-Object { $_.AssignedByGroup -eq $null }
301
+
302
+ $licensesToRemove = @()
303
+ if($user)
304
+ {
305
+ if ($user.count -ge 2) {
306
+ foreach ($u in $user) {
307
+ $userLicenses = $u.SkuId
308
+ $licensesToRemove += $userLicenses | Where-Object { $_ -in $groupLicenses }
309
+ }
310
+ }
311
+ else {
312
+ $userLicenses = $user.SkuId
313
+ $licensesToRemove = $userLicenses | Where-Object { $_ -in $groupLicenses }
314
+ }
315
+ } else {
316
+ Write-Host "No conflicting licenses found for the user $($member.AdditionalProperties.displayName)" -ForegroundColor Green
317
+ }
318
+
319
+
320
+
321
+ # Remove the licenses from the user
322
+ if ($licensesToRemove) {
323
+ Write-Host "Removing the license $($licensesToRemove) from user $($member.AdditionalProperties.displayName) as inherited from group $($group.DisplayName)" -ForegroundColor Green
324
+ $result = Set-MgUserLicense -UserId $member.Id -AddLicenses @() -RemoveLicenses $licensesToRemove
325
+ $obj = [PSCustomObject]@{
326
+ User = $result.DisplayName
327
+ Id = $result.Id
328
+ LicensesRemoved = $licensesToRemove
329
+ LicenseInheritedFromGroup = $group.DisplayName
330
+ GroupId = $group.Id
331
+ }
332
+
333
+ $output += $obj
334
+
335
+ }
336
+ else {
337
+ Write-Host "No action required for $($member.AdditionalProperties.displayName)" -ForegroundColor Green
338
+ }
339
+
340
+ }
341
+ }
342
+ }
343
+ else {
344
+ Write-Host "The licensed group $($group.DisplayName) has no members, exiting now!!" -ForegroundColor Yellow
345
+ }
346
+
303
347
}
348
+
349
+ $output | Format-Table -AutoSize
350
+ }
351
+ else {
352
+ Write-Host "No groups found with licenses assigned." -ForegroundColor Cyan
304
353
}
305
354
```
306
355
0 commit comments