Jump to content

Recommended Posts

Posted (edited)

Hi all.

 

I'm trying to build an automatic licensing script for our site (with a few more bells and whistles than the previous versions)

 

This script will run for all users (Staff and Students), licensing new users automatically. I've all of the components working, but I can't get it to query

 

So far I can retrieve the groups required using Get-MsolGroupMember, but then I want to query/edit this list so that it only contains unlicensed users

 

There are very few parameters, so could the results be piped to Get-MsolUser to end up with just unlicesed users?

 

This is my first serious attempt at powershell, so I'm a little bit stuck here - it may be that I'm going the wrong way about it.

 

Thanks in advance, Ben

Edited by Mr.Ben
Posted

This is how we get our unlicensed student users for our automated script. All of their usernames start STU, so it's an easy filter, but you can change it to be any other value that was uploaded from AD, such as description.

 

$users = Get-MsolUser -UnlicensedUsersOnly -Synchronized -MaxResults 50 | Where-Object {$_.UserPrincipalName -like "STU????-*" }

  • Thanks 1
Posted

That would work for our students (who all start with their intake year). but not for our staff, who have no defining username feature.

 

I can't use department (as this changes for our room booking system, and description isn't any good either for this, hence trying to find a way of getting the licensing status using the group membership.

 

Hmm. May be something to sleep on! :-)

Posted

In AD, I make use of the "Office" field to store if the member of staff is a teaching or non-teaching.

Where-Object {$_.Office -like "Teaching Staff" } would pull those records alone. You can use any other AD field that is being synchronised within reason.

  • 3 months later...
Posted

Hello,

 

Sorry to resurrect this but... I am in the same boat, and its something I have finally got round to looking at.

Does anyone have an example script for this?

looking to assign a licence to students and a different license to staff depending on an attribute in ad account or if belonging to an ad group if that's possible?

 

thanks

Posted

I currently use state, and put either student or staff in there.

 

I don't have my script right now but I'll post it here once I get back to work.

 

It sets location for each user, a license and also the new student advantage for students too. I have set a task on the server to trigger on an event which is logged after dirsync.

Posted

Here is what I'm using:

 

#This script Assigns the default licensing options for Office 365 for Staff and all Year Groups
#Create Credentials (Password from Secure String)
#If this needs to be changed, run Read-Host -AsSecureString | ConvertFrom-SecureString | Out-File C:\ScheduledTasks\O356PW.txt
$Password = type C:\ScheduledTasks\O356PW.txt|ConvertTo-SecureString
$Credentials = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist “[email protected]”,$Password
#Connect to MSOL Service
Connect-MsolService -Credential $Credentials
#Licensing Types and options
$StaffLic = New-MsolLicenseOptions -AccountSKUID chewvalleyschool:STANDARDWOFFPACK_FACULTY -DisabledPlans SHAREPOINTWAC_EDU,SHAREPOINTSTANDARD_EDU
$StudentLic  = New-MsolLicenseOptions -AccountSKUID chewvalleyschool:STANDARDWOFFPACK_STUDENT -DisabledPlans SHAREPOINTWAC_EDU,MCOSTANDARD,SHAREPOINTSTANDARD_EDU
#Search each group for unlicensed users
$UnlicencedStaffUsers=Get-MsolUser -UnlicensedUsersOnly -Synchronized -All|Where-Object {$_.Office -eq  "Chew Valley School"}
$Unlicenced13Users = Get-MsolUser -UnlicensedUsersOnly -Synchronized -All|Where-Object {$_.UserPrincipalName -like "13*@schoolname.co.uk"}
$Unlicenced12Users = Get-MsolUser -UnlicensedUsersOnly -Synchronized -All|Where-Object {$_.UserPrincipalName -like "12*@schoolname.co.uk"}
$Unlicenced11Users = Get-MsolUser -UnlicensedUsersOnly -Synchronized -All|Where-Object {$_.UserPrincipalName -like "11*@schoolname.co.uk"}
$Unlicenced10Users = Get-MsolUser -UnlicensedUsersOnly -Synchronized -All|Where-Object {$_.UserPrincipalName -like "10*@schoolname.co.uk"}
$Unlicenced09Users = Get-MsolUser -UnlicensedUsersOnly -Synchronized -All|Where-Object {$_.UserPrincipalName -like "09*@schoolname.co.uk"}
$Unlicenced08Users = Get-MsolUser -UnlicensedUsersOnly -Synchronized -All|Where-Object {$_.UserPrincipalName -like "08*@schoolname.co.uk"}
$Unlicenced07Users = Get-MsolUser -UnlicensedUsersOnly -Synchronized -All|Where-Object {$_.UserPrincipalName -like "07*@schoolname.co.uk"}
# For each user found apply user settings (location and licence)
#Staff
foreach ($UnlicencedStaffUser in $UnlicencedStaffUsers) 
{Write-Host $UnlicencedStaffUser.UserPrincipalName
Set-MsolUser -UserPrincipalName $UnlicencedStaffUser.UserPrincipalName -UsageLocation GB
Set-MsolUserLicense -UserPrincipalName $UnlicencedStaffUser.UserPrincipalName -AddLicenses "chewvalleyschool:STANDARDWOFFPACK_FACULTY" -LicenseOptions $StaffLic}
#Intake 13
foreach ($Unlicenced13User in $Unlicenced13Users) 
{Write-Host $Unlicenced13User.UserPrincipalName
Set-MsolUser -UserPrincipalName $Unlicenced13User.UserPrincipalName -UsageLocation GB
Set-MsolUserLicense -UserPrincipalName $Unlicenced13User.UserPrincipalName -AddLicenses "schoolname:STANDARDWOFFPACK_STUDENT" -LicenseOptions $StudentLic
Set-MsolUserLicense -UserPrincipalName $Unlicenced13User.UserPrincipalName -AddLicenses "schoolname:OFFICESUBSCRIPTION_STUDENT"}
#Intake 12
foreach ($Unlicenced12User in $Unlicenced12Users) 
{Write-Host $Unlicenced12User.UserPrincipalName
Set-MsolUser -UserPrincipalName $Unlicenced12User.UserPrincipalName -UsageLocation GB
Set-MsolUserLicense -UserPrincipalName $Unlicenced12User.UserPrincipalName -AddLicenses "schoolname:STANDARDWOFFPACK_STUDENT" -LicenseOptions $StudentLic
Set-MsolUserLicense -UserPrincipalName $Unlicenced12User.UserPrincipalName -AddLicenses "schoolname:OFFICESUBSCRIPTION_STUDENT"}
#Intake 11
foreach ($Unlicenced11User in $Unlicenced11Users) 
{Write-Host $Unlicenced11User.UserPrincipalName
Set-MsolUser -UserPrincipalName $Unlicenced11User.UserPrincipalName -UsageLocation GB
Set-MsolUserLicense -UserPrincipalName $Unlicenced11User.UserPrincipalName -AddLicenses "schoolname:STANDARDWOFFPACK_STUDENT" -LicenseOptions $StudentLic
Set-MsolUserLicense -UserPrincipalName $Unlicenced11User.UserPrincipalName -AddLicenses "schoolname:OFFICESUBSCRIPTION_STUDENT"}
#Intake 10
foreach ($Unlicenced10User in $Unlicenced10Users) 
{Write-Host $Unlicenced10User.UserPrincipalName
Set-MsolUser -UserPrincipalName $Unlicenced10User.UserPrincipalName -UsageLocation GB
Set-MsolUserLicense -UserPrincipalName $Unlicenced10User.UserPrincipalName -AddLicenses "schoolname:STANDARDWOFFPACK_STUDENT" -LicenseOptions $StudentLic
Set-MsolUserLicense -UserPrincipalName $Unlicenced10User.UserPrincipalName -AddLicenses "schoolname:OFFICESUBSCRIPTION_STUDENT"}
#Intake 09
foreach ($Unlicenced09User in $Unlicenced09Users) 
{Write-Host $Unlicenced109User.UserPrincipalName
Set-MsolUser -UserPrincipalName $Unlicenced09User.UserPrincipalName -UsageLocation GB
Set-MsolUserLicense -UserPrincipalName $Unlicenced09User.UserPrincipalName -AddLicenses "schoolname:STANDARDWOFFPACK_STUDENT" -LicenseOptions $StudentLic
Set-MsolUserLicense -UserPrincipalName $Unlicenced09User.UserPrincipalName -AddLicenses "schoolname:OFFICESUBSCRIPTION_STUDENT"}
#Intake 08
foreach ($Unlicenced08User in $Unlicenced08Users) 
{Write-Host $Unlicenced08User.UserPrincipalName
Set-MsolUser -UserPrincipalName $Unlicenced08User.UserPrincipalName -UsageLocation GB
Set-MsolUserLicense -UserPrincipalName $Unlicenced08User.UserPrincipalName -AddLicenses "schoolname:STANDARDWOFFPACK_STUDENT" -LicenseOptions $StudentLic
Set-MsolUserLicense -UserPrincipalName $Unlicenced08User.UserPrincipalName -AddLicenses "schoolname:OFFICESUBSCRIPTION_STUDENT"}
#Intake 07
foreach ($Unlicenced07User in $Unlicenced07Users) 
{Write-Host $Unlicenced07User.UserPrincipalName
Set-MsolUser -UserPrincipalName $Unlicenced07User.UserPrincipalName -UsageLocation GB
Set-MsolUserLicense -UserPrincipalName $Unlicenced07User.UserPrincipalName -AddLicenses "schoolname:STANDARDWOFFPACK_STUDENT" -LicenseOptions $StudentLic
Set-MsolUserLicense -UserPrincipalName $Unlicenced07User.UserPrincipalName -AddLicenses "schoolname:OFFICESUBSCRIPTION_STUDENT"}
exit;

  • Thanks 1
Posted

This is the script i use at the moment.

 

# AutoProvisionUsersAfterDirSync.ps1
# Powershell Script to be ran automatically with after each sync.
#
# Import MSol Module
Write-Host "Import MSOnline Module"
Import-Module MSOnline

# Create Credentials
Write-Host "Create Credentials"
$username = "admin_account"
$password = ConvertTo-SecureString "password" -AsPlainText -Force
$MsolCred = New-Object -TypeName System.Management.Automation.PSCredential ($username, $password)

# Connect to Msol
Write-Host "Connect to Msol Service"
Connect-MsolService -Credential $MsolCred

# Connect to Exchange Online 
Write-Host "Connect to Exchange Online"
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $MsolCred -Authentication Basic -AllowRedirection
Import-PSSession $Session

# set Usage Location for unlicensed users (all licensed users should have a location already)
Write-Host "Start Setting usage location"
$users = Get-MsolUser -All -UnlicensedUsersOnly |%{Write-Host "Set usage location - " $_.UserPrincipalName; Set-MsolUser -UserPrincipalName $_.UserPrincipalName -UsageLocation GB}

# Assign Staff Licenses
Write-Host "Assign Staff Licenses"
$users = Get-MsolUser -All -State "Staff" -UnlicensedUsersOnly |%{Write-Host "Assign Staff License to " $_.UserPrincipalName;Set-MsolUserLicense -UserPrincipalName $_.UserPrincipalName -AddLicenses "office365domain:STANDARDWOFFPACK_FACULTY"}

# Assign Student Licenses
Write-Host "Assign Student Licenses"
$users = Get-MsolUser -All -State "Student" -UnlicensedUsersOnly |%{Write-Host "Assign Student License to " $_.UserPrincipalName;Set-MsolUserLicense -UserPrincipalName $_.UserPrincipalName -AddLicenses "office365domain:STANDARDWOFFPACK_STUDENT"}
$users = Get-MsolUser -All -State "Student" -UnlicensedUsersOnly |%{Write-Host "Assign Student License to " $_.UserPrincipalName;Set-MsolUserLicense -UserPrincipalName $_.UserPrincipalName -AddLicenses "office365domain:OFFICESUBSCRIPTION_STUDENT"}


# Set TimeZone & Language
Write-Host "Set TimeZone & Language"
Get-Mailbox -ResultSize unlimited -Filter {(RecipientTypeDetails -eq "UserMailbox")} | Set-MailboxRegionalConfiguration -TimeZone "GMT Standard Time" -Language 2057

# Turn Archive on for each Staff mailbox
Write-Host "Set Archive for Staff"
Get-Mailbox -Filter {(RecipientTypeDetails -eq "UserMailbox") -and (ArchiveStatus -eq "None")}| where{$_.UserPrincipalName -like "*@domain.co.uk"} | Enable-Mailbox -Archive

# Set Retention of deleted emails to 30 days
Write-Host "Set E-mail retension to 30 days"
Get-Mailbox -ResultSize unlimited -Filter {(RecipientTypeDetails -eq 'UserMailbox')} | Set-Mailbox -RetainDeletedItemsFor 30

# Disconnect to Exchange Online 
Write-Host "Disonnect to Exchange Online"
Remove-PSSession $Session

 

A few notes...

 

storing the password like this is not the best way, you can generate an encrypted password and use that as long as it's on the same server.

 

the license to assign to staff/students should start with the domain that you have registered with office 365, so school.co.uk becomes schoolco for me.

 

You can use a powershell command to find you license names.

 

The last 3 commands, setting the time zone, archive and retention time of deleted items i would like to do for only new users but i haven't found a good way of filtering once connected to Exchange Online.

 

The command to set archive on i filter but the end of upn/e-mail as i use @students.school.co.uk and @school.co.uk for staff.

 

Please let me know if you have any questions or ideas on how to improve this.

  • Thanks 1
Posted

A note on @Marshall_IT's script - I had problems setting the timezone & language in the same script as assigning the licence, as it takes time for the mailbox to be created after the licence is assigned and until that point the timezone part will error. I ended up dropping it in a separate script and running that section later once I'd checked that the mailboxes were created successfully.

 

Might just be me, though, I've only specced scripting to Cludge on my character sheet :)

Posted

I've not had it throw up many errors, but this script doesn't log anything yet, I've not had time to go through error checking and validation with this yet.

 

Just to add, i've just switched to Mr Ben's way of generating the password.

Posted

Yes, just to clear up, -State is the State or Province field from the Address tab in AD.

I used this field as i hadn't installed the Exchange extended attributes yet. I have now and will be changing to use this in the future.

  • Thanks 1
  • 4 weeks later...
Posted

Sorry to bring this up again.... but yes that is how ling it has taken me do get my head around Powershell :$

 

I have a working script, a bit of both of those combined - thank you.

 

I have a server that runs azure ad sync and If I manually, aka right click and run as administrator - the script runs and does what's required changing a test account to the correct licensing choices, super duper.

 

So I have setup scheduled task to run this, I sued this guide: How to schedule a Powershell script using Scheduled tasks in Windows Server 2008 R2 | MicrosoftPro.nl

 

However It appears that the schedule - set to run every hour, doesn't "kick in", but if I manually run the task, it does run BUT doesn't appear to actually run the PowerShell script, nothing much in event logs to go on from where I am looking, but scheduled tasks reports its fine and dandy and did start PowerShell, I have set the schedule to run as a domain admin, and its the same account I use when manually running the script.

 

Just hoping someone may take pity on a poor old GUI tick box checker like me and get me over this final hurdle!

  • 4 weeks later...
Posted (edited)

@sonofsanta - If your script needs to create accounts then assign the timezone, the trick is to use Test-MAPIconnectivity against the last account you created and wait until it returns success before looping through and setting the timezone, customattributes,etc.

 

Here is the function to do that that I use in my script:

 

Function Wait_for_MAPI($AddrToCheck)

{

$sleeptime = 60 #number of seconds to sleep per loop

$maxattempts = 180 #number of times to loop before giving up - 3 hours

 

$testresult=(Test-MapiConnectivity $AddrToCheck).Result

$attempts = 0

 

While (($testresult -ne "Success") -and ($attempts -lt $maxattempts) )

{

Sleep -s $sleeptime;

$testresult=(Test-MapiConnectivity $AddrToCheck).Result

$attempts++

}

 

if ( $testresult -eq "Success" )

{ return $true }

else

{ return $false }

}

 

So basically create your user accounts, then call wait_for_mapi, giving it the email address of the last account created. If it returns true, loop through and set the timezones, customattributes,etc.

If it returns false, well, something went wrong.

Edited by DavidD
  • Thanks 1

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now



×
×
  • Create New...