Zachary Loeber

The personal website of Zachary Loeber.

Lync Client: Automatic Fortune Cookie Utility

2015-02-08 6 min read Lync Microsoft Powershell Zachary Loeber

Here’s a just for fun powershell script for the Lync user. In the not so old days of Unix administration it was not too uncommon to have a ‘fortune cookie’ display when logging into a system. I’ve always thought that it would be neat to have something similar in the Lync client that would allow for an easy rotation of your personal note field. Little did I realize how easy it would be to add such functionality myself with some powershell and the Lync SDK!

Introduction

I’ll preface this write up by letting the world in on a dirty little secret of mine. I’m really not the best end user. I rarely use the Lync client to the levels many power users do on a daily basis. I can setup or fix entire infrastructures but the actual Lync client itself I use for 3-4 tasks regularly and that is about it. So unsurprisingly I rarely update my ‘personal note’ with clever and cool quotes and sayings like all my coworkers tend to do.

image

Totally boring default Lync personal note.

This will not be the case moving forward though because all that time saved not coming up with witty Lync personal notes I recently spent on automating the task instead.

Updated personal note with far more personality!

This semi-random quote came from the heart.

So the task at hand is:

  1. Get random clever quotes and sayings from somewhere.
  2. Update the personal note in the Lync client after a user has logged into their workstation and started Lync.
  3. Schedule steps 1 and 2 to occur on a semi-regular basis.

This ended up being only slightly more involved than I initially imagined. With the Lync SDK installed you can grab running instances of the client, check the login status, update personal contact information, and a slew of other tasks much in the same way you can instantiate instances of Outlook or Word. Here is a function I put together which grabs any number of your personal contact information properties using the SDK and a little bit of clever enumeration.

function Get-LyncPersonalContactInfo {
    <#
    .EXAMPLE
    Get-LyncPersonalContactInfo 'PersonalNote'
    .EXAMPLE
    Get-LyncPersonalContactInfo
    #>
    param(
        [string[]]$TypeNames
    )

    if (-not (Get-Module -Name Microsoft.Lync.Model)) {
        $LyncSDKLoaded = $false
        try { # Try loading the 32 bit version first
            Import-Module -Name (Join-Path -Path ${env:ProgramFiles(x86)} -ChildPath "Microsoft Office\Office15\LyncSDK\Assemblies\Desktop\Microsoft.Lync.Model.dll") -ErrorAction Stop
        }
        catch {}
        try { # Otherwise try the 64 bit version
            Import-Module -Name (Join-Path -Path ${env:ProgramFiles} -ChildPath "Microsoft Office\Office15\LyncSDK\Assemblies\Desktop\Microsoft.Lync.Model.dll") -ErrorAction Stop
        }
        catch {
            #New-Popup -Buttons 'OK' -Message 'Lync 2013 SDK unavailable. Please download and install from http://www.microsoft.com/en-us/download/details.aspx?id=36824' -Title 'Whoops!'
            Write-Warning "Microsoft.Lync.Model not available, download and install the Lync 2013 SDK http://www.microsoft.com/en-us/download/details.aspx?id=36824"
            throw
        }
    }
    $validtypes = @()
    [System.Enum]::GetNames('Microsoft.Lync.Model.ContactInformationType') | Foreach {$validtypes += $_}
    if ($TypeNames.Count -eq 0) {$TypeNames += $validtypes}
    if ((Compare-Object -ReferenceObject $validtypes -DifferenceObject $TypeNames).SideIndicator -contains '=>') {
        Write-Error 'Invalid contact information type requested!'
        throw
    }
    else {
        $client = [Microsoft.Lync.Model.LyncClient]::GetClient()
        if ($client.State -eq "SignedIn") {
            $contact = $client.Self.Contact
            $retvals = @{}
            foreach ($typename in $TypeNames) {
                try {
                    $contact.GetContactInformation([Microsoft.Lync.Model.ContactInformationType]::$typename) | Out-Null
                    if ($TypeNames.Count -gt 1) {
                        $retvals.$typename = $contact.GetContactInformation([Microsoft.Lync.Model.ContactInformationType]::$typename)
                    }
                    else {
                        return $contact.GetContactInformation([Microsoft.Lync.Model.ContactInformationType]::$typename)
                    }
                }
                catch {}
            }
            New-Object psobject -Property $retvals
        }
        else {
            Write-Warning "Lync is not running or signed in, no action was performed"
        }
    }
}

Assuming that your SDK files are in default locations you can get the current personal note you can use the above function like so:

Get-LyncPersonalContactInfo 'PersonalNote'

I’ve also used a customized version of the reverse function found here for publishing the lync contact information. I then wrapped everything up with a few functions I created; get-iQuote, Load-LyncSDK, New-ScheduledPowershellTask. I also included a small sampling of example quotes to use if you wanted to not use iQuote for the quote source.

Requirements/Notes

  • The Lync SDK is an obvious requirement. You can save yourself the hassle of installing all the visual studio bits (which forces you to install the silverlight SDK as well) of the SDK by following the directions found here. Here are the relevant notes on how that is done:
  • Download the Lync SDK
  • In order to avoid having to install visual studio, extract the lyncsdk86.msi from thesdkexe file usingwinrar or other software
    • The SDK need to match the bitness of your Lync client
  • The script will check both for 32 and 64 bit versions of the sdk in the relevant default locations. I’ve not set any parameter to pass a different location but I did pull out the loading and checking of the dll for the sdk into the Load-SDK function. If you make some modifications around every call of that function you can change the location on your own.
  • You will also need to be logged into the Lync client when the script is run. I set some default values for retry and delay of validating the process is running and the user is logged in.
  • You can run the script stand alone but you may as well just be copying and pasting random quotes into Lync. The best use of this script is if you automate it to run on a semi-regular basis. The default scheduled time is once a week at 9am if you run with the ‘CreateScheduledTask’ switch.

Example Usage

As already mentioned, you can simply run the script and it will automatically use the online iQuote database (all categories) and prompt the Lync user if they want to replace their personal note or not. But I’ve also included a few more interesting methods within the script that may be more to your liking.

<#
.EXAMPLE
.\LyncClientFortuneCookie.ps1 -Silent -CreateScheduledTask

Description
-----------
Run the script to create a scheduled task that runs itself without user input (by default at 9am every monday)

.EXAMPLE
.\LyncClientFortuneCookie.ps1 -CreateScheduledTask -QuoteCategories 'fortune','codehappy'

Description
-----------
Run the script to create a scheduled task that runs itself without user input (by default at 9am every monday). 
When the task runs the iQuote site is queried for a random quote from either fortune or codehappy categories.
The a pop-up is used to prompt the end user if they want to change their Lync note to the quote or not.

.EXAMPLE
.\LyncClientFortuneCookie.ps1 -CreateScheduledTask -QuoteSource 'File' -QuoteFile 'example-quotes.txt'

Description
-----------
Run the script to create a scheduled task that runs itself. When the scheduled task triggers and the lync client is logged into a the example-quotes.txt file
will be polled for a random quote and the current user will be prompted if they want to replace their current status note in Lync or not.

.EXAMPLE
.\LyncClientFortuneCookie.ps1 -CreateScheduledTask -QuoteSource 'File' -QuoteFile 'example-quotes.txt' -Silent

Description
-----------
Same as the prior example except it is assumed that all the quotes in example-quotes.txt are acceptable and the random quote is simply assigned in Lync silently.
#>

By default (without the Silent option you get a pop-up similar to this:

Hopefully the most difficult decision you have had all day.

Hopefully the most difficult decision you have had all day.

If you do choose to use a file as the source you simply put each quote on its own line for the time being. This input method is well suited for manually paring down your quotes to ensure you get business appropriate or personalized notes. Using an input file and the silent option so as to never get a pop-up will likely be how I personally use this little script.

Possible Improvements

– Maybe a little quote management GUI for the input file

– A deployment batch script or installer?

Download

The script and example quote file can be downloaded from the Microsoft Technet Gallery (please rate it if you like it!) or from my Github repository. I hope the community enjoys this goofy little experiment of mine as much as I enjoyed creating it.

This is not how I actually look.

This is not how I actually look.

comments powered by Disqus