Automate O365 License Assignment based on AD Group membership

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.

PowerShell
############################################################### 
#            Author: Vikas Sukhija (http://msexchange.me) 
#            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($msgexit 
}  
 
##############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($msgexit 
}  
 
 
#######################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($msgexit 
}  
 
############################################### 
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($msgexit 
}  
 
#####################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

Sukhija Vikas

http://msexchange.me

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s