Wednesday 23 April 2014

Script for automatic enabling users for Lync based on AD group membership

Today a customer requested a script for all new members of a certain Active Directory Security Group to be enabled for Lync Server 2013.

This was a rather easy task to create a Powershell script and a scheduled task for handling this.

Here is how I did it.

Powershell script:

#
# First set some parameters
#
# Set AD Group for Lync users (between the "")
$ADGroup = "AdSecGroup"
# Set Site ID for user to register to
$SiteID = 1
#
# Script executes from here
#
Import-Module Lync
$Members = Get-ADGroupMember $ADGroup -Recursive
$cssite = get-cssite $SiteID
$regpool = Get-CsService -registrar | where {$_.SiteId -eq $CSSite.Identity}
ForEach ($user in $Members)
{
    $SID = $user.SID
    $ADUser = get-csaduser -Filter {SID -eq $SID}     
    $adexist = get-csaduser | where {$_.SID -eq $SID}  
    $display = $ADUser.FirstName + " " + $ADUser.LastName  
    $samaccountname = $ADUser.SamAccountName  
    if ($adexist -eq $null)        
    {
        $usernotinad = $true  
    }     
    else    
    {
        $usernotinad = $false
    }
    if ($usernotinad -ne $true)    
    {
        $enabled = Get-CsUser -filter {SamAccountName -eq $SamAccountName}     
        # Check if user is enabled for for OCS/Lync    
        if ($enabled)
        {        
            # Check if user is enabled for OCS            
            if ($enabled.RegistrarPool -eq $null)            
            { 
               # Write-Host "User is on OCS, enabling for Lync" -foregroundcolor Yellow -backgroundcolor Black 
                $pool = get-csservice -registrar | where {$_.ServiceID -eq $RegPool.ServiceId}
                Move-CsLegacyUser -Identity $ADUser.SipAddress -Target $pool.PoolFQDN -Force -Confirm:$false 
               # Write-Host "Successfully moved $display to Lync Server 2013"            
            }         
            else        
            {
               # Write-Host "$display is already on Lync - Skipping..." -foregroundcolor Yellow -backgroundcolor Black
            }
        }
        else
        {
           # Write-Host "Enabling user for Lync - Processing..." -foregroundcolor Yellow -backgroundcolor Black                 
            $pool = get-csservice -registrar | where {$_.ServiceID -eq $RegPool.ServiceId}         
            get-csaduser | where {$_.samaccountname -eq $samaccountname} | Enable-Csuser -registrarpool $pool.PoolFQDN -sipaddresstype emailaddress 
           # Write-Host "Successfully enabled $display for Lync Server 2013" -foregroundcolor Yellow -backgroundcolor Black    
        }
    }    
 }

The script basically takes all members of the Active Directory Security Group (this is done recursive, so also members of a group, which is a member of this group, is added) and checks if they are enabled for Lync and enables them for Lync (it also checks for legacy user (Pre-Lync) and then moves the user to the Lync pool). The script was made for a small deployment with only one site and one pool in this site, for multiple sites and/or pools this should be addressed properly.

Scheduled task:

Start by creating a Scheduled Task, select Basic task.

Fill in the fields and click Next

Select Daily, click Next

Select time for execution (we set 05:00:00 in the morning), click Next

 Select Start a program and click Next


Fill in powershell.exe in the program field, fill -file "C:\Install\Lync2013AutoenableUsers.ps1" or appropriate name and location of your script in Argument field, click Next

Not much here really, click Finish

Now open the task and make sure the task is run under an appropriate service account or the System account.
Click OK

Now we have everything beautifully together ready for testing in the morning.



Friday 11 April 2014

Publish Lync 2013 Webservices with Web Application Proxy

An interesting scenario at a customer site, where they wish to publish the Lync External Webservices using Web Application Proxy on a Windows Server 2012 R2.

Web Application Proxy is a service of the Remote Access feature build into any Windows Server 2012 R2, which by total coincident is what we were doing here. Other options include the Kemp Loadmaster series, but that is a different story. For in-depth about the Web Application Proxy service, check this technet article.

This is the setup we were doing at this customer.
The WAP server is a workgroup (non-domain) server placed in DMZ with 2 NIC, 1 towards the Internet and 1 towards the LAN. A persistant route is added to the WAP so all traffic towards the LAN uses the second NIC using this DOS command in an elevated prompt: Route add <NetworkAddress> Mask <SubnetMask> <Gateway> IF <IPofNIC> -p e.g.: 
Route add 10.1.0.0 Mask 255.255.0.0 172.16.1.1 IF 172.16.1.3 -p

To be able to route to the LAN based Lync Frontend server, the Reverse Proxy server should know the inside destination of th simple URLs, so either host this in a local DMZ based DNS server og put the following lines into the hosts file of the server. Remember the IP address (10.1.0.5 in this example) should be the web service load balancer (or single Lync Frontend server).
10.1.0.5 dialin.domain
10.1.0.5 meet.domain
10.1.0.5 lyncweb.domain
10.1.0.5 lyncdiscover.domain

Make sure the WAP server should have 1 (no more or no less) default gateway, placed on the first (Internet facing) NIC.

Make sure you have a certificate issued by a public trusted CA. You also need to have installed and configured Active Directory Federation Services (AD FS) in your domain. The Lync External Webservice does not make use of AD FS, but it is a requirement for WAP.

To import the certificate on the server, open IIS Manager from Server Manager, go to the Server Home and click Server Certificates.

Click Import.

Browse to .pfx file containing the certificate (and private key), enter the password for the file and click OK.


To install the WAP service on the server, start the Add Roles and Features Wizard from Server Manager, click Next.

Click Next.

Click Next.

Select Remote Access server role, click Next.

Click Next.

Click Next.

Check Web Application Proxy.

The wizard wishes to add additional features, click Add Features.

Click Next.

Click Install.

Service are installing. Time for coffee.

When the installation is finished, click Open The Web Application Proxy Wizard.

Now we should configure the AD FS connection. 
Click Next

Enter the name of the internal AD FS service, credentials for a user who has admin rights on the AD FS server (e.g. Domain Admin). Click Next.

Select the certificate you imported in the beginning. Click Next.

Click Configure.

Service is being configured, time for a quick cup of coffee.

Done. Click Close

Now it is time to publish the web service, so go to Remote Access Management Console. Click Publish

The Publish New Application Wizard opens, click Next


As the Lync webservices does not use AD FS for authentication, select Pass-through and click Next.

Fill in the fields, do not forget to add :4443 to the Backend Server URL, click Next.


Click Publish

Repeat the above, untill you have all the URLs filled out. Please note this deployment did not contain an Office Web App Server, otherwise that should be published as well.

Web Application Proxy coming soon to a server near you...

Thursday 3 April 2014

Enabling quality of service in Lync 2013 deployment

At a customer deployment, we had to implement portbased DSCP QoS. Together with the network chaps, we decided to go with the following options:


Modality Srv ports Client ports DSCP value
Audio 49152-57500 20000-20019 46
Video 57501-65535 20020-20039 32
Appsharing 40803-49151 20040-20059 no marking
Filetransfer - 20060-20079 no marking
SIP signaling 5061 5061 no marking

These values gives every client 20 sessions for each modality, which in this senario is quite sufficient, DSCP values are defined in the networking equipment for different priority queues, these have to be addressed with the local network team.

To implement these settings we had to write 3 Lync PS commands and create some Group Policy Objects for the clients.

By default Application Sharing port range is overlapping the Audio port range, so we had to adjust the Application Sharing port range to be below the Audio port range, 40803-49151.
Get-CsService -ConferencingServer | ForEach-Object {Set-CsConferenceServer -Identity $_.Identity -AppSharingPortStart 40803 -AppSharingPortCount 8348}
Get-CsService -ApplicationServer | ForEach-Object {Set-CsApplicationServer -Identity $_.Identity -AppSharingPortStart 40803 -AppSharingPortCount 8348}

By default client port range overlaps all modalities, so we had to change ports to be able to seperate the different modalities.
Set-CsConferencingConfiguration -ClientMediaPortRangeEnabled $true
Set-CsConferencingConfiguration -ClientAudioPort 20000 -ClientAudioPortRange 20 -ClientVideoPort 20020 -ClientVideoPortRange 20 -ClientAppSharingPort 20040 -ClientAppSharingPortRange 20 -ClientFileTransferPort 20060 -ClientFileTransferPortRange 20

As GPOs are assigned to domain members only, we had to make sure that non-GPO enabled devices (tablet, smartphones, Lync phones etc.) are QoS enabled with DSCP tag 46
Set-CsMediaConfiguration -Identity global -EnableQoS $true
Set-CsUCPhoneConfiguration -VoiceDiffServTag 46

GPO:
Client GPO is asssigned to the OUs where the client computers are placed and applied to all authenticated users.


Server GPO is assigned to the root domain of the servers and applied to a group containing all internal Lync servers.

As the Edge servers are not members of the internal domain, all edge servers have to get the DSCP settings with a Local Group Policy.