What Computer is Being Used to Connect to Lync?

One of my users came to me complaining that he was logging out of his computer at the end of the day, but when he would come in the next day, he would often have emails showing that others were trying to IM. He did a little digging and found out that he was showing as away, even though he was logged out of his computer.

Well, logic dictates that Lync is awesome and doesn’t screw up. Smile So, that means that he must have been logged in on another computer. The question is, how do you find what computer has his session running.

So, to help this ONE person, I spend a couple of hours and put this script together and tested it. You can just change the $UserName variable, and it will do the rest. The code is below.

CLS

# The name information below may need to be changed to include the SIP Suffix.

$UserName = “russ.kaufmann”

$FirstPriority = Get-CsUserPoolInfo $UserName | Select –ExpandProperty PrimaryPoolMachinesInPreferredOrder | Select fqdn -First 1

$ServerName = $FirstPriority.fqdn

$SQLQuery = “Select

                IsServerSource,

                ClientApp,

                ContactInfo,

                SipHeaderFrom

From RegistrarEndpoint

WHERE SipHeaderFrom LIKE ‘%$UserName%'”

$connection = New-Object system.data.sqlclient.sqlconnection

$Connection.connectionString=”Data Source=$ServerName\RTCLOCAL;Initial Catalog=RTCDyn;Integrated Security=SSPI”

$Connection.open()

$Command = $Connection.CreateCommand()

$Command.Commandtext = $SqlQuery

$DataAdapter = New-Object System.Data.SqlClient.SqlDataAdapter $Command

$Dataset = New-Object System.Data.Dataset

$DataAdapter.Fill($Dataset)

# $Dataset.Tables[0] | Export-CSV UserIP.csv -notype

$connection.close()

$connection = $null

$Results = $dataset.tables[0].rows

ForEach ($r in $Results){

                if ($r.IsServerSource -ne “False”){

                                  $ClientApp = $r.ClientApp

                                 $ContactInfo = $r.ContactInfo

                                $SipHeaderFrom = $r.SipHeaderFrom

                                $EncodingType = “System.Text.ASCIIEncoding”

                                $Encode = new-object $EncodingType

                                $ClientApp = $Encode.GetString($ClientApp)

                                $ContactInfo = $encode.getstring($ContactInfo)

                                $SipHeaderFrom = $encode.getstring($SipHeaderFrom)

                                # Strip garbage from $ContactInfo to get IP

                                                $CI = $ContactInfo.split(‘;’)

                                                $CI2 = $CI[0]

                                                $CI3 = $CI2.split(‘:’)

                                                $ClientIp = $CI3[1]

                                #Strip garbage from $Sip User to get SIP address in SMTP format

                                                $Sip = $SipHeaderFrom.split(‘:’)

                                                $Sip2 = $Sip[1]

                                                $Sip3 = $Sip2.split(‘>’)

                                                $SipAddress = $Sip3[0]

                                write-host $SipAddress

                                write-host $ClientIp    

                                write-host $ClientApp 

    }

}

What you will get is a result something like here:

2                                                     

russ.kaufmann@infrastructurehelp.com

10.1.1.101                                          

UCCAPI/15.0.4641.1000 OC/15.0.4641.1000 (Microsoft Lync)

russ.kaufmann@infrastructurehelp.com

10.2.1.105                                          

UCCAPI/15.0.4641.1000 OC/15.0.4641.1000 (Microsoft Lync)PS D:\ece_scripts>                                     

The “2” is the number of incidents found., then the output from the script is provided in the form of the SIP address, the IP address, and the client application information.

Posted in Uncategorized | 4 Comments

Lync Server Issue – Certificate Status: Missing

Symptom: Yesterday, one of the Lync Front-End servers failed. Almost all of the Lync services were not running, and the services would not start manually. Reviewing the Event Logs, which is something that none of us do until we are well into our troubleshooting, I found the following Event Log errors:

Event 32014, LS Application Server

The application threw an exception while starting.

The application urn:application:testbot threw the following exception when starting: Exception: System.Runtime.Serialization.SerializationException

> Message: The constructor to deserialize an object of type ‘Microsoft.Rtc.Internal.Sip.LocalCertificateNotFoundException’ was not found.

> TargetSite: Void CallStartAsync()

> StackTrace:    at Microsoft.Rtc.ApplicationServerCore.ApplicationLoader.CallStartAsync()

> Source: Microsoft.Rtc.ApplicationServerCore

Cause: Startup errors.

Resolution:

Check the events prior to this to resolve the service startup issue.

 

Event 61002, LS MCU Infrastructure.

No certificate has been configured for secure transport.

The certificate assigned to process ReplicationApp(3756) was not found. 

Certificate serial number: 46ae547f00000000fcda

Certificate issuer name: CN=IHelp CA, DC=infrastructurehelp, DC=com.

Cause: Incorrect configuration of the server or the certificate assigned to the server was deleted from the certificate store

Resolution:

Verify that a valid certificate has been configured.

 

Event 48005, LS Routing Data Sync Agent

The Routing Data Sync Agent has encountered an unexpected Exception: [Operation is not valid due to the current state of the object.], Trace: [   at Microsoft.Rtc.Server.McuInfrastructure.HttpTransport.LoadCertificate(CertificateInfo certificate)

   at Microsoft.Rtc.Server.McuInfrastructure.HttpTransport.LoadCertificate()

   at Microsoft.Rtc.Server.McuInfrastructure.HttpTransport..ctor(String listeningUrl, ICccpConfigurationProvider config, XmlWriterSettings writerSettings)

   at Microsoft.Rtc.Server.Replication.Http.ReplicationHttpAdapter..ctor(String listenerUri, ICccpConfigurationProvider config)

   at Microsoft.Rtc.Server.Replication.Http.ReplicationHttpAdapter..ctor(String listenerUri, ServiceConsumer serviceConsumer, StoreAccessor regStoreAccessor, StoreAccessor uscStoreAccessor)

   at Microsoft.Rtc.Server.Replication.ReplicationApp.Initialize(AutoResetEvent workerStartedEvent, ManualResetEvent serverProcessDiedEvent, ManualResetEvent shutdownEvent, ManualResetEvent updateMasterStateEvent)

   at Microsoft.Rtc.Server.Replication.ReplicationApp.Main(String[] args)]

OK, the errors make it sound like a certificate error. Actually, it was pretty clear that it was a certificate error.. So, I opened up the Certificates MMC and verified that the cert was still there. It wasn’t accidentally deleted or anything like that. In fact, the cert still has almost a year before it expires. I started the Deployment Wizard and found the following:

clip_image002

The Certificate Wizard shows the certificate, shows that it is not expired ( today is September 30th, 2014), and that it is “partially” assigned in that the Web services internal shows assigned while the other services show the certificate is missing.

Resolution: I found that I could either replace the existing certificate with a new one, or I could just use the Assign option and re-assign the same certificate. In both cases, the Status became Assigned for all of the services, and the Lync services all started back up properly.

Cause: I am not sure. I know that some patching has been done recently, but I have no idea what patch might have caused this issue. BTW, I also found this issue existing on almost all of the Front-End servers, but only the one server had the services stopped. I am betting that if any of the other Front-End servers were restarted, they would have failed in exactly the same way.

Posted in Uncategorized | Leave a comment

Cleaning up Federation in Lync

I had a recent situation where I had to enable Federation for most of the company’s users because of an acquisition. It made perfect sense to enable Federation for them as they had the need to engage the newly acquired company’s staff on a very regular basis.

Now that the acquired company has been completely merged into the same Lync environment, it is time to clean up Federation. Actually, a month had passed before anyone realized that Federation should be cleaned up. I will take the blame for that. Smile

There are two steps to this process.

  • First, I needed to identify which users were still using Federation to collaborate with other companies. Then I took the list and vetted it to make sure that only those that needed Federation were still using it.
  • Second, I needed to remove Federation from all remaining users.

To meet the needs, I created a script to identify those that were still using Federation.

CLS

$SQLQuery = “Select

       S.User1Id,

       S.User2Id,

       S.IsUser1Internal,

       S.IsUser2Internal,

       U.UserUri ‘User1URI’,

       UU.UserUri ‘User2URI’,

       S.SessionIdTime

From SessionDetails S

Inner join Users U on S.User1Id = U.UserId

Inner join Users UU on S.User2Id = UU.UserId

WHERE S.IsUser1Internal = 0 OR S.IsUser2Internal = 0

Group by

       S.User1Id,

       S.User2Id,

       S.IsUser1Internal,

       S.IsUser2Internal,

       U.UserUri,

       UU.UserUri,

       S.SessionIdTime”

$connection = new-object system.data.sqlclient.sqlconnection

$Connection.connectionString=”Data Source=SQLServerName\InstanceName;Initial Catalog=LcsCDR;Integrated Security=SSPI”

$Connection.open()

$Command = $Connection.CreateCommand()

$Command.Commandtext = $SqlQuery

$DataAdapter = New-Object System.Data.SqlClient.SqlDataAdapter $Command

$Dataset = New-Object System.Data.Dataset

$DataAdapter.Fill($Dataset)

$Dataset.Tables[0] | Export-CSV FederationActivity.csv -notype

$connection.close()

$connection = $null

$File = Get-Content FederationActivity.csv

$Null | Out-File FederationActivity.csv

ForEach ($f in $File) {

                $f | Out-File FederationActivity.csv -append

}

$Results = Import-Csv FederationActivity.csv

ForEach ($r in $Results){

                $FU = Get-Content FederationUsers.txt

                $User1 = $r.User1URI

                $User2 = $r.User2URI

                If($User1 -imatch “DomainName.com”){

                                $Test = $FU -contains $User1

                                If($Test -eq $False){

                                                $User1 | Out-File FederationUsers.txt -Append

                                }

                }

                If($User2 -imatch “DomainName.com”){

                                $Test = $FU -contains $User2

                                # Write-Host $Test is the test value

                                If($Test -eq $False){

                                                $User2 | Out-File FederationUsers.txt -Append

                                }

                }

}

 

The first script creates a nice file of the users. You can run it multiple times, and it will just add the names to the existing file. The FederationUsers.txt file is used in the second script to test whether the person should have Federation removed.

CLS

$Users = Get-CsUser -resultsize unlimited

$FU = Get-Content FederationUsers.txt

$Null | Out-File FederationRemoval.txt

ForEach ($u in $Users){

               $u1 = $u.SamAccountName

                $u1 = $u1 + “@DomainName.com”

                $Test = $FU -contains $u1

                If($Test -eq $False){

                                $Test1 = $u.externalaccesspolicy.friendlyname

                                If ($Test1){

                                                Grant-CsExternalAccessPolicy $u1 -policyname $null

                                                $u1 | Out-File -append FederationRemoval.txt

                                }

                }

}

 

While others may not have the same needs, these scripts might help. Good luck.

Posted in Uncategorized | 1 Comment

Custom Presence in Lync 2013–Where did my Custom Presence States Go After I Upgraded?

Consider this post a follow-up to my previous post a few years ago for Lync 2010.

I have heard a few complaints lately about people losing their Custom Presence States when they upgrade the Lync 2010 client to the Lync 2013 client. No problem, we can do it again, and do it for Lync 2013.

imageCustom Presence has always been a hot topic for many users as they want to have something that just isn’t in the box. The basics just don’t give enough information in many cases. After all, it is much nicer to show that you are not just Away, but you are at Lunch, so that everyone knows you are working today, and that you will be back soon.

Custom Presence requires:

  • Permission to edit the registry of the computer, or the ability to deploy the Registry settings via a Group Policy object
  • The actual Registry entries
  • An XML file that contains the settings for your Custom Presence States

The process is covered really well on many blogs, and is also covered here on the TechNet site. However, I already have your attention, so I will cover the basics here.

1. Create the .XML file.

The XML is pretty simple to write, but if you need help, you can use the file that I have here and then copy and paste it into a file named something really creative, like, custompresence.xml. Note: Doing a direct copy of the XML code below will add some strange characters, so make sure you paste it as straight text. Again, feel free to right click the link in the first part of this step and then save the file. It is easier to edit what works than to write something new.

<?xml version=”1.0″ encoding=”utf-8″?>
<customStates>
  <customState ID=”1″ availability=”Online”>
    <activity LCID=”1033″>Working from home</activity>
  </customState>
  <customState ID=”2″ availability=”Online”>
    <activity LCID=”1033″>I am a happy camper</activity>
  </customState>
  <customState ID=”3″ availability=”do-not-disturb”>
    <activity LCID=”1033″>In a conference call</activity>
  </customState>
  <customState ID=”4″ availability=”do-not-disturb”>
    <activity LCID=”1033″>Wrapping up for the day</activity>
  </customState>
< /customStates>

If you double-click the XML file, it will pop up in Internet Explorer and look just like this image to the right. My XML file is available right here at this link: http://infrastructurehelp.com/custompresence.xml. imageYou can access the file from a Web server or a file server. I bounce around between computers and networks, so I use my website to host the file so I can get to it anywhere.

Some restrictions exist:

  • You can only have up to four different Presence states
  • Your text in the Presence state is limited to 64 characters. I really doubt you need anything near that long, though.
  • You can only use one of the following availability states: Online, Busy, or Do-Not-Disturb. You can’t use Away or Offline.
2. Configure the Registry.

While you can create the Registry entries and use a .reg file to deploy the settings, I prefer to manually edit the Registry. It really is easy.

Run regedit.exe to open the registry editor. In the registry editor, navigate to one of the following:

  • HKEY_LOCAL_MACHINE\Software\Policies\Microsoft\Office\15.0\Lync
  • HKEY_CURRENT_USER\Software\Policies\Microsoft\Office\15.0\Lync image

Notice that the location for the Registry settings are different? Yep, that might explain why the Custom Presence States are not there anymore after upgrading the client.

HKLM settings take priority over the HKCU settings, but you can configure the settings in either location. In either case, you will probably have to create the Office key, the 15.0 key, and the Lync key so it looks like the image to the right.

Next, you need to take two steps, which are shown in the Registry Editor to the right.

  1. You need to create a DWORD for for EnableSIPHighSecurityMode and set it to 0. If you are storing the XML file on a Web server that is configured with a certificate, you can use HTTPS instead of HTTP and not need to disable the setting.
  2. Next, you need to create a String Value for the CustomStateURL value. In my case, I use http://infrastructurehelp.com/custompresence.xml for the value. If you want, you can store your custompresence.xml file on the local hard drive. If it is on the local drive, you can just enter file:///c:/FolderName/custompresence.xml instead of using a Web url.

3. Sign out of Lync 2013 and then sign back in again.

In the notification area in the task bar, right-click the Lync 2013 icon and select Sign Out, imagethen start up Lync 2013 again.

If all went according to plan, you should see the custom presence states as shown here.

Note: Custom presence states will not be visible to Federated users that view your presence. In order for them to see your new custom presence states, you will need to add them to your Colleagues container in the Lync client.
Posted in Uncategorized | 1 Comment

Issue Upgrading Lync 2010 Client to Lync 2013

I haven’t seen much written about this, but there is a bit of an issue with upgrading the client and how it signs in to Lync.

First, some people will see the short-cut where they are used to seeing it on either the clip_image002desktop or the taskbar. However, the short-cut doesn’t have the old Lync 2010 icon, it is just a blank icon. If you click on the blank icon, you will get this error message.

The biggest issue, though, is that most users will see the error that says they Can’t sign in to Lync, when trying to log into Lync 2013 the first time. that they try to open it. There are two potential fixes:

  1. imageWait a few minutes and try again. Most likely, it will fix itself.
  2. Click on the Delete my sign-in info link and it will delete any existing certificates and allow a new certificate to be downloaded from the Lync servers.

The issue is a simple one. Lync 2010, before it was upgraded, was using a certificate that it received from the Lync server environment so that the client could use the certificate for easier authentication. The certificate isn’t valid for the new client installation, and needs to be replaced.

After resolving this issue, then you will most likely be prompted to enter your username and password. The standard user name for your organization is all that needed for the user name field. You can use the UPN, or you can also use the old style of DomainName\UserName format.

clip_image006

It is a good idea to provide a simple document to Lync users before the upgrade so they will not flood the helpdesk with too many calls that they can resolve themselves.

Posted in Uncategorized | Leave a comment

Lync 2013 Client and Group Chat 2010–Co-existence Issue

An interesting co-existence problem came up yesterday. It appears that there is a known issue with the Lync 2010 client and Windows 8, where it is possible to fire off multiple instances of communicator.exe, which then causes the Lync 2010 client not to even launch.

Well, the Lync 2013 client has some new coding that prevents multiple instances from starting. Now, this is a bit interesting because, in the past, OCS/Lync clients have never been backwards compatible. In case of Lync 2013, it does work with Lync 2010. Until… you add in Group Chat 2010 in the mix.

The Lync 2013 client will, as a single client, work with Lync Server 2013 and Persistent Chat. One of the nice selling points is that running 2013 means reducing the need for a separate chat client.

Well, the thought was, why not deploy Lync 2013 to connect to Lync Server 2010, andclip_image002 continue using the Group Chat 2010 client to connect to the Group Chat server? Well, the answer is that the Group Chat 2010 client doesn’t recognize that the Lync 2013 client is running and this causes the Group Chat 2010 client to not only display all rooms, but also display all contacts as shown here. Yes, I had to hack this one up to protect the innocent. Smile

Anyway, as you can see from the image, it is possible to send/receive IMs in the Group Chat 2010 client, even though the Lync 2013 client is also running. What is the answer? I have no idea…

Posted in Lync | Leave a comment

Generate a Simple Group Chat Report

I get all sorts of odd, and fun, requests. Recently, I was asked to provide a quick and dirty report on which users are configured for Group Chat and to list the rooms they can join.

I really don’t want to get too good at this SQL stuff, but this one was good fun.

$SQLQuery = “SELECT isMember,isManager,prinID,prinName,prinDisabled,nodeName,nodeDesc,disabled,visibility

FROM [GroupChatDB].[dbo].[Exp_RoleView]

       INNER JOIN [GroupChatDB].[dbo].[tblPrincipal] on Exp_RoleView.principalId=tblPrincipal.prinGuid

           INNER JOIN [GroupChatDB].[dbo].[tblPrincipalType] on tblPrincipal.prinTypeID=dbo.tblPrincipalType.ptypeID

           INNER JOIN [GroupChatDB].[dbo].[tblNode] on Exp_RoleView.nodeDbId=tblNode.nodeID

      ORDER BY prinName”

 

$Connection = new-object system.data.sqlclient.sqlconnection

$Connection.connectionString=”Data Source=VSQLNCSB0010CDC\N1SQL01;Initial Catalog=GroupChatDB;Integrated Security=SSPI”

$Connection.open()

$Command = $Connection.CreateCommand()

$Command.Commandtext = $SqlQuery

$DataAdapter = New-Object System.Data.SqlClient.SqlDataAdapter $Command

$Dataset = New-Object System.Data.Dataset

$DataAdapter.Fill($Dataset)

$Dataset.Tables[0] | Export-CSV ConnectionList.csv -notype

$Connection.close()

$Connection = $null

 

Posted in Uncategorized | 1 Comment