Adi was right, it is some sort of permissions issue. I actually resolved this just now when a coworker ran the query and got proper results, however he used his own login account. Im addition he "ran as administrator" to elevate the PS console. When I did this it worked correctly. I have no idea how I never had to do this in the past, and also I am a domain admin and therefore local admin on the DCs, but whatever. It now works using elevated PS prompt. For the record I went into ADSIedit with my regular using account and did not launch elevated session.....Strange but I'll take it.
You definitely want to use a for-each loop to enumerate each user and apply the license. The loop needs to call up the .UserPrincipalName
from each object returned in your Get-ADUser
query, as Office365 needs to work with that value when setting licenses:
Get-ADUser | %{ Set-MSOLUserLicense -UserPrincipalName $_.UserPrincipalName }
I have created my own answer here to explain a common case that I think you're describing in your question: You don't want to blanket apply the same license options to everyone.
A TechNet Blog on this matter is immensely helpful. You may not want to give your Finance team access to SharePoint Online/OneDrive for Business for data leakage reasons, or you may have a call center who you don't want to enable for Lync/Skype for Business.
To get information on your tenant, start at the top:
Get-MSOLAccountSku
This will return the license packs you have in your tenant. Some common SKUs are ENTERPRISEPACK and DESKLESSPACK. These will be listed by yourorg:LICENSEPACK
under AccountSkuId.
It is important to note that each of these License packs can have features disabled from them when you apply via PowerShell (similarly, you can choose to check/uncheck option boxes in the Admin Center).
To create this subset of license options, create a new variable and leverage the New-MSOLLicenseOptions
cmdlet:
$LicOpt = New-MsolLicenseOptions -AccountSkuId "yourorg:ENTERPRISEPACK" -DisabledPlans OFFICESUBSCRIPTION,MCOSTANDARD,SHAREPOINTWAC,SHAREPOINTENTERPRISE,RMS_S_ENTERPRISE
(The above options would correspond to the screenshot above, I'm sure you could guess that I totally pulled it from a provisioning script.)
Finally, we can tie this back to your Set-MsolUserLicense
in your ForEach loop:
$LicOpt = New-MsolLicenseOptions -AccountSkuId "yourorg:ENTERPRISEPACK" -DisabledPlans OFFICESUBSCRIPTION,MCOSTANDARD,SHAREPOINTWAC,SHAREPOINTENTERPRISE,RMS_S_ENTERPRISE
Get-ADUser | %{ Set-MsolUserLicense -UserPrincipalName $_.UserPrincipalName -AddLicenses "yourorg:ENTERPRISEPACK" -LicenseOptions $LicOpt }
As always, your tenant may vary. I hope I've given enough info for you to discover the options available and apply appropriately!
Best Answer
In most Remote Desktop/Terminal Server licensing situations I have worked with, this information is stored against the user object in Active Directory. So getting this info out is a matter of knowing either the right LDAP filter or properties to query.
I've got a JScript-based report that I run to pull this information out, using
cscript.exe
, but the principals should be the same in Powershell.In older servers/domains (<=2003), this information was stored in a single property,
terminalServer
; and in newer ones (>2003), this is spread across three properties (that I know of), calledmsTSManagingLS
,msTSLicenseVersion
andmsTSExpireDate
. Obviously, with more information to go on, it is easier to pull this from newer domains (but, since you are working with Powershell, this is probably fine).As such, assuming a version of Powershell and the AD module that supports scriptblock-style filters, the following (while slightly inefficient) should get you close:
If you are running on an older Powershell version, you may need to craft the filter in a more LDAP-friendly fashion. Maybe:
Once you have the relevant AD objects in the pipeline, you can call regular Powershell on them (such as
Where-Object { $_.msTSExpireDate -lt [DateTime]::Today.AddDays(-30) } | Disable-Account
)Note that you'll want to do a lot more work than I have done above to make sure you don't disable any reasonable accounts (especially as it might render you and/or other admins unable to access your own machines to resolve). At a minimum, I'd certainly look to limit this to users within a specific OU, e.g. by applying valid
-SearchBase
and-SearchScope
parameters to yourGet-ADUser
call, or do more checking in yourWhere-Object
filter (such as usingGet-ADPrincipalGroupMembership
to make sure they're not in the Domain Admins group).Also note that this only works for Remote Desktop servers running the full-blown Remote Desktop Services with a Remote Desktop Licensing Server. You can't use this to check users who remote in using the two-connection Admin mode.