This is my first blog. To introduce myself, I have over 13 years of experience in a messaging environment and have automated my tasks using PowerShell.
Being an Office365 Admin, you might have entered into a difficult situation where Microsoft has rolled out new license features, like (Todo, TEAMS, Staffhub, Flow....etc.) in E1, E3, E4, or E5. And, your IT security team wants to disable this feature license for all the users immediately. This script will help you to disable that specific license without impacting other licenses.
The following script will help you to disable a specific service plan from each license.
Let me explain the script.
$Users = Import-Csv .\Users.csv
The above line gets the input from the CSV file, updates the path of the CSV file where the CSV file is located and make "users.csv" your input file. Have the header called "Email" and the header value will be Userprincipalname.
$ldo += “BPOS_S_TODO_2”,"STREAM_O365_E3"
This line is the important one. Mention the service plan you want to disable. For each license service plan, the Name will differ.
You can get the service plan by executing the below cmdlet.
  1. $t = Get-MsolUser -UserPrincipalName <UPN>
  2. $t.Licenses[0].servicestatus
  3. if($ld.AccountSkuId -eq “<AccountSkuId>”)
You need to specify the AccountSKUID. You will find the accountskuid by running the below cmdlet.
Get-MsolAccountSKU Cmdlet in Azure Msol
At the end, the script will give you the following output logs.
Powershell transcript file. <Transcript-DD-MM-YYYY-T>
License before disabling. <Disable_LicensePlan_Before-DD-MM-YYYY-T>
License after disabling <Disable_LicensePlan_After-DD-MM-YYYY-T>
Script
  1. #Variable declaration
  2. $Global: Eventlog = @()
  3. $Global: Eventlog1 = @()
  4. $Logfiles = @()
  5. $currentUser = [Environment]::UserName
  6. $TimeStamp = get - date - uformat "%d-%m-%Y-%T"
  7. $Logfilename = "Disable_LicensePlan_Before-$($TimeStamp.Replace(": ",$null)).csv"
  8. $Logfilename1 = "Disable_LicensePlan_After-$($TimeStamp.Replace(": ",$null)).csv"
  9. $Trans = "Transcript-$($TimeStamp.Replace(": ",$null)).txt"
  10. Start - Transcript - Path ".\$trans"###
  11. Funtion
  12. for Logs
  13. Function Logwrite([String] $UPN, [String] $Loginfo) {
  14. $Emailaddress = $UPN
  15. $Loginformation = $Loginfo
  16. $Admin = [Environment]::UserName
  17. $Logstatus = $Status
  18. # Write - host
  19. $Status
  20. $TimeStamp = get - date - uformat "%d-%m-%Y-%T"
  21. $Logs = New - Object PsObject
  22. $Logs | add - member - membertype NoteProperty - name "TimeStamp" - value $TimeStamp
  23. $Logs | add - member - membertype NoteProperty - name "UserprincipalName" - value $Emailaddress
  24. $Logs | add - member - membertype NoteProperty - name "Log Information" - value $Loginfo
  25. $Logs | add - member - membertype NoteProperty - name "Script Executedby" - value $currentUser
  26. $Logfiles += $logs
  27. Return $Logfiles
  28. }
  29. $Users = Import - Csv.\Users.csv
  30. Foreach($act in $users) {
  31. $upn = $act.Email
  32. # current licenses(this pulls the top level, like Office 365 Enterprise, Project Online etc.$Lic = Get - MsolUser - UserPrincipalName $upn - ErrorAction 0 If($Lic.UserPrincipalName - notlike $null) {
  33. $ouserlicense = $Lic.Licenses | Select - Object - ExpandProperty ServiceStatus
  34. $EnabledServices_Before = ($ouserlicense | Where - Object - Property ProvisioningStatus - EQ "Success").ServicePlan.ServiceName
  35. $DisablededServices_Before = ($ouserlicense | Where - Object - Property ProvisioningStatus - EQ "Disabled").ServicePlan.ServiceName
  36. $CurrentLic = $Lic.Licenses.AccountSkuId
  37. $Log1 = Logwrite "$upn"
  38. "Current Enabled Plan: $CurrentLic : $EnabledServices_Before"
  39. $Global: Eventlog += $Log1
  40. $Log2 = Logwrite "$upn"
  41. "Current Disabled Plan:$CurrentLic : $DisablededServices_Before"
  42. $Global: Eventlog += $Log2
  43. $licensedetails = (Get - MsolUser - UserPrincipalName $upn).Licenses
  44. #Using an array to pull all of my disabled plans together– and start with the new one I want to disable
  45. $ldo = @()
  46. $tmp = @()
  47. $ldo_Disable
  48. # = @()
  49. $DisabledServicesNew = @()
  50. <
  51. #You can add the service name you want to disable below.,
  52. if you want to add mulitple service add each service separated by comma line below“ SWAY”, "FLOW_O365_P1", "POWERAPPS_O365_P1", "TEAMS1", "Deskless"
  53. Following are the service plan you can see in E3 Subscription.
  54. ServicePlan Description
  55. -- -- -- -- -- - -- -- -- -- -- -- -- -- - MYANALYTICS_P2 MyAnalytics
  56. BPOS_S_TODO_2 TODO
  57. FORMS_PLAN_E3 Forms
  58. STREAM_O365_E3 Stream
  59. Deskless Staff Hub
  60. FLOW_O365_P2 Flow
  61. POWERAPPS_O365_P2 PowerApps
  62. TEAMS1 Teams
  63. PROJECTWORKMANAGEMENT Microsoft Planner
  64. SWAY Sway
  65. INTUNE_O365 Intune MDM
  66. YAMMER_ENTERPRISE YAMMER
  67. RMS_S_ENTERPRISE Azure Rights Management
  68. OFFICESUBSCRIPTION Office Proplus
  69. MCOSTANDARD Skype
  70. for Business
  71. SHAREPOINTWAC Office Online
  72. SHAREPOINTENTERPRISE SharePoint Online
  73. EXCHANGE_S_ENTERPRISE Exchange Online
  74. # > $ldo += “BPOS_S_TODO_2”, "STREAM_O365_E3"
  75. $ldo_Disable = $ldo
  76. $Log1 = Logwrite "$upn"
  77. "Selected plan to disable: $ldo"
  78. $Global: Eventlog += $Log1
  79. $licensedetails.Count;
  80. #Making sure there are some licenses
  81. if ($licensedetails.Count - gt 0) {
  82. foreach($ld in $licensedetails) {
  83. #AccountSkuId = Provide the AccountSKUid
  84. for License E1 / E3 / E5 etc.
  85. #You can get AccountSkuid using Get - MsolAccountSKU Cmdlet in Azure Msol.
  86. if($ld.AccountSkuId - eq“ < AccountSkuId > ”) {
  87. $UPN
  88. $CurrentLic
  89. $ld.ServiceStatus
  90. foreach($lds in $ld.ServiceStatus) {
  91. if ($lds.ProvisioningStatus - like“ Success”) {
  92. #looking for ones that are already Enabled and adding them to my array
  93. $Temp1 = $lds.ServicePlan.ServiceName.ToString()
  94. $ldo_Success = $ldo + $Temp1
  95. }
  96. if ($lds.ProvisioningStatus - like“ Disabled”) {
  97. #looking for ones that are already disabled and adding them to my array
  98. $temp2 = $lds.ServicePlan.ServiceName.ToString()
  99. $temp2
  100. Foreach($l in $ldo) {
  101. #$l
  102. If($l - eq $temp2) {
  103. $AlreadyDisabled = $l
  104. Write - host "Plan already Disabled $l"
  105. }
  106. }
  107. if ($AlreadyDisabled - eq $temp2) {
  108. #Write - host "Plan already Disabled $l"
  109. }
  110. Else {
  111. $tmp = $tmp + $temp2
  112. }
  113. }
  114. }
  115. $ldo_Disable = $ldo + $tmp
  116. $ldo_Disable
  117. $tmp = $null
  118. Write - host "Following Plan will be disabled $ldo_Disable for $upn"
  119. #then create a new license option– and set the DisabledPlans to my array– Planner plus the others it finds
  120. Try {
  121. $LO = New - MsolLicenseOptions - AccountSkuId“ AccountSKUID” - DisabledPlans $ldo_Disable
  122. Set - MsolUserLicense - UserPrincipalName $upn - LicenseOptions $LO - Erroraction Stop
  123. }
  124. Catch {
  125. $ErrorMessage = $_.Exception.Message
  126. Write - host "ERROR: $ErrorMessage" - Foreground red
  127. $Log = Logwrite "$upn"
  128. "ERROR occured during execution $ErrorMessage"
  129. $Global: Eventlog += $Log
  130. Break
  131. }
  132. $ldo_Disable = $null
  133. }
  134. Else {
  135. Write - host "Error: The account $upn User License deosn't Match with AccountSKUID" - Foreground red
  136. $Log = Logwrite "$upn"
  137. "ERROR: The User License deosn't Match with AccountSKUID"
  138. $Global: Eventlog += $Log
  139. }
  140. }
  141. }
  142. $Lic = Get - MsolUser - UserPrincipalName $upn
  143. $ouserlicense = $Lic.Licenses | Select - Object - ExpandProperty ServiceStatus
  144. $EnabledServices = ($ouserlicense | Where - Object - Property ProvisioningStatus - EQ "Success").ServicePlan.ServiceName
  145. $DisablededServices = ($ouserlicense | Where - Object - Property ProvisioningStatus - EQ "Disabled").ServicePlan.ServiceName
  146. $Log2 = Logwrite "$upn"
  147. "Enabled Plan Post Change $CurrentLic :$EnabledServices"
  148. $Global: Eventlog1 += $Log2
  149. $Log3 = Logwrite "$upn"
  150. "Disabled Plan Post Change $CurrentLic : $DisablededServices"
  151. $Global: Eventlog1 += $Log3
  152. }
  153. Else {
  154. Write - host "The account $upn deosn't exist in cloud" - Foreground red
  155. $Log3 = Logwrite "$upn"
  156. "The account deosn't exist in cloud"
  157. $Global: Eventlog += $Log3
  158. }
  159. }
  160. If($Global: Eventlog1 - ne $null) {
  161. $Global: Eventlog1 | Export - csv.\$Logfilename1 - notype
  162. }
  163. If($Global: Eventlog - ne $null) {
  164. $Global: Eventlog | Export - csv.\$Logfilename - notype
  165. }
  166. Stop - Transcript