Retrieve Available Contacts
With the Microsoft Lync 2010 SDK you can write scripts that retrieve all sorts of information about the contacts in the currently-running instance of Lync. What kind of information, you ask? Well, things like the contacts’ activity status (free, busy, etc.); their out of office message; and what time they started being “away.” Now, why would you want to use a script to retrieve that information? In the immortal words of Alfred Lord Tennyson, “Ours is not to reason why….”
Note. The quote, from The Charge of the Light Brigade, is actually “Theirs not to reason why/Theirs but to do and die.” But that was a little morbid for us.
Note. Granted, we were able to come up with a few sneaky reasons why you might want to gather some of this information, but we tend to be sneaky kind of people. Well, okay, one of us is a sneaky kind of person. Which one depends on your point of view.
Actually, we did come up with a couple of very valid, and not the least bit sneaky, reasons you might want to retrieve activity status on your contacts from a script. One reason we stole from someone else (we told you we were sneaky): it’s a good testing tool. When you install a patch or service pack or whatever, you might need to try everything, including your Lync connections and functionality, in a test environment. You can log on some test users, then run a script to monitor their status as you modify the availability of the various users. The other reason we came up with is this:
Suppose you frequently contact members of a specific contact group. You open up Lync and scroll through to see who’s available to talk to you. With the Lync SDK, you can write a script that quickly displays all the members of a group who are available. From there you could expand the script to open an instant messaging session with the first available person in the list (or, if you want to get fancy, a random person in the list).
Note. The scripts in this article require the use of the Lync 2010 SDK. For information on what you need to work with the Lync SDK in Windows PowerShell, see the first few pages of the article Send an Instant Message from a Script.
We’ll start with the simplest version of the script, one that retrieves all the users in a group (in this case the “Super Helpers” group) who are currently available:
$assemblyPath = "C:\Program Files (x86)\Microsoft Lync\SDK\Assemblies\Desktop\Microsoft.Lync.Model.DLL"
Import-Module $assemblyPath
$DisplayName = 10
$Activity = 7
$cl = [Microsoft.Lync.Model.LyncClient]::GetClient()
$gs = $cl.ContactManager.Groups
foreach ($g in $gs)
{
if ($g.Name -eq "Super Helpers" )
{
foreach ($contact in $g)
{
if ($contact.GetContactInformation($Activity) -eq "available")
{
Write-Host $contact.GetContactInformation($DisplayName)
}
}
}
}
The first two lines of the script are required anytime you work with the Lync 2010 SDK. With these lines, you import into your script the classes, methods, properties, and so on that are available in the SDK. If you don’t explicitly import these items, and thus tell Windows PowerShell where they are, you can’t use them.
$assemblyPath = "C:\Program Files (x86)\Microsoft Lync\SDK\Assemblies\Desktop\Microsoft.Lync.Model.DLL"
Import-Module $assemblyPath
The next two lines are simply declaring a couple of variables that we’ll use later to determine which contact information to retrieve:
$DisplayName = 10
$Activity = 7
Now it’s time to grab an instance of the Lync client. We do that by calling the GetClient method, like this:
$cl = [Microsoft.Lync.Model.LyncClient]::GetClient()
Keep in mind that there must be a running, logged-on instance of Lync running on the local computer for this command to work.
Now that we have a variable that represents the currently running instance of Lync, we can retrieve all the contact groups defined in that instance. We do that by accessing the client’s Groups collection, like this:
$gs = $cl.ContactManager.Groups
We now have a collection of all the contact groups saved in the variable $gs. In order to find the group we’re interested in, the Super Helpers group, we need to set up a foreach loop to loop through the collection, then check the Name property of each group:
foreach ($g in $gs)
{
if ($g.Name -eq "Super Helpers" )
We set up an if statement to see if the Name property of the group is equal to (-eq) the string “Super Helpers”. If it is, we go into another foreach loop, this one to loop through all the contacts in the group:
foreach ($contact in $g)
We now want to check the current activity of that contact. We do that by calling the GetContactInformation method on the contact, passing it the variable $Activity. Earlier we assigned $Activity a value of 7, which tells the GetContactInformation method to return the contact’s current activity status. We then check to see if that activity status is equal to “Available”:
if ($contact.GetContactInformation($Activity) -eq "available")
If the contact’s activity status is Available, we write the display name of the contact to the screen. We retrieve the display name by once again calling the GetContactInformation method, this time passing the variable $DisplayName (which contains a value of 10). We then use the Write-Host cmdlet to write the display name to the output:
Write-Host $contact.GetContactInformation($DisplayName)
That’s all there is to it. One thing to note is that the Activity is returned as a simple string. You can do some experimenting to see what types of Activity values you might expect from the contacts in your organization. If you’d like to work with a stricter set of return values, you can retrieve the contact’s Availability (value 0) rather than their Activity. The only thing to be aware of there is that the Availability is returned as an integer value and you’ll have to translate it into something readable. Here’s an example:
$assemblyPath = “C:\Program Files (x86)\Microsoft Lync\SDK\Assemblies\Desktop\Microsoft.Lync.Model.DLL”
Import-module $assemblyPath
$DisplayName = 10
$Availability = 0
$Free = 3500
$cl = [microsoft.lync.model.lyncclient]::GetClient()
$gs = $cl.ContactManager.Groups
foreach ($g in $gs)
{
if ($g.Name -eq "Current Contacts" )
{
foreach ($contact in $g)
{
if ($contact.GetContactInformation($Availability) -eq $Free)
{
Write-Host $contact.GetContactInformation($DisplayName)
}
}
}
}
We’ve declared two new variables, $Availability (0) and $Free (3500). Then, instead of checking for an Activity of “Available” we’re checking Availability to see if the value is $Free:
if ($contact.GetContactInformation($Availability) -eq $Free)
This table shows the other values that can be returned for Availability:
Value |
Description |
-1 |
Invalid |
0 |
None |
3500 |
Free |
5000 |
FreeIdle |
6500 |
Busy |
7500 |
BusyIdle |
9500 |
DoNotDisturb |
12500 |
TemporarilyAway |
15500 |
Away |
18500 |
Offline |
So now we know who’s available. Let’s start an instant messaging session with one of our available contacts. Here’s the script:
$assemblyPath = "C:\Program Files (x86)\Microsoft Lync\SDK\Assemblies\Desktop\Microsoft.Lync.Model.DLL"
Import-Module $assemblyPath
$DisplayName = 10
$Activity = 7
$IMType = 1
$PlainText = 0
$cl = [Microsoft.Lync.Model.LyncClient]::GetClient()
$gs = $cl.ContactManager.Groups
foreach ($g in $gs)
{
if ($g.Name -eq "Super Helpers" )
{
foreach ($contact in $g)
{
if ($contact.GetContactInformation($Activity) -eq "available")
{
$conv = $cl.ConversationManager.AddConversation()
$null= $conv.AddParticipant($contact)
$d = New-Object "System.Collections.Generic.Dictionary[Microsoft.Lync.Model.Conversation.InstantMessageContentType,String]"
$d.Add($PlainText, "Hey, do you have a second?")
$m = $conv.Modalities[$IMType]
$null = $m.BeginSendMessage($d, $null, $d)
break
}
}
break
}
}
We’re not going to explain this whole script here. For an explanation of sending an instant message to a contact, see the aptly-title article Send an Instant Message from a Script.
The one thing we noticed in testing this is that the message tended to always go to the first contact in the group (alphabetically speaking) who was available. (Something this author’s manager was thrilled with, given that her name starts with a C. Several test messages wound up in her direction.) So we came up with a script that randomly chooses one of the available contacts from the group and sends the instant message to that contact. Here it is:
$assemblyPath = "C:\Program Files (x86)\Microsoft Lync\SDK\Assemblies\Desktop\Microsoft.Lync.Model.DLL"
Import-Module $assemblyPath
$DisplayName = 10
$Activity = 7
$IMType = 1
$PlainText = 0
$ac = @()
$cl = [Microsoft.Lync.Model.LyncClient]::GetClient()
$conv = $cl.ConversationManager.AddConversation()
$gs = $cl.ContactManager.Groups
foreach ($g in $gs)
{
if ($g.Name -eq "Super Helpers" )
{
foreach ($contact in $g)
{
if ($contact.GetContactInformation($Activity) -eq "available")
{
$ac += $contact
}
}
}
}
$sendto = $ac | Get-Random
$null= $conv.AddParticipant($sendto)
$d = New-Object "System.Collections.Generic.Dictionary[Microsoft.Lync.Model.Conversation.InstantMessageContentType,String]"
$d.Add($PlainText, " Hey, do you have a second?")
$m = $conv.Modalities[$IMType]
$null = $m.BeginSendMessage($d, $null, $d)
In this script we declare the variable $ac as an array (the @() means “array”):
$ac = @()
When we find an available contact within our Super Helpers group, we add that contact to the array:
$ac += $contact
After we’ve added all the available contacts, we run this line:
$sendto = $ac | Get-Random
Here we’re taking the contents of the array that contains all our available contacts and piping it to the Get-Random cmdlet. That cmdlet does exactly what it sounds like: it randomly selects an element from the array. In this case it’s randomly selecting on of our available contacts. We save that contact to the $sendto variable, then use that variable to add the randomly-chosen contact as a participant to our instant messaging session.
And that’s about all there is to retrieving contacts and their current activities from the currently running instance of Lync. Nothing sneaky about that.