To use call admission control or location-based routing in Lync, one of the first steps is to define all the sites and subnets used in the company and to assign the sites to network regions. In larger companies, this can be a tedious process if this information is not stored in a central, easily accessible location.
One place where network site/subnet information can sometimes be centrally found is within Active Directory itself. Active Directory and other applications such as Exchange uses site/subnet information to determine where to direct clients for authentication services (among other things). Ideally, every site and subnet should be defined using the Active Directory Sites and Services snap-in. If the Active Directory administrator has diligently defined all the sites/subnets, this information can be easily parsed and used in Lync.
I've created a short script that will automate the creation of network sites and subnets using the information stored in AD Sites and Services. Again, this script is only useful if all the sites/subnets have been defined in AD. Thanks to Greig Sheridan who fixed the script to deal with AD site names that have characters that are invalid for Lync site names (such as underscore).
Copy the below script into a .PS1 file on a Lync server and run it. As always, be careful and test this in a lab first. I can't be responsible for any damage this script will cause.
The script will first check to see if a Lync network region already exists. If so, it will select the first one it sees as the base for all the subnets. If one doesn't exist, it will create one using the first Lync site as the base. If need be, you can define additional network sites later.
The script will then create all the sites/subnets based on information from AD. All the sites will be assigned to the one network region selected according to the rules in the previous paragraph. Since there is no way for the script to know which site belongs to which region, this will have to be done manually if multiple Lync network regions exist.
IMPORTANT: The script will also create the required subnets for all the Lync edge A/V public IP addresses with a 32-bit subnet mask as per the requirements for call admission control. You will have to manually assign these subnets to the sites where you deployed the edge servers.
While this script doesn't try to do everything associated with setting up call admission control, it does go a long way towards automating a good chunk of the process. A future revision of the Lync Optimizer will hopefully close the loop and help completely automate the work required to setup location-based routing.
As a final side note, one thing I don't understand is why Lync can't leverage AD Sites & Services for this information directly. Exchange versions since 2007 have used AD Sites & Services for mail routing, so its not like it hasn't been done before. Maybe a future version of Lync will add this functionality. Until then, this script should help those who have well-defined site/subnet information in Active Directory.
Great script Ken. Iv also thought the same regarding Sites/Services and why Lync isn't incapable of using this for its sub-net configuration. Maybe its a deliberate omission from the Lync team. As as you rightly say Exchange moved to this model since Exchange 2007. But may be its because in many environments iv worked in iv yet to see sites and services configured correctly to match the underlying network. Bearing in mind how important voice is would you want it to be left at the behest of a AD admin who hasn't configured Sites and Services properly? Either way i hope this feature does appear in future version(s). It would certainly save a lot of manual labor as does your script.
ReplyDeleteFantastic script Ken - just what the Dr ordered...
ReplyDeleteI managed to break it quickly because my sole AD site in my Lab has dashes in the name, which is an invalid character in Lync:
New-CSNetworkSite : Cannot create item "My-AD-Site": "Invalid value for NetworkSiteID: Must be a string of at most 32 characters. Only letters, digits, "_", ".", and spaces are permitted."
I added a couple of lines to trap this, as well as check for maximum length (which it brutally chops at 32 chars):
# Create Lync network sites based on AD site
$SiteObj = Get-ADObject $Site.distinguishedName -properties "siteObjectBL", "description"
$SiteObjName = [regex]::replace($SiteObj.Name, "([^0-9a-zA-Z_. ])" , "")
If ($SiteObjName.Length -gt 32){$SiteObjName = $SiteObjName.SubString(0,32)}
New-CSNetworkSite -NetworkSiteID $SiteObjName -Description $SiteObj.Description -NetworkRegionID $SiteName -ea si
I had to create $SiteObjName as a new variable as I wasn't able to change the existing $SiteObj.Name
I also took the liberty of adding "-ea si" to the end of each of the "new-[object]" lines, and that way the script doesn't output an error if the object already exists (because you might have already run the script before).
Thanks again. - Greig.
Thanks Greig!
DeleteIf you don't mind, can I incorporate these changes into the script posted here?
Ken
Gladly!
Delete