forked from 12Knocksinna/Office365itpros
-
Notifications
You must be signed in to change notification settings - Fork 0
/
RemoveServicePlan3.PS1
117 lines (105 loc) · 5.91 KB
/
RemoveServicePlan3.PS1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
# RemoveServicePlan3.PS1
# Remove an individual service plan from a SKU assigned to Microsoft 365 accounts
# Version of https://github.com/12Knocksinna/Office365itpros/blob/master/RemoveServicePlan.PS1 using Microsoft Graph PowerShell SDK cmdlets instead of MSOL cmdlets
# to remove service plans from licenses.
# https://github.com/12Knocksinna/Office365itpros/blob/master/RemoveServicePlan3.PS1
Function Get-Response ([string]$Prompt,[int]$NumberPossibleAnswers) {
# Help function to prompt a question and get a response
$OKtoProceed = $False
While ($OKToProceed -eq $False) {
[int]$Answer = Read-Host $Prompt
If ($Answer -gt 0 -and $Answer -le $NumberPossibleAnswers) {
$OKtoProceed = $True
Return ($Answer) }
ElseIf ($Answer -eq 0) { #break out of loop
$OKtoProceed = $True
Return ($Answer)}
} #End while
}
Connect-MgGraph
Select-MgProfile Beta
$CSVOutputFile = "c:\temp\ServicePlanRemovals.csv"
# Find the set of SKUs used in the tenant
[array]$Skus = (Get-MgSubscribedSku)
Write-Host " "
Write-Host "Which Office 365 product do you want to remove a service plan from?"; [int]$i=0
ForEach ($Sku in $Skus) {
$i++
Write-Host $i ":" $Sku.SkuPartNumber }
[Int]$Answer = Get-Response -Prompt "Enter the number of the product to edit" -NumberPossibleAnswers $i
If (($Answer -gt 0) -and ($Answer -le $i)) {
$i = ($Answer-1)
[string]$SelectedSku = $Skus[$i].SkuPartNumber
[string]$SelectedSkuId = $Skus[$i].SkuId
Write-Host "OK. Selected product is" $SelectedSku
$ServicePlans = $Skus[$i].ServicePlans | Select ServicePlanName, ServicePlanId | Sort ServicePlanName
} #end if
Elseif ($Answer -eq 0) { #Abort
Write-Host "Script stopping..." ; break }
# Select Service plan to remove
Write-Host " "
Write-Host "Which Service plan do you want to remove from" $SelectedSku; [int]$i=0
ForEach ($ServicePlan in $ServicePlans) {
$i++
Write-Host $i ":" $ServicePlan.ServicePlanName }
[Int]$Answer = Get-Response -Prompt "Enter the number of the service plan to remove" -NumberPossibleAnswers $i
If (($Answer -gt 0) -and ($Answer -le $i)) {
[int]$i = ($Answer-1)
[string]$ServicePlanId = $ServicePlans[$i].ServicePlanId
[string]$ServicePlanName = $ServicePlans[$i].ServicePlanName
Write-Host " "
Write-Host ("Proceeding to remove service plan {0} from the {1} license for target users." -f $ServicePlanName, $SelectedSku)
} #end If
Elseif ($Answer -eq 0) { #Abort
Write-Host "Script stopping..." ; break }
#
Write-Host "Searching for licensed Azure AD accounts"
[array]$Users = Get-MgUser -Filter "assignedLicenses/`$count ne 0 and userType eq 'Member'" -ConsistencyLevel eventual -CountVariable Records -All | Sort DisplayName
Write-Host ("Total of {0} licensed Azure AD accounts found" -f $Users.count) -Foregroundcolor red
# Main loop through mailboxes to remove selected service plan from a SKU if the SKU is assigned to the account.
$Report = [System.Collections.Generic.List[Object]]::new()
ForEach ($User in $Users) {
Write-Host "Checking licenses for" $User.DisplayName
If ($SelectedSkuId -in $User.AssignedLicenses.SkuId) { # User has selected SKU
# Fetch enabled service plans
[array]$AllLicenses = Get-MgUserLicenseDetail -UserId $User.Id | Select-Object -ExpandProperty ServicePlans | Sort-Object ServicePlanId -Unique
[array]$Licenses = $AllLicenses | Where-Object {$_.ProvisioningStatus -eq 'Success'}
[array]$DisabledLicenses = $AllLicenses | Where-Object {$_.ProvisioningStatus -eq 'Disabled'}
# Figure out if any service plans are already disabled and add to the set to update
[array]$DisabledSPs = $ServicePlanId
If ($DisabledLicenses) {
If ($DisabledLicenses.Count -eq 1) {
$DisabledSPs += $DisabledLicenses.ServicePlanId }
Else {
ForEach ($SP in $DisabledLicenses) {
$DisabledSPs += $SP.ServicePlanId }
}
} # End if
If ($ServicePlanId -in $Licenses.ServicePlanId) {
Write-Host ("Removing service plan {0} from SKU {1} for account {2}" -f $ServicePlanName, $SelectedSKUId, $User.DisplayName) -foregroundcolor Red
$LicenseOptions = @{SkuId = $SelectedSkuId ; DisabledPlans = $DisabledSPs }
Try {
$Status = Set-MgUserLicense -UserId $User.Id -AddLicenses $LicenseOptions -RemoveLicenses @() }
Catch {
}
$LicenseUpdateMsg = $ServicePlanName + " service plan removed from account " + $User.DisplayName + " on " + (Get-Date) + " from " + $SelectedSku
Write-Host ("Service plan {0} removed from SKU {1} for {2}" -f $ServicePlanName, $SelectedSku, $User.DisplayName)
$ReportLine = [PSCustomObject][Ordered]@{
DisplayName = $User.DisplayName
UPN = $User.UserPrincipalName
Info = $LicenseUpdateMsg
SKU = $SelectedSKUId
"Service Plan" = $ServicePlanName
"ServicePlanId" = $ServicePlanId }
$Report.Add($ReportLine)
} # End if Service Plan
} # End if License
} #End Foreach User
Write-Host ("Total Licenses Removed: {0}. Output CSV file available in {1}" -f $Report.Count, $CSVOutputFile)
# Output the report
$Report | Out-GridView
$Report | Export-CSV -NoTypeInformation $CSVOutputFile
# An example script used to illustrate a concept. More information about the topic can be found in the Office 365 for IT Pros eBook https://gum.co/O365IT/
# and/or a relevant article on https://office365itpros.com or https://www.practical365.com. See our post about the Office 365 for IT Pros repository # https://office365itpros.com/office-365-github-repository/ for information about the scripts we write.
# Do not use our scripts in production until you are satisfied that the code meets the need of your organization. Never run any code downloaded from the Internet without
# first validating the code in a non-production environment.