• Show me as Inactive when my computer has been idle for this many minutes

     

     

    Registry locations

    HKCU\Software\Microsoft\Communicator\IdleThreshold

    Allowed registry values

    Any integer value between 5 and 360, inclusive (represents time, in minutes)

    Registry value type

    REG_DWORD

    Default setting

    5 minutes

     

    Broadcasting presence information to people is of little use if that information isn’t up-to-date; after all, what’s the point of announcing to people that you're available when it turns out that you really aren’t available? One way Microsoft Lync tries to help you keep your presence information up-to-date is by monitoring idle time on your computer: by default, if your computer has sat idle for 5 minutes (that is, if no one has typed anything on the keyboard or used the mouse in the past 5 minutes) then Lync automatically sets your current status to Inactive.

     

    Note. Yes, for some of us Inactive probably is our permanent status. But that’s a different story.

     

    If you don’t like the default period of 5 minutes of inactivity, well, that’s easy enough to change; in fact, that can either be done by using the Lync user interface or by writing a script. If you want to change this value using Lync, just open Status option of the Options dialog box and change the value of the Show me as Inactive when my computer has been idle for this many minutes box:

     

     

    As for writing a script, that’s just as easy: all you have to do is modify the HKCU\SOFTWARE\Microsoft\Communicator\IdleThreshold registry value. Set IdleThreshold to any value between 5 and 360 and, in return, Lync will wait that number of minutes before marking you as Inactive.

     

    We told you it was easy.

     

     

     

    Before we show you how to change the idle timeout let's show you how to retrieve the current value of IdleThreshold from the local computer. If you'd prefer to retrieve this value from a remote computer, just set the value of the variable $computer to the name of that remote computer. For example:

     

    $computer = "atl-ws-001.litwareinc.com"

     

    Here’s how you get the IdleThreshold value:

     

    $computer = "."

     

    $registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("CurrentUser", $computer)

    $key = $registry.OpenSubKey("SOFTWARE\Microsoft\Communicator", $True)

     

    Write-Host "Show me as Inactive when my computer has been idle for this" `

        " many minutes:",($key.GetValue("IdleThreshold",$null))

     

    And here's how you change that value. In this case, the script sets the idle timeout period to 10 minutes; that's done by setting IdleThreshold to 10. What if you want to set the timeout period to 30 minutes? That's fine; just set IdleThreshold to 30:

     

    $key.SetValue("IdleThreshold",30,"DWORD")

     

    Here's the script:

     

    $computer = "."

     

    $registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("CurrentUser", $computer)

    $key = $registry.OpenSubKey("SOFTWARE\Microsoft\Communicator", $True)

     

    $key.SetValue("IdleThreshold",10,"DWORD")

     

     

     

  • How Do We Love Performance Counters? Let Us Count the Ways

     

     

    If you happen to be up on your poetry (as those of us here at the Lync Server PowerShell blog, the home of the daily Lync Server PowerShell haiku, obviously are) then you are no doubt familiar with the poem How Do I Love Thee? by Elizabeth Barrett Browning. And even if you aren't up on your poetry (for shame!) then you're probably still familiar with the poem's opening lines:

     

    How do I love thee? Let me count the ways.

    I love thee to the depth and breadth and height

    My soul can reach, when feeling out of sight

    For the ends of Being and ideal Grace.

     

    After that opening stanza, Browning goes on to list all the ways that she loves thee, which seems to be about 8 different ways. (To tell you the truth, we kind of lost count as we were reading.) At any rate, How Do I Love Thee? is considered by many people to be the most romantic poem ever written. a judgment that we really can't argue with, even though we do expect that, over time, our very own haiku #2 will eventually be considered the most romantic poem ever written:

     

    The elephant missed

    His plane. He forgot his trunk

    Configuration.

     

    But, admittedly, it might be a while before that happens.

     

    English professors will tell you that Elizabeth Barrett Browning was one of the greatest poets of all time. But here's something that those academic eggheads won't tell you: Elizabeth Barrett Browning would have been a terrible Microsoft Lync Server 2010 administrator. How can we say that? Well, for one thing, Elizabeth Barrett Browning was born in 1801 and people born during that era have never really made much of a splash as Lync Server administrators.

     

    Note. She also suffered from nervous hysteria and was addicted to morphine, things which are rarely mentioned in ads for Lync Server administrators:

     

    WANTED: Experienced Lync Server administrator. Applicants must suffer from nervous hysteria and be addicted to morphine. Non-smokers only.

     

    Perhaps more important, however, is the fact that Elizabeth Barrett Browning was hopelessly inefficient. Consider How Do I Love Thee? In that poem, Browning laboriously lists each and every way that she loves her soon-to-be-husband Robert Browning. That approach might have worked back in the 1800s; after all, without TV, Twitter, or Facebook people didn't really have anything to do anyway. But in today's hectic, high-paced world no one has the time to tediously count up all the ways that they love someone. Do you have any idea how many Facebook pokes you might miss while counting up all the ways that you love someone? Exactly.

     

    And that's why Elizabeth Barrett Browning would make such a lousy Lync Server administrator. For example, suppose Elizabeth Barrett Browning needed to know how many incoming SIP messages had been received on a Front End server. No doubt she would sit there and count those messages one-by-one: "Here's one from Ken Myer. And here's one from Pilar Ackerman. Oh, and here's another one from Ken Myer." Is that the way a good Lync Server administrator would do this? Hardly. Instead, a good Lync Server administrator would do this:

     

    Get-Counter -Counter "\LS:SIP - 02 - Protocol\SIP - 000 - Incoming Messages" | Select-Object –ExpandProperty CounterSamples | Select-Object CookedValue

     

    And if you’re thinking "That's cool, but what exactly is that?" well, have no fear: that (using Windows PowerShell to work with Lync Server performance counters) just happens to be the topic of this article.

     

    Note. Hey, you had to figure we'd get to the topic sooner or later, right?

     

     

    Lync Server Performance Counters

     

    We're assuming that everyone out there is already familiar with performance counters but, just in case, here's a quick overview. Performance counters are values that can be used to analyze the usage and/or the health of an application (or of the operating system, for that matter). For example, Lync Server 2010 ships with hundreds of performance counters: there are performance counters for the Response Group application, performance counters for the Call Park Service, performance counters for CAA, CAS, PDP, QMS, and pretty much any Lync Server acronym you can think of. And the best part is that you don't need to do anything to implement these counters: performance counters are installed when you install Lync Server, and, once they are installed, Lync Server takes care of continually updating those counters. The only thing you have to do is occasionally check the values of your performance counters. And if you don’t know how to do that, well, just keep reading.

     

    Wait: one quick caveat before you keep reading. Keep in mind that this is not a detailed description on the performance counters that ship with Lync Server 2010, nor does it offer any insights on which Lync Server performance counters you might find the most useful. After all, we're PowerShell guys, which means that all we can do is show you how to use Windows PowerShell to access performance counters. (And that means any performance counter, not just Lync Server performance counters.) Explaining what each performance counter does, and explaining why you might be interested in using a given performance counter, lies a bit outside our area of expertise.

     

    Note. So what lies inside the area of our expertise? Well, um, there's, uh – say, could we hold all questions until the end, please? Thank you.

     

    Speaking of questions, let's start with an obvious one: what performance counters are available for Lync Server, and how can we get a list of those counters? To begin with, we should point out that individual performance counters are collected in performance counter sets. For example, Lync Server includes a set of performance counters named this:

     

    ·         LS:RGS - 00 - Response Group Service Hosting

     

    Inside that set, you'll find the following individual performance counters:

     

    ·         RGS - 000 - Total number of incoming calls that were declined because of a Match Making failure

    ·         RGS - 001 - Total number of different workflows loaded in memory

    ·         RGS - 002 - Total number of different application endpoints

    ·         RGS - 003 - Total number of failures when binding to the Collaboration Platform

    ·         RGS - 004 - Total number of failures when binding Match Making to WCF

    ·         RGS - 005 - Total number of application endpoint binding failures

    ·         RGS - 006 - Total number of certificate validation failures

    ·         RGS - 007 - Total number of successful certificate validations

    ·         RGS - 008 - Total number of application endpoint terminations

    ·         RGS - 009 - Duration of the call in milliseconds

     

    Is that important? As a matter of fact, it's very important: when we refer to an individual performance counter we'll have to specify a path that includes both the name of the counter set and the name of the performance counter. For example, here's a path that shows the counter set name in red and the counter name in blue:

     

    ·         \LS:RGS - 00 - Response Group Service Hosting\RGS - 001 - Total number of different workflows loaded in memory

     

    That's what we thought, too: pretty as a picture.

     

    OK, let's now see if we can get a list of all the performance counter sets for Lync Server 2010. (Note that we're going to start off by doing everything locally; that is, on a computer currently running one or more Lync Server services or server roles. We'll talk about performing these same tasks on remote computers later on.) Are we concerned that we won't be able to retrieve this information? On the contrary; we're extremely confident that we will be able to retrieve this information, and for two reasons:

     

    ·         Windows PowerShell 2.0 includes the Get-Counter cmdlet, which makes it easy to retrieve performance counter information.

    ·         Lync Server's performance counter sets all use a standard naming convention: each set name begins with the characters LS:.

     

    Why does that make us co confident? That's easy: that means that we can use a command like this one to return a list of all of Lync Server's performance counter sets:

     

    Get-Counter -ListSet "LS:*"

     

    As you can see, that's not a very complicated command, to say the least. All we do is call the Get-Counter cmdlet followed by the ListSet parameter (as the name implies, this asks Get-Counter to return a list of performance counter sets). The parameter value passed to ListSet is nothing more than a good old-fashioned wildcard value: "LS:*" which, as you already know, simply says "Show me all the counter sets that begin with the string value LS:." And remember, this same approach works with all performance counters and performance counter sets, not just with Lync Server-related counter sets. Are there any performance counter sets that work with disk drives? Well, try running this command and see for yourself:

     

    Get-Counter -ListSet "*Disk*"

     

    Note. And, of course, you can run the following command to return information about all your performance counter sets:

     

    Get-Counter -ListSet "*"

     

    So will we get back any information when we run the command Get-Counter -ListSet "LS:*"? You might say that. On our test computer (a Front End Server) we got back information for 142 different performance counter sets, with each set returning data similar to this:

     

    CounterSetName     : LS:SipEps - 02 - SipEps Connections

    MachineName        : .

    CounterSetType     : MultiInstance

    Description        : This object includes counters that apply to Lync Server

                         IPEPS stack

    Paths              : {\LS:SipEps - 02 - SipEps Connections(*)\SipEps - 000 –

                         Bytes Received, \LS:SipEps - 02 - SipEps

                         Connections(*)\SipEps - 001 - Bytes

                         Received/sec, \LS:SipEps - 02 - SipEps      

                         Connections(*)\SipEps - 002 - Bytes Sent, \LS:SipEps –

                         02 - SipEps Connections(*)\SipEps - 003 - Bytes Sent/sec...}

    PathsWithInstances : {\LS:SipEps - 02 - SipEps Connections(_Total)\SipEps –

                         000 - Bytes Received, \LS:SipEps - 02 - SipEps

                         Connections(server.3528_mediationserversvc_appdom_1)\

                         SipEps - 000 - Bytes Received, \LS:SipEps - 02 - SipEps

                         Connections(server.3240

                         _ocsappserverhost_appdom_2)\SipEps - 000 - Bytes

                         Received, \LS:SipEps - 02 - SipEps

                         Connections(server.3200_ocsappserverhost_appdom_2)\

                         SipEps - 000 - Bytes Received...}

    Counter            : {\LS:SipEps - 02 - SipEps Connections(*)\SipEps - 000 –

                         Bytes Received, \LS:SipEps - 02 - SipEps

                         Connections(*)\SipEps - 001 - Bytes Received/sec,

                         \LS:SipEps - 02 - SipEps Connections(*)\SipEps - 002 –

                         Bytes Sent, \LS:SipEps - 02 – SipEps

                         Connections(*)\SipEps - 003 - Bytes Sent/sec...}

     

    And yes, come to think of it, that is a lot of information, isn't it? In fact, that's probably too much information when all you really want to do is get an overview of the type of Lync Server performance counters available to you. Because of that, you might want to run this command instead, a command that returns only the name and description for each counter set:

     

    Get-Counter -ListSet "LS:*" | Select-Object CounterSetName, Description | Format-List

     

    That command returns information that might be a little easier to digest:

     

    CounterSetName : LS:USrv - 30 - Pool Conference Statistics

    Description    : This object reports general pool-wide conferencing statistics.

     

    CounterSetName : LS:USrv - 31 - Authorize delegate sproc

    Description    : This object includes counters that apply to the AuthorizeDelegate stored procedure used by Lync Server User Services Module.

     

    CounterSetName : LS:USrv - 32 - Unmanaged Certificate Auth Provider

    Description    : This object includes counters that apply to the unmanaged certificate auth provider.

     

    Still with us? Excellent. Our next step is to zoom in on a performance counter set of interest; in other words, we now need to retrieve a list of the individual performance counters in a counter set. As you saw a moment ago, one of the properties of a counter set is the Counter property; this property lists all the performance counters within the counter set. However, we typically don't get to see all those counters; instead, we see a truncated list of the first few counters, with the remaining items hidden somewhere in the aether:

     

    {\LS:SipEps - 02 - SipEps Connections(*)\SipEps - 000 – Bytes Received, \LS:SipEps - 02 - SipEps Connections(*)\SipEps - 001 - Bytes Received/sec,

    \LS:SipEps - 02 - SipEps Connections(*)\SipEps - 002 – Bytes Sent, \LS:SipEps - 02 – SipEps Connections(*)\SipEps - 003 - Bytes Sent/sec...}

     

    Note. If you're new to Windows PowerShell, the three dots at the end of the list means that there are more items in the property; they just won't all fit on screen.

     

    Needless to say, a truncated list isn't much better than no list at all. How can we retrieve a complete list of the performance counters that make up a counter set? Why, like this, of course:

     

    Get-Counter -ListSet "LS:RGS - 00 - Response Group Service Hosting" | Select-Object –ExpandProperty Counter

     

    So what have we done here? Well, as you can see, we started off by using Get-Counter to return one specific counter set: LS:RGS - 00 - Response Group Service Hosting. However, instead of displaying that information as-is, we piped all the data to the Select-Object cmdlet and asked Select-Object (via the ExpandProperty parameter) to show us all the items stashed in the Counter property. The net result? The net result is a list of all the performance counters found in that counter set:

     

    \LS:RGS - 00 - Response Group Service Hosting\RGS - 000 - Total number of incoming calls that were declined because of a Match Making failure

    \LS:RGS - 00 - Response Group Service Hosting\RGS - 001 - Total number of different workflows loaded in memory

    \LS:RGS - 00 - Response Group Service Hosting\RGS - 002 - Total number of different application endpoints

    \LS:RGS - 00 - Response Group Service Hosting\RGS - 003 - Total number of failures when binding to the Collaboration Platform

    \LS:RGS - 00 - Response Group Service Hosting\RGS - 004 - Total number of failures when binding Match Making to WCF

    \LS:RGS - 00 - Response Group Service Hosting\RGS - 005 - Total number of application endpoint binding failures

    \LS:RGS - 00 - Response Group Service Hosting\RGS - 006 - Total number of certificate validation failures

    \LS:RGS - 00 - Response Group Service Hosting\RGS - 007 - Total number of successful certificate validations

    \LS:RGS - 00 - Response Group Service Hosting\RGS - 008 - Total number of application endpoint terminations

    \LS:RGS - 00 - Response Group Service Hosting\RGS - 009 - Duration of the call in milliseconds

     

    Now we're getting somewhere. Or as Elizabeth Barrett Browning would say … well, we don't actually know what Elizabeth Barrett Browning would say. But it would probably be something a bit more poetical than "Now we're getting somewhere." Something along the lines of:

     

    Nowforth draws near

    As something hastens in its approach.

     

     

    Isn't It About Time We Actually Did Something With Performance Counters?

     

    That's a good point: what fun are performance counters unless you actually get to use them to monitor performance? With that in mind, let's see if we can figure out how to use a performance counter. Let's start with the simplest possible task: retrieving a single value for a single performance counter. That's something we can do with a command similar to this one:

     

    Get-Counter -Counter "\LS:SIP - 02 - Protocol\SIP - 000 - Incoming Messages"

     

    Again, there's nothing too-terribly complicated about this command. As usual, we're using the Get-Counter cmdlet; however, this time we don't use the ListSet parameter. (Why not? Because we don't want a counter set, we want a specific counter.) Instead, we use the Counter parameter followed by the path to the performance counter we want to retrieve information from (remember, the path is a combination of the counter set name and the counter name).

     

    Note. Where did we get that performance counter name from? You got it: by using the ListSet parameter to retrieve all the counters found in a given counter set. In this case, that's the counter set LS:SIP - 02 – Protocol.

     

    That's all we have to do. In return, Windows PowerShell will show us information similar to this:

     

    Timestamp                 CounterSamples

    ---------                 --------------

    5/5/2011 3:10:47 PM       \\server\ls:sip - 02 - protocol\sip - 000 –

                              incoming messages :

                              395020

     

    OK, not bad. A little cluttered, but not bad. As you can see, the returned value (395020) is sitting by itself on the final line of the output.

     

    But that's a good point: why should we settle for "a little cluttered?" After all, the only thing we're really interested in is the current value of the counter:

     

    395020

     

    Shouldn't there be a way to get just the value of the performance counter, without the timestamp and the counter path and all that other gobbledygook?

     

    Well, not only should there be a way, there is a way:

     

    Get-Counter -Counter "\LS:SIP - 02 - Protocol\SIP - 000 - Incoming Messages" | Select-Object –ExpandProperty CounterSamples | Select-Object CookedValue

     

    Admittedly, this is a tiny bit more complicated than our original command but, as you're about to see, you don't need to be a rocket scientist to figure out how it works.

     

    Note. Which is just as well, seeing as how rocket scientists typically don't spend a whole lot of time using Windows PowerShell to return performance counter data for Lync Server.

     

    What we did in the preceding command was grab the data for the SIP - 000 - Incoming Messages performance counter and then pipe that data to the Select-Object cmdlet. We used Select-Object to "expand" the value of the CounterSamples property, then used Select-Object a second time to limit the displayed data to the CookedValue property. What will that look like when all is said and done? When all is said and done, that will look something like this:

     

    CookedValue

    -----------

    395026

     

    Much less cluttered. And if you'd like to see the counter name as well as the value (which you probably will want to do when you start retrieving values from more than one performance counter), just run this command instead:

     

    Get-Counter -Counter "\LS:SIP - 02 - Protocol\SIP - 000 - Incoming Messages" | Select-Object –ExpandProperty CounterSamples | Select-Object Path, CookedValue | Format-List

     

    That gives us output similar to this:

     

    Path        : \\server\ls:sip - 02 - protocol\sip - 000 - incoming messages

    CookedValue : 395054

     

    Which, again, is a little cleaner and a little easier to read than the output we got the first time around.

     

    A Brief Aside: What Are Cooked Values?

     

    We had a feeling someone would ask that: what exactly is a "cooked value?" Well, performance counters typically have raw values, second values, and cooked values. The raw values and second values are the raw ingredients used by the performance counter, and the "cooked value" is the result of "cooking" those ingredients into something for human consumption.

     

    What does that mean? Beat us. Tell you what: instead of trying to create some weird cooking-related metaphor, let's just show you a simple example using disk drives. Suppose you use the LogicalDisk(*)\% Free Space performance counter to retrieve information about the percentage of free space available on a logical disk. Let's further suppose that you grab this information, pipe it to the Select-Object cmdlet, and then ask Select-Object to display all the properties of the returned object (Select *). Why would you do that? To answer that question, let's first call the performance counter as-is:

     

    Get-Counter -Counter "\LogicalDisk(*)\Disk Reads/sec" | Select-Object -ExpandProperty CounterSamples

     

    If you do that, you'll get back the "cooked value" for each logical disk drive:

     

    Path                                      InstanceName   CookedValue                         ------------                              -----------    -----------

    \\server1\logicaldisk(c:)\% free space    c:             68.1037705530888

     

    The CookedValue tells us that we have approximately 68% free disk space.

     

    Now let's try the Select * variation of this same command:

     

    Get-Counter -Counter "\LogicalDisk(*)\Disk Reads/sec" | Select-Object -ExpandProperty CounterSamples | Select *

     

    Here's the kind of output that command generates:

     

    Path             : \\server1\logicaldisk(c:)\% free space

    InstanceName     : c:

    CookedValue      : 68.1057381403677

    RawValue         : 207683

    SecondValue      : 304942

    MultipleCount    : 1

    CounterType      : RawFraction

    Timestamp        : 5/23/2011 2:55:24 PM

    Timestamp100NSec : 129506361244260000

    Status           : 0

    DefaultScale     : 0

    TimeBase         : 2597714

     

    If you look closely at the output (which we've highlighted in red), you'll see that the SecondValue is 304942; that happens to be the total size of the drive in kilobytes (about 297 gigabytes). The RawValue, which is the amount of free space, is 207683 kilobytes. Do we care about those values? Probably not; after all, the whole idea here was to determine the percentage of free disk space on the drive. That's something we can calculate by dividing 207683 by 304942.

     

    Alternatively, we can take the easy way out and let the performance counter do the math for us. That's what the CookedValue is. The CookedValue is also the default value shown by the Get-Counter cmdlet. Why? Because this is almost always the value that we care about; in general, we aren't interested in the raw data used to make that calculation.

     

    Note. Although, as you can see, it is possible to get at that raw data if you really want it.

     

    So much for cooked values vs. raw values. Before we go any further, let's take another question from the audience: what if you want to return data from more than one performance counter? Is that going to be a problem?

     

    Nope; in fact, that will probably be the least of your problems. You say you'd like to get data from more than one performance counter (for example, both incoming messages and outgoing messages)? Piece of cake:

     

    Get-Counter -Counter "\LS:SIP - 02 - Protocol\SIP - 000 - Incoming Messages", "\LS:SIP - 02 - Protocol\SIP - 019 - Outgoing Messages" | Select-Object -ExpandProperty CounterSamples | Select-Object Path, CookedValue | Format-List

     

    So how hard was it to get data from two different performance counters? As you can see, not hard at all: all we had to do was specify the path to each counter, separating the paths by using a comma:

     

    -Counter "\LS:SIP - 02 - Protocol\SIP - 000 - Incoming Messages", "\LS:SIP - 02 - Protocol\SIP - 019 - Outgoing Messages"

     

    That command is going to return data similar to this:

     

    Path        : \\server\ls:sip - 02 - protocol\sip - 000 - incoming messages

    CookedValue : 395054

     

    Path        : \\server\ls:sip - 02 - protocol\sip - 019 - outgoing messages

    CookedValue : 404144

     

    Two performance counters, two values. Like we said, piece of cake.

     

    Ah, but what if you wanted to retrieve data from 3 different counters, or 4 different counters, or 5 or 6 or X number of counters? No problem: just separate each counter by using a comma:

     

    Get-Counter -Counter "\LS:SIP - 02 - Protocol\SIP - 000 - Incoming Messages", "\LS:SIP - 02 - Protocol\SIP - 017 – Local Requests in Server", "\LS:SIP - 02 - Protocol\SIP - 019 - Outgoing Messages", "\LS:SIP - 02 - Protocol\SIP - 025 – Events in Processing" | Select-Object -ExpandProperty CounterSamples | Select-Object Path, CookedValue | Format-List

     

    Etc., etc.

     

    If that command looks a little too unwieldy, then stash all your counter paths in variable (say, $x) and then pass that variable to the Counter parameter:

     

    $x = "\LS:SIP - 02 - Protocol\SIP - 000 - Incoming Messages", "\LS:SIP - 02 - Protocol\SIP - 017 – Local Requests in Server", "\LS:SIP - 02 - Protocol\SIP - 019 - Outgoing Messages", "\LS:SIP - 02 - Protocol\SIP - 025 – Events in Processing"

     

    Get-Counter -Counter $x | Select-Object -ExpandProperty CounterSamples | Select-Object Path, CookedValue | Format-List

     

    Either way will work just fine.

     

    Oh, and here's a neat little trick: a command that returns data for all the performance counters in a counter set:

     

    Get-Counter –ListSet "LS:SIP - 02 - Protocol" | Select-Object –ExpandProperty Counter | ForEach-Object {Get-Counter -Counter $_}

     

    How does that command work? Much easier than you might expect. We start off by using the Get-Counter cmdlet to return all the performance counters in the counter set LS:SIP - 02 – Protocol. We pipe that data to Select-Object, and expand the value of the Counter property. We then pipe that data to the ForEach-Object cmdlet. ForEach-Object then loops through the set of performance counters and, for each one, calls the Get-Counter cmdlet:

     

    {Get-Counter -Counter $_}

     

    Give it a try and see what happens. We have a feeling you'll end up saying this:

     

    The soul's Rialto hath its merchandise;

    I barter curl for curl upon that mart,

    And from my poet's forehead to my heart

    Receive this lock which outweighs argosies,--

    As purply black, as erst to Pindar's eyes

    The dim purpureal tresses gloomed athwart

     

    Well, OK, maybe you won’t say that. But at least you'll be happy with the results.

     

     

    Once is Not Enough

     

    So where do we stand at the moment? Well, at the moment we know that our test server has received exactly 395,054 incoming SIP messages. Is that good? Is that bad? What exactly does it mean to receive 395,054 incoming SIP messages?

     

    To be honest, without a little more context there's really no way to answer that question. After all, suppose our server has been up for 395,054 minutes (about 274 days). One SIP message received per minute? Most likely we can handle that.

     

    But suppose our system has only been up for an hour. That would mean that we're getting over 6,000 incoming SIP messages every minute. That's a whole 'nother story.

     

    Which simply means that we might benefit from monitoring incoming SIP messages over time; for example, we might want to check the value every 60 seconds and thus determine how many messages we're receiving per minute. Can we do that using the Get-Counter cmdlet? Do you even have to ask:

     

    Get-Counter –Counter "\LS:SIP - 02 - Protocol\SIP - 000 - Incoming Messages" –SampleInterval 60 –MaxSamples 10 | Select-Object –ExpandProperty CounterSamples | Select-Object Path, CookedValue | Format-Table

     

    So what do we have here? Well, as usual, we've again called the Get-Counter cmdlet along with the path to the counter that reports back the total number of SIP messages received (\LS:SIP - 02 - Protocol\SIP - 000 - Incoming Messages). However, this time around we've also included a pair of optional parameters:

     

    ·         SampleInterval. The SampleInterval parameter allows us to specify how long (in seconds) we want to wait between measurements. For this command we wanted to check the value of the incoming messages at 1-minute intervals; because of that, we set the sample interval to 60. If we didn't specify a sample interval, then Get-Counter will take a new measurement every second.

    ·         MaxSamples. The MaxSamples parameter tells Get-Counter how many measurements we want to take before calling it quits. In our example, we're taking 10 measurements; as soon as we've gotten measurement number 10 Get-Counter will automatically stop. What if we wanted to take an infinite number of measurements? That's fine; instead of using the MaxSamples parameter we’d use the Continuous parameter instead:

    Get-Counter –Counter "\LS:SIP - 02 - Protocol\SIP - 000 - Incoming Messages" –SampleInterval 60 –Continuous

    The preceding command will continue to take samples until you press Ctrl+C or until you close the Windows PowerShell window.

    Or until October 21, 2011, when the
    world might come to an end. Whichever comes first.

    After we retrieve the data using Get-Counter we then pipe that data to Select-Object and expand the CounterSamples property. We next pipe the expanded data to Select-Object, asking that cmdlet to extract only the Path and the CookedValue properties. Finally, we pipe those values to Format-Table, which displays output in a table that looks something like this:

     

    Path                                                             CookedValue

    ----                                                             -----------

    \\atl-cs-001\ls:sip – 02 – protocol\sip – 000 – in ...                461211

    \\atl-cs-001\ls:sip – 02 – protocol\sip – 000 – in ...                461314

    \\atl-cs-001\ls:sip – 02 – protocol\sip – 000 – in ...                461497

    \\atl-cs-001\ls:sip – 02 – protocol\sip – 000 – in ...                461558

     

    As you can see, we started out at 461,211 incoming messages and, three minutes later, we had 461,558 messages. That means we received 347 messages in those 3 minutes, or about 116 messages per minute.

     

    Note. Can’t we write a script that would make PowerShell do that math for us? Yes we can, and that's something we'll do in a future article.

     

    If you're interested.

     

     

    Didn't You Say Something About Remote Computers?

     

    Probably; if you think you get lost reading these articles imagine what happens to those of us who are trying to write these articles? But yes, everything we've shown you works just as well on a remote computer as it does on a local computer. If you want to retrieve performance counter information from a remote computer, just tack on the ComputerName parameter:

     

    Get-Counter -ListSet "LS:*" –ComputerName atl-cs-001.litwareinc.com

     

    That's all you have to do.

     

     

    So Where Do We Go From Here?

     

    Believe it or not, we've only scratched the surface of all the ways you can monitor performance using Windows PowerShell. For example, we've only hinted at the possibility of using a script to jazz up your performance monitoring, and we haven't even mentioned the ability to import and export performance counter logs (using the Import-Counter and Export-Counter cmdlets, respectively). Will we ever cover those topics? We'll see. If there's enough interest, yes. If there's not enough interest, well, then probably not. Let us know either way.

     

    We also haven't done much – OK, we haven't done anything – in regards to telling you which Lync Server performance counters are worth monitoring and which ones aren't; as we noted earlier, that's a bit outside our area of expertise. Nevertheless, here's a command that you might find useful: it tells you how many users are currently connected to a Front End server. Enjoy!

     

    Get-Counter –Counter "\LS:SIP – 01 – Peers(*)\SIP – 000 – Connections Active" | Select-Object –ExpandProperty CounterSamples | Where-Object {$_.InstanceName –eq "clients"}

     

    Note. Our understanding is that there is documentation in the works that will explain a large number of Lync Server performance counters and how you might best make use of them. When will that documentation be released and where will you be able to get it from? Well, remember when we talked about things that were outside our area of expertise? Add those two items to that list. If and when we get more information, we'll let you know.

     

    One thing that we did do (or so we hope) is put to rest the belief that Elizabeth Barrett Browning would have a made a good Lync Server administrator. A great poet? Sure. But remember, Elizabeth Barrett Browning needed to write 14 lines of poetry in order to determine how many ways she loved Robert Browning. We could have done the same thing with a single line of Windows PowerShell code:

     

    Get-Counter –Counter "\Robert Browning – 000 - How Do I Love Thee\Total Ways(*)"

                        

    Case closed.

     

     

     

     

     

     

     

  • Play sounds in Lync (including ringtones for incoming calls and IM alerts)

     

     

    Registry locations

    HKCU\Software\Microsoft\Communicator\PlaySoundFeedback

    Allowed registry values

    ·         0 – Lync will not play sounds when significant events occur

    ·         1 – Lync will play sounds when significant events occur

    Registry value type

    REG_DWORD

    Default setting

    1: Sounds are played in Lync when significant events occur

     

    Any time someone calls you or sends you an instant message, a "toast" pops up in the lower right-hand corner of your computer screen. (That's right: just like toast popping up from a toaster.) The Lync toast – like any good piece of toast – notifies of you of the incoming communication:

     

     

    In addition to this visual notification, Lync can optionally play a sound any time a significant event takes place. To be more specific, Lync can optionally play sounds to accompany events like these:

     

    • Busy signal
    • Call ended
    • Call error
    • Connecting tone
    • Data sharing invitation
    • Dial tone
    • Howler
    • Incoming call
    • Incoming call in full screen mode
    • Incoming instant message
    • Incoming private line call
    • Incoming Response Group call
    • Incoming team call
    • Muting message
    • New message
    • On hold
    • Outgoing call
    • Redirect call
    • Second incoming call
    • Status alert
    • Untag

     

     

    Note. How do we know those are the events that can be accompanied by sounds? That's easy: we spent literally hundreds and hundreds of hours carefully reverse-engineering Microsoft Lync. 

     

    And when that didn't work, we looked in Control Panel at the Sound dialog box:

     

     

     

    So how do you turn auditory feedback on and off in Microsoft Lync? There are two ways that we know of to do this. One way is to enable the Play sounds in Lync option in the Lync user interface:

     

     

    And the other way? By modifying the HKCU\SOFTWARE\Microsoft\Communicator\PlaySoundFeedback registry value. If this value is set to 1 then Lync will play sounds to accompany significant events. If this value is set to 0 then Lync will remain quiet (at least as far as notifications go) any time these significant events take place.

     

    It's entirely up to you.

     

    If you're interested in using Windows PowerShell (which we assume you are, seeing as how you're here at the Lync Server PowerShell blog), the following script retrieves the current value of PlaySoundFeedback on the local computer. If you'd prefer to retrieve this value from a remote computer, simply set the value of the variable $computer to the name of that remote computer. For example:

     

    $computer = "atl-ws-001.litwareinc.com"

     

    As promised, here's the script for retrieving the PlaySoundFeedback value:

     

    $computer = "."

     

    $registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("CurrentUser", $computer)

    $key = $registry.OpenSubKey("SOFTWARE\Microsoft\Communicator", $True)

     

    $value =$key.GetValue("PlaySoundFeedback",$null)

    if ($value -eq 1) {$value = "Yes"}

    if ($value -eq 0) {$value = "No"}

    Write-Host "Play sounds in Lync (including ringtones for incoming calls" `

        " and IM alerts): $value"

     

    And here's a script for actually changing the value of PlaySoundFeedback. In this case, the script enables sound feedback; that's done by setting PlaySoundFeedback to 1. To disable sound feedback, set PlaySoundFeedback to 0, like so:

     

    $key.SetValue("PlaySoundFeedback",0,"DWORD")

     

    In other words:

     

    $computer = "."

     

    $registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("CurrentUser", $computer)

    $key = $registry.OpenSubKey("SOFTWARE\Microsoft\Communicator", $True)

     

    $key.SetValue("PlaySoundFeedback",1,"DWORD")

     

    Now, what if you want to change the sounds used for a Lync event? Well, that can be done using the Sound dialog box from Control Panel. As near as we can tell, it can also be done by modifying values in the HKEY_CURRENT_USER\AppEvents\Schemes\Apps\Communicator portion of the registry. For example, to change your ringtone, you can modify the Default value found in this registry key:

     

    HKEY_CURRENT_USER\AppEvents\Schemes\Apps\Communicator\

    COMMUNICATOR_ringing\.Current

     

    We won't show you an example of using PowerShell to make this change simply because we didn't do extensive testing on this, and because we assume that this isn't the recommended way to make these changes. However, in playing around with it a little it all seemed to work. Just make sure you use a .WAV file; as far as we know, that's the only format that will work with Lync events.

     

     

     

  • Lync Product Version

     

     

    Registry locations

    HKCU\Software\Microsoft\Communicator\ProductVersion

    Allowed registry values

    Any string value

    Registry value type

    REG_SZ

    Default setting

    Version number of the installed version of Microsoft Lync

     

    Ah, good question: how do you know if someone has the correct version of Microsoft Lync installed on their computer? Well, one thing you can do is go to their computer, fire up Microsoft Lync, click Help, and then click About Microsoft Lync:

     

     

    That's one way to do it. Another way to determine the version of Microsoft Lync that someone is running is to use a Windows PowerShell script that reads the HKCU\SOFTWARE\Microsoft\Communicator\ProductVersion registry value. For example, the following PowerShell script retrieves the current value of ProductVersion on the local computer. If you'd prefer to retrieve this value from a remote computer just set the value of the variable $computer to the name of that remote computer. For example:

     

    $computer = "atl-ws-001.litwareinc.com"

     

    Here's the script for retrieving the version of Microsoft Lync currently in use on a computer:

     

    $computer = "."

     

    $registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("CurrentUser", $computer)

    $key = $registry.OpenSubKey("SOFTWARE\Microsoft\Communicator", $True)

     

    Write-Host "Microsoft Lync product version:",($key.GetValue("ProductVersion",$null))

     

  • Haiku #122

    Drink to your health! And,

    While you're at it, manage your

    Web service settings.

     

    If you've ever wondered why we do a daily haiku devoted to the Lync Server PowerShell cmdlets, we actually have a pretty good reason for that: the daily haiku provides a way for us to bring you information that you might not be able to find anywhere else. What kind of information are we talking about? Information like this: did you know that the Michelin Man has a name.

     

    Note. No, it's not "The Michelin Man." Although that's probably what we would have named him.

     

    If you didn't know that the Michelin Man has a name, well, don't feel bad: we didn't know that either. But it's true: the Michelin Man (who's been around since 1894) is named Bibendum which, roughly translated, means "the drinking man" in Latin. The name was derived from the very first Michelin Man poster, which included this Latin motto:

     

    Nunc est bibendum!!..

    C'est à dire: À votre santé. Le pneu Michelin boit l'obstacle

     

    Which, believe it or not, translates to this:

     

    Now is the time to drink.

    That is to say, to your health. The Michelin tire drinks up obstacles.

     

    Note. Hey, we couldn't have made that up if we tried.

     

    By the way, here's the first-ever ad featuring our friend Bibendum. If you're like us, you're going to have nightmares for a week now.

     

    At any rate, learning that the Michelin Man has a name (and a Latin name, to boot!) immediately raises two important questions: 1) Does this mean that the Keebler Elves have names, too; and, 2) What does any of this have to do with Microsoft Lync Server 2010?

     

    Let's start by answering the first question. As it turns out, the Keebler Elves do have names. The head elf is named Ernie the Elf which, in Latin means, uh, Ernie the Elf. Other Keebler Elves include Zoot; J.J.; Ma and Elmer Keebler; Fast Eddie; and Sam the peanut butter maker. Who knew, eh?

     

    Note. Although we regret to inform you that the little girl on the Morton Salt can, the one carrying the umbrella, does not have a name. Nor does Ronald McDonald.

     

    Oh, wait; forget that last one, OK?

     

    As for the second question, "What does any of this have to do with Microsoft Lync Server 2010?" well, as it turns out, the CsWebServiceConfiguration cmdlets were originally going to be named the CsBibendum cmdlets. However, because of a concern over trademark issues, we decided to name them the CsWebServiceConfiguration cmdlets (Get-CsWebServiceConfiguration, New-CsWebServiceConfiguration, Remove-CsWebServiceConfiguration, and Set-CsWebServiceConfiguration) instead.

     

    Note. Is that really true? Well, if by "true" you mean "false," then yes, it's really true. Otherwise, no, it's not.

     

    So what exactly is a CsWebServiceConfiguration cmdlet? Well, we can tell you two things about the CsWebServiceConfiguration cmdlets. First, the name does not translate into Latin; we tried several different online translators and none of them could come up with a Latin equivalent.

     

    Yes, we were disappointed, too.

     

    Second, the CsWebServiceConfiguration cmdlets provide a way for you to manage the Web-based features of Microsoft Lync Server. What's nice is that the Web service configuration settings can be assigned to the global scope, the site scope, or even individual Web server scopes. That gives you enormous flexibility in determining what can (and cannot) be done with your Web servers.

     

    Ah, good question: what can (or cannot) be done with your Web servers? Well, there are actually a whole bunch of settings and capabilities that can be managed using the Web service configuration cmdlets. For example, there are a bunch of properties related to authentication: you can enable (or disable) certificate authentication; enable or disable PIN authentication; and specify whether you will allow Windows authentication (that is, will you allow users to be automatically be authenticated using the same credentials they used when they logged on to Windows). How hard is it to configure authentication settings? Not too hard. For example, this command enables PIN authentication at the global scope:

     

    Set-CsWebServiceConfiguration –Identity global –UsePinAuth $True

     

    The CsWebServiceConfiguration cmdlets are also used to manage group expansion in Microsoft Lync. As you probably know, if you configure a distribution group to be one of your Microsoft Lync contacts, you have the default ability to "expand" that group in the Contact window; that simply means that you can open up the group and see all the individual group members. But that's the default capability. What if you don't want to give people this ability? That's fine; that's what the CsWebServiceConfiguration cmdlets are for:

     

    Set-CsWebServiceConfiguration –Identity global –EnableGroupExpansion $False

     

    So why wouldn't you want to allow group expansion? Well, suppose you have a group that has 500 users in it. If you expand that group, Microsoft Lync will have to contact the server, retrieve the name and status information for all 500 of those users, and then display all that information. If you have lots of users and lots of users playing around with group expansion, that could result in a lot of traffic flitting about the network, and a lot of strain placed on your Front End servers. One way to limit that strain is to simply disable group expansion.

     

    Another way to limit that strain is to place a limit on the size of a group that can be expanded. By default, Microsoft Lync will expand any group that has 100 or fewer members. If that seems like too many, then use the Set-CsWebServiceConfiguration cmdlet to change the maximum size of a group that can be expanded. You know, like this:

     

    Set-CsWebServiceConfiguration –Identity global –MaxGroupSizeToExpand 25

     

    After running that command, users will only be able to see the first 25 members of a group. What if a group has 26 members? Too bad: Microsoft Lync will only show you the first 25 members, and that 26th user will be out of luck.

     

    You know, life is unfair sometimes, isn't it?

     

    As you might expect, the Set-CsWebServiceConfiguration cmdlet is used to modify existing Web service settings; to create new settings (at the site or service scope) use the New-CsWebServiceConfiguration cmdlet:

     

    New-CsWebServiceConfiguration –Identity "site:Redmond" –MaxGroupSizeToExpand 25

     

    If you get tired of any of these new settings you can dispose of them using the Remove-CsWebServiceConfiguration cmdlet:

     

    Remove-CsWebServiceConfiguration –Identity "site:Redmond"

     

    And, of course, the Get-CsWebServiceConfiguration cmdlet provides a way for you to retrieve and review all your existing Web service settings. For example, do you actually have any Web service settings where group expansion has been disabled? This command will tell you:

     

    Get-CsWebServiceConfiguration | Where-Object {$_.EnableGroupExpansion –eq $False}

     

    And this command returns all the setting collections that allow PIN authentication:

     

    Get-CsWebServiceConfiguration | Where-Object {$_.UsePinAuth –eq $True}

     

    That's what we said: Nunc est bibendum!

     

    See you tomorrow.