Export (0) Print
Expand All
Expand Minimize

PowerShell Scripting Communicator Automation API Using Primary Interop Assembly

Summary:   In this article you will learn how to automate Microsoft Lync 2010 using PowerShell scripting against the primary interoperable assembly of the native Microsoft Office Communicator 2007 Automation API type library.

In PowerShell Scripting Communicator Automation API Using Native Type Library, I explained how you can automate Microsoft Lync 2010 with Microsoft PowerShell scripting against the native type library. Because the native type library is built into Lync, you do not need to install Microsoft Office Communicator 2007 SDK for this to work. As long as Lync is running, you are good to go.

However, working with COM object directly in a script has many limitations. You need to find a way work around calling an enumeration member name exposed in the type library. It is also difficult, if not impossible, to catch and handle events defined in the type library. Thanks to COM-interoperability with .NET Framework, a native COM library can be converted into a primary interoperable assembly (PIA) where the native COM types are wrapped by .NET types. With PIA, you work with .NET types including enumerations and event handling. In addition, PowerShell scripting can even be applied to the types or members in the .NET Framework assembly that are deemed non-scriptable in the native type library.

In this article I explain how to use PowerShell scripting against the PIA of the Communicator 2007 Automation API to call the .NET wrappers of the native COM types. The primary interoperable assembly of Communicator 2007 Automation API is distributed as part of Office Communicator 2007 SDK.

To automate Lync 2010 using the Office Communicator 2007 Automation API primary interoperable assembly in PowerShell, you must have Microsoft Office Communicator 2007 SDK installed. For information about installing the SDK, see Additional Resources. The primary interoperable assembly is CommunicatorAPI.DLL. By default, this is installed in the %ProgramFiles%\Microsoft Office Communicator\SDK directory.

In addition, you must have Lync 2010 and Windows PowerShell installed. To run Lync, you must also be a member of a network serviced by Microsoft Lync Server 2010. On Microsoft Windows 7, PowerShell is preinstalled.

Before invoking any Microsoft Office Communicator 2007 Automation API features to automate Lync 2010, you must first create a Lync proxy that takes your commands on behalf of a locally running Lync instance. In Office Communicator 2007 Automation API, this proxy is an instance of the Messenger co-class. To obtain this object and to have other API types accessible in a PowerShell script against the primary interoperable assembly, you must import the PIA module into your PowerShell session. Importing an assembly into a PowerShell session amounts to adding a reference to the assembly into a C# application project.

To import the PIA of Communicator 2007 Automation API, use the Import-Module cmdlet of PowerShell, assuming that the PIA is in the default installation directory of %ProgramFiles%\Microsoft Office Communicator\SDK.

Import-module “c:\Program Files (x86)\Microsoft Office Communicator\SDK\CommunicatorAPI.DLL”

Now, you can obtain a Lync proxy as an entry point to using Communicator 2007 Automation API. To do this, use PowerShell’s New-Object cmdlet:

$communicator = new-object 'CommunicatorAPI.MessengerClass'

The string value (“CommunicatorAPI.MessengerClass”) of the argument to the New-Object cmdlet specifies the MessengerClass type in the CommunicatorAPI namespace as shown in the API’s primary interoperable assembly. MessengerClass corresponds to the Messenger coclass that makes available by default the IMessenger, IMessenger2, IMessenger3, and IMessengerAdvanced interfaces. These and other interfaces are documented in Office Communicator 2007 Automation API documentation. For more information about Office Communicator 2007 Automation API documentation, see Additional Resources.

You can examine the exposed members of these interfaces by using the following PowerShell command:

$communicator | Get-Member

For comparison with the members available on the native COM object (listed in PowerShell Scripting Communicator Automation API Using Native Type Library), a few entries of the output from the previous command appear next:

   TypeName: CommunicatorAPI.MessengerClass

Name                               MemberType            Definition                  
----                               ----------            ----------                     
……
OnIMWindowContactAdded             Event                 CommunicatorAPI.DMessengerEv...
……
AddContact                         Method                System.Void AddContact(int h...
add_OnAppShutdown                  Method                System.Void add_OnAppShutdow...
……
add_OnIMWindowContactAdded         Method                System.Void add_OnIMWindowCo...
……
AutoSignin                         Method                void AutoSignin ()                               
CreateGroup                        Method                System.Object CreateGroup(st...
FindContact                        Method                System.Void FindContact (int, string, string, Variant, ...
……
remove_OnIMWindowContactAdded      Method                System.Void remove_OnIMWindo...

The .NET wrapper class of the native Messenger coclass exposes more members. The additional members count for events and the methods are used to add and remove event handlers. This points to the advantage of using the primary interoperable assembly over its native counterpart. COM events are converted into .NET events and become visible and can be easily manipulated in scripting. In the next section, I explain how to register and handle events in PowerShell scripts using the PIA of Communicator 2007 Automation API.

Once the MessengerClass object ($communicator) is properly instantiated, you can proceed to invoke any scriptable Communicator 2007 Automation API features to perform appropriate Lync automation tasks. As with scripting the native type library, you can call instance properties or methods, following the syntax prescribed in the Office Communicator 2007 API documentation. The following PowerShell script example was presented in PowerShell Scripting Communicator Automation API Using Native Type Library and is reproduced for your convenience.


$c = $communicator.GetContact("adamb@contoso.com", $communicator.MyServiceId)
$status = $c.Status

Furthermore, member invocations are no longer restricted to the members that are declared as scriptable in the Office Communicator 2007 Automation API documentation. Thus, no exceptions will be thrown when the following PowerShell statements are called against the primary interoperable assembly of the Communicator 2007 Automation API.


$communicator.MyStatus =[CommunicatorAPI.MISTATUS]::MISTATUS_ONLINE
$communicator.FindContact($null, “Adam”, “Barr”)

As mentioned earlier, one benefit of using the PIA, instead of the native type library, is that event handling in PowerShell becomes much more manageable. In this section I present an example to demonstrate how you can handle a scriptable event.

In Microsoft Office Communicator 2007 Automation API Type Library, all events are defined as members of the DMessengerEvents interface supporting the OLE Automation. The instance of the Messenger coclass, obtained earlier, provides the sole source for all these events. For example, when you launch a conversation window and add a participant to the conversation, a OnIMWindowContactAdded event that is defined as a method on the DMessengerEvents interface, is raised by the $communicator object. To register and handle this event in a PowerShell script, use the Register-ObjectEvent cmdlet of PowerShell 2.0 and supply a script block, to serve as the event handler, after the –action parameter.

The following PowerShell script example shows how the OnIMWindowContactAdded event is registered and how it may be handled in the action script block.

Register-ObjectEvent $communicator -EventName "OnIMWindowContactAdded" -SourceIdentifier "DMessengerEvents.OnIMWindowContactAdded" `
    -action { 
        Write-Host "OnIMWindowContactAdded received on " $Event.TimeGenerated; 
        
        foreach($i; $i -lt $event.SourceArgs.Length; $i++)
        {
            if ($i -eq 0)
            {
                $addedContact = $event.SourceArgs[$i]
                Write-Host "Contact, " $addedContact.FriendlyName ", added "
            }
            elseif ($i = 1)
            {
                $imwindow = $event.SourceArgs[$i]
                write-host "IM window created"
                if ($imwindow.IsClosed)
                {
                    $imwindow.Show()
                }
            }
          
        }

In the previous example, the Register-ObjectEvent cmdlet has one argument and three parameters:

  • The argument that follows the Register-ObjectEvent ($communicator) immediately specifies the event source. The –EventName parameter specifies the name of an interested event. In Communicator 2007 Automation API this must be one of the names of the methods on the DMessengerEvents interface.

  • The –SourceIdentifier parameter defines a session-unique event ID. This value is used to cancel the registration of the specified event.

  • The –action parameter declares a script block that enclosed by a pair of braces ({ }). This block is invoked when the OnIMWindowContactAdded event is raised. When the script block is invoked, the following so-called automatic variables are available.

    NoteNote

    For more information, see About_Automatic_Variables.

    • $Event: This represents the event with all the information, including the event arguments (SourceArgs or SourceEventArgs) and the time when the event as generated (TimeGenerated). For Communicator 2007 Automation API, the SourceArgs parameter of the $event variable contains the parameters of the specified DMessengerEvents member method. The order of the event arguments follows the order of the method parameters. The SourceEventArgs property of the $event variable is not defined.

    • $Sender: This contains the object that generated this event, namely the event source. In this example, this corresponds to the instance of $communicator. The type casting operation shown in the previous example returns the $communicator instance.

    • $SourceArgs: This contains the event arguments of the event that is being processed. In this example, the variable is null.

    • $SourceEventArgs: This contains the first event argument that derives from EventArgs of the event that is being processed. With Communicator 2007 Automation API, this variable is not assigned.

To cancel the event registration, use the Unregister-Event cmdlet, specifying the SourceIdentifier parameter with the value assigned in the Register-ObjectEvent cmdlet.

Unregister-Event "DMessengerEvents.OnIMWindowContactAdded"

Another advantage of using the PIA of the native Communicator 2007 Automation API Type Library is that the enumeration types are now visible for scripting. For example, the following PowerShell statement displays the local status with a member name of the MISTATUS type.

write-host $communicator.MyStatus

When the local user is online, the output from the previous statement is “MISTATUS_ONLINE”.

To examine the presence status of a remote user, however, you may find that the Status property on the remote contact object returns a numeric value. For example, the following PowerShell example tries to display the status of a remote user.

$c = $communicator.GetContact("adamb@contoso.com", $communicator.MyServiceId)
Write-Host $c.Status

When adamb@contoso.com is online, the output of the previous example is 2.

To display this status using a member name of the MISTATUS enumeration type, you can cast the $c.Status property into the MISTATUS type:

write-host ($c.Status -as [CommunicatorAPI.MISTATUS])

This time, the output is “MISTATUS_ONLINE” when the remote user is online. Be sure to use parentheses (“( )”) to group the typecasting operation. Otherwise, PowerShell will fail to understand your statement. Notice also the use of brackets (“[ ]”) to express a type in PowerShell.

In this article, I explained some benefits of using the primary interoperable assembly of the native Communicator 2007 Automation API Type Library in Windows PowerShell:

  • Support of event handling.

  • Explicit manipulation of enumeration types.

  • Relaxation of any non-scriptable restrictions in member invocation.

Furthermore, I presented a few PowerShell code examples to illustrate the following tasks:

  • How to use the Import-Module cmdlet to add reference of the PIA into a PowerShell session.

  • How to instantiate the .NET wrapper class (CommunicatorAPI.MessengerClass) to obtain a Lync proxy.

  • How to call the Register-ObjectEvent cmdlet to register and catch an event defined as a member of the DMessengerEvents interface.

  • How to cancel the event registration using the Unregister-Event cmdlet.

  • How to use enumeration types.

  • How to do typecasting in PowerShell.

In addition, I compared and contrasted the use of the PIA with its native assembly of the Office Communicator 2007 Automation API and provided a few tips in typecasting and use of automatic variables in PowerShell.

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

Show:
© 2015 Microsoft