Script: Grant-CsPolicyByADGroup.ps1 – Assign Lync/Skype for Business Policies to Users According to AD Group
This idea is from a LinkedIn post that I responded to. The original poster wanted to know if there was a way to manage Lync external access policies based on AD group membership. Absolutely!
This is a fairly simple script that uses a scheduled task that runs every 4 hours, looks at the members of a given AD security group, including nested groups, and applies a Lync policy to each member. The name of the AD security group and the type and name of the policy are all configurable. The ActiveDirectory and Lync PowerShell modules are used to complete this. The actual moving parts are pretty simple – really just two lines of code. But some extra error catching, installation code, and safeguards make it a tad bigger.
Caveat – users get policies when they launch the Lync client. So even though a policy might be assigned to a user, they won’t see any change until the client is restarted.
Caveat #2 – if you configure this script with several scheduled tasks to handle different policies and different AD groups, make sure users don’t end up in multiple groups, or you could have unintended results. Also removing a user from a group does NOT revert their policy back. The reason I didn’t add that is because moving a user from one group to another could cause problems if the script set them back to a default policy, yet another group needed to change it to a different policy.
Installation
Execution Policy: Third-party PowerShell scripts may require that the PowerShell Execution Policy be set to either AllSigned, RemoteSigned, or Unrestricted. The default is Restricted, which prevents scripts – even code signed scripts – from running. For more information about setting your Execution Policy, see Using the Set-ExecutionPolicy Cmdlet.
Download the script from the DOWNLOAD section below. Open it in your favorite text editor.
Find the line that reads
[string]$GroupDN = "",
and put the Distinguished Name of the group in between the quotes. For example
[string]$GroupDN = "CN=Lync Policy Group,DC=contoso,DC=com",
Next, define the policy that will be granted to members of the group. Find the line that reads
[string]$PolicyName = "",
and put the name of the Lync policy in between those quotes, such as
[string]$PolicyName = "Executives External Access Policy",
The last thing we need to do in the script file is define what KIND of policy we’re going to grant.
Find the line that reads
[string]$PolicyType = "ExternalAccess",
And adjust accordingly. The allowed values are Archiving,Client,ClientVersion,Conferencing,ExternalAccess,HostedVoicemail,Location,Mobility,Pin,Presence,Voice to represent the various types of policies you can apply to a user. The default is ExternalAccess.
Next, ensure that the server where the script will run has both the ActiveDirectory and Lync PowerShell modules installed. Domain controllers typically have the ActiveDirectory module, and Lync servers have the Lync module. Install the appropriate ones using these steps.
To install the ActiveDirectory module, open PowerShell and type the following:
Import-Module ServerManager Add-WindowsFeature -name AD-Domain-Services -IncludeManagementTools
To install the Lync Server Management Tools, which includes the PowerShell module, install the core components. See Install Lync Server Administrative Tools for details.
This will ensure that both modules are available. The ActiveDirectory module is used to get the members of the AD security group, and the Lync module is used to actually grant the policy.
The script must run as a member of the CsUserAdministrator or CsAdministrator groups, as those have the rights to assign policies.
Next, open PowerShell and run the script with the -install switch. The script will prompt for the password of the currently logged on user, and then create the scheduled task to run the script every 4 hours.
Grant-CsPolicyByADGroup.ps1 -install
The scheduled task will run every 4 hours, with a start time of when you ran the -install option. You can open the scheduled task in Task Manager and adjust as needed.
You can run the script manually as well. Just run
Grant-CsPolicyByADGroup.ps1
Note that it may take a while before the policy is visible on the user account due to AD replication.
Donations
I’ve never been one to really solicit donations for my work. My offerings are created because *I* need to solve a problem, and once I do, it makes sense to offer the results of my work to the public. I mean, let’s face it: I can’t be the only one with that particular issue, right? Quite often, to my surprise, I’m asked why I don’t have a “donate” button so people can donate a few bucks. I’ve never really put much thought into it. But those inquiries are coming more often now, so I’m yielding to them. If you’d like to donate, you can send a few bucks via PayPal at https://www.paypal.me/PatRichard. Money collected from that will go to the costs of my website (hosting and domain names), as well as to my home lab.
Download
v1.7 – 02-03-2017 – Grant-CsPolicyByADGroup.v1.7.zip
v1.6 – 09-23-2014 – Grant-CsPolicyByADGroup.v1.6.zip
v1.5 – 02-08-2014 – Grant-CsPolicyByADGroup.v1.5.zip
v1.4 – 01-27-2014 – Grant-CsPolicyByADGroup.v1.4.zip
v1.2 – 10-16-2012 – Grant-CsPolicyByADGroup.v1.2.zip
v1.1 – 09-19-2012 – Grant-CsPolicyByADGroup.v1.1.zip
v1.0 – 09-10-2012 – Grant-CsPolicyByADGroup.v1.0.zip
Changelog
See the changelog for this script for a description of changes with each release.
Pat, Very nice. You have no idea how timely this is for me! John
Pat, Very nice. You have no idea how timely this is for me! http://tsoorad.blogspot.com/2012/09/assign-lync-policies-to-users-according.html John
Updated to v1.1 today. Now supports nested AD groups, and defining the policy type is a little easier.
Do you really have to edit the script, or could you just run:
Grant-CsPolicyByADGroup.ps1 -GroupDN “CN=Lync Policy Group,DC=contoso,DC=com” -PolicyName “Executives External Access Policy” -PolicyType “ExternalAccess”
You can certainly run it with switches. The problem is that when running things with scheduled tasks, there is a limit to how long the command line can be. So orgs with longer OU names or group names run into issues.
Hey Pat,
Having some issues with the script. Is this an appropriate time to reach out.
PS C:\Grant-CsPolicyByADGroup> .\Grant-CsPolicyByADGroupv2.ps1
Where-Object : Cannot bind parameter ‘FilterScript’. Cannot convert the “Name”
value of type “System.String” to type “System.Management.Automation.ScriptBlock
“.
At C:\Grant-CsPolicyByADGroup\Grant-CsPolicyByADGroupv2.ps1:93 char:48
+ if (Get-Module -ListAvailable | Where-Object <<<< Name -eq "$nam
e") {
+ CategoryInfo : InvalidArgument: (:) [Where-Object], ParameterBi
ndingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerSh
ell.Commands.WhereObjectCommand
The term 'Get-ADGroupMember' is not recognized as the name of a cmdlet, functio
n, script file, or operable program. Check the spelling of the name, or if a pa
th was included, verify that the path is correct and try again.
At C:\Grant-CsPolicyByADGroup\Grant-CsPolicyByADGroupv2.ps1:156 char:30
+ $Members = Get-ADGroupMember <<<< -Identity $Group
+ CategoryInfo : ObjectNotFound: (Get-ADGroupMember:String) [], C
ommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Get-CsAdUser : Cannot bind parameter 'Identity'. Cannot convert value "" to typ
e "Microsoft.Rtc.Management.AD.UserIdParameter". Error: "The parameter "identit
y" of type "UserIdParameter" is empty. Specify a valid value and then try again
."
At C:\Grant-CsPolicyByADGroup\Grant-CsPolicyByADGroupv2.ps1:166 char:21
+ if ((Get-CsAdUser <<<< $name -ea 0).enabled){
+ CategoryInfo : InvalidArgument: (:) [Get-CsAdUser], ParameterBi
ndingException
+ FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.Rtc.Man
agement.AD.Cmdlets.GetAdUserCmdlet
Hey Pat,
Script version 1.5 was the one I had trouble with. I switched it for 1.4 and it works like a charm. Thank you for this script saved me.
Great script, it would be even more powerful if it could also remove users that are no longer in the AD group. We
I’m trying v1.6 of this script and get the following when trying to install:
At C:\scripts\Grant-CsPolicyByADGroup.ps1:170 char:56
+ Write-Verbose “Failed granting `”$PolicyName`” to $name:
$error”
+ ~~~~~~
Variable reference is not valid. ‘:’ was not followed by a valid variable name
character. Consider using ${} to delimit the name.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : InvalidVariableReferenceWithDrive
I’m also getting this error:
At C:\scripts\Grant-CsPolicyByADGroup.ps1:170 char:56
+ Write-Verbose “Failed granting `”$PolicyName`” to $name:
$error”
+ ~~~~~~
Variable reference is not valid. ‘:’ was not followed by a valid variable name
character. Consider using ${} to delimit the name.
+ CategoryInfo : ParserError: (:) [], ParseException
+ FullyQualifiedErrorId : InvalidVariableReferenceWithDrive
It’s working now – thanks!
I receive the following error message. Any ideas? Thanks.
Write-Log : The term ‘Write-Log’ is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was
included, verify that the path is correct and try again.
At C:\Users\Gluttonyt\Desktop\Grant-CsPolicyByADGroup.ps1:188 char:7
+ Write-Log -Message “Current version. Version $Ga is latest version.” -NoCo …
+ ~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (Write-Log:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Hi, Please help me to assign Voice policy to Azure AD group for MS Teams? what to do for Teams? Regards