Tuesday 2 December 2014

Response group queue overflow and timeout

A customer wanted to give an announcement to callers and disconnect the call, when the queue length was more than 2 calls. 

This must be done using Lync Management Shell.

$w = New-CsRgsPrompt -TextToSpeechPrompt "Announcement to caller"
$y = New-CsRgsCallAction -Prompt $w -Action Terminate
$z = Get-CsRgsQueue -Identity service:ApplicationServer:<pool-FQDN> -Name "<Queue-name>"
$z.OverflowAction = $y
$z.OverflowCandidate = "NewestCall"
$z.OverflowThreshold = "2"
Set-CsRgsQueue -Instance $z

Speaking of this, giving an announcement to callers before timeout disconnect can be done this way.

$w = New-CsRgsPrompt -TextToSpeechPrompt "Announcement to caller"
$y = New-CsRgsCallAction -Prompt $w -Action Terminate
$z = Get-CsRgsQueue -Identity service:ApplicationServer:<pool-FQDN> -Name "<Queue-name>"
$z.TimeoutAction = $y
$z.TimeoutThreshold = "60"
Set-CsRgsQueue -Instance $z
Happy shell'ing 

Tuesday 25 November 2014

User is not validly homed on target

At a new deployment I saw an issue when some users were enabled for Lync, they could not sign in.

When we investigated the client certificates, I saw this error:

Disable and re-enable the user did not change anything.

Luckily we also had a Survivable Branch Appliance (SBA) in the deployment, so forcely moving the user to the SBA, did change something, so the user was able to login. Hey now things work, but having the user at the SBA was not what we wanted, so we moved the user back to main pool and we were back at the beginning... The user could not sign in. 

Luckily we had also a test user with this problem, so production users would work and we could do more investigation for this problem.

I escalated the problem to Microsoft PSS, who is working on it now... Hopefully this post will be updated soon.

Update: The problem was caused by some incorrect routing group IDs, the problem was identified by event id 30057 in the Lync Server eventlog, text is:
msRTCSIP-UserRoutingGroupId attribute for a user is incorrect in Active Directory domain:<AD-domain>
The user with these attributes has DN:<USER-DN>
These incorrect attribute cannot be updated in the database.
Source of replication is: LocalRegistrarReplication.
Resolution:
This is usually caused due to home pool information change in Active Directory using unsupported tools or direct edits to AD. To resolve this condition, move all the affected user back to the original Pool using Move-CsUser and then move the user again to this Pool gracefully using Move-CsUser.

Neither moving the user (who btw originated on this very pool), removing the content of MSRTCSIP-UserRoutingGroupID field of the object nor a full reset of the pool did resolve this issue. So we decided to renew the local databases.

First backup userdata (just in case):
Export-CsUserData -PoolFQDN <fqdn> -FileName <filename>

Then on all FEs:
Stop-CsWindowsServices
Install-CsDatabase -LocalDatabases -Clean
Restart-Server

After all the servers are back online the error was gone.

The problem was also causing some response groups to stay in offline mode with event id 30058 in the Lync Server eventlog, this was also solved with this action.

Thursday 13 November 2014

Forwarding hunt group calls to a group voicemail

During a deployment, we were met with the request of calls in a hunt group (or queue) should be able to go to an Exchange UM enabled mailbox for the department/function.

HG name is department@sipdomain e.g. test@kml.local
Exchange mailbox is department@sipdomain e.g. test@kml.local
UPN for the Exchange mailbox is the same as the e-mailaddress

The mailbox account is (should be) disabled in AD, so first move is to enable the account. Then I enable the account for Lync using Powershell:
Get-CsAdUser -Identity "test@kml.local"|Enable-CsUser -RegistrarPool Lyncpool.kml.local -SipDomain kml.local -SipAddress sip:vm.test@kml.local

The Lync user should be Enterprise Voice enabled to be able to utilize the UM mailbox
Set-CsUser -Identity test@kml.local -EnterpriseVoiceEnabled $True

Next step is UM enabling the mailbox (implies that a UM Mailbox Policy has already been defined) this could be done using the Exchange Control Panel or Powershell:
Enable-UMMailbox -Identity "test@kml.local" -UMMailboxPolicy UmPolicy1 -Extensions 2000 -PIN 13579 -SIPResourceIdentifier "test@kml.local"

Now we'll use SEFAUtil to set the Lync forwarding destination for test@kml.local.
.\SEFAUtil.exe /server:lyncpool.kml.local test@kml.local /enablefwdimmediate /setfwddestination:"sip:test@kml.local;app=voicemail"

Now we can assign the Forward to Voicemail destination in the HG setup and don't forget to record a greeting in the Exchange mailbox.

After recording a greeting, you should consider disabling the AD account again. If you decide to disable the account, the users of the mailbox cannot record a new greeting unless an administrator (you) reenable the account again.

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.