Use PowerShell to integrate with the Lync 2013 SDK for Skype for Business – Part 2

Summary: Learn how to extend PowerShell with Lync 2013 SDK to explore groups and contacts information in Skype for Business 2016 client.

MVP Chendrayan Venkatesan is back again to show us how to get started with the Lync 2013 SDK to enable us to do some cool stuff with PowerShell and Skype for Business!

Take it away Chen!

Skype for Business 2016 client is great for business users for quick chat, sharing, presentation, organizing meetings, calls etc. Here is the Skype for Business client quick start guide. Please refer to it to understand and manage groups, contacts, and status (presence information). It’s a very good document collection for Skype for Business beginners, and it contains information about the Skype for Business client.

This blog post is about exploring groups and contacts in Skype for Business client by extending PowerShell with the Lync 2013 SDK and how to toggle privacy relationship. To begin, let’s retrieve all the Skype for Business group information, like name, type, and count of contacts, in our Skype for Business client. To get the information, we need to retrieve information from the Groups property from the ContactManager class.

Import-Module 'C:\Program Files (x86)\Microsoft Office 2013\LyncSDK\Assemblies\Desktop\Microsoft.Lync.Model.dll'

$Client = [Microsoft.Lync.Model.LyncClient]::GetClient()
$Groups = $Client.ContactManager.Groups
$Groups | Select Name , Type , Count


Groups returns group collections. The output is illustrated in the following image. Most Used Contacts is the FrequentContacts type. Favorites is the FavoriteContacts type. The rest are a CustomGroup type, which is created by a user. Other Contacts is created when you add a contact and skip to choose the group.

Illustration of returned groups with their names, types, and counts of contacts

Let’s try to retrieve information, like display name, primary email address, company, status, tag information etc., for a single contact.


$Client = [Microsoft.Lync.Model.LyncClient]::GetClient()
$Contact = $Client.ContactManager.GetContactByUri("")
DisplayName = $Contact.GetContactInformation([Microsoft.Lync.Model.ContactInformationType]::DisplayName)
Status = $Contact.GetContactInformation([Microsoft.Lync.Model.ContactInformationType]::Activity)
Company = $Contact.GetContactInformation([Microsoft.Lync.Model.ContactInformationType]::Company)
Email = $Contact.GetContactInformation([Microsoft.Lync.Model.ContactInformationType]::PrimaryEmailAddress)
IsTagged = $Contact.Settings.GetValueAt(0)




The following screenshot shows a demo of information that we retrieved for minimal information of a single contact from the Skype for Business client.

Demo of information that we retrieved for minimal information of a single contact from the Skype for Business client

It’s time to proceed one step ahead to retrieve all possible Contact Information in each group. Download the full script from the TechNet Gallery . Yes, its Contact Information that we see in the contact card! We can retrieve valid or required information from the ContactInformationType enumeration by modifying the script.

#Retrieves all the external contacts
Get-xSKBContact | ? {$_.PrivacyRelationShip -eq "External"}

All contact information for a group

It seems strange that the TimeZone information has the “W. Europe Standard Time” ID. Instead, let’s show the current date-time of the users TimeZone.

Note: The TimeZone ID should show your local system time zone information; if not, it returns nothing.

Get-xSKBContact |
Select Uri , Company, Status , PrivacyRelationShip , @{n="TimeZone";E={[System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId([datetime]::Now,$_.TimeZone)}}

Results of the DateTime object

In Skype for Business, client contacts are organized as Groups and can filtered as Status, Relationships, and New in each view. For example, STATUS view organizes and groups the contacts by presence information where the UNAVAILABLE group shows offline and Out of office contacts. Using the PowerShell script, we can retrieve users who have enabled out of office as shown in the following example.

Get-xSKBContact | ? {$_.IsOutofOffice} | Select GroupName , IsOutofOffice

Users who have enabled out of office

Note: ? is an alias of Where-Object and the IsOutofOffice note property is a bool type. By default, it’s True, so need to query like $_.IsOutofOffice -eq $true.

Let’s share another cool trick by using the same PowerShell script! The ContactInformationType enumeration that we used in our script to retrieve the contacts information has NextCalendarState and NextCalendarStateStartTime properties that fetch the users outlook calendar information. Using these properties, we can see the next availability for users.

Get-xSKBContact| ? {$_.NextCalendarState -ne "NotAvailable"} |
select Displayname , Status , NextCalendarStateStartTime , NextCalendarState

Users next calendar availability

Check the highlighted contact in the preceding image. The Status shows the current presence information. At 10:30:00, the user has an appointment where the calendar state changes to busy, that is, “Free Until 10:30:00”, and that appears in the Skype for Business client UI as in the following illustration.

Free until 10:30 status in Skype client UI

Now, it’s time to see a programmatic approach to change the privacy relationship. For more information about how to control presence information, see Control access to your presence information in Lync. In Skype for Business, each contact has an access level, which is nothing but a privacy relationship chosen by us. For example, go to Groups in the Skype for Business client and right-click a contact to show the Change Privacy Relationship option and different levels like Friends and Family, Workgroup, Colleagues, External Contacts, Blocked Contacts, and Auto-Assign relationship. When we choose Auto-Assign relationship, Skype for Business automatically sets the access level. In the Skype for Business client UI, it appears as shown in the following screenshot.

Change Privacy Relationship option

To retrieve the contacts in our groups and the privacy relationship status like External, use the following snippet.

Get-xSKBContact | ? {$_.PrivacyRelationShip -eq "External"} | Select GroupName , Source , PrivacyRelationShip

Groups that have the External privacy relationship

Consider the following scenario. A user messed up the Skype for Business contacts by choosing the wrong privacy relationship option. For example, a contact in enterprise is Colleague by default. Accidentally, a user might have pinned one more enterprise contacts as External. Look at the following image where a contact in our enterprise shows as External because it’s pinned as External in the Change Privacy Relationship option. (For demo)

Example of incorrectly chosen privacy relationship option

We should retrieve all the contacts that have source network as Enterprise and map them to Colleague by using a simple PowerShell trick as shown in the following example. By changing the value of [Microsoft.Lync.Model.AccessLevel], it’s easy to toggle the privacy relationship.

Import-Module 'C:\Program Files (x86)\Microsoft Office 2013\LyncSDK\Assemblies\Desktop\Microsoft.Lync.Model.dll'
$Client = [Microsoft.Lync.Model.LyncClient]::GetClient()
$Users = @("SIP1" , "SIP2")
foreach($User in $Users)

$contact = $Client.ContactManager.GetContactByUri($User)

if([Microsoft.Lync.Model.SourceNetworkType]$contact.GetContactInformation([Microsoft.Lync.Model.ContactInformationType]::SourceNetwork) -eq [Microsoft.Lync.Model.SourceNetworkType]::Enterprise)



$AR = $contact.BeginChangeSetting([Microsoft.Lync.Model.ContactSetting]::AccessLevel,[Microsoft.Lync.Model.AccessLevel]::Colleague,$null,$null)
$contact.Uri + " privacy relationship changed to " + [Microsoft.Lync.Model.AccessLevel]$contact.Settings.GetValueAt(2)




How does this work? The script retrieves the contact information to check the source network type. If the type is Enterprise, the script determines whether the settings for the contact can be changed. If a change is allowed, the script changes the access level (Privacy Relationship) to Colleague from External.

Note: We can choose the Source Network Type as Default to make the type Auto-Assign relationship. It’s not required here because it changes other contacts privacy relationship settings.

Result of updating group

In this post, we showed a few tips and tricks to retrieve group and contact information by using a tiny PowerShell script with Lync 2013 SDK. In the next blog post, we’ll talk about how to register events, add groups, remove groups, rename groups, and organize contacts by integrating PowerShell with Lync 2013 SDK.

I invite you to follow the Scripting Guys on Twitter and Facebook. If you have any questions, send email to them at, or post your questions on the Official Scripting Guys Forum. See you tomorrow.

Until then always remember that with Great PowerShell comes Great Responsibility.

Sean Kearney
Honorary Scripting Guy
Cloud and Datacenter Management MVP

Comments (0)

Skip to main content