{"id":79855,"date":"2016-09-16T00:01:04","date_gmt":"2016-09-16T07:01:04","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/?p=79855"},"modified":"2019-02-18T09:10:28","modified_gmt":"2019-02-18T16:10:28","slug":"use-powershell-to-integrate-with-the-lync-2013-sdk-for-skype-for-business-part-2","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/use-powershell-to-integrate-with-the-lync-2013-sdk-for-skype-for-business-part-2\/","title":{"rendered":"Use PowerShell to integrate with the Lync 2013 SDK for Skype for Business \u2013 Part 2"},"content":{"rendered":"<p><strong>Summary<\/strong>: Learn how to extend PowerShell with Lync 2013 SDK to explore groups and contacts information in Skype for Business 2016 client.<\/p>\n<p>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!<\/p>\n<p>Take it away Chen!<\/p>\n<p>Skype for Business 2016 client is great for business users for quick chat, sharing, presentation, organizing meetings, calls etc. Here is the <a target=\"_blank\" href=\"https:\/\/docs.com\/OfficeTraining\/9869\/skype-for-business-quick-start-guides\">Skype for Business client quick start guide<\/a>. Please refer to it to understand and manage groups, contacts, and status (presence information). It\u2019s a very good document collection for Skype for Business beginners, and it contains information about the Skype for Business client.<\/p>\n<p>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\u2019s 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 <strong>Groups<\/strong> property from the <strong>ContactManager<\/strong> class.<\/p>\n<p style=\"padding-left: 30px\"><code>Import-Module 'C:\\Program Files (x86)\\Microsoft Office 2013\\LyncSDK\\Assemblies\\Desktop\\Microsoft.Lync.Model.dll'\ntry\n{<\/code><\/p>\n<p style=\"padding-left: 60px\"><code>$Client = [Microsoft.Lync.Model.LyncClient]::GetClient()\n$Groups = $Client.ContactManager.Groups\n$Groups | Select Name , Type , Count<\/code><\/p>\n<p style=\"padding-left: 30px\"><code>}\ncatch\n{\n$_.Exception.Message\n}<\/code><\/p>\n<p><strong>Groups<\/strong> returns group collections. The output is illustrated in the following image. <strong>Most Used Contacts<\/strong> is the <strong>FrequentContacts<\/strong> type. <strong>Favorites<\/strong> is the <strong>FavoriteContacts<\/strong> type. The rest are a <strong>CustomGroup<\/strong> type, which is created by a user. <strong>Other Contacts<\/strong> is created when you add a contact and skip to choose the group.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1-HSG-091616.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/1-HSG-091616.png\" alt=\"Illustration of returned groups with their names, types, and counts of contacts\" width=\"535\" height=\"161\" class=\"alignnone size-full wp-image-79865\" \/><\/a><\/p>\n<p>Let\u2019s try to retrieve information, like display name, primary email address, company, status, tag information etc., for a single contact.<\/p>\n<p style=\"padding-left: 30px\"><code>try\n{<\/code><\/p>\n<p style=\"padding-left: 60px\"><code>$Client = [Microsoft.Lync.Model.LyncClient]::GetClient()\n$Contact = $Client.ContactManager.GetContactByUri(\"Chendrayan.Venkatesan@contoso.com\")\n[pscustomobject]@{\nDisplayName = $Contact.GetContactInformation([Microsoft.Lync.Model.ContactInformationType]::DisplayName)\nStatus = $Contact.GetContactInformation([Microsoft.Lync.Model.ContactInformationType]::Activity)\nCompany = $Contact.GetContactInformation([Microsoft.Lync.Model.ContactInformationType]::Company)\nEmail = $Contact.GetContactInformation([Microsoft.Lync.Model.ContactInformationType]::PrimaryEmailAddress)\nIsTagged = $Contact.Settings.GetValueAt(0)\n}<\/code><\/p>\n<p style=\"padding-left: 30px\"><code>}\ncatch\n{<\/code><\/p>\n<p style=\"padding-left: 60px\"><code>$_.Exception.Message<\/code><\/p>\n<p style=\"padding-left: 30px\"><code>}<\/code><\/p>\n<p>The following screenshot shows a demo of information that we retrieved for minimal information of a single contact from the Skype for Business client.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2-HSG-091616.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/2-HSG-091616.png\" alt=\"Demo of information that we retrieved for minimal information of a single contact from the Skype for Business client\" width=\"513\" height=\"109\" class=\"alignnone size-full wp-image-79875\" \/><\/a><\/p>\n<p>It\u2019s time to proceed one step ahead to retrieve all possible <strong>Contact Information<\/strong> in each group. Download the full script from the <a target=\"_blank\" href=\"https:\/\/gallery.technet.microsoft.com\/Get-Skype-for-Business-c7d696d4\/file\/158454\/1\/Get-xSKBContact.ps1\">TechNet Gallery<\/a> . Yes, its <strong>Contact Information<\/strong> that we see in the contact card! We can retrieve valid or required information from the <a target=\"_blank\" href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/microsoft.lync.model.contactinformationtype_di_3_uc_ocs14mreflyncclnt(v=office.14).aspx\">ContactInformationType<\/a> enumeration by modifying the script.<\/p>\n<p style=\"padding-left: 30px\"><code>#Retrieves all the external contacts\nGet-xSKBContact | ? {$_.PrivacyRelationShip -eq \"External\"}<\/code><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3-HSG-091616.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/3-HSG-091616.png\" alt=\"All contact information for a group\" width=\"505\" height=\"140\" class=\"alignnone size-full wp-image-79885\" \/><\/a><\/p>\n<p>It seems strange that the <strong>TimeZone<\/strong> information has the \u201cW. Europe Standard Time\u201d ID. Instead, let\u2019s show the current date-time of the users <strong>TimeZone<\/strong>.<\/p>\n<p style=\"padding-left: 30px\"><strong>Note<\/strong>: The <strong>TimeZone<\/strong> ID should show your local system time zone information; if not, it returns nothing.<\/p>\n<p style=\"padding-left: 30px\"><code>Get-xSKBContact |\nSelect Uri , Company, Status , PrivacyRelationShip , @{n=\"TimeZone\";E={[System.TimeZoneInfo]::ConvertTimeBySystemTimeZoneId([datetime]::Now,$_.TimeZone)}}<\/code><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4-HSG-091616.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/4-HSG-091616.png\" alt=\"Results of the DateTime object\" width=\"542\" height=\"88\" class=\"alignnone size-full wp-image-79895\" \/><\/a><\/p>\n<p>In Skype for Business, client contacts are organized as <strong>Groups<\/strong> and can filtered as <strong>Status<\/strong>, <strong>Relationships<\/strong>, and <strong>New<\/strong> in each view. For example, <strong>STATUS<\/strong> view organizes and groups the contacts by presence information where the <strong>UNAVAILABLE<\/strong> 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.<\/p>\n<p style=\"padding-left: 30px\"><code>Get-xSKBContact | ? {$_.IsOutofOffice} | Select GroupName , IsOutofOffice<\/code><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5-HSG-091616.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/5-HSG-091616.png\" alt=\"Users who have enabled out of office \" width=\"538\" height=\"86\" class=\"alignnone size-full wp-image-79905\" \/><\/a><\/p>\n<p style=\"padding-left: 30px\"><strong>Note: ?<\/strong> is an alias of <strong>Where-Object<\/strong> and the <strong>IsOutofOffice<\/strong> note property is a <strong>bool<\/strong> type. By default, it\u2019s <strong>True<\/strong>, so need to query like <code>$_.IsOutofOffice -eq $true<\/code>.<\/p>\n<p>Let\u2019s share another cool trick by using the same PowerShell script! The <a target=\"_blank\" href=\"https:\/\/msdn.microsoft.com\/en-us\/library\/microsoft.lync.model.contactinformationtype_di_3_uc_ocs14mreflyncclnt(v=office.14).aspx\">ContactInformationType<\/a> enumeration that we used in our script to retrieve the contacts information has <strong>NextCalendarState<\/strong> and <strong>NextCalendarStateStartTime<\/strong> properties that fetch the users outlook calendar information. Using these properties, we can see the next availability for users.<\/p>\n<p style=\"padding-left: 30px\"><code>Get-xSKBContact| ? {$_.NextCalendarState -ne \"NotAvailable\"} |\nselect Displayname , Status , NextCalendarStateStartTime , NextCalendarState<\/code><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6-HSG-091616.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/6-HSG-091616.png\" alt=\"Users next calendar availability\" width=\"575\" height=\"197\" class=\"alignnone size-full wp-image-79915\" \/><\/a><\/p>\n<p>Check the highlighted contact in the preceding image. The <strong>Status<\/strong> shows the current presence information. At 10:30:00, the user has an appointment where the calendar state changes to busy, that is, \u201cFree Until 10:30:00\u201d, and that appears in the Skype for Business client UI as in the following illustration.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7-HSG-091616.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/7-HSG-091616.png\" alt=\"Free until 10:30 status in Skype client UI\" width=\"184\" height=\"117\" class=\"alignnone size-full wp-image-79925\" \/><\/a><\/p>\n<p>Now, it\u2019s time to see a programmatic approach to change the privacy relationship. For more information about how to control presence information, see <a href=\"https:\/\/support.office.com\/en-us\/article\/Control-access-to-your-presence-information-in-Lync-2fbfdcc5-d04b-49fe-ad90-264a42f7cce1\">Control access to your presence information in Lync<\/a>. In Skype for Business, each contact has an access level, which is nothing but a privacy relationship chosen by us. For example, go to <strong>Groups<\/strong> in the Skype for Business client and right-click a contact to\u00a0show the <strong>Change Privacy Relationship<\/strong> option and different levels like <strong>Friends and Family<\/strong>, <strong>Workgroup<\/strong>, <strong>Colleagues<\/strong>, <strong>External Contacts<\/strong>, <strong>Blocked Contacts<\/strong>, and <strong>Auto-Assign relationship<\/strong>. When we choose <strong>Auto-Assign relationship<\/strong>, Skype for Business automatically sets the access level. In the Skype for Business client UI, it appears as shown in the following screenshot.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/8-HSG-091616.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/8-HSG-091616.png\" alt=\"Change Privacy Relationship option\" width=\"433\" height=\"353\" class=\"alignnone size-full wp-image-79935\" \/><\/a><\/p>\n<p>To retrieve the contacts in our groups and the privacy relationship status like <strong>External<\/strong>, use the following snippet.<\/p>\n<p style=\"padding-left: 30px\"><code>Get-xSKBContact | ? {$_.PrivacyRelationShip -eq \"External\"} | Select GroupName , Source , PrivacyRelationShip<\/code><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/9-HSG-091616.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/9-HSG-091616.png\" alt=\"Groups that have the External privacy relationship\" width=\"666\" height=\"134\" class=\"alignnone size-full wp-image-79945\" \/><\/a><\/p>\n<p>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 <strong>Colleague<\/strong> by default. Accidentally, a user might have pinned one more enterprise contacts as <strong>External<\/strong>. Look at the following image where a contact in our enterprise shows as <strong>External<\/strong> because it\u2019s pinned as <strong>External<\/strong> in the <strong>Change Privacy Relationship<\/strong> option. (For demo)<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/10-HSG-091616.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/10-HSG-091616.png\" alt=\"Example of incorrectly chosen privacy relationship option\" width=\"592\" height=\"101\" class=\"alignnone size-full wp-image-79955\" \/><\/a><\/p>\n<p>We should retrieve all the contacts that have source network as <strong>Enterprise<\/strong> and map them to<strong> Colleague<\/strong> by using a simple PowerShell trick as shown in the following example. By changing the value of <strong>[Microsoft.Lync.Model.AccessLevel]<\/strong>, it\u2019s easy to <strong>toggle the privacy relationship<\/strong>.<\/p>\n<p style=\"padding-left: 30px\"><code>Import-Module 'C:\\Program Files (x86)\\Microsoft Office 2013\\LyncSDK\\Assemblies\\Desktop\\Microsoft.Lync.Model.dll'\n$Client = [Microsoft.Lync.Model.LyncClient]::GetClient()\n$Users = @(\"SIP1\" , \"SIP2\")\nforeach($User in $Users)\n{<\/code><\/p>\n<p style=\"padding-left: 60px\"><code>$contact = $Client.ContactManager.GetContactByUri($User)<\/code><\/p>\n<p style=\"padding-left: 30px\"><code>if([Microsoft.Lync.Model.SourceNetworkType]$contact.GetContactInformation([Microsoft.Lync.Model.ContactInformationType]::SourceNetwork) -eq [Microsoft.Lync.Model.SourceNetworkType]::Enterprise)<\/code><\/p>\n<p style=\"padding-left: 60px\"><code>{<\/code><\/p>\n<p style=\"padding-left: 90px\"><code>if($contact.CanChangeSetting([Microsoft.Lync.Model.ContactSetting]::AccessLevel))\n{<\/code><\/p>\n<p style=\"padding-left: 120px\"><code>$AR = $contact.BeginChangeSetting([Microsoft.Lync.Model.ContactSetting]::AccessLevel,<strong>[<\/strong><strong>Microsoft.Lync.Model.AccessLevel]::Colleague<\/strong>,$null,$null)\n$contact.EndChangeSetting($AR)\n$contact.Uri + \" privacy relationship changed to \" + [Microsoft.Lync.Model.AccessLevel]$contact.Settings.GetValueAt(2)<\/code><\/p>\n<p style=\"padding-left: 90px\"><code>}<\/code><\/p>\n<p style=\"padding-left: 60px\"><code>}<\/code><\/p>\n<p style=\"padding-left: 30px\"><code>}<\/code><\/p>\n<p><strong>How does this work?<\/strong> The script retrieves the contact information to check the source network type. If the type is <strong>Enterprise<\/strong>, 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 <strong>Colleague<\/strong> from <strong>External<\/strong>.<\/p>\n<p style=\"padding-left: 30px\"><strong>Note<\/strong>: We can choose the Source Network Type as Default to make the type <strong>Auto-Assign relationship<\/strong>. It\u2019s not required here because it changes other contacts privacy relationship settings.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/11-HSG-091616.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/11-HSG-091616.png\" alt=\"Result of updating group\" width=\"589\" height=\"136\" class=\"alignnone size-full wp-image-79965\" \/><\/a><\/p>\n<p>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\u2019ll talk about how to register events, add groups, remove groups, rename groups, and organize contacts by integrating PowerShell with Lync 2013 SDK.<\/p>\n<p>I invite you to follow the Scripting Guys on <a target=\"_blank\" href=\"http:\/\/bit.ly\/scriptingguystwitter\">Twitter<\/a> and <a target=\"_blank\" href=\"http:\/\/bit.ly\/scriptingguysfacebook\">Facebook<\/a>. If you have any questions, send email to them at <a target=\"_blank\" href=\"mailto:scripter@microsoft.com\">scripter@microsoft.com<\/a>, or post your questions on the <a target=\"_blank\" href=\"http:\/\/bit.ly\/scriptingforum\">Official Scripting Guys Forum<\/a>. See you tomorrow.<\/p>\n<p>Until then always remember that with Great PowerShell comes Great Responsibility.<\/p>\n<p><strong>Sean Kearney<\/strong>\nHonorary Scripting Guy\nCloud and Datacenter Management MVP<\/p>\n","protected":false},"excerpt":{"rendered":"<p>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 [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[568,685,641],"tags":[696,56,59,45],"class_list":["post-79855","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-hey-scripting-guy","category-scripting-techniques","category-windows-powershell","tag-chendrayan-venkatesan","tag-guest-blogger","tag-sharepoint","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>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 [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/79855","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=79855"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/79855\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=79855"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=79855"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=79855"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}