PowerShell Scripting Lync 2010 SDK Using Lync Extensibility API

Summary:   In this article, you will learn how to automate Microsoft Lync 2010 using Microsoft PowerShell scripting against Microsoft Lync Extensibility API.

Applies to:   Microsoft Lync 2010 | Microsoft Lync 2010 SDK | Microsoft Windows PowerShell 2.0 | Published:   December 2010 | Provided by:   Kurt De Ding, Microsoft | About the Author

Contents

  • Introduction

  • Getting Ready to Script Lync 2010 Extensibility API

  • Getting Automation Object of Lync Extensibility API

  • Launching the Add a Contact Wizard Using the Automation Object

  • Starting a Conversation Using the Automation Object

  • Inviting a User to a Conference Call

  • Conclusion

  • Additional Resources

Introduction

Microsoft Lync 2010 SDK supports the Lync 2010 Model API and Lync 2010 Extensibility API. Lync Model API consists of the .NET types in the Microsoft.Lync.Model namespace and the supporting namespaces. Lync Extensibility API corresponds to the Microsoft.Lync.Model.Extensibility namespace and the supporting namespaces. These are .NET Framework APIs. They constitute a major improvement to the Lync programmability and they offer more advanced programming features than their predecessor, the COM-based Microsoft Office Communicator 2007 Automation API.

Windows PowerShell provides an interactive scripting environment to manipulate .NET objects directly. It can be used to automate the testing process for a .NET API. For a developer using the Lync Model or Lync Extensibility API, PowerShell offers an interactive development environment to experiment with new ideas and to explore application prototypes.

In this article, I show you how to automate Microsoft Lync 2010 by calling the .NET-based Lync Extensibility API in Windows PowerShell. I discuss what is required of using the Lync Extensibility API in PowerShell and present a few PowerShell code examples as a quick demonstration. In some cases, I will compare the coding patterns between PowerShell scripting patterns and C# programming patterns. The example scripts cover the following tasks:

  • Adding assembly reference to Lync Extensibility API into your PowerShell session.

  • Calling static methods of a .NET type in PowerShell.

  • Creating an object of a generic type with the argument types that are defined in the referenced assembly.

  • Performing necessary type casting in PowerShell.

  • Launching an Add a Contact wizard to add contact and assign a privacy relationship to the contact.

  • Launching conversation windows to start a conversation.

  • Adding a participant to a conference call.

Getting Ready to Script Lync 2010 Extensibility API

To automate Lync using Microsoft Lync Extensibility API in PowerShell, you must have the Microsoft Lync 2010 SDK assembly that contain the API installed on your local computer. The API is contained in the assembly file (Microsoft.Lync.Model.DLL) and is installed as part of the Lync 2010 SDK, which can be downloaded from MSDN. By default, the assembly file is installed to the %ProgramFiles%\Microsoft Lync\SDK\Assemblies\Desktop directory.

Note

If you install the assembly file to a different directory, you must update your reference to the assembly in a PowerShell session. Substitute the $assemblyPath variable value appearing in the following example with your updated installation path.

As in any .NET Framework application project, you must add the assembly reference to your PowerShell session. This makes the API types that are contained in the assembly visible to PowerShell. To add a reference to the Microsoft.Lync.Model.DLL assembly in PowerShell, you can use the following Import-Module cmdlet:

# Assume assembly is installed in the default installation directory
$assemblyPath = “C:\Program Files (x86)\Microsoft Lync\SDK\Assemblies\Desktop\Microsoft.Lync.Model.DLL”

# Import the assembly into the PowerShell session
Import-module $assemblyPath

The $assemblyPath variable specifies the location of the assembly that contain the Lync API. There are other PowerShell cmdlets that let you to add references to the API. The reason why you should use the Import-Module cmdlet is explained later in this article.

You may need to refer to the API documentation to determine the signature of a particular member. The documentation is also installed as part of the Lync 2010 SDK in the %ProgramFiles%\Microsoft Lync\SDK directory.

Getting Automation Object of Lync Extensibility API

To use the Lync Extensibility API features, you must first obtain the Microsoft.Lync.Model.Extensibility.Automation object. You do this by calling the static method GetAutomation on the Microsoft.Lync.Model.LyncClient type.

# Get Lync 2010 Extensibility API
$auto = [Microsoft.Lync.Model.LyncClient]::GetAutomation()

$auto is a PowerShell variable and [Microsoft.Lync.Model.LyncClient]::GetAutomation() is the PowerShell equivalent of the Microsoft.Lync.Model.LyncClient.GetAutomation() call in C#. Notice that the PowerShell type specification is enclosed between a pair of brackets ([ ]) and :: is used between the type specification and its static member.

Note

The static member call convention in PowerShell differs from its instance member call convention.

With the resultant Automation object, you can now start an Add a Contact wizard, start a conversation with one or more users. These tasks are initiated or facilitated by calling the LaunchAddContactWizard, BeginStartConversation, EndStartConversation, and GetConversationWindow methods. To discover these and other members of the Automation class, pipe the $auto variable into the Get-Member PowerShell cmdlet. This is illustrated in the following PowerShell example, in which the result of Get-Member is in turn piped into the Format-List cmdlet to present the output as a list.

$auto | Get-Member | Format-List

Launching the Add a Contact Wizard Using the Automation Object

To start an Add a Contact wizard, call the following PowerShell statement:

$auto.LaunchAddContactWizard("adamb@contoso.com")

When successfully executed, this command creates an Add a Contact window. If the specified user is not already in your contact list, they are added to the list and you can then change the privacy relationship in the wizard. If the specified user is already in the contact list, the wizard displays an alert stating the fact. You can also use an empty string as the argument. In this case, the Add a Contact wizard is started waiting for you to provide a contact email address in its input field.

Starting a Conversation Using the Automation Object

Starting a conversation involves a .NET asynchronous call pattern using BeginStartConversation and EndStartConversation. The input parameters to the BeginStartConversation method specify the conversation modality, invited participants, and any contextual information about the conversation. The conversation modality is specified with a Microsoft.Lync.Model.Extensibility.AutomationModalities value. The participants are represented by an enumerable collection of strings. Each element specifies the URI of a participant. The contextual data is represented as a collection of key-value pairs, with the key being of the Microsoft.Lync.Model.Extensibility.AutomationModalitySettings type and the value being of the System.Object type.

The following C# code example starts a conversation.

//Create string array of conversation invitees.
string[] invitees = {“elise@contoso.com”};

// Create a generic Dictionary object to contain conversation setting objects.
Dictionary<AutomationModalitySettings, object> settings = new Dictionary<AutomationModalitySettings, object>();
settings.Add(AutomationModalitySettings.FirstInstantMessage, ″Hello″);
settings.Add(AutomationModalitySettings.SendFirstInstantMessageImmediately, true);

// Start the conversation.
IAsyncResult ar =  LyncClient.GetAutomation().BeginStartConversation(
    AutomationModalities.InstantMessage, 
    invitees, 
    settings,
    null,
    null);

//Block UI thread until conversation is started and Conversation Window is displayed.
LyncClient.GetAutomation().EndStartConversation(ar);

To do the same in PowerShell, I have translated the previous C# code example into the following PowerShell code:

//Create string array of conversation invitees.
$invitees = @( ‘elise@contoso.com’)

// Create a generic Dictionary object to contain conversation setting objects.
$settings = new-object 'System.Collections.Generic.Dictionary[Microsoft.Lync.Model.Extensibility.AutomationModalitySettings, Object]'
$settings.Add([Microsoft.Lync.Model.Extensibility.AutomationModalitySettings]::FirstInstantMessage, "hello")
$settings.Add([Microsoft.Lync.Model.Extensibility.AutomationModalitySettings]::SendFirstInstantMessageImmediately, $true)

$modality = [Microsoft.Lync.Model.Extensibility.AutomationModalities]::InstantMessage 

# Start a conversation
$ar = $auto.BeginStartConversation($modality,`
    $invitees -as [System.Collections.Generic.IEnumerable[String]], `
    $settings -as [System.Collections.Generic.IEnumerable[System.Collections.Generic.KeyValuePair[Microsoft.Lync.Model.Extensibility.AutomationModalitySettings, Object]]], `
    $null, $null) 

//Block UI thread until conversation is started and Conversation Window is displayed.
$window = $auto.EndStartConversation($ar)

There are a few things worthy noting when we compare the C# code example to the corresponding PowerShell code example:

  • A PowerShell array can be constructed using the @(…) construct, whereas a C# array can be created by using {…}.

  • In PowerShell a generic type argument is enclosed in brackets like [T], whereas in C# it is enclosed by angle brackets like <T>.

  • In PowerShell, type casting can be done by using the –as operator whereas in C# the typecasting uses the as operator. Thus, the following PowerShell and C# statements are equivalent:

    $invitees –as [System.Collections.Generic.IEnumerable[string]]
    
    invitees as System.Collections.Generic.IEnumerable<string>
    
  • In PowerShell, an explicit typecasting is necessary to convert an array of strings to the generic type of [System.Collections.Generic.IEnumerable[string]]. In C# this is not necessary.

  • In PowerShell an explicit typecasting is necessary to convert the generic type of [System.Collections.Generic.Dictionary[Microsoft.Lync.Model.Extensibility.AutomationModalitySettings, Object]] to the generic type of [System.Collections.Generic.IEnumerable[System.Collections.Generic.KeyValuePair[Microsoft.Lync.Model.Extensibility.AutomationModalitySettings, Object]]]. In C# this is not necessary.

  • For any generic type that is defined in the Microsoft.Lync.Model.DLL assembly to be recognized in PowerShell, the assembly reference must be added to a PowerShell session by using the Import-Module cmdlet. Otherwise, the generic type is not recognized.

Note

Although the following PowerShell commands appear to have the same effect of adding the assembly reference to a PowerShell session, neither one will make generic types that are defined in the added assembly visible in the PowerShell session.

Unknown List Class

Inviting a User to a Conference Call

While a conversation is ongoing, you can add another contact as a participant to the conversation.

//Continue from Task 4
$conference = $window.Conversation

$contact = [Microsoft.Lync.Model.LyncClient]::GetClient().ContactManager.GetContactByUri("sam@contoso.com")

$conference.AddParticipant($contact);

For this to work, all the prospective participants must be enabled for unified communications and their capabilities to participate in the given conversation mode must be enabled.

The previous code example is an example of the dial-out mode for a participant joining a conference. Alternatively, the participant can join the conference through the dial-in mode using a conference Uri that can be obtained as follows:

//Continue from Task 4
$conference = $window.Conversation

$id = $conference.Properties[[Microsoft.Lync.Model.Conversation.ConversationProperty]::Id]
$uri = $conference.Properties[[Microsoft.Lync.Model.Conversation.ConversationProperty]::ConferencingUri]
$confUri = "conf:" + $uri + "?" + $id

The resultant conference Uri must be provisioned to the prospective participants before they can join the conference. For more information about dialing in to join a conference, see Microsoft Lync 2010 SDK documentation.

Note

A conference Uri is automatically assigned to a conversation when more than two participants have been added to the conference.

Conclusion

In this article, I explained how to script Microsoft Lync 2010 Extensibility API using Windows PowerShell. The discussion and code examples discussed the following tasks.

  • Using the Import-Module cmdlet to add the Lync assembly reference to a PowerShell session.

  • Calling the static LyncClient.GetAutomation method to gain an entry point to the Lync Extensibility API.

  • Calling Automation.StartAddContactWizard instance method to start the Add a Contact wizard.

  • Using the Automation object to start an instant messaging conversation.

  • Adding another participant to escalate the conversation into a conference.

  • Comparing the PowerShell syntax with the C# syntax.

  • Contrasting the syntaxes for static and instance member calls in PowerShell.

I hope that you find the examples and discussions provided here helpful to get you started in using PowerShell to script the Lync 2010 Extensibility API.

Additional Resources

For more information, see the following resources:

About the Author

Kurt De Ding is a Senior Programming Writer, Microsoft Office Content Publishing (UA) group.