Trigger something whenever you’re on a Lync call

Articles in the "Lync call handling script" series

  1. Trigger something whenever you’re on a Lync call [This article]
  2. Update to Lync call handling script
  3. Lync call handling script updated

A coworker of mine works out of his home office and wanted his family to know when he is on a phone call so they won’t interrupt him. He already had a network-controllable light that he put into the hallway outside the office. What he needed was a way to trigger the light when he is on the phone (he is enterprise voice-enabled in Lync). Here are the details of the PowerShell script that I wrote for him.

The script leverages the API in the Lync SDK. You only need to install the Lync SDK runtime library, but there isn’t an individual download for that. To install the Lync SDK, however, requires that Visual Studio is installed. That may not be the case for many of you, so I have included the redistributable runtime library (a mere 750KB MSI) in the script download.

The runtime library installs the assemblies into the global access cache (GAC), so to use one of them in a script, you need to load the assembly:

You can then create an object for the Lync client:

In order to know someone’s current presence state (or activity in Lync parlance), you work against a contact object. Therefore, to know your own activity, you first need to create an object for yourself as a contact:

To get your current activity, you use the GetContactInformation() method, with the argument being the type of information to retrieve:

The activities that indicate you are on the phone, or off-hook in telecom parlance, are In a call and In a conference call. To use this information to do something, you need to know when Lync changes to and/or from these activities, and for that you can use .NET Framework object events. Instead of constantly querying for your activity, you can use events to have PowerShell act when something happens. The Contact class has an event for when contact information changes, and here is the list of what properties will result in that event firing.

To register for an event, you have to include the object whose class contains the event, as well what action to take:

$event is one of the built-in variables that the event can include in the response. And this is the function that will run as a result of the event firing:

Since the list of changed properties that triggers a changed contact event is numerous, the first thing the function does is check to see if the changed property is Activity. The event doesn’t include what the activity is, so you have to get the current activity. If the activity is one of the values that indicates you are on the phone, it calls a function to run your code that does something. (I did it this way, instead of having you put your code inside this function, so that it is easier to paste your code into a function at the beginning of the script and for doing so if there are future versions of the script.) A global variable of $offhook is set. This allows the script to keep track of whether you are off the phone, after having been on the phone, in subsequent event firings. If you are no longer on the phone, after having been on the phone, it calls another function to run your code that “undoes” whatever it did when you got on the phone.

The script will normally not output anything to the screen, allowing you to run it in a shell you are using for something else. If you are testing your code or just want to see more information about your activity changes, you can include the -Verbose parameter. This will result in more details being output to the screen as they occur, such as current activity, functions being called, and whether the client is signed in. If you do this, you will likely want to run the script in its own shell so it doesn’t get in the way of what you might be doing in the first shell.

Now, to put all of this into a reusable script, there are other things to consider. If you sign out, or get otherwise disconnected from Lync, the contact object is no longer valid and has to be created again when you sign in. To account for this, I use another event that fires on client state changes. If not signed in, it unregisters the contact change event, and when you get signed in again it creates the contact object and registers the event.

Another consideration is the scope of the script. When you run a script, its code is run in its own scope, terminating when the script reaches the end. Since the registered events will call functions after the script has completed, they need to be run in a scope that stays resident upon completion, i.e., global scope. To do this, you dot-source the script by entering a period and a space before the path to the script. To account for this, the script checks to ensure that it was dot-sourced when executed, otherwise it presents an error.

As for using the -Verbose parameter, I found that it worked fine when using Write-Verbose in the script’s main block and initial functions. It did not work in the functions called by the events. The function would just hang at the point of running the cmdlet. I have not been able to find out why this is the case, so I wrote a function to mimic the output of the Write-Verbose cmdlet. This function is used in the functions called by the events.

To make use of this script in your environment, you will want to modify the first function, called OffHook-Action, by replacing lines 13 and 19 with code to “do” something and “undo” something, respectively. If those lines of code are dependent on other functions, you can put them in the subsequent region that is labeled for your dependent functions.

As a side note, since I don’t have a network-controllable light at work, I needed something else for it to do so I could be sure it was running correctly. I use Winamp, so it was appropriate for me to have it pause when I am on the phone, and resume if I am off the phone (but only if it is already paused). The code in the script, therefore, includes functions for controlling Winamp and reference to a COM object the provides this. I left it in so you can see an example of the custom code that you will need to put in your version. It is worth nothing that the COM object for controlling Winamp is a 32-bit library. If you are running PowerShell on a 64-bit system and reference a library that is only compiled for a 32-bit system, you will need to run the x86 version of PowerShell (there is a Start Menu item for it). (The Lync SDK runtime is accessible in both versions of the shell.)

The download of the full version of the script (and the Lync SDK runtime library) is below, but you can also see the full script by expanding the code block below: (640.5 KiB)

2 thoughts on “Trigger something whenever you’re on a Lync call

  1. hi,

    i am trying your code and once i have run the script, it seems that it is stuck with “Waiting for Lync process to start (15-second intervals)…” any idea?


  2. Make sure you have the appropriate line (62 or 63) commented for use with Lync 2013 or with Lync 2010/Communicator, respectively.

Leave a Reply

Your email address will not be published. Required fields are marked *