+ Post New Thread
Results 1 to 14 of 14
Cloud Services Thread, Office 365 Licensing Powershell Query in Technical; Hi all. I'm trying to build an automatic licensing script for our site (with a few more bells and whistles ...
  1. #1
    Mr.Ben's Avatar
    Join Date
    Jan 2008
    Location
    A Pirate Ship
    Posts
    942
    Thank Post
    182
    Thanked 157 Times in 126 Posts
    Blog Entries
    2
    Rep Power
    65

    Office 365 Licensing Powershell Query

    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
    Last edited by Mr.Ben; 19th November 2013 at 03:37 PM.

  2. #2
    Boredguy's Avatar
    Join Date
    Jun 2011
    Location
    Swindon
    Posts
    600
    Thank Post
    4
    Thanked 133 Times in 124 Posts
    Rep Power
    50
    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????-*" }

  3. Thanks to Boredguy from:

    Mr.Ben (19th November 2013)

  4. #3
    Mr.Ben's Avatar
    Join Date
    Jan 2008
    Location
    A Pirate Ship
    Posts
    942
    Thank Post
    182
    Thanked 157 Times in 126 Posts
    Blog Entries
    2
    Rep Power
    65
    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! :-)

  5. #4
    Boredguy's Avatar
    Join Date
    Jun 2011
    Location
    Swindon
    Posts
    600
    Thank Post
    4
    Thanked 133 Times in 124 Posts
    Rep Power
    50
    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.

  6. #5
    jbailey's Avatar
    Join Date
    Jan 2011
    Posts
    77
    Thank Post
    21
    Thanked 31 Times in 17 Posts
    Rep Power
    34
    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

  7. #6
    Marshall_IT's Avatar
    Join Date
    Jul 2011
    Location
    Leeds
    Posts
    519
    Thank Post
    77
    Thanked 66 Times in 57 Posts
    Blog Entries
    1
    Rep Power
    19
    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.

  8. #7
    Mr.Ben's Avatar
    Join Date
    Jan 2008
    Location
    A Pirate Ship
    Posts
    942
    Thank Post
    182
    Thanked 157 Times in 126 Posts
    Blog Entries
    2
    Rep Power
    65
    Here is what I'm using:

    Code:
    #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 “administrator@schoolname.onmicrosoft.com”,$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;

  9. Thanks to Mr.Ben from:

    jbailey (6th March 2014)

  10. #8
    Marshall_IT's Avatar
    Join Date
    Jul 2011
    Location
    Leeds
    Posts
    519
    Thank Post
    77
    Thanked 66 Times in 57 Posts
    Blog Entries
    1
    Rep Power
    19
    This is the script i use at the moment.

    Code:
    # 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.

  11. Thanks to Marshall_IT from:

    jbailey (6th March 2014)

  12. #9

    sonofsanta's Avatar
    Join Date
    Dec 2009
    Location
    Lincolnshire, UK
    Posts
    5,003
    Thank Post
    874
    Thanked 1,458 Times in 1,002 Posts
    Blog Entries
    47
    Rep Power
    644
    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

  13. #10
    Marshall_IT's Avatar
    Join Date
    Jul 2011
    Location
    Leeds
    Posts
    519
    Thank Post
    77
    Thanked 66 Times in 57 Posts
    Blog Entries
    1
    Rep Power
    19
    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.

  14. #11

    Join Date
    Feb 2013
    Location
    South West England
    Posts
    172
    Thank Post
    0
    Thanked 29 Times in 28 Posts
    Rep Power
    31
    What is the -State switch and how do you define Student or Staff? Is it in AD?

  15. #12
    Marshall_IT's Avatar
    Join Date
    Jul 2011
    Location
    Leeds
    Posts
    519
    Thank Post
    77
    Thanked 66 Times in 57 Posts
    Blog Entries
    1
    Rep Power
    19
    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.

  16. Thanks to Marshall_IT from:

    jbailey (6th March 2014)

  17. #13
    jbailey's Avatar
    Join Date
    Jan 2011
    Posts
    77
    Thank Post
    21
    Thanked 31 Times in 17 Posts
    Rep Power
    34
    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!

  18. #14

    Join Date
    Apr 2014
    Location
    Waleska
    Posts
    6
    Thank Post
    4
    Thanked 1 Time in 1 Post
    Rep Power
    0
    @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.
    Last edited by DavidD; 22nd April 2014 at 07:45 PM.

  19. Thanks to DavidD from:

    sonofsanta (23rd April 2014)

SHARE:
+ Post New Thread

Similar Threads

  1. Office 365 auto-assign licenses
    By themightymrp in forum Cloud Services
    Replies: 9
    Last Post: 7th February 2014, 07:56 AM
  2. Office 365 upgrade query - Skydrive Pro
    By tj2419 in forum Cloud Services
    Replies: 3
    Last Post: 10th September 2013, 08:21 PM
  3. Bulk change Office 365 user names using Powershell?
    By adamf in forum Cloud Services
    Replies: 7
    Last Post: 10th July 2013, 08:14 AM
  4. Office 365 Powershell command, not doing what I expect
    By mbedford in forum Cloud Services
    Replies: 3
    Last Post: 7th June 2013, 08:37 PM
  5. Office 365 Useful Powershell
    By sottonk in forum Cloud Services
    Replies: 2
    Last Post: 8th March 2013, 01:54 PM

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •