Posts tagged ‘Lync’

#Lync mobile hanging on “getting contacts”

I have just been troubleshooting a weird issue where a user complained about Lync mobile taking a long time signing in, and then  not showing the buddy list until several days after sign in. Push would also not work until after the contact list was downloaded.

After reading a lot of logs and traces and not finding anything we tried finding things that were different from this user and everyone else. It turned out he had added some Cisco video conferencing endpoints to his contact list. In a desperate attempt we tried deleting these from his buddy list, and the problem disappeared.

Seems that the mobile client has some issues getting presence from integrated SIP domains or something like that. I tried replicating the problem with my user, and managed to do so:

I added the Cisco E20 on my desk to my buddy list:

And tried logging in on my iPad:

The client is in norwegian, but it says “No contacts”, and I guess “getting contacts” on the bottom.

This is what I see until I either delete the contact from my buddy list or wait for up to several days. In this state I can recieve IMs if I am in the client, but push does not work.

On my windows phone, the contact list is just empty, there are no messages of any kind and it has the same behavior, can recieve IMs, but no push.

I have not tried on an android yet.

I’ve tried reading through logs as well, but I can’t figure out what is causing this, so the fix for now seems to be to delete those types of contacts

Adding external contacts to the #Lync addressbook

There are some scenarios where it would be nice to be able to add external contacts to the Lync addresse so that they are searchable for everyone in the organization. Or at least external in the sence that the contact has a sip domain that isn’t supported in the Lync topology.

One such scenario could be an integration with an internal Cisco Telepresence solution.

The way to solve this is to add a contact object to AD that has the msRTCSIP-PrimaryUserAddress attribute populated, and the contact should be added to the address book on the next synchronization pass. I’ve made a script to create this kind of object:

Note that displayName is not required, but if you don’t add it the contact will only display the sipadress in the Lync client. I guess it’s also possible to append other AD attributes to the user such as telephoneNumber.

I got a question about telephoneNumber as well, so I’ve added it as an optional parameter in the script.


#####################################################################################
# New-SipContact.ps1
#
# Creates a contact object in AD that will be included in Lync/OCS address books.
#
#
# Passing parameters:
# .\New-SipContact.ps1 -cn "John Spencer" -path "OU=SIPContacts,DC=contoso,DC=com" -sipaddress "john.spencer@litwareinc.com" -displayname "John Displayname Spencer"
#
# Written by Tom-Inge Larsen (http://www.codesalot.com)
#
#####################################################################################
param($cn,$OUpath,$sipAddress,$displayName="",$telephoneNumber="")

$fullpath= "LDAP://" + $OUpath
$SIPContactOU = [ADSI]$fullpath

$SIPContact = $SIPContactOU.create("contact", "cn=" + $cn)
$SIPContact.Put("Description","SIP Contact Object")
$SIPContact.Put("msRTCSIP-PrimaryUserAddress", "sip:" + $sipAddress)
if ($displayName -ne "") {
 $SIPContact.Put("displayName", $displayName)
}
$SIPContact.Put("msRTCSIP-PrimaryUserAddress", "sip:" + $sipAddress)
if ($telephoneNumber -ne "") {
 $SIPContact.Put("telephoneNumber", $telephoneNumber)
}
$SIPContact.setInfo()

I’ve also created one to bulk create contacts from a .csv file


#####################################################################################
# New-SipContactBulk.ps1
#
# Creates a contact object in AD that will be included in Lync/OCS address books.
#
#
# Passing parameters:
# .\New-SipContactBulk.ps1 -OUpath "OU=SIPContacts,DC=contoso,DC=com" -csv "c:\newcontacts.csv"
#
#
# Written by Tom-Inge Larsen (http://www.codesalot.com)
#
#####################################################################################
param($OUpath,$csv)

$fullpath= "LDAP://" + $OUpath
$SIPContactOU = [ADSI]$fullpath

$contacts = Import-Csv -path $csv -header "cn","displayName","sipaddress"

foreach ($contact in $contacts) {

$SIPContact = $SIPContactOU.create("contact", "cn=" + $contact.cn)
 $SIPContact.Put("Description","SIP Contact Object")
 $SIPContact.Put("msRTCSIP-PrimaryUserAddress", "sip:" + $contact.sipaddress)
 if ($contact.displayname -ne "") {
 $SIPContact.Put("displayName", $contact.displayName)
 }
 $SIPContact.setInfo()
}

The example csv file is here: newcontacts.csv

List static routing config

After adding a static route to Lync (for example when adding a CTP integration) you can use the following command to show the route:
Get-CsStaticRoutingConfiguration Service:Registrar:lspool01.contoso.com
Identity : Service:Registrar:lspool01.contoso.com
Route    : {MatchUri=video.contoso.com;MatchOnlyPhoneUri=False;Enabled=True;ReplaceHostInRequestUri=False}

This will list the static route, but it won’t show all the route details (specifically the route target which is semi often used in troubleshooting) as they are contained inside a Route object in the StaticRoutingConfiguration object. To list the details of the route, do:


$stroute = Get-CsStaticRoutingConfiguration Service:Registrar:lspool01.contoso.com
$stroute.Route

This will give you the content of the route.

Transport               : TransportChoice=Certificate=Microsoft.Rtc.Management.WritableConfig.Settings.SipProxy.UseDefaultCert;Fqdn=vcsc.contoso.com;Port=5061
MatchUri                : video.contoso.com
MatchOnlyPhoneUri       : False
Enabled                 : True
ReplaceHostInRequestUri : False

Playing with PS: Script: Start remote Lync management session

I wrote a script to start a remote Lync management shell session based on this post. This of course is a big bloated way to do it (it can be done as a twoliner), but I need the PS training :P

##########################################################################################################################
# New-RemoteCSPSsession.ps1
#
# Opens a remote session to a Lync Management Shell and imports all commands
#
# Uses current logged inn credentials, but can optionally supply other credentials.
#
# eg.
# Prompt for fefqdn:
# .\New-RemoteCSPSsession.ps1
#
# Use other credential:
# .\New-RemoteCSPSsession.ps1 -othercredential $true
#
# Ignore certificates on fe:
# .\New-RemoteCSPSsession.ps1 -notrust $true
#
# fefqdn can be passed in arguments as well:
# .\New-RemoteCSPSsession.ps1 -csfe lync-admin.contoso.local
#
# Written by Tom-Inge Larsen (www.codesalot.com), based on this blogpost:
# (http://blogs.technet.com/b/csps/archive/2010/06/16/qsremoteaccess.aspx)
# this script can also easily be run as a twoliner:
# (http://blog.powershell.no/2010/12/05/lync-server-2010-remote-administration/)
#
# $session = New-PSSession -ConnectionUri https://lync-admin.contoso.local/OcsPowershell -Credential (Get-Credential)
# Import-PSSession -Session $session
#
#
##########################################################################################################################
param($othercredential,$notrust,$csfe)

$env = get-host
$majorversion = $host.version.major

if ($majorversion -lt 2) {
 write-Host "You need to run at least Powershell 2.0 to run this script. http://support.microsoft.com/kb/968929"
} else {

if ($csfe -eq $null) {
 $csfe = Read-Host "Please enter the FQDN of the Lync Front End pool you want to connect to"
 }

 $connectionURI = "https://"+$csfe+"/OcsPowershell"
 $cmdstring = 'New-PSSession -ConnectionUri $connectionURI'

 if ($othercredential -eq $true) {
 $credential = Get-Credential
 $cmdstring += ' -Credential $credential'
 }
 if ($notrust -eq $true) {
 $sessionoption = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck
 $cmdstring += ' -SessionOption $sessionoption'
 }

 $session = & $executioncontext.invokecommand.NewScriptBlock($cmdstring)

 Import-PSSession $session
}

What to do if users are enabled for LCS?

I just had a Lync installation where it turned out that about 5 years ago they had tried installing LCS 2005 in AD, an installation that had failed and the servers had been taken down without being disabled.

The users that had been enabled that time was therefore still enabled for LCS in AD, and first of all did not appear when trying to search for them in the “enable users” UI. Searching for them with “Legacy users” filter on showed them, but failed when trying to move them with the “Move users” script in BigFin. It is also not supported to move LCS enabled users to Lync. Disabling them in BigFin will also not work. The error message will say something about users not enabled for rich presence, which was added in 2007 R2.

What will work though is the cmdlet Disable-CsUser. Run the cmdlet on the affected users, and then enable them as a normal non-enabled user again after that. I guess that old buddy lists and settings from LCS will be removed by this as well, so it is not a recommended migration path though. In my case this was not important.

Script – New-CiscoTelepresenceIntegration.ps1

Script to enable routes from Lync to VCS Control:
######################################################################################################################################################################################
# New-CiscoTelepresenceIntegration.ps1
#
# Adds config in Lync 2010 for integration with Cisco Telepresence (Tandberg)
#
# Can optionally write logs to file or screen using -verbose and/or -logFile inputs
#
# eg.
# Clean Lync installation
# .\New-CiscoTelepresenceIntegration.ps1 -vcscfqdn vcsc011.contoso.com -lsfepool lspool01.contoso.com -CTPSipDomain video.contoso.com -logFile "c:\logfile.txt"
#
# Coexisting with OCS 2007 R2
# .\New-CiscoTelepresenceIntegration.ps1 -coexistence $true -r2pool r2pool01.contoso.com -lsfepool lspool01.contoso.com -CTPSipDomain video.contoso.com -logFile "c:\logfile.txt"
#
# Migration from OCS 2007 R2 to Lync
# .\New-CiscoTelepresenceIntegration.ps1 -hascoexisted $true -vcscfqdn vcsc011.contoso.com -lsfepool lspool01.contoso.com -CTPSipDomain video.contoso.com -logFile "c:\logfile.txt"
#
# Important:
# This will delete any existing static routes created ! Do not run the script with hascoexisted = $true if you have added manual routes other than OCS/Lync/CTP integration
#
# Written by Tom-Inge Larsen (<a href="http://www.codesalot.com">www.codesalot.com</a>), Peder Saether and Trond Egil Gjelsvik-Bakke
# Based on config made by Marjus Sirvinsks (marjuss.wordpress.cm)
#
#######################################################################################################################################################################################
param($logFile,$coexistence=$false,$hascoexisted,$CTPSipDomain,$lsfepool,$r2pool,$vcscfqdn)

if ($logFile -ne $null) {
 $a = "Steps made to enable integration with Cisco Telepresence: `n"
 Out-File -FilePath $logfile -InputObject $a
}

if ($lsfepool -eq $null) {
 $lsfepool = Read-Host "Please enter Lync Front End pool FQDN."
}

if ($CTPSipDomain -eq $null) {
 $CTPSipDomain = Read-Host "Please enter the SIP domain in the Cisco Telepresence environment."
}

if ($coexistence -eq $false) {
 #Change encryption level if SRTP option is not available for VCS
 $mediaconfiguration = get-csmediaconfiguration
 $requireencryption = ($mediaconfiguration.EncryptionLevel -eq "RequireEncryption")
 if ($requireencryption) {
 write-warning "This will set the media encryption level to Support Encryption. Are you sure you want to do this? (y/n)"
 $confirmation = Read-Host

 } else {
 $confirmation = 'y'
 }
 switch ($confirmation) {
 'y' {
 set-CsMediaConfiguration -EncryptionLevel supportencryption

 $registrarid = "service:registrar:"+$lsfepool
 $trustedappregistrar = "Registrar:"+$lsfepool

 if ($hascoexisted -eq $true) {
 Remove-CsStaticRoutingConfiguration -Identity $registrarid
 }

 if ($vcscfqdn -eq $null) {
 $vcscfqdn = Read-Host "Please enter the FQDN for the VCS Control"
 }

 #Establish trust
 $applicationpooladded = $true
 New-CsTrustedApplicationPool -Identity $vcscfqdn -Registrar $trustedappregistrar -site 1 -RequiresReplication $false -ThrottleAsServer $true -TreatAsAuthenticated $true -force

New-CsTrustedApplication -ApplicationID "CiscoTelepresenceDirectSIP" -TrustedApplicationPoolFqdn $vcscfqdn -Port 5061

 #Create static routes if needed

 if ($hascoexisted -eq $true) {
 New-CsRegistrarConfiguration -Identity $registrarid
 }

 New-CsStaticRoutingConfiguration -identity $registrarid

$route = New-CsStaticRoute -TLSRoute -destination $vcscfqdn -port 5061 -matchuri $CTPSipDomain -usedefaultcertificate $true

Set-CsStaticRoutingConfiguration -identity $registrarid -route @{Add=$route}

 Enable-CsTopology
 }
 'n' {
 Write-Warning "No change was made to the topology. Media Encryption Level must be set to Support Encryption"
 if ($logFile -ne $null) {
 $a = "No change has been made. `n"
 Out-File -FilePath $logfile -InputObject $a -Append
 }
 }
 }
}

else {

# If we coexist with R2, we might want to route all traffic via R2 FE, to possibly avoid
 # compromising security with deployments using TCP or if Lync is only intended as a
 # pilot.

 if ($r2pool -eq $null) {
 $r2pool = Read-Host "Please enter OCS 2007 R2 Front End pool FQDN."
 }

 $registrarid = "service:registrar:"+$lsfepool

 New-CsRegistrarConfiguration -Identity $registrarid
 New-CsStaticRoutingConfiguration -identity $registrarid

$route = New-CsStaticRoute -TLSRoute -destination $r2pool -port 5061 -matchuri $CTPSipDomain -usedefaultcertificate $true
 Set-CsStaticRoutingConfiguration -identity $registrarid -route @{Add=$route}

Enable-CsTopology
}

if ($logFile -ne $null) {

$a = "Route added: `n"
 Out-File -FilePath $logfile -InputObject $a -Append
 Get-CsStaticRoutingConfiguration $registrarid | Select-Object -ExpandProperty Route | Where-Object {$_.MatchUri -eq $CTPSipDomain} | Out-File -FilePath $logfile -Append
 if ($applicationpooladded -eq $true){
 $a = "`nTrusted Application Pool added:`n"
 Out-File -FilePath $logfile -InputObject $a -Append
 Get-CsTrustedApplicationPool $vcscfqdn | Out-File $logfile -append
 }
 $a = "`nRegistrar added:`n"
 Out-File -FilePath $logfile -InputObject $a -Append
 Get-CsStaticRoutingConfiguration $registrarid | Out-File $logFile -append

 if ($confirmation -eq 'y') {
 $a = "`nMedia encryption level was already set to or was set to Support Encryption.`n"
 Out-File -FilePath $logfile -InputObject $a -Append
 }

 Write-Host "Logfile: " $logFile "is written."
}