Sharing a very useful Script that can be utilized in every office 365 enviornment & can be used for automating the license assignment based on
Active Directory Group Membership. We have used it to assign two services “Sway” & “Office” but you can modify as per environmental needs.
Quest AD module has been used to fetch group membership recursively from AD group.
Below Logic has been used:
- Fetch users UPN from AD group recursively(nested groups are covered). (If error exit/Alert)
- Collect users by connecting to the cloud if they are not already assigned sway & office. (If error exit/Alert)
- Loop thru the collection of licensed users, assign sway & office (not altering their existing applied services)
- For unlicensed users assign license & only activate sway & office.(Usage location parmeter as per enviornment)
- Send a report after users have been processed.
- Script can be run in read-only mode by altering $mode variable.
- if changes are more than specified number than script will exit & Alert
- Recycle logs after 60 days.
Extract the zip file from below link & you are ready to go, for encryption of cloud credentials I have included the Encryptpass folder.
https://gallery.technet.microsoft.com/scriptcenter/Automate-O365-License-0b05d9b7
Just run the batch file inside it to encrypt the password, securepassword.txt file will get generated & from that you can copy the password inside the script.
Change the below variables as per your needs:
$report = “E:\scripts\LicenseMgmt\report” + “\” + “Report_Licassign” + $date1 + “_” + $time + “_.csv”
————————————————————————————————
$countofchanges = “100”
$licenseent = “Company:ENTERPRISEPACK”
$service1 = “SWAY”
$service2 = “OFFICESUBSCRIPTION”$Disabledsvcs=@(“PROJECTWORKMANAGEMENT”,”INTUNE_O365″,
“YAMMER_ENTERPRISE”,”RMS_S_ENTERPRISE”,”MCOSTANDARD”,”SHAREPOINTWAC”,”SHAREPOINTENTERPRISE”,”EXCHANGE_S_ENTERPRISE”)
$email1 = “vikass@labtest.com”
$from = “DoNotReply@labtest.com”
$smtpserver = “smtpserver”
$mode = “Readonly” ################### for Assigning Licenses change mode to “Write”
$group = “o365ADgroup” ######################Adgroup that will be used for License Assignment
————————————————————————————————–
Update below for Cloud connectivity:
$encrypted = “01000000d08c9ddf0115d1118c7a00c04fc297eb01000000fbd4194448820c140000007dacefa1e19356da0cf57bf36d320d7050919799”
$user = “cloudadmin@domain.onmicrosoft.com”$password = ConvertTo-SecureString -string $encrypted
—————————————————————————————————
After making changes, just run the batch file(don’t forget to change the $mode variable to “Write” when you are ready to implement it)
Here is the interactive result:
CSV report in Email:
Update means that services are updated, user already had license assigned but sway or office proplus was not present.
Applied means user was unlicensed & license has been assigned (office proplus & sway has been activated)
Note:-
1. Encryption of password is machine & account specific.
2. Usage Location parameter has been used in the script as US.
Quest AD & Azure AD shell is required for this script execution.
############################################################### # Author: Vikas Sukhija (http://techwizard.cloud) # Date: 9/28/2016 # Reviewer: # # Description: Office 365 Users License Assignment # Apply Sway & Proplus only # Updated: Readonly Mode ############################################################### $date1 = get-date -format d $date1 = $date1.ToString().Replace("/","-") $time = get-date -format t $time = $time.ToString().Replace(":", "-") $time = $time.ToString().Replace(" ", "") $logs = ".\Logs" + "\" + "Processed_PS_" + $date1 + "_" + $time + "_.log" $report = "E:\scripts\LicenseMgmt\report" + "\" + "Report_Licassign" + $date1 + "_" + $time + "_.csv" $limit = (Get-Date).AddDays(-60) #for report recycling $path1 = ".\report\" $path2 = ".\Logs\" $collusers=@() $collection=@() ###################Variables to be defined####################### $countofchanges = "100" $licenseent = "Company:ENTERPRISEPACK" $service1 = "SWAY" $service2 = "OFFICESUBSCRIPTION" $Disabledsvcs=@("PROJECTWORKMANAGEMENT","INTUNE_O365","YAMMER_ENTERPRISE","RMS_S_ENTERPRISE","MCOSTANDARD","SHAREPOINTWAC","SHAREPOINTENTERPRISE","EXCHANGE_S_ENTERPRISE") $email1 = "vikass@labtest.com" $from = "DoNotReply@labtest.com" $smtpserver = "smtpserver" $mode = "Readonly" ################### for Assigning Licenses change mode to "Write" $group = "Ad group" ######################Adgroup that will be used for License Assignment Start-Transcript -Path $logs get-date if($mode -eq "Write"){Write-host "Script will run in Implementation mode" -foregroundcolor green} else{Write-host "Script will run in Readonly mode" -foregroundcolor Blue} ####################Encrypted password for MSOL################ $encrypted = "01000000d08c9ddf0115d1164876789a0000000100000002753034465a7b3cd5c1cb57d2a2328d8280000003f629e1c6817afc387a930353fc6cb7f793775abd30e08c199d91b54fd37f7963ce1a7fb492e6be4140000008f64e40ec5186af161d62af27a082839eb967c8e" $user = "clouduaadmin@company.onmicrosoft.com" $password = ConvertTo-SecureString -string $encrypted $Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $User, $password ##########Connect to MSOL##################### Connect-MsolService -Credential $Credential $AllLicensingPlans = Get-MsolAccountSku | where{$_.AccountSkuId -eq $licenseent} ############################################### if($error -ne $null){ $msg = new-object Net.Mail.MailMessage $smtp = new-object Net.Mail.SmtpClient($smtpServer) $msg.From = $from #mail recipient $msg.To.Add($email1) $msg.Subject = "Error occured in Connecting to cloud" $msg.Body = $error $smtp.Send($msg) exit } ##############Add Snapins##################### If ((Get-PSSnapin | where {$_.Name -match "Quest.ActiveRoles.ADManagement"}) -eq $null) { Add-PSSnapin Quest.ActiveRoles.ADManagement } $users = Get-QADGroupMember $group -sizelimit 0 -Indirect | where{$_.type -eq "user"} | Select UserprincipalName $users.count ############################################### if($error -ne $null){ $msg = new-object Net.Mail.MailMessage $smtp = new-object Net.Mail.SmtpClient($smtpServer) $msg.From = $from #mail recipient $msg.To.Add($email1) $msg.Subject = "Error occured in Fetching AD group members" $msg.Body = $error $smtp.Send($msg) exit } #######################Process Fectched UPN############################## foreach($upn in $users){ $user = $upn.UserprincipalName $lic = get-msoluser -UserPrincipalName $user ############fetch users with sway or office subscription not activated###### $status = $lic.Licenses.servicestatus if($status -ne $null){ foreach($svc in $status) { $svcnm = $svc.Serviceplan.ServiceName $svcsts = $svc.ProvisioningStatus if((($svcnm -eq $service1) -and ($svcsts -eq "Disabled")) -or (($svcnm -eq $service2) -and ($svcsts -eq "Disabled"))){ $collusers+=$user} } } else{ $collusers+=$user } } $collusers = $collusers | select -Unique $collusers $collusers.count if($collusers.count -ge $countofchanges){ $msg = new-object Net.Mail.MailMessage $smtp = new-object Net.Mail.SmtpClient($smtpServer) $msg.From = $from #mail recipient $msg.To.Add($email1) $msg.Subject = "License assignment Script Count of changes is more than $countofchanges" $msg.Body = $error $smtp.Send($msg) exit } ############################################### if($error -ne $null){ $msg = new-object Net.Mail.MailMessage $smtp = new-object Net.Mail.SmtpClient($smtpServer) $msg.From = $from #mail recipient $msg.To.Add($email1) $msg.Subject = "Error occured in Fetching users" $msg.Body = $error $smtp.Send($msg) exit } #####################users that we want to process now################# if($collusers){ $collusers | foreach-object{ $USR = $_ $lic1 = get-msoluser -UserPrincipalName $USR $status1 = $lic1.Licenses.servicestatus $mcoll = "" | Select Userprincipalname,Licensestatus if($status1 -ne $null){ $collnmsts=@() foreach($svc1 in $status1){ $svcnm1 = $svc1.Serviceplan.ServiceName $svcsts1 = $svc1.ProvisioningStatus if((($svcsts1 -eq "Disabled") -and ($svcnm1 -ne $service1)) -and (($svcsts1 -eq "Disabled") -and ($svcnm1 -ne $service2))){ $collnmsts += $svcnm1}} $O365Licences=$null for($i = 0; $i -lt $AllLicensingPlans.Count; $i++){ $O365Licences = New-MsolLicenseOptions -AccountSkuId $AllLicensingPlans[$i].AccountSkuId -DisabledPlans $collnmsts} if($mode -eq "Write"){Set-MsolUserLicense -UserPrincipalName $USR -LicenseOptions $O365Licences} if($error){Write-host "Error occured applying license for $USR" -foregroundcolor yellow $mcoll.Userprincipalname=$USR $mcoll.Licensestatus="error" $error.clear()} else{Write-host "Updating license for $USR" -foregroundcolor magenta $mcoll.Userprincipalname=$USR $mcoll.Licensestatus="Updated"} } else { $O365Licences=$null $O365Licences = New-MsolLicenseOptions -AccountSkuId $licenseent -DisabledPlans $Disabledsvcs if($mode -eq "Write"){ Set-MsolUser -UserPrincipalName $USR -UsageLocation US Set-MsolUserLicense -addlicenses $licenseent -UserPrincipalName $USR -LicenseOptions $O365Licences} if($error){Write-host "Error occured applying license for $USR" -foregroundcolor yellow $mcoll.Userprincipalname=$USR $mcoll.Licensestatus="error" $error.clear()} else{Write-host "Applying license for $USR" -foregroundcolor blue $mcoll.Userprincipalname=$USR $mcoll.Licensestatus="Applied"} } $collection+=$mcoll } } else{ Write-host "Nothing to process" -foregroundcolor green } if($collection){$collection | export-csv $report -notypeinfo $msg = new-object Net.Mail.MailMessage $smtp = new-object Net.Mail.SmtpClient($smtpServer) $msg.From = $from $attach = new-object Net.Mail.Attachment($report) #mail recipient $msg.To.Add($email1) $msg.Subject = "o365 License Assignment User Report" $msg.Body = "o365 License Assignment User Report" $msg.Attachments.Add($attach) $smtp.Send($msg) } ########################Recycle reports & logs############## Get-ChildItem -Path $path1 | Where-Object { $_.CreationTime -lt $limit } | Remove-Item -recurse -Force Get-ChildItem -Path $path2 | Where-Object { $_.CreationTime -lt $limit } | Remove-Item -recurse -Force get-date stop-transcript ######################################################################################
Regards
Tech Wizard