Lync PowerShell

  • Haiku #144

    It's almost July

    Fourth, and that means fireworks and

    CS server apps!

     

    Today is July 1st, which, at first glance, might not seem all that exciting to you. However, if you do the math, and you do the math correctly, you'll realize that Monday is July 4th, a national holiday in the US of A. And if you do even more math, you'll realize that this upcoming weekend is a three-day weekend. And that is exciting, to say the least.

     

    Note. In all fairness, the author of today's haiku should point out that it's very possible that he did not do the math correctly. After all, it's nearly 9:00 this morning, and his building is totally empty: he has yet to see a single person, or to even hear a single person. Maybe this was supposed to be a four-day weekend, but he got his calculations wrong.

     

    July 4th, of course, is Independence Day in the US: the day that the American colonies declared their independence from Great Britain. Of course, in typical American fashion, July 4th actually isn't the day that the American colonies declared their independence from Great Britain; that actually occurred on July 2, 1776. July 4, 1776 was simply the day that the Declaration of Independence was adopted. But then again, history – like math – has never been our strong suit here in the US.

     

    At any rate, the Fourth of July has always been a pretty festive occasion here in the US, a day typically marked by picnics, barbecues, parades, and fireworks. And, of course, American ingenuity occasionally comes into play as well. For example, a few years ago, some local neighbors celebrated the Fourth of July by burning down the house belonging to the author of today's haiku. Now that was a memorable Fourth of July!

     

    OK, so technically, they didn't actually burn down the house, although they did torch his garage pretty good. And, technically, the fire inspector didn't put the blame on the neighbors, saying that it was possible that the fire was the result of an electrical malfunction. "But it's the Fourth of July, and your neighbors shot off fireworks for 8 straights hours," he said. "I look around the neighborhood and I see firework debris everywhere. And then, that night, something smolders and your house catches on fire. You tell me what that sounds like."

     

    "Sounds like an electrical malfunction to me."

     

    Note. But after burning down someone's house, did the neighbors learn their lesson about the dangers of fireworks? You bet they did. Come the next Fourth of July, they only shot off fireworks for 7 straight hours.

     

    Hey, you can never be too careful, right?

     

    Another traditional way to celebrate the Fourth of July is to run one or more of the CsServerApplication cmdlets: Get-CsServerApplication, New-CsServerApplication, Remove-CsServerApplication, and Set-CsServerApplication. Server applications are individual applications that run as part of Microsoft Lync Server 2010. Give you an example of a server application? We'll do better than that; we'll give you a command that returns information about all your server applications:

     

    Get-CsServerApplication

     

    Or, if you'd rather just see the names of your server applications, run this command instead:

     

    Get-CsServerApplication | Select-Object Name

     

    On our test computers, that command returns the following server applications:

     

    ClientVersionFilter

    TranslationServer

    IncomingFederation

    UserServices

    InterClusterRouting

    IIMFilter

    UserPinService

    QoEAgent

    DefaultRouting

    ExumRouting

    OutboundRouting

    OutgoingFederation

    AcpRouting

    IIMFilter

    OptionsHandler

     

    In other words, all the fun and excitement of fireworks, but less likely to burn down your house.

     

    Admittedly, most of the time you run a CsServerApplication cmdlet you'll probably be running Get-CsServerApplication. Why? Two reasons. First, you can't just configure any old application as a server application; someone (i.e., a developer) has to write an application specifically designed to run under Lync Server. You say that someone did write an application specifically designed to run under Lync Server? That's fine; in that case, you can use the New-CsServerApplication cmdlet to register that application with the system:

     

    New-CsServerApplication -Identity "EdgeServer:atl-edge-001.litwareinc.com/EdgeMonitor" -Uri http://www.litwareinc.com/edgemonitor -Critical $False

     

    Likewise, you could then use the Set-CsServerApplication cmdlet to modify that new application. For example, in the command shown above we set the value of the Critical property to False. The Critical property determines what Lync Server will do if the server application cannot be started. In our example, we decided that Lync Server should start even if our server application can't be started; therefore, we set the Critical property to False. But suppose we decided that this new application was so important that, if the application can't be started, then we don't want to run Lync Server at all. In that case, we could simply set the Critical property to True:

     

    Set-CsServerApplication -Identity "EdgeServer:atl-edge-001.litwareinc.com/EdgeMonitor" -Critical $True

     

    And if we decide that we never should have registered this application in the first place, well, we can rectify matters by using Remove-CsServerApplication to unregister the thing:

     

    Remove-CsServerApplication -Identity "EdgeServer:atl-edge-001.litwareinc.com/EdgeMonitor"

     

     

    Of course, you aren't limited to modifying custom applications; can also use these commands to modify the server applications that ship with Lync Server. Do we recommend that you just start willy-nilly modifying and deleting the built-in server applications? Not exactly, no. We have no idea what will happen if you start changing the built-in server applications, but we don't expect it would be good; in fact, we wouldn't be surprised if your house caught on fire.

     

    Well, OK, we'd be a little surprised. But you probably shouldn't mess around with the built-in server applications unless some sort of official Microsoft support person specifically tells you to mess around with them.

     

    But, as we noted earlier, what you can do is get information about those applications. For example, this command returns the names of all your critical server applications:

     

    Get-CsServerApplication | Where-Object {$_.Critical -eq $True} | Select-Object Name

     

    And this one returns information about all the registered server applications that are currently disabled:

     

    Get-CsServerApplication | Where-Object {$_.Enabled -eq $False} | Select-Object Name

     

    And, last but surely not least, this command returns the names and priorities of your server applications, sorted in priority order:

     

     Get-CsServerApplication | Sort-Object Priority | Format-Table Priority, Name -AutoSize

     

    Note. What's the priority order all about? Well, the priority order specifies the order of execution for server applications. The application with priority 0 is started first; the application with priority 1 is started second; and so on. If you'd like to know more about priority orders, and how to work with them, well, do we have the perfect article for you or what?

     

    That's all we have for today. Enjoy the Fourth of July, and try not to burn down anyone's house.

     

    Or at least not the house belonging to the author of today's haiku, OK? After all, for him that's one of those "been there, done that" sort of things

     

     

     

     

     

  • Haiku #143

    Smile! After all, you

    (And Hugh) can run the User

    Server cmdlets.

     

    So it turns out that there was a monastery in this one town where something weird happened and the monks all went crazy; as a result, they started growing these man-eating flowers that began terrorizing the town. The townspeople tried everything they could to stop these ferocious flowers, but nothing they tried worked: the flowers just kept eating all the town folk, one-by-one. Just when things looked hopeless, however, a man named Hugh approached the monks. "Leave our little village right now," he commanded, and the monks immediately grabbed all their man-eating flowers and took off for parts unknown, never to be heard from again.

     

    The moral of the story? Only Hugh can prevent florist friars.

     

    Ha! Get it? You know, because Smokey the Bear always says that only you can prevent forest fires, except that in this case we're saying that only Hugh can prevent – well, never mind. We apologize, but, sadly, that's pretty much the only joke that the author of today's haiku knows.

     

    Note. What's that? You say that everyone who knows the author of today's haiku knows at least one joke themselves? Ha! Good one!

     

    Hey, wait a minute: what's that supposed to mean?

     

    As you might have guessed it's already been one of those days: despite having been to work for over two hours now, the author of today's haiku hasn't managed to get any work done whatsoever.

     

    Note. Yes, most of his colleagues would argue that, despite having been to work for nearly 11 years now, the author of today's haiku hasn't managed to get any work done whatsoever. But that's another story.

     

    Instead of working, the author of today's haiku has spent his morning trying to help people who are experiencing issues with, or have questions about, Lync Server. Not necessarily Lync Server PowerShell, mind you, but Lync Server in general. Apparently anyone who runs into a problem with Lync Server thinks, "Who would be the best possible person to try and answer this question for me? Oh, I know: what about that guy who writes haikus?"

     

    When in doubt, go with the obvious choice, right?

     

    At any rate, the author of today's haiku actually enjoys trying to help people; he's just not always very good at helping people. If someone has a question about Lync Server PowerShell he can usually help them. However, sometimes people have questions like this:

     

    "I'm trying to configure a 9 double camulator load balancer to talk to a 64-bit hotzenjammer in server emulation mode, but I don't want to enable ABC-QDR 5 unless I absolutely have to. (Our company policy is to only use thread-nine compliant protocols.) Am I going to have a problem if I allow RDPPP traffic throw my half-duplexing firewall?"

     

    If he was a betting man, the author of today's haiku would be willing to bet that yes, you definitely are going to have a problem in that situation. But because he isn't a betting man, and has no idea what that question even means, he ends up trying to track down someone on the product team who can help, and then serves as a go-between between the person who asked the question and that someone on the product team who can answer the question.

     

    And that's pretty much how the author of today's haiku has spent his entire morning, which explains why he thought it would be a good idea to lighten things up by telling a funny joke.

     

    And yes, as soon as actually learns a funny joke, he'll do just that.

     

    In the meantime, another good way to lighten the mood is to talk about the Set-CsUserServer cmdlet. The Set-CsUserServer cmdlet is used to – oh, you guessed it, didn't you? Well, you're right: the Set-UserServer cmdlet is used to manage the User Servers employed by Microsoft Lync Server 2010. If you aren't familiar with User Servers, this server role is a sort of catch-all component that performs a number of useful management tasks. For example, User Servers provide presence information; they help manage conferences (through the Focus and Focus Factory); they assist with user authorization and user-level routing; and they serve as the primary interface to the back-end database.

     

    You say that's not enough? OK; User Servers also assist with provisioning user accounts.

     

    We thought you'd be impressed by that.

     

    At any rate, the Set-CsUserServer cmdlet lets you manage three key properties of your User Servers:

     

    ·         ConferenceServer – Obviously this is the Conferencing server associated with the User Services pool. To set this, just specify the service Identity of the Conferencing server; for example:

    -ConferenceServer "ConferenceServer:atl-cs-001.litwareinc.com"

    ·         McuFactorySipPort – The port used for connecting to the Focus Factory (McuFactory). The Focus Factory allocates media control units (MCUs) in order to add specific media types such as audio to conferences.

    ·         UserDatabase – Another obvious one: the user database associated with the User Services pool. Again, just specify the service Identity of the database; for example:

    -UserDatabase "UserDatabase:atl-cs-001.litwareinc.com"

     

    And that's really it. How do you actually use the Set-CsUserServer cmdlet to change one of these property values? Well, here's one example:

     

    Set-CsUserServer -Identity "UserServer:atl-cs-001.litwareinc.com" -McuFactorySipPort 445

     

    And here's another:

     

    Set-CsUserServer -Identity "UserServer:atl-cs-001.litwareinc.com" –ConferenceServer "ConferenceServer:atl-cs-001.litwareinc.com"

     

    That's pretty much all you have to do. And, for that matter, pretty much all that you can do.

     

    Just a couple quick notes about the Set-CsUserServer cmdlet before we call it a day. First, you might have noticed that this is the only cmdlet in the CsUserServer family: there is no Get-CsUserServer cmdlet. So how do you get information about your User Servers? Well, like many of the service/server roles in Lync Server, you need to use the Get-CsService cmdlet to retrieve information. For example, this command returns information about all your User Servers:

     

    Get-CsService –UserServer

     

    To get back information for a specific server, use a command like this one, which specifies the server Identity:

     

    Get-CsService –Identity "UserServer:atl-cs-001.litwareinc.com"

     

    And, in keeping with our light-hearted and carefree mood, here's a command that finds all the User Servers that have their MCU Focus Factory SIP port set to something other than the default port 444:

     

    Get-CsService –UserServer | Where-Object {$_.McuFactorySipPort –ne 444}

     

    Here's another thing to keep in mind: you can't pipe information directly to the Set-CsUserServer cmdlet. For example, suppose you want to set all your Focus Factory SIP ports to 445; with that in mind, you try running this command:

     

    Get-CsService –UserServer | Set-CsUserServer -McuFactorySipPort 445

     

    Is that going to work? Well, not exactly:

     

    Set-CsUserServer : The input object cannot be bound to any parameters for the command either because the command does not take pipeline input or the input and its properties do not match any of the parameters that take pipeline input.

     

    So what does that mean? That means that you need to use a command like this one, which pipes the data to the ForEach-Object cmdlet instead of the Set-CsUserServer cmdlet:

     

    Get-CsService -UserServer | ForEach-Object {Set-CsUserServer -Identity $_.Identity -McuFactorySipPort 445}

     

    As you can see, that's no big deal. It's just something you need to be aware of.

     

    Is there anything else you need to be aware of? Just this: a group of chess players were standing in the lobby of a hotel, bragging about all their recent victories and accomplishments. After a few minutes the hotel manager came out and told them they'd have to leave. "But why?" asked one of the chess enthusiasts. "I'll tell you why," said the hotel manager. "Because I don't like chess nuts boasting in an open foyer."

     

    You see, because of the Christmas song, the one about chestnuts roasting on an– well, never mind. Here's something that is guaranteed to lighten your mood and bring a smile to your face: that's all we have for today. See you tomorrow.

     

  • Haiku #142

    Somewhere, a dog howled.

    Would you stop if we explain

    Response Group settings?

     

    It's a conspiracy, that's what it is.

     

    That's right: a conspiracy. As it turns out, the entire world – or at least the animal world – is out to get the author of today's haiku.

     

    For three weeks the author of today's haiku experienced the … joy … of cat-sitting a cat. To be honest, the cat was actually a pretty decent little cat, except for her somewhat-annoying habit getting up at 4:30 every morning and, in the process, waking up everyone else in the house as well. The cat has now been returned to its rightful owners, but the conspiracy lives on. Now the dogs have gotten involved.

     

    As it turns out, the people who live next door to the author of today's haiku have three gigantic dogs. (Or maybe it's two gigantic dogs and a medium-sized hippopotamus; to be honest, it's kind of hard to tell.) For the most part these dogs seem pretty laid-back, and pretty much oblivious to the world. For example, one afternoon the three dogs were outside when the author of today's haiku went out to work in the yard. He was working right in front of the dogs for about half an hour or so before one of them suddenly realized, "Oh, shoot, there's someone out here with us. I think I'm supposed to bark or something!" and immediately started barking at him. But then, having done his duty for 10 seconds or so, he immediately laid down and went to sleep.

     

    Which, come to think of it, sounds an awful lot like the typical work day for the author of today's haiku.

     

    At any rate, the people next door have been out of town for a few days, and they left the dogs in the care of a dog sitter. However, this isn't a live-in dog sitter; instead, it's just someone who comes by periodically to check in on the dogs. Unfortunately, the dog sitter doesn't come by at 2:00 in the morning, or 5:00 in the morning, which turns out to be right about the time these three gigantic dogs (or two gigantic dogs and a medium-sized hippopotamus) start barking.

     

    And then continue barking for a good half hour to 45 minutes.

     

    Wait, scratch the word good from that last sentence: And then continue barking for a half hour to 45 minutes.

     

    Note. In case you're wondering, the loudest animal in the world is – and we kid you not – the Tiger Pistol Shrimp, which is capable of making a sound that exceeds 200 decibels; that's louder than a jet engine, which checks in at around 140 decibels. And yes, that's what we said, too. But you can look it up for yourself. The loudest land animal is the howler monkey, whose screeching can be heard as far as 10 miles away.

     

    But we think that the dogs next door can give the howler monkey a run for its money.

     

    So what did the author of today's haiku do to deserve all of this? Well, he's not sure. If the people in the world organized a conspiracy against him well, that he could understand: he's probably offended several million people this year alone. But animals? What did he ever do to animals?

     

    Note. Well, he did step on an ant the other day, and his wife is always making him kill spiders. But who hasn't stepped on an ant or killed a spider during his or her lifetime?

     

    But it doesn't really matter who's at fault here. All that really matters is that the author of today's haiku is willing to make a deal: if the dogs next door are willing to stop barking, then he's willing to explain to them what the CsRgsConfiguration cmdlets are for.

     

    Note. And yes, he is willing to discuss all three cmdlets: Get-CsRgsConfiguration, Move-CsRgsConfiguration, and Set-CsRgsConfiguration.

     

    As you might have guessed, the CsRgsConfiguration cmdlets provide a way for you to manage configuration settings for each instance of the Response Group application running in your organization. As it turns out, that only means three settings you need to worry about:

     

    ·         AgentRingbackGracePeriod – If an agent declines a call, the AgentRingbackGracePeriod represents the amount of time (in seconds) that can elapse before the call returns to the same agent.

    ·         DefaulltMusicOnHoldFile – The music that, by default, will be played any time a caller is placed on hold.

    ·         DisableCallContext – Indicates whether each agent is able to see the call context (information such as caller wait time as well as workflow questions and answers) whenever a call is received.

     

    So does that mean that the CsRgsConfiguration cmdlets are really easy and straightforward to use? Yes it does.

     

    Except for the tricky parts.

     

    Let's start with the Get-CsRgsConfiguration cmdlet. As you probably know, you can have multiple instances of the Response Group application running in your organization; for example, you could have one instance for each of your Application servers. With that in mind, you might think you could use a command like this to return information about each of those instances:

     

    Get-CsRgsConfiguration

     

    Unfortunately, however, that command won't return anything; instead, you'll be prompted to enter the instance Identity. In fact, you always have to specify an Identity when using Get-CsRgsConfiguration. To return information about a single instance, you need to use a command like this one:

     

    Get-CsRgsConfiguration -Identity "service:ApplicationServer:atl-cs-001.litwareinc.com"

     

    And what if you want to return information about all your instances? Well, that's fine; you just have to use this approach:

     

    Get-CsService -ApplicationServer | Where-Object {$_.Applications -contains "urn:application:RGS"} | ForEach-Object {Get-CsRgsConfiguration -Identity $_.Identity}

     

    Please don't start barking; we're going to explain how this command works. As you can see, we start out by using the Get-CsService cmdlet to return a collection of all our Application servers. (Why? Because the Response Group application can only be run on an Application server.) We then pipe this collection to the Where-Object cmdlet, which looks for any Application servers that have an application name urn:application:RGS. That, needless to say, means that the Application server is running the Response Group application. Any relevant Application servers are then piped to the ForEach-Object cmdlet, which – at long last – uses Get-CsRgsConfiguration to return setting information for each instance of the Response Group application.

     

    Whew!

     

    You have to take a similar approach when using the Set-CsRgsConfiguration cmdlet. For example, suppose you want to set the ringback period to 30 seconds for a particular instance of the Response Group application. That's reasonably easy:

     

    Set-CsRgsConfiguration -Identity "service:ApplicationServer:atl-cs-001.litwareinc.com" -AgentRingbackGracePeriod 30

     

    So what happens if you want to set the ringback period for all your response Group instances to 30 seconds? You got it: you'll have to first look for all the Application servers running the urn:application:RGS application. In other words:

     

    Get-CsService -ApplicationServer | Where-Object {$_.Applications -contains "urn:application:RGS"} | ForEach-Object {Set-CsRgsConfiguration -Identity $_.Identity -AgentRingbackGracePeriod 30}

     

    Is that the easiest thing in the world to do? Well, no, not really. But it works. And, fortunately, you won't need to modify your Response Group applications on a daily basis anyway.

     

    We hear some growling out there, but don't worry: we haven't forgotten about the Move-CsRgsConfiguration cmdlet. The Move-CsRgsConfiguration cmdlet has only one purpose in life: it moves your Response Group application from Office Communications Server 2007 R2 to Microsoft Lync Server 2010. If you aren't running the Response Group application of Office Communications Server 2007 R2, or if you aren't ready to move that application to Lync Server, well, then you don't have much use for the Move-CsRgsConfiguration cmdlet.

     

    If you do need to make this migration, then the first thing you have to do is install the Windows Management Instrumentation (WMI) Backward Compatibility interfaces package; this application is installed by running OCSWMIBC.msi. (The file OCSWMIBC.msi can be found in the installation package in the Setup folder.) If you don't do that, migration will fail and you'll get this error message:

     

    Move-CsRgsConfiguration : WMI provider is not installed. Install it using OCSWMIBC installer.

     

    Assuming that you have installed the Backward Compatibility interfaces package, you can migrate the response Group application using one simple command, where the Source parameter specifies the 2007 R2 pool where the Response Group application is currently installed and the Destination parameter represents the Lync Server pool where the application is to be moved to:

     

    Move-CsRgsConfiguration -Source atl-ocsrgs-001.litwareinc.com -Destination redmond-lyncrgs-001.litwareinc.com

     

    Move-CsRgsConfiguration will move all the configuration settings, audio files, and contact objects from Office Communications Server 2007 R2 to Lync Server. After that, all calls to a Response Group phone number will be handled by Lync Server, meaning that calls will no longer be handled by the Office Communications Server 2007 R2 version of the service.

     

    One important note. If Office Communications Server is running Microsoft SQL Server 2005 then you must also install the Microsoft SQL Server 2005 Native Client on the computer where you will be running the Move-CsRgsConfiguration cmdlet. If the Native Client is not installed you will receive the error message "Cannot access WMI settings" when you call Move-CsRgsConfiguration.

     

    Oh: and the migration attempt will fail.

     

    That's all we have time for today. For all the cats, dogs, hippopotamuses, howler monkeys, and Tiger Pistol Shrimp who are reading today's haiku, well, the author has done his part. Truce?

     

     

     

     

     

     

  • Haiku #141

    If I call, how do

    I know you will be there? Test

    Dial-in conferencing.

     

    So last night the author of today's haiku had the chance of a lifetime, and he let it slip through his fingers.

     

    Which, come to think of it, is pretty much the story of his life, isn't it?

     

    At any rate, when the author of today's haiku went to the gym last night he started to climb on to the StairMaster and was practically thrown off when the machine started up at a surprisingly high rate of speed. (Yes, usually the stairs start moving a little any time you climb on, but nowhere near as fast as those stairs were moving last night.) He tried again, almost fell off again, then tried a third time and managed to get up on the machine. At that point he pressed the Stop button thinking he would stop and reset the crazy thing. The StairMaster refused to stop; the stairs just kept flying along. Not only that, but at that point the author of today's haiku realized that, instead of marking time second-by-second, the machine was marking time minute-by-minute. That was weird. On the other hand, that also meant that if he was willing to play along, he could complete his 45-minute workout in just 45 seconds. Leaving plenty of time for him to go home, eat a couple pieces of cheesecake, and lie around watching Baseball Tonight.

     

    Note. What's the point of even going to the gym in the first place if all you're going to do is go home, eat a couple pieces of cheesecake, and lie around watching Baseball Tonight? Beats us; the author of today's haiku gave up questioning his existence years ago.

     

    Needless to say, so did his wife.

     

    Unfortunately, though, doing a 45-minute workout in 45 seconds would have been cheating, and while the author of today's haiku currently holds the world's record for most flaws in a single human being, he usually doesn't cheat. (As we all know, you can't do a workout in just 45 seconds; a real workout requires at least 4 minutes to complete.) Being too honest for his own good, he went over to a different StairMaster and put in a full 45 minutes on the stairs.

     

    And then went home to eat a couple pieces of cheesecake, and watch Baseball Tonight.

     

    As you might expect, his only regret is that the broken time clock had to happen at the gym rather than at work. If that had happened at work then, when someone asked if he put in 45 minutes of Project X like he promised he would, he could truthfully say, "Hey, just look at the time clock. It says 45 minutes, doesn't it?"

     

    Note. Could he really get away with something like that? Well, it might be tough, considering the fact that no one around here ever gets assigned to work on a project for a specific amount of time. Well, that and the fact we don't actually have time clocks at Microsoft.

     

    On the other hand, the only people he'd have to fool would be his fellow Microsoft employees. Hmmm ….

     

    The important thing is that the author of today's haiku learned that there are no shortcuts in life: if you want something done, and want that something done right, then you need to put in the required time and effort. And then, he came in to work this morning, started up the Lync Server Management Shell, and realized that Lync Server PowerShell offers nothing but shortcuts.

     

    What kind of shortcuts, you ask? Well, take dial-in conferencing, to name one. How are you supposed to know if dial-in conferencing is working in your organization? Well, what you could do is create and start a new conference, dutifully write down the dial-in conferencing access number and the meeting code, haul out your cell phone, dial in to the conference, enter the meeting code and your PIN number, and verify that you were able to join the conference. We estimated that would take you approximately 45 minutes.

     

    Or, alternatively, you could simply run the following Lync Server PowerShell command, which we estimate would take approximately 45 seconds:

     

    Test-CsDialInConferencing –TargetFqdn atl-cs-001.litwareinc.com

     

    That's all you have to do, assuming that: 1) you've set up a couple of health monitoring test accounts for the Registrar pool atl-cs-001.litwareinc.com; and, 2) you have at least one dial-in conferencing access number configured for that pool. If all of that is true, then the Test-CsDialInConferencing cmdlet will attempt to log on the Lync Server using one of your health monitoring test accounts. If logon is successful, the system will then try to make a call to the first dial-in conferencing access number configured for the specified pool. If the call is established, the cmdlet will join the test user to the "conference," exit the conference, and terminate the call. Test-CsDialInConferencing will then proceed to try the same procedure with the next dial-in conferencing access number configured for the pool.

     

    Note. Why did we say that the cmdlet will join the test user to the "conference," with conference in quotation marks? Well, that's because there isn't really a conference, and Test-CsDialInConferencing doesn't really make a phone call. All the cmdlet does is verify that if someone really did make a phone call and try to join a conference, Lync Server is properly configured to allow that to happen.

     

    But what if you don't have test accounts configured for a pool, or what if you need to determine if a specific user can use dial-in conferencing (e.g., someone who just called in and complained that they were unable to use dial-in conferencing)? No problem. All you need to do us include the user's logon credentials and SIP address in the command:

     

    $cred1 = Get-Credential "litwareinc\pilar"

     

    Test-CsDialInConferencing -TargetFqdn atl-cs-001.litwareinc.com -UserSipAddress "sip:pilar@litwareinc.com" -UserCredential $cred1

     

    Note. Yes, when we say "the user's logon credentials" that means you need to supply both the user name (litwareinc\pilar) and their password.

     

    If all goes well, you'll get back a report that looks like this:

     

    TargetFqdn : atl-cs-001.litwareinc.com

    Result     : Success

    Latency    : 00:00:00

    Error      :

    Diagnosis  :

     

    And if all doesn't go well? Well, in that case you'll get back at least some information concerning the problem that Test-CsDialInConferencing ran into. Here's the report we got back when we ran this test using an invalid dial-in access number:

     

    TargetFqdn : atl-cs-001.litwareinc.com

    Result     : Failure

    Latency    : 00:00:00

    Error      : 404, Not Found

    Diagnosis  : ErrorCode=33034,Source=atl-cs-001.litwareinc.com.Reason=Ms-Application-Aor header is not valid. Microsoft.Rtc.Signaling.DiagnosticHeader

     

    OK, granted, that might not be the most intuitive error message and diagnosis you've ever received. Because of that, you might want to include the Verbose parameter any time you run the Test-CsDialInConferencing cmdlet (or any of the Test-Cs cmdlets, for that matter):

     

    Test-CsDialInConferencing –TargetFqdn atl-cs-001.litwareinc.com -Verbose

     

    That command will give you a blow-by-blow account of everything the cmdlet does; for example:

     

    VERBOSE: 'Register' activity started.

    Sending Registration request:

      Target Fqdn      = atl-cs-001.litwareinc.com

      User Sip Address = sip:kmyer@litwareinc.com

      Registrar Port = 5061

    Auth Type 'Trusted' is selected.

    'Register' activity completed in '0.094552' secs.

     

    Etc., etc.

     

    And there you have it. The most important thing to take away from today's column is that – oops, sorry but, according to the time clock, our 45 minutes is up. See you tomorrow!

     

     

     



     

     

     

     

     

     

     

  • Haiku #140

    The bandwidth service

    Settings: They aren't real flashy,

    But at least they work

     

    Well, it's Monday again, but this Monday is different: this promises to be a great week. How do we know that? Well, yesterday was an almost-nice-day here in the great Pacific Northwest, so the author of today's haiku and his wife decided to go for a bike ride. About 4 ½ miles or so into their ride, the author's bike began to make funny noises, like it was shifting even though he wasn't actually shifting. Another half mile or so up the road the bike suddenly began shifting by itself, even when he had his hands off the handlebars and wasn't even pedaling.

     

    And yes, as a magic trick that would have been pretty cool. But as a way to ride a bike, not quite as cool.

     

    To say the least.

     

    As a result, the author of today's haiku ended up parking the bike after an unexpectedly-brief ride, and then sat around for 45 minutes while his wife rode back to the car and came and got him. All told, his day went like this:

     

    ·         40 minutes to drive to the bike trail.

    ·         28 minutes actually riding his bike.

    ·         45 minutes sitting around waiting for his wife.

    ·         40 minutes to drive back home from the bike trail.

     

    Did we mention that it's going to be a great week?

     

    So was the author of today's haiku mad about his bike falling apart? Of course not. After all, he bought the bike way back in January of 2011. You can't expect these things to last forever, can you?

     

    Trivia note. Based on the cost of the bike and the number of miles he's put it on it so far, the author of today's haiku estimates that it's cost him $20 for each mile ridden. That means that, if he was able to ride to his bike to work (which he can't: the streets around here are too scary to drive on, let alone ride a bike on) it would cost him $200 each day.

     

    So is there a bright side to all of this? No; we tried to think of one, but there's absolutely no bright side whatsoever to a bike that's barely six months old falling apart. Therefore, let's talk about something completely different, and something much more pleasant: the CsBandwidthPolicyServiceConfiguration cmdlets (Get-CsBandwidthPolicyServiceConfiguration, New-CsBandwidthPolicyServiceConfiguration, Remove-CsBandwidthPolicyServiceConfiguration, and Set-CsBandwidthPolicyServiceConfiguration).

     

    What's so pleasant about the CsBandwidthPolicyServiceConfiguration cmdlets? Well, for one thing, Remove-CsBandwidthPolicyServiceConfiguration is one of the two Lync Server PowerShell cmdlets that have 44 characters in the cmdlet name (tying it with Remove-CsDialInConferencingDtmfConfiguration); those are the two longest Lync Server cmdlet names.

     

    Note. The cmdlet with the shortest name? Test-CsIM, with just 9 characters.

     

    Perhaps more important, the CsBandwidthPolicyServiceConfiguration cmdlets are used to help manage the bandwidth policy service. What's the bandwidth policy service? Well, as you no doubt know, the Call Admission Control service introduced in Lync Server 2010 provides a way for you to place a limit on the amount of network bandwidth that can be used for audio and/or video transmissions between two sites; in turn, that lets you do things like ensure that 20,000 users in your Redmond location don't all suddenly make video calls to their peers in Dublin, thus totally overwhelming your network.

     

    Note. Is that really that big of a deal? Yes, it is. Remember, with Voice over IP technologies like Enterprise Voice, audio and video calls travel over the same network as all your other data. If you have too many people using up too much network bandwidth for audio and video calls, that won't just wreak havoc with those calls, it will also wreak havoc with email, file transfers, Web sites, and anything else that uses the network.

     

    In order to place limits on the connections between network sites, you create bandwidth policies. And in order to manage the bandwidth policy service, you use the CsBandwidthPolicyServiceConfiguration cmdlets.

     

    Granted, that might sound like a big chore; it's not. As it turns out, managing the bandwidth policy service really only means two things: managing bandwidth policy logging, and configuring the length of time you can use a bandwidth policy authentication token before that token expires. If you want to enable logging all you have to do is set the EnableLogging property to True (hey, we told you it was easy):

     

    Set-CsBandwidthPolicyServiceConfiguration –Identity global –EnableLogging $True

     

    Note. In case you're wondering, logging is disabled by default.

     

    You can also use the Set-CsBandwidthPolicyServiceConfiguration cmdlet to set the maximum file size for a log file and the amount of time a log file will remain on the system before the log is automatically deleted. For example:

     

    Set-CsBandwidthPolicyServiceConfiguration –Identity global –LogCleanUpInterval 30.00:00:00 –MaxLogFileSizeMb 10

     

    The LogCleanUpInterval property can be set to any value between 1 day and 60 days, inclusive. Be sure and take note of the format that you have to use when configuring this property:

     

    –LogCleanUpInterval 30.00:00:00

     

    The value 30.00:00:00:00 means 30 days, 00 hours, 00 minutes, and 00 seconds. If you wanted to set an oddball time interval (like 30 days, 7 hours, 11 minutes, and 44 seconds) you can do so using a value like this:

     

    –LogCleanUpInterval 30.07:11:44

     

    Why would you want to do that? We have no idea. But it's entirely up to you.

     

    As for the maximum file size, that can be set to pretty much any integer value, anything from 0 to 999999999 megabytes. (The default value is 3.) You can even use a decimal value when setting the maximum file size:

     

    –MaxLogFileSizeMb 10.4

     

    If you do that, however, Lync Server will simply round the value off to the nearest whole number. Thus a value of 10.4 will be rounded down to 10.

     

    Last, but surely not least, the MaxTokenLifetime parameter (which uses the same data format as LogCleanUpInterval) can be set to any value between 1 hour and 24 hours, inclusive. Want a token to last for 12 hours? No problem:

     

    Set-CsBandwidthPolicyServiceConfiguration –Identity global –MaxTokenLifetime 0.12:00:00

     

    Etc., etc.

     

    And what about the other CsBandwidthPolicyServiceConfiguration cmdlets? Well, Get-CsBandwidthPolicyServiceConfiguration lets you retrieve information about your current bandwidth policy service settings. For example:

     

    Get-CsBandwidthPolicyServiceConfiguration

     

    Not fancy enough for you? OK, well how about this command, which returns any bandwidth policy service settings where the token lifetime is greater than the default value of 8 hours:

     

    Get-CsBandwidthPolicyServiceConfiguration | Where-Object {$_.MaxTokenLifetime –gt "08:00:00"}

     

    We thought you might like that one better. Meanwhile, the New-CsBandwidthPolicyServiceConfiguration cmdlet lets you create custom bandwidth policy service settings (at the site scope only), while the Remove-CsBandwidthPolicyServiceConfiguration cmdlet lets you go back later on and remove those settings. Want to get rid of all the bandwidth policy service settings configured at the site scope? Sure; why not:

     

    Get-CsBandwidthPolicyServiceConfiguration –Filter "site:*" | Remove-CsBandwidthPolicyServiceConfiguration

     

    Best of all, when you run the CsBandwidthPolicyServiceConfiguration cmdlets the brakes won't squeak, the chain won't fall off, and the derailleur won't start dragging on the ground.

     

    Which, at the moment anyway, makes the CsBandwidthPolicyServiceConfiguration cmdlets a much better deal than a mountain bike.

     

    Something to keep in mind if you've been thinking about going out and spending several hundred dollars on a new bike.

     

     

     

  • Haiku #139

    Is there a problem?

    Then maybe diagnostic

    Headers should be on.

     

    Hey, everyone. Today marks the 139th in our series of daily Lync Server PowerShell haikus and in honor of the occasion (and because we couldn't think of anything else to write about) we decided to look up some interesting facts about the number 139. Here's what we found:

     

    ·         139 is the natural number following 138 and preceding 140.

     

    OK, well, that's kind of interesting, though not totally unexpected. Let's see what else we can dig up:

     

    ·         One hundred [and] thirty-nine is the 34th prime number, so it is divisible only by itself and 1. It is a twin prime with 137. Because 141 is a semiprime, 139 is a Chen prime. 139 is the smallest prime before a prime gap of length 10

     

    Hmmm …. Well, obviously we knew that 139 was a Chen prime (duh!), but we weren't aware that 141 was a semiprime. So that's pretty cool, right? Oh, and how about this:

     

    ·         [139] is the smallest factor of 64079, the smallest composite Lucas number with a prime index. It is also the smallest factor of the first nine terms of the Euclid–Mullin sequence, making it the tenth term.

     

    We have to admit that we were a little skeptical about that: since when is 64079 a Lucas number in the first place? But it turns out that 64709 is a Lucas number:

     

    2, 1, 3, 4, 7, 11, 18, 29, 47, 76, 123, 199, 322, 521, 843, 1364, 2207, 3571, 5778, 9349, 15127, 24476, 39603, 64079, 103682, 167761, 271443, 439204, 710647, 1149851, 1860498, 3010349, 4870847, 7881196, 12752043, 20633239, 33385282

     

    We stand corrected.

     

    Other than that, well, 139 happens to be the atomic number of Untriennium, something that would be totally fascinating if Untriennium actually existed. (It remains a hypothetical and as-yet undiscovered element. Much like the author's bank account balance.)

     

    Oh, and speaking of hypothetical elements, in researching this column, the author of today's haiku stumbled upon a Web site where you can ask homework questions like this one:

     

    "Consider the hypothetical elements X and Y. Suppose the enthalpy of formation for the compound XY is 336 kJ/mol, the bond energy for X2 is 414 kJ/mol, and the bond energy for Y2 is 159 kJ/mol. Estimate the XY bond energy in units of kJ/mol."

     

    OK, yes, that question is way too easy, but you get the idea. At any rate, the point is that you post the question and then indicate how much you're willing to pay for the answer (a minimum of $5). Experts (or at least so-called experts) in the field will read your question and, if you're willing to pay enough, will answer it for you.

     

    Interesting, huh?

     

    Note. On a totally unrelated topic, if anyone out there has any questions on Lync Server PowerShell, well ….

     

    At any rate, we could go on and on and on about the number 139, except for one thing: we're more bored with this than you are. Therefore, let's switch gears and talk about something truly exciting: the CsDiagnosticHeaderConfiguration cmdlets!

     

     

    So what's so interesting about the CsDiagnosticHeaderConfiguration cmdlets? Well, for one thing Remove-CsDiagnosticHeaderConfiguration has 38 characters in its name, which is sort of, kind of, vaguely related to that whole 139 thing we tried to use earlier. Perhaps slightly more important than that (hey, we said perhaps) is this: Lync Server can be configured so that each SIP message sent in your organization includes an ms-diagnostic header. This header contains information that might be useful in troubleshooting connection issues or in reporting errors. For example, the diagnostic header might contain error codes that enable the client application to take a predetermined course of action should a problem arise.

     

    Useful, right? Yes. On the other hand, diagnostic headers do contain some information (such as the FQDNs of all your SIP servers) that maybe you would just as soon people in the outside world don't have access to. For example, a diagnostic header might look something like this (emphasis added):

     

    Warning: 309 lcs.microsoft.com "Message contents not allowed by policy"

    ms-diagnostics: 16002;reason="Message contents not allowed by policy";source="atl-cs-001.litwareinc.com";appName="IIMFilter" Server: IIMFilter/4.0.0.0

     

    This is where the CsDiagnosticHeaderConfiguration cmdlets prove to be useful. With these cmdlets, you can decide whether or not you want these diagnostic headers included on messages sent to the following users:

     

    Users on external networks. If you'd rather not have users outside your firewall have access to these diagnostic headers, then leave the SendToExternalNetworks property set to its default value of False. If you're OK with sending these headers to people outside the firewall then set SendToExternalNetworks to True. For example:

     

    Set-CsDiagnosticHeaderConfiguration –Identity global –SendToExternalNetworks $True

     

    Unauthenticated users. By default, diagnostic headers are not sent to users unless those users have logged on to, and been unauthenticated by, Lync Server.  You say you'd prefer that these users get diagnostic headers? No problem; just set the SendToOutsideUnauthenticatedUsers property to True:

     

    Set-CsDiagnosticHeaderConfiguration –Identity global –SendToOutsideUnauthenticatedUsers $True

     

    If you're wondering what else you can do with the CsDiagnosticHeaderConfiguration cmdlets, well, that's really about it: there are only two properties to manage. As you might expect, you can use the New-CsDiagnosticHeaderConfiguration cmdlet to create new diagnostic header settings at the site or the service scope (Edge Servers or Registrars only). Remove-CsDiagnosticHeaderConfiguration provides a way to remove any such settings you create at the site or the service scope, and Get-CsDiagnosticHeaderConfiguration lets you return information about your diagnostic header settings. For example, do you have any settings that allow you to send headers to external users? This command will tell you:

     

    Get-CsDiagnosticHeaderConfiguration | Where-Object {$_.SendToExternalNetworks -eq $True}

     

    What about sending headers to unauthenticated users? That's an easy one; that's what this command is for:

     

    Get-CsDiagnosticHeaderConfiguration | Where-Object {$_.SendToOutsideUnauthenticatedUsers -eq $True}

     

    And, of course, the pièce de résistance: a command that lets you know if you have settings that allow you to send headers to external users or unauthenticated users (or both). You know, a command like this one:

     

    Get-CsDiagnosticHeaderConfiguration | Where-Object {$_.SendToExternalNetworks -eq $True -or $_.SendToOutsideUnauthenticatedUsers -eq $True}

     

    Granted, some people won't find that half as exciting as the fact that 139 Juewa is a large and dark Main belt asteroid discovered in 1874. But we think it's pretty cool.

     

    That's all for today. See you on Monday, when we explore number 140, an "… abundant number and a harmonic divisor number. It is the sum of the squares of the first seven integers, which makes it a square pyramidal number, and in base 10 it is divisible by the sum of its digits, which makes it a Harshad number."

     

    OK, good point. In that case, we'll see most of you on Tuesday.

     

     

     

     

     

     

  • Haiku #138

    Hello? Are you there?

    I guess you must have changed your

    Presence policy.

     

    Hey, everyone. Well, the Summer Solstice has come and gone, we're now well into summer itself, and right now the temperature in Redmond is 52 degrees Fahrenheit, and raining. How does that compare with the rest of the world? Well, in Fairbanks, Alaska it's currently 54 degrees (and not raining). In cold, damp London, England it's 63 degrees (and not raining), even though it's evening time in London. Fargo, North Dakota? 63 degrees and sunny.

     

    Depressing? Of course. After all, those of you in Base Arturo Prat, Antarctica have to deal with 6 degrees and snow. And in Nome, AK it's only 42 degrees and cloudy. So, all in all, those of us here in Redmond consider ourselves pretty lucky.

     

    Even if it is 59 degrees in Minneapolis-St. Paul. And 53 degrees in both Hammerfest, Norway and Reykjavik, Iceland.

     

    But you know what they say. No, we mean besides "The weather in Seattle really sucks." They say, "It's always a good day as long as you have Lync Server PowerShell cmdlets to play with." Which means it's going to be a really good day here, because we have plenty of Lync Server PowerShell cmdlets to play with.

     

    Note. Who said "It's always a good day as long as you have Lync Server PowerShell cmdlets to play with"? To be honest, we don't recall right offhand. But we think it might have been Winston Churchill.

     

    As noted, today promises to be an especially good day, partly because we have an all-hands meeting in less than two hours (hurray!) but also because today we're going to talk about the CsPresencePolicy cmdlets: Get-CsPresencePolicy, Grant-CsPresencePolicy, New-CsPresencePolicy, Remove-CsPresencePolicy, and Set-CsPresencePolicy.

     

    If you're thinking to yourself, "What the heck is a presence policy?" well, don't feel bad: we're not totally convinced that anyone really knows what a presence policy is. Presence policies are used to manage two properties (that's right, just two):

     

    MaxPromptedSubscriber. This is kind of an oddball one, but it works like this. By default, any time you are added to another user’s Contacts list a notification dialog appears on screen informing you of that you've been added to the list, and giving you the chance to, say, add the person to your own Contacts list, or maybe block that person from viewing your presence. Until you take action and dismiss the dialog box, each notification counts as a prompted subscriber. By default, Lync Server only allows you to have 200 of these undismissed dialog boxes at a time.

     

    So would anyone ever have 200 undismissed dialog boxes at a time? Beats us. But that's the default value. If that seems too high (or too low) you can use the Set-CsPresencePolicy cmdlet to change the value (any integer value between 0 and 600, inclusive):

     

    Set-CsPresencePolicy –Identity global –MaxPromptedSubscriber 500

     

    So what happens if you exceed the number of allowed dialog boxes? Nothing really. You'll still get added to the other person's Contact list; you just won't see a notification that you've been added to the Contact list. If you set MaxPromptedSubscribers to 0 then you'll never see a notification when you're added to someone's Contact list.

     

    MaxCategorySubscription. OK, this one's a little trickier, and probably a little more meaningful. When you add someone to your Contact list, you actually create a number of subscriptions that request presence information for that person: in particular, you ask to receive information for the other person's contact card, calendar data, notes, services, and current status.

     

    Got that? In other words, for each person on your Contact list, you create 5 category subscriptions.

     

    So what does the MaxCategorySubscription property (which has a default value of 1000) do? It determines the maximum number of subscriptions that can be made to any one user account. Take Ken Myer, for example. Using the default value of 1000 subscriptions, that means that 200 people can receive presence information for Ken (1000 subscriptions divided by 5 subscriptions per Contact list equals 200). Does that mean that only 200 people can have Ken on their Contact list? No, a million people can have Ken on their Contact list if they want. But suppose 200 people have Ken on their Contact list, which means his category subscriptions are maxed out. What happens if Pilar Ackerman tries to become the 201st person to add Ken to her Contact list?

     

    Two things happen. First, Ken will be added to Pilar's Contact list; there's no problem there. However, Pilar will not receive presence information for Ken; instead, she'll simply see a message stating the presence data is not available because Ken has reached his maximum number of followers. Ken will still be a valid contact; Pilar just won't know whether his status is Available, Away, or Do Not Disturb.

     

    Now here's the tricky part. Suppose someone other than Pilar, someone who also has Ken on their Contact list, logs off of Microsoft Lync. Well guess what? That means that only 199 people are currently subscribed to Ken's account. In turn, that means that Pilar will now start receiving Ken's presence information: she's now number 200 on the list rather than number 201. Remember that guy who logged off of Lync? Well, if he logs back on, now he won't see Ken's presence information. Why not? Because there are already 200 subscribers ahead of him. It's first-come, first-served.

     

    And yes, we know. But if you think about it for a bit, it will start to make sense. For example, suppose you want to use instant messaging but you don't want people exchanging presence information. That's fine; just set MaxCategorySubscription to 0:

     

    Set-CsPresencePolicy –Identity global –MaxCatgeorySubcription 0

     

    With that command you can still add people to your Contact list, but you won't be able to view their presence information.

     

    Of course, maybe there are just certain people – for example, your executives – who don't want their presence information shared with the world. That's fine: that's why presence information is wrapped up in a policy instead of configuration settings. If Ken Myer is your CEO and he doesn't want his presence information shared with anyone all you have to do is create a new presence policy and set the MaxCategorySubscription property to 0:

     

    New-CsPresencePolicy –Identity "ExecutivePresencePolicy" –MaxCatgeorySubcription 0

    And then simply use the Grant-CsPresencePolicy cmdlet to assign that policy to the appropriate users:

     

    Grant-CsPresencePolicy –Identity "Ken Myer" –PolicyName "ExecutivePresencePolicy"

     

    That's all you have to do.

     

    And that's all we have to do, too, at least for now. (But don't worry: we'll be back tomorrow.) In the meantime, the temperature here in Redmond has risen all the way to – uh, 52 degrees. But hey, it's only 48 degrees in Angmagssalik, Greenland. Bet you Greenlanders really wished you lived here, don't you?

     

     

     

     

     

  • Haiku #137

    I sense a very

    Real connection between us.

    CS Management.

     

    Yesterday the author of today's haiku was the lone member of the user assistance (UA) team to sit in on a meeting. As such, he was almost immediately peppered with questions about documentation:

     

    "Do you know who's going to be working on the documentation for this?"

     

    "No."

     

    "Do you know if you guys have started planning the documentation set for this?"

     

    "No."

     

    "Do you know when your team expects to have the documentation done?"

     

    "No."

     

    "Do you know who holds the Major League record for most runs scored in a career?"

     

    "Yes. Rickey Henderson."

     

    OK, no one actually asked that last question, which is too bad: after all, Rickey Henderson does hold the Major League record for most runs scored in a career. But no one ever asks the author of today's haiku about important things, like baseball or college basketball. Instead, they always ask him things about work priorities and deadlines. Work priorities and deadlines? Why would you ever ask someone who writes haikus about Lync Server PowerShell questions about work priorities and deadlines?!?

     

    Note. True story: several years ago the author of today's haiku was sitting in a meeting with someone who had lived in Seattle all her life. Somehow or another, Ken Griffey, Jr.'s name was mentioned, and this woman asked, "Who's that?" Despite living in Seattle her entire life, she had never even heard of Ken Griffey, Jr. That's life at Microsoft.

     

    But wait, there's more. In reply to her question, someone said, "He's the Willie Mays of our generation." And she said, "Who's Willie Mays?"

     

    At any rate, if you want to know who holds the Major League record for most doubles in a season (Earl Webb), ask the author of today's haiku. But that's pretty much the extent of his knowledge. If you want to know something besides the name of the player who holds the Major League record for most doubles in a season, well, you'll have to ask someone else.

     

    No, wait! As it turns out, the author of today's haiku does know one other thing: he knows what the CsManagementConnection cmdlets (Get-CsManagementConnection, Remove-CsManagementConnection, and Set-CsManagementConnection) are used for.

     

    So what are the CsManagementConnection cmdlets used for? We were afraid someone was going to ask that. Well, as you probably know, most of the configuration information used by Lync Server 2010 is stored in a SQL database known as the Central Management Store. Where exactly is that SQL database? To tell you the truth, we have no idea. But the Get-CsManagementConnection cmdlet will typically tell you:

     

    Get-CsManagementConnection

     

    Run that command, and you will typically get back something similar to this:

     

    StoreProvider : Sql

    Connection    : DataSource=atl-sql-001.litwareinc.com\rtc;InitialCatalog=xds;IntegratedSecurity=True

    ReadOnly      : False

     

    So why do we keep saying that things "typically" work like this? Well, typically, you configure your SQL Server database (and, by extension, your management connection) when you install Lync Server and, from that point on, you never have to worry about either the database or your management connection. However, suppose that something does go wrong?

     

    Note. Yes, we know: nothing could ever go wrong with Lync Server. But just pretend, OK?

     

    For example, suppose your database has crashed, and you need to point your management connection to a backup database. How do you do that? One way is to use the Set-CsManagementConnection cmdlet:

     

    Set-CsManagementConnection -StoreProvider Sql -Connection "atl-sql-001.litwareinc.com\rtcbackup"

     

    As you can see, that's not too terribly hard: you simply set the StoreProvider parameter to Sql and set the Connection parameter to the path to the backup database. Will you ever have to do that? Probably not. But it doesn't hurt to know that you can do that, if need be.

     

    Here's something else that you'll probably never need to do, but can: you can actually set your management connection to the local file store. In that case, you'll do all your work locally and will not be connected to the Central Management Store:

     

    Set-CsManagementConnection -StoreProvider FileSystem -Connection "C:\Test"

     

    So why would you ever want to do that? Well, two reasons. One, it gives you a test environment where you can play around with doing things like creating and deleting policies, all without ever affecting the real Central Management Store. For example, if you create a new voice policy, that policy won't get stuffed into the Central Management Store where another administrator could inadvertently start assigning the policy to actual users. Instead, it just becomes an XML file on your local hard disk. A good, risk-free way to play around with Lync Server PowerShell.

     

    Another possibility is this: you need to create a bunch of new policies and stuff, but your network is having problems and you can't connect to the Central Management Store. Well, if you wanted to, you could switch your management connection to the file system, create your policies, export them to a slightly-different XML format, and then later (after the connection has been restored) import them to the Central Management Store.

     

    OK, good question: what does that mean? Well, it means that you could do something like this:

     

    $x = New-CsExternalAccessPolicy –Identity "TestExternalAccessPolicy"

    Export-Clixml –Path C:\Test\TestExternalPolicy.xml –InputObject $x

     

    All we've done here is create a new external access policy and stored it in a variable named $x; we then use the Export-Clixml cmdlet to save that policy to an XML file named C:\Test\TestExternalPolicy.xml.

     

    What's the point of that? Well, let's suppose the network is back up and running, and we've switched our management connection back to the Central Management Store. Is there an easy way to get this new external access policy into the Central Management Store? Of course there is:

     

    $x = Import-Clixml –Path C:\Test\TestExternalPolicy.xml

    Set-CsExternalAccessPolicy –Instance $x

     

    As you can see, we've imported the policy, stored it in a variable named $x, then used the Set-CsExternalAccessPolicy cmdlet to save that policy to the Central Management Store. Again, this might not be something you'll ever find yourself doing, but, hey, stranger things have happened, right?

     

    Note. No, we can't think of any either, at least not off the tops of our heads. Still ….

     

    By the way, how do you switch back to using the Central Management Store as your management connection? By running this command:

     

    Remove-CsManagementConnection

     

    Yes, that looks dangerous, doesn't it? But it's not. If you don't specifically define a management connection then Lync Server PowerShell automatically looks in Active Directory to see if it can find a service control point that reports the path to the Central Management database. Assuming that this service control point can be found, then your management connection will automatically point towards that database.

     

    Two quick notes about this. First, you can only change the management connection for your local computer; you cannot remotely connect to another machine and change its management connection.

     

    Note. Yes, that would be a hilarious practical joke, wouldn’t it? But it can't be done.

     

    Second, any change you make to your management connection lasts only as long as your current instance of Windows PowerShell. Suppose you switch your management connection to the file system and then exit the Lync Server Management Shell. The next time you start the Management Shell, your management connection will once again point to the Central Management Store. (Why? Because the Management Shell retrieves the service control point from Active Directory each time it starts up.)

     

    And there you have it: now you know all about the CsManagementConnection cmdlets. Oh, and you also now know that Ty Cobb holds the Major League record for most triples hit in a career. Is there anything else that you need to know? Not that we can think of.

     

    See you tomorrow.

     

     

  • Haiku #136

    Daylight beckons but

    The windows just won't open.

    Audio testing.

     

    Happy Summer Solstice everyone! Yes, today is June 21st, which means it's once again the Summer Solstice, the longest day of the year.

     

    Note. Slight clarification: we should say that today is the day that has the most daylight hours. The longest day of the year is more typically the day in which those of us here at Microsoft are required to attend an "all-hands" meeting.

     

    At any rate, as the day with the most daylight of any day of the year, the author of today's haiku is spending his Summer Solstice sitting in his office (the one with the windows that are designed not to open) writing today's Lync Server PowerShell haiku. That, by the way, is exactly how the ancient Druids used to spend their Summer Solstice.

     

    Note. Which explains why there aren't very many ancient Druids still around. "We're going to spend our Summer Solstice doing what?!? I'm starting to have second thoughts about this whole Druid thing …."

     

    In case you're wondering, the reason we have a Summer Solstice in the first place (that is, the reason that days vary in their amount of daylight hours) has to do with the fact that the Earth is tilted somewhat in relation to the sun. (Many of the people on the Earth are also tilted, although that's a different story.) This tilting is known as the "obliquity of the ecliptic." When the author of today's haiku was a freshman in college (back in the days when people still believed that the sun revolved around the Earth) he took an astronomy class. At one point in that class the professor said that, "Guys, if you want to be irresistible to women, just remember this: the obliquity of the ecliptic in 23-and-one-half degrees." Ever since then, the author of today's haiku has remembered that the obliquity of the ecliptic in 23-and-one-half degrees. Has that made his irresistible to women? Well, actually he – say, aren't we supposed to be talking about Lync Server PowerShell here?

     

    In honor of the Summer Solstice (Latin for "sun standing still"), we thought we'd talk about the CsAudioTestServiceApplication cmdlets: Get-CsAudioTestServiceApplication and Set-CsAudioTestServiceApplication. As it turns out, these were the two cmdlets most often used by the ancient Druids. Why? Well, the ancient Druids liked the fact that Microsoft Lync 2010 gave them an option to test their network connections before they actually tried to make a phone call. How did they do that? That's easy: from the Microsoft Lync Contact window they opened the Options dialog box, clicked the Audio Device tab, and then clicked Check Call Quality. A call would then be placed to an "audio bot" which would answer the phone and ask the Druid to record a short message. That message would then be played back, and the Druid could decide for himself (or herself) if call quality was up-to-snuff.

     

    Of course, if you start up Microsoft Lync and click the Audio Device tab, you might not see the Check Call Quality button. Is this yet another example of advanced technology (such as time barrier gates) that were possessed by the Druids but have been lost to the ages? No. Instead, you'll only have the Check Call Quality button, and the ability to make a test call, if you install the Audio Test Service, something you can do by running Ats.msi, a file found in the Lync Server setup folder.

     

    Note. Not sure if you've installed the Audio Test Service or not? Then just run this command:

     

    Get-CsWindowsService –Name RTCATS

     

    If nothing comes back (well, nothing other than an error message), that means that service has not been installed.

     

    When you run Ats.msi, you'll not only get a new service, but you'll also get a new contact object representing your audio bot. This, in turn, is where the CsAudioTestServiceApplication cmdlets come into play.

     

    Before we go any further, we should note that installing the Audio Test Service is the only way to get one of these audio bots (and, by extension, one of these contact objects); there is no New-CsAudioTestServiceApplication cmdlet.

     

    Note. Did the ancient Druids have a New-CsAudioTestServiceApplication cmdlet? Well, needless to say, that's a very controversial subject, and we'd just as soon not get everyone riled up about that.

     

    However, there is a Get-CsAudioTestServiceApplication cmdlet, which enables you to retrieve information about your audio test contact objects. Need to see detailed information about each one of these objects? Then just run this command:

     

    Get-CsAudioTestServiceApplication

     

    If you'd rather see information just for a specific contact object then use a command like this one, which includes the Identity parameter and the contact object's SIP address:

     

    Get-CsAudioTestServiceApplication -Identity "sip:RedmondAudioTest@litwareinc.com"

     

    And here's an exciting one. This command returns all the contact objects that use US English (en-US) as their primary language:

     

    Get-CsAudioTestServiceApplication | Where-Object {$_.PrimaryLanguage –eq "en-US"}

     

    Man, those ancient Druids really knew how to live, didn't they?

     

    Meanwhile, the Set-CsAudioTestServiceApplication provides a way for you to modify the properties of a contact object. For example, this command changes the primary language for a contact object to French:

     

    Set-CsAudioTestServiceApplication -Identity "sip:RedmondAudioTest@litwareinc.com" –PrimaryLanguage "fr-FR"

     

    And this one changes the contact object's SIP address:

    Set-CsAudioTestServiceApplication -Identity "sip:RedmondAudioTest@litwareinc.com" –SipAddress "sip:USAudioTest@litwareinc.com"

     

    And so on and so on.

     

    By the way, contact objects are a little unusual in that they include a number of properties that are real, live properties, but don't actually mean anything. For example, you can set these property values if you want, but they won't actually do anything:

     

    ·         DisplayNumber

    ·         LineUri

    ·         SecondaryLanguages

     

    These properties exist only because they are properties of the underlying Active Directory object that the audio bot contact objects are derived from. But they make absolutely no difference: you can assign 10 million different secondary languages to an audio bot, but that bot will never use any of those secondary languages.

     

    Ever.

     

    Note. Were the audio bots used by the ancient Druids capable of using secondary languages? Yes. But don’t tell anyone we said that, OK?

     

    That's about it for the CsAudioTestServiceApplication cmdlets. As for the Summer Solstice, here's an interesting piece of trivia for you. The Druids referred to the first full moon in the month of June as the "Honey Moon," and believed that this represented the best time of the year to gather honey. In turn, this honey was fed to newly-wed couples as a way to encourage love and fertility. And that is where the notion of a "honeymoon" came from.

     

    Well, we thought it was interesting. Or at least one of us did.

     

     

     

     

  • Haiku #135

    Basketball, noodles,

    And conference directories:

    Happy Father's Day!

     

    We know that everyone out there is just dying to hear how the author of today's haiku spent his Father's Day yesterday, so here goes. Father's Day morning was very exciting: the author of today's haiku went out to the Black Lagoon (the corner of the yard that gets no sunshine but, being the first flat spot in the neighborhood, does get all the runoff from all the other yards on the street) and pulled weeds.

     

    A whole bunch of weeds.

     

    Note. Shouldn't the author have spent the morning with his son, seeing as how it was Father's Day? Let's put it this way: his son is a college student home for the summer. He has no idea that the month of June even has mornings.

     

    In the afternoon, father and son went to the gym to play basketball. Dad won several games of H-O-R-S-E, relying on his ability to score from behind the basket and to – twice – make a shot from three-quarters court. He also relied on his ability to make the humble free throw: on two different occasions he clinched a game when his son was unable to make even 1 of 2 free throws. Interestingly enough, in the one game of H-O-R-S-E that his son did win, the son got the winning basket by bouncing the ball from the free throw line. Dad suggested that, from now on, maybe his son shoot all his free throws by bouncing the ball, and – for once – his son actually agreed with him.

     

    Note. Sadly, we must also report that neither player could make a full-court shot, although both managed to hit the rim on a couple of tries. Also, neither player was able to make a three-point shot with his back to the basket; a three-point shot while sitting cross-legged on the court; or a three-point shot by whipping the ball around his back.

     

    Oh: and neither one could make a basket by throwing the ball off a concrete wall and having it carom back into the hoop. All in all, a pretty tough day.

     

    After playing H-O-R-S-E for a while, the two then played a game of one-on-one. Who came out ahead in that battle? Who knows? After all, it was just a friendly game of one-on-one between a father and his son.

     

    Note. Actually, there is no such thing as a friendly game of one-on-one between a father and his son. Which means that the son might have been the winner after all.

     

    But that's only because he's not old, slow, and fat, like some of the other players in the game might have been.

     

    Like we said, might have been.

     

    And then, that evening, the author's wife made dinner: spaghetti with homemade noodles. How did that go? Let's put it this way: about as well as the game of one-on-one went.

     

    But the food at the restaurant was top-notch.

     

    Note. For some bizarre reason which no one could figure out, the dough for the noodles came out as a big, giant, inert blob. Which bore a remarkable resemblance to what the author of today's haiku must have looked like as his son repeatedly zipped past him on the way to an easy lay-in.

     

     

    Finally, we capped the day off the way all families cap off their Father's Day festivities: by running the Import-CsLegacyConferenceDirectory cmdlet.

     

    Actually, we should clarify that a little: we should probably say that running the Import-CsLegacyConferenceDirectory cmdlet is the way most families cap off their Father's Day festivities. We say that simply because this cmdlet is only used by families (or organizations) that are simultaneously running both Microsoft Lync Server 2010 and Office Communications Server 2007 R2. If you've already migrated the whole family to Lync Server, then there's no need to run Import-CsLegacyConferenceDirectory.

     

    Why not? That's an easy one: because Import-CsLegacyConferenceDirectory is used to keep your Lync Server conference directories in synch with your Office Communications Server conference directories.

     

    Note. You say that you know what a conference directory is, but your … son … doesn't know what a conference directory is? Then you – uh, then your son should take a look at haiku #103.

     

    To be a little more specific, Import-CsLegacyConferenceDirectory uses WMI (remember WMI?) to read legacy data from Office Communications Server 2007 R2, then uses that data to create corresponding objects in Lync Server: in other words, for each conferencing directory found in your installation of Office Communications Server 2007 R2, a corresponding directory will be created in your new installation of Lync Server. It's just like human cloning, other than the fact that it's not the least bit like human cloning.

     

    It's recommended that you run Import-CsLegacyConferenceDirectory anytime conference directories are added, deleted, or moved in Office Communications Server 2007 R2. The cmdlet should also be run anytime Merge-CsLegacyTopology is run; this helps to ensure that the conference directories and the topology remain in sync.

     

    And how exactly do you run the Import-CsLegacyConferenceDirectory cmdlet? Like this:

     

    Import-CsLegacyConferenceDirectory

     

    If you're wondering where all the other parameters are, well, there really aren't any other parameters: all you need to do is call the cmdlet and let Import-CsLegacyConferenceDirectory take it from there. But what if you're dead set on using additional parameters? Well, in that case, we suppose you could tack on the Report parameter, which lets you specify the file path for the report that gets generated when you run Import-CsLegacyConferenceDirectory:

     

    Import-CsLegacyConferenceDirectory –Report "C:\Logs\ImportDirectories.html"

     

    But that's up to you, and definitely isn't something you have to do.

     

    Speaking of which, we should also note that there is one thing that you do have to do. Before you can run Import-CsLegacyConferenceDirectory, you must first install the Windows Management Instrumentation (WMI) Backward Compatibility interfaces package; this application is installed by running OCSWMIBC.msi. (Where do you get that file from? From the Lync Server Setup folder.) After installing the Compatibility interfaces package, you should next run Merge-CsLegacyTopology. And then, at long last, you and your son can run Import-CsLegacyConferenceDirectory.

     

    Note. Can you and your daughter run Import-CsLegacyConferenceDirectory as well? Well, not having a daughter himself, the author of today's haiku can't say this with 100 percent certainty. But we don't see why not, and we definitely believe that girls should have the same chance as boys do to experience the sheer joy of running Import-CsLegacyConferenceDirectory.

     

    And there you have it: the story of Import-CsLegacyConferenceDirectory, and the story of how the author of today's haiku spent his Father's Day. But don't worry, even though Father's Day is over, the author's son won't forget his dear old Dad.

     

    Or at least he won't forget his dear old Dad's wallet.

     

    See you tomorrow.

     

     

     

     

     

     

  • Haiku #134

    Together at last:

    Microsoft and Google, and

    Network region links.

     

    Remember that big thing about Microsoft buying Skype? Well, you can forget that. Here's something even bigger: Microsoft has bought Google!

     

    Or maybe Google has bought Microsoft; to be honest, the details are a little hazy. All the author of today's haiku knows at the moment is that he has won 950,000 British pounds in the Microsoft and Google Anniversary Contest. As his award notification points out:

     

    "Microsoft and Google is now the biggest search engine worldwide and in an effort to make sure that it remains the most widely used search engine, we ran an online e-mail beta test which your email address won 950,000,00. GBP {Nine Hundred And Fifty Thousand Great British Pounds}"

     

    Pretty cool, huh? At the current exchange rate, 950,000 pounds equates to a little over $1.5 million; for the author of today's haiku, that's like two years' pay! And that's just for the beta test of the contest. Imagine how much he could have won if he'd won the real contest!

     

    Of course, you might be thinking, "Well, that all sounds nice, but there's no way that the author of today's haiku could meet the requirements for winning the contest." Au contraire, naysayers: not only did the author of today's haiku meet the requirements for winning the contest, but he also passed the "… statutory obligations, verifications, validations and satisfactory report Test conducted for all online winners." So there!

     

    At any rate, the author of today's haiku has often wondered what it would be like if Microsoft and Google combined forces to produce a single search engine, and now he knows: he'd end up with $1.5 million.

     

    Which is just exactly what he deserves.

     

    What do you mean, "I bet this is some kind of a scam." How could it be a scam? After all, the prize notification included both a file reference and a batch number:

     

    FILE REF: HL/5564/08/09/MICS
    BATCH: MC11/834/5PDH /EU

     

    And here's an interesting piece of trivia: the file reference and batch number are exactly the same as the file reference and batch number of someone who won a completely different contest! What do you suppose the odds are of that?!?

     

    Note. The author of today's haiku is actually glad that he didn't win that other contest. In that contest, second prize was worth 950,000 pounds, but first prize was worth only 15,000 pounds. Whoever said that "winning is everything" obviously never took part in an online sweepstakes.

     

    At any rate, while we wait for the " … Courier Delivery Of your Certified Winning Cheque Name" (and yes, that is a little disconcerting: we'd prefer to get the actual check rather than just the name of that check) we thought we'd talk about the CsNetworkRegionLink cmdlets. (That's right, the Microsoft Google Anniversary Contest and the CsNetworkRegionLink cmdlets, all in one day!) For those of you who like to keep track of this sort of thing, there are four CsNetworkRegionLink cmdlets:

     

    ·         Get-CsNetworkRegionLink

    ·         New-CsNetworkRegionLink

    ·         Remove-CsNetworkRegionLink

    ·         Set-CsNetworkRegionLink

     

    And why do we even need any network region link cmdlets? We're glad you asked that question. Network region links are used as part of Call Admission Control, the technology introduced in Microsoft Lync Server 2010 that enables administrators to manage bandwidth use between two network regions.

     

    Note. What? You say you don't know what a network region is? Please don't tell us you've already forgotten about haiku #123?

     

    Let's assume that you have two network regions – Northwest and Europe – and that the network connection between the two regions is a little shaky at times; because of that, you've created a bandwidth policy that places a limit on the amount of audio/video traffic that can travel between the two regions at any given time. That's good: we now have two regions, and we have a policy that limits audio/video traffic. That leaves us with just one problem: how do we apply that policy to traffic that travels between the Northwest region and the Europe region?

     

    How do we do that? Hey, what do we care? After all, we just won $1.5 million; you can figure this one out yourselves.

     

    No, hey, just kidding. The answer, of course, is that we create a network region link between the two regions, and then assign the bandwidth policy to that link. Why wouldn't we assign the policy to the two regions instead? Well, remember, there isn't anything wrong with either the Northwest region or the Europe region; we just have problems with the connection between the two. By creating a link and then assigning the policy to the link, we're able to place some limits on that one connection. Suppose we have an Asia region as well, but our connectivity between Europe and Asia and between Northwest and Asia is perfectly fine. That's great: in that case, we don't place any restrictions on those links. See how that works?

     

    At any rate, the New-CsNetworkRegionLink cmdlet makes it pretty easy to create a network region link:

     

    New-CsNetworkRegionLink -Identity NorthwestToEurope -NetworkRegionID1 Northwest -NetworkRegionID2 Europe -BWPolicyProfileID RestrictedAudioVideoTraffic

     

    We told you it was easy, didn't we? Basically all we need to do is give the link itself an Identity (NorthwestToEurope) and then specify the two regions using the parameters NetworkRegionID1 and NetworkRegionID2. (Does it make any difference which region gets tabbed as region 1 and which one gets tabbed as region 2? Nope.) We then assign a bandwidth policy using the BWPolicyProfileID parameter. What if you don't know the Identities of your bandwidth policies? That's OK; just run this command:

     

    Get-CsNetworkBandwidthPolicyProfile

     

    That's really all there is to it. If you need to make a change to this link somewhere along the way (for example, if you want to use a different bandwidth policy) just use the Set-CsNetworkRegionLink cmdlet:

     

    Set-CsNetworkRegionLink -Identity NorthwestToEurope -BWPolicyProfileID LessRestrictedAudioVideoTraffic

     

    As you might expect, Remove-CsNetworkRegionLink deletes the links defined by any two regions (while leaving those regions exactly as-is), and Get-CsNetworkRegionLink returns information about your existing network links. For example, this command returns information about all your links:

     

    Get-CsNetworkRegionLink

     

    And this command returns information about all the links that use the policy RestrictedAudioVideoTraffic:

     

    Get-CsNetworkRegionLink | Where-Object {$_.BWPolicyProfileID –eq "RestrictedAudioVideoTraffic"}

     

    And so on and so on.

     

    Before we go, we should also note that, as much as we'd like to, we cannot share our winning PIN number with you, thus giving you a chance to try and stake a claim to those 950,000 British pounds. As our notification email states:

     

    "The Microsoft and Google Promotion Award Team has reached a decision from headquarters that any double claim discovered by the Lottery Board will result to the canceling of that particular winning, making a loss for both the double claimer and the real winner, as it is taken that the real winner was the informer to the double claimer about the lottery."

     

    Hopefully you'll understand why we can't take any chances here. After all, the email concludes that we must " … keep your winnings strictly confidential until you claim your prize."

     

    Note. What's that? Oh, there's nothing to worry about there. After all, if you want to keep something confidential and make sure that no one ever, ever reads it, well, what better place to publish that thing than a daily haiku about Lync Server PowerShell?

     

    If you know what we mean.

     

     

     

     

  • New Articles: Working with Microsoft Lync Registry Settings

     

    When the registry was first introduced in its current form in the Microsoft Windows 95 operating system, everyone at Microsoft was told “DO NOT tell users to touch anything in the registry. Ever.” We then proceeded to tell people that in some cases the only way to change something was to modify the registry.

     

    Flash forward 16 years to 2011. The message from Microsoft today is “DO NOT tell users to touch anything in the registry. Ever.” Hey, at least we’re consistent.

     

    But, again, there are exceptions. One of those exceptions happens to be if you’re writing Windows PowerShell scripts. In the set of articles Working with Microsoft Lync Registry Settings, we show you how to change Microsoft Lync 2010 settings by using scripts to modify the registry. Keep in mind that you can also modify these settings directly from the client, but if you’d like to use a script instead, this is how you do it.

     

    http://blogs.technet.com/b/csps/archive/2011/06/15/regintroduction.aspx

     

     

  • Haiku #133

    But there is no joy

    In Mudville: where are the A

    V Edge cmdlets?

     

    Last night the author of today's haiku and his son went to watch the Seattle Mariners take on the Los Angeles Angels of Anaheim. (Who still retain their title of "team with the dumbest name in all of sports.") Are we going to report back the highlights of the game? Of course we are:

     

    ·         The woman with the world's smallest head sat in front of the author and his son. Which, if anyone is going to sit in front of you, the woman with the world's smallest head is a good choice.

    OK, fine: her head wasn't that small. It just looked small because she was wearing a sweater with these big, huge shoulder pads.

    ·         The author of today's haiku defeated his son in the game-long "predict what the next hitter will do" contest. (Which is pretty much what the name implies: before the hitter steps into the batter's box you have to predict what he will do during that at-bat; for example, "He will single to left centerfield, and the runner on first will have to stop at second.") Included in the author's uncanny predictions: his spot-on pronouncement that Greg Halman would hit a home run (his first-ever Major League home run) to centerfield.

    ·         The author's son correctly predicted that the green boat would win the hydroplane race, although the ending of the race remains controversial. The red boat, the one picked by the author of today's haiku, had broken free of the pack and was on its way to a sure win when a giant whale lifted the green hydroplane onto its back and carried the green boat to victory. The author of today's haiku protested, but his son retorted that there's nothing in the hydroplane racing rule book that says a giant whale can't pick up your boat and carry it across the finish line. As it turns out, he was right.

    ·         The people in front of the author and his son spent their entire game fiddling with their cell phones; they also ate sushi, teriyaki, crepes, and Caesar salad. The author and his son did not see anyone eat a hot dog.

    ·         The author's son correctly picked Semi-Charmed Life by Third Eye Blind as the song that would be played – in its entirety! – later in the game. The author of today's haiku picked Good Lovin' by the Rascals; big mistake.

    ·         Fortunately, the author of today's haiku redeemed himself by knowing that Deep Purple released the song Smoke on the Water in 1972. Well, OK, he didn't actually know that Deep Purple released the song Smoke on the Water in 1972; he guessed that. But the author and his son are highly competitive, and a win is a win. And at least the author didn't have to rely on a giant whale to tell him when the song was released.

    What's that? Who won the game? Good question. Probably someone did. With so much else going on we didn't have time to actually watch the game, you know.

     

    Note. At one point the author's son, in reference to trivia contests, blooper videos, guess-how-many-times-Felix-Hernandez'-baseball-card-will-appear-on-the-screen competitions, etc., etc., asked, "Can't anyone sit for even 30 seconds without having to be entertained?" The answer, of course, is no, they can't. Which is why you were encouraged to get up and dance, or snap a picture with your cell phone and see if it can be displayed on the jumbo video screen, or guess which hat the ball is under, or ….

     

    As near as the author of today's haiku could tell, about the only thing that they didn't do in between innings or whenever there was a pitching change was talk about the CsAVEdgeConfiguration cmdlets: Get-CsAVEdgeConfiguration, New-CsAVEdgeConfiguration, Remove-CsAVEdgeConfiguration, and Set-CsAVEdgeConfiguration. How could they let us know that Justin Smoak's favorite snack is beef jerky, yet not tell us about the CsAVEdgeConfiguration cmdlets? We have no idea. But we'll take care of that matter right now.

     

    Note. Actually, there's a chance that they did tell everyone about the CsAVEdgeConfiguration. For better or worse, however, the author and his son had seats at the end of the row, which meant they had to stand up 3 or 4 times an inning in order to let people in or out. Among other things, people can no longer sit through an entire half inning of baseball without having to get up and go – well, somewhere.

     

    So what exactly are the CsAVEdgeConfiguration cmdlets? Well, as you probably know, A/V Edge servers enable audio and video traffic to be exchanged across your firewall. In turn, this allows users to access Microsoft Lync Server 2010 from across the Internet, and to exchange audio and video data with users who have logged onto the system from inside the firewall. The AV Edge server configuration settings can be assigned at the global scope, the site scope, and the service scope. (Which service? The Edge Server service, of course.) The A/V Edge configuration settings enable administrators to manage the amount of time that user authentication is valid before it must be renewed, and to limit the amount of bandwidth that can be used by a single user or a single port.

     

    Not quite as exciting as the hydroplane races, but way better than picking the song that will be played – in its entirety! – later in the game.

     

    Because there are so few parameters available for AV Edge servers, using these cmdlets is incredibly easy. For example, suppose you want to limit the global Edge server settings to the following: no more than 5000 kilobits per second of bandwidth allocated to a single port, and no more than 8000 kilobits per second of bandwidth allocated to a single user. How do you do that? Why, like this, of course:

     

    Set-CsAVEdgeConfiguration -Identity global –MaxBandwidthPerPortKb 5000 –MaxBandwidthPerUserKb 8000

     

    That's really all there is to it. If you want to allow an authentication token to be used for 24 hours before it expires then use a command like this:

     

    Set-CsAVEdgeConfiguration -Identity global –MaxTokenLifetime 1.00:00:00

     

    With that syntax, 1.00:00:00 represents 1 day, 00 hours, 00 minutes, and 00 seconds. What if you wanted to limit the token lifetime to 12 hours? Then you'd use syntax like this:

     

    Set-CsAVEdgeConfiguration -Identity global –MaxTokenLifetime 12:00:00

     

    It's that easy.

     

     

    Needless to say, you can use the New-CsAVEdgeConfiguration cmdlet to create new AV Edge settings (at the site or service scope); use Remove-CsAVEdgeConfiguration to remove any existing AV Edge settings; and call Get-CsAVEdgeConfiguration any time you want to review those existing settings. This command returns all your AV Edge settings:

     

    Get-CsAVEdgeConfiguration

     

    Not fancy enough for you? OK, well, this command tells you whether you have any settings where the token lifetime is greater than the default value of 8 hours:

     

    Get-CsAVEdgeConfiguration | Where-Object {$_.MaxTokenLifetime –gt "08:00:00"}

     

    And this one lets you know if any of your settings allow any one user fewer than 10000 kilobits per second of bandwidth (also a default value):

     

    Get-CsAVEdgeConfiguration | Where-Object {$_.MaxBandwidthPerUserKb –lt 10000}

     

    Let's be honest: would your average baseball fan prefer to know how to retrieve information about their AV Edge server configuration settings, or would your average baseball fan prefer to know that Jack Wilson's favorite type of food is Mexican? That's what we thought. But like we said, for some reason the CsAVEdgeConfiguration cmdlets didn't come up during last night's game. No wonder attendance was only 19,321: you have to give the people what they want.

     

    Note. 19,321? To quote the old baseball cliché, apparently a whole bunch of people came disguised as empty seats.

     

    Oh, and in case the suspense is killing you, the Mariners won the game 3-1. The score was tied 0-0 with two outs in the bottom of the 7th when Carlos Peguero hit a ground ball up the middle that looked like it would end the rally. Right before the shortstop could make the play, however, the ball hit second base and ricocheted into the outfield and two runs scored.

     

    Either that or the ball hit a giant whale and ricocheted into the outfield. Regardless, two runs scored and the Mariners won.

     

    See you tomorrow.

     

     

     

     

     

     

  • Working with Microsoft Lync Registry Settings

     

    Remember the registry? Of course you do: the registry was first introduced in Windows 3.1 and now, almost 20 years later, the registry is still very much alive and kicking. We're the first to admit that the registry hasn't always been the most-beloved piece of software that Microsoft ever created, but it still maintains its importance as a central storehouse for both operating system and application configuration information.

     

    And yes, as a matter of fact, that does include configuration information for Microsoft Lync 2010. There's no doubt that the client policy settings introduced in Microsoft Lync Server 2010 give administrators considerable centralized control of the behavior of Microsoft Lync; for example, an administrator can configure a policy that enables free/busy information to be included in your presence information, or a policy that prevents users from including emoticons in any instant messages that they send or receive. That's nice, and there are other policy settings that control such things as the display of the Activity Feeds tab, the ability of users to save instant message transcripts, and whether or not a disclaimer appears in the Conversation Window each time you participate in a new instant messaging session.

     

    That said, there are many other Lync settings that are not available as client policy settings; instead, they're available only as user preferences. What does that mean? That simply means that the users can decide for themselves whether or not they want to enable a feature. For example, there happens to be a user preference that determines whether or not Microsoft Lync automatically starts each time the user logs on to Windows. Who controls that setting? The user does, and by doing nothing more complicated than selecting (or deselecting) a checkbox in the Options dialog box:

     

     

    So what happens when a user enables (or disables) one of these user preferences? Well, in many cases, that information is recorded in the registry. For example, if you enable the option Automatically start Lync when I log on to Windows then this registry value gets set to 1:

     

    HKEY_CURRENT_USER\Software\Microsoft\Communicator\AutoRunWhenLogonToWindows

     

    And if you disable that setting? Then that same registry value will be set to 0. Each time you start Lync, the application reads these values from the registry and then configures itself accordingly.

     

    In other words, many of the Lync user preferences rely on values stored in the registry. So does that mean that you're thinking what we're thinking?

     

    Oh. Well, that's definitely not what we were thinking. We were thinking this: if preference information is stored in the registry, that means that you could use a Windows PowerShell script to retrieve the values of those registry-based settings. In fact, you could even use a Windows PowerShell script to change the values of those settings.

     

    That's what we were thinking.

     

    Of course, by now you're thinking, "Why would I even want to do that?" Well, imagine this scenario. A user calls you up and tells you that "Microsoft Lync used to start up every time I logged into Windows and now it doesn't. Why not?"

     

    The most obvious reason is because he or she has cleared the Automatically start Lync when I log on to Windows option. But how can you be sure that this is what happened? One way, of course, is to ask the user. But another way is to run a script like this one, a script that retrieves the value of AutoRunWhenLogonToWindows from the computer atl-ws-001.litwareinc.com:

     

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

     

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

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

     

    Write-Host "Automatically start Lync when I log on to Windows:",`

        ($key.GetValue("AutoRunWhenLogonToWindows",$null))

     

    If this script returns a 0, that means that Automatically start Lync when I log on to Windows has been disabled; in turn, that's probably why Lync is no longer starting up whenever the user logs on to Windows. If the script returns a 1, then you know that this option actually is enabled, which means that something else must be preventing Lync from auto-starting. Either way, you've managed to get this information without having to guide the user through the Lync UI, and without running the risk of the user accidentally clicking something else and making the problem even more complicated than it was before.

     

    But wait: it gets even better. If you want to, you could even run a script that modifies the registry and thus re-enables the setting:

     

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

     

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

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

     

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

     

    Now, admittedly, we typically don't recommend that people make changes to an application by modifying the registry; after all, if you assign the wrong value to the wrong setting, well …. But keep in mind that we're not saying that you have to do this; we're just saying that you could do this. Being able to run a script that returns a considerable amount of information about how Microsoft Lync has been configured could be extremely useful for administrators and help desk personnel. Being able to run a script that modifies one of those settings could be equally valuable. For example, imagine a script that you could run after installing a new copy of Microsoft Lync, a script that would immediately configure that copy of Lync with your organization's preferred settings. Useful? It sounds useful. But that's your call.

     

    We should also point out that modifying a registry value does not prevent the user from going in and changing things back. For example, suppose you set AutoRunWhenLogonToWindows to 1, thus configuring Lync to automatically start any time the user logs on to Windows. What's to prevent the user from simply opening up the Options dialog box and disabling auto-start? Absolutely nothing. After all, that's how user preferences work.

     

    Note. This is as good a time as any to mention that there are a few cases where policies and preferences overlap. For example, users can decide for themselves if they want to use emoticons in instant messages; however, there's also a client policy setting (DisableEmoticons) that administrators can use to prevent users from employing emoticons. So what happens when worlds collide; that is, what happens if a user has enabled the use of emoticons but an administrator has disabled the use of emoticons?

     

    Actually, there's a very simple answer to that: the policy set by the administrator always wins. Always. If an administrator uses a client policy to disable emoticons then it doesn't matter what the user has set in the Options dialog box and it doesn’t matter what value might be configured in the registry. And, while there might be one or two privacy-related exceptions, after a setting has been configured via a policy, the user will no longer have the option of changing that setting. In this case, for example, the Show emoticons in instant messages option will be grayed-out and will no longer be available to the user.

     

    As we hinted at a moment ago, the purpose of this series of articles is to introduce some of the registry settings used by Microsoft Lync and to explain how those settings relate both to the Lync user interface and, in some cases, to Lync Server client policies. Our goal here is purely educational: we're just reporting back the things we discovered while exploring Lync and the Lync registry settings. Do these articles contain useful nuggets of administrative information? That's something you'll have to decide for yourself. You know what they say: we report, you decide.

     

    Here are the Lync features that we've managed to map to the registry, at least up to this point in time:

     

    ·         Allow Microsoft to collect information about how I use Lync

    ·         Always on Top

    ·         Automatically start Lync when I log on to Windows

    ·         Display my Out of Office Information to contacts in my Friends and Family, Workgroup, and Colleagues privacy relationships

    ·         File Transfer Save to

    ·         Hide the Notification Balloon

    ·         Join meeting audio from

    ·         Keep sounds to a minimum when my status is Busy

    ·         Keep sounds to a minimum when my status is Do Not Disturb

    ·         Last Dialed Number

    ·         Lync Language

    ·         Minimize to the notification area instead of the task bar

    ·         Mute incoming IM alert sounds when viewing an IM conversation

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

    ·         Lync Product Version

    ·         Prompt me before joining to confirm or select another audio source

    ·         Show an alternating background color for messages in the conversation window

    ·         Show emoticons in instant messages

    ·         Show Lync in foreground when it starts

    ·         Show me as Away when my status has been Inactive for this many minutes

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

    ·         Show photos of contacts

    ·         Show the Menu Bar

    ·         Turn logging on in Lync

    ·         Turn on TYY mode

    ·         Turn on Windows Event logging for Lync

     

    And here's a script that can return detailed information about Microsoft Lync and how it's been configured. As written, the script returns this information for the local computer. To retrieve this data from a remote computer, simply assign the name of that computer to the variable $computer. For example:

     

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

     

    Here's the script:

     

    $computer = "."

     

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

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

     

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

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

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

    Write-Host "Show emoticons: $value"

     

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

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

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

    Write-Host "Show an alternating background color for messages in the" `

        "conversation: $value"

     

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

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

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

     

    Write-Host "Allow Microsoft to collection information about how I use" `

        "Lync: $value"

     

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

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

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

    Write-Host "Turn logging on in Lync: $value"

     

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

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

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

    Write-Host "Turn on Windows event logging for Lync: $value"

     

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

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

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

    Write-Host "Minimize to the notification area instead of the task bar: $value"

     

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

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

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

    Write-Host "Automatically start Lync when I log on to Windows: $value"

     

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

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

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

    Write-Host "Show Lync in foreground when it starts: $value"

     

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

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

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

    Write-Host "Display my Out of Office information to contacts in my Friends" `

        "and Family, Workgroup, and Colleagues privacy relationships: $value"

     

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

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

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

    Write-Host "Show photos of contacts: $value"

     

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

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

     

    Write-Host "Show me as Away when my status has been Inactive for this" `

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

     

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

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

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

    Write-Host "Turn on TTY mode: $value"

     

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

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

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

    Write-Host "Prompt me before joining to confirm or select another audio" `

        "source: $value"

     

    $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"

     

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

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

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

    Write-Host "Mute incoming IM alert sounds when viewing an IM conversation: $value"

     

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

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

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

    Write-Host "Keep sounds to a minimum when my status is Busy: $value"

     

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

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

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

    Write-Host "Keep sounds to a minimum when my status is Do Not Disturb: $value"

     

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

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

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

    Write-Host "Always on tops: $value"

     

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

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

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

    Write-Host "Hide notification balloon: $value"

     

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

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

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

    Write-Host "Show menu bar: $value"

     

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

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

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

    Write-Host "Show photos of contacts: $value"

     

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

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

    if ($value -eq 0) {$value = "Do not join meeting audio"}

    Write-Host "Join audio conference from: $value"

     

    Write-Host "File transfer Save to folder:",($key.GetValue("FtReceiveFolder",$null))

    Write-Host "Last Dialed Number:",($key.GetValue("LastDialedNumber",$null))

    Write-Host "Product Version:",($key.GetValue("ProductVersion",$null))

     

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

    switch ($value) {

        1025 {$value = "Arabic "}

        1026 {$value = "Bulgarian "}

        1027 {$value = "Catalan "}

        2052 {$value = "Chinese - Simplified "}

        1028 {$value = "Chinese - Traditional "}

        3076 {$value = "Chinese Hong Kong "}

        1050 {$value = "Croatian "}

        1029 {$value = "Czech "}

        1030 {$value = "Danish "}

        1043 {$value = "Dutch "}

        1033 {$value = "English "}

        1061 {$value = "Estonian "}

        1035 {$value = "Finnish "}

        1036 {$value = "French "}

        1031 {$value = "German "}

        1032 {$value = "Greek "}

        1037 {$value = "Hebrew "}

        1081 {$value = "Hindi "}

        1038 {$value = "Hungarian "}

        1040 {$value = "Italian "}

        1041 {$value = "Japanese "}

        1042 {$value = "Korean "}

        1062 {$value = "Latvian "}

        1063 {$value = "Lithuanian "}

        1044 {$value = "Norwegian "}

        1045 {$value = "Polish "}

        2070 {$value = "Portuguese (Portugal) "}

        1046 {$value = "Portuguese (Brazil) "}

        1048 {$value = "Romanian "}

        1049 {$value = "Russian "}

        2074 {$value = "Serbian "}

        1051 {$value = "Slovak "}

        1060 {$value = "Slovenian "}

        3082 {$value = "Spanish "}

        1053 {$value = "Swedish "}

        1054 {$value = "Thai "}

        1055 {$value = "Turkish "}

        1058 {$value = "Ukrainian"}

    }

     

    Write-Host "Lync Language: $value"

     

    And what the heck: here's a bonus script, one that resets the Lync registry settings to their default values:

     

    $computer = "."

     

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

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

     

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

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

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

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

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

    $key.SetValue("AlwaysShowMenu",[byte[]]@(0,0,0,0),"Binary")

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

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

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

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

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

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

    $key.SetValue("FtReceiveFolder","$env:userprofile\Documents\My Received Files","String")

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

    $key.SetValue("DsBkgndMode",[byte[]]@(0,0,0,0),"Binary")

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

    $key.SetValue("AwayThreshold",5,"DWORD")

    $key.SetValue("AlwaysOnTop",[byte[]]@(0,0,0,0),"Binary")

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

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

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

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

     

    Enjoy!

  • Keep sounds to a minimum when my status is Busy

     

     

    Registry locations

    HKCU\Software\Microsoft\Communicator\suspendSoundWhenBusy

    Allowed registry values

    ·         0 – Lync will not suppress sounds when your status is set to Busy

    ·         1 – Lync will suppress sounds when your status is set to Busy

    Registry value type

    REG_DWORD

    Default setting

    0: Sounds are not muted when your status  is set to Busy

     

    Let’s say you’re currently talking on the phone and your Microsoft Lync status has been set to Busy. Under those conditions, do you really want your computer to start chirping at you each time you get a new instant message, or each time one of your tagged contacts logs on or logs off? Well, maybe you do, and maybe you don’t. Either way, there’s a setting within Microsoft Lync that lets you decide whether or not you want sounds played any time you are Busy. You can find this setting on the Ringtones and Sounds tab in the Options dialog box:

     

     

    So is there another way to configure this setting? Of course there is: just modify the HKCU\SOFTWARE\Microsoft\Communicator\suspendSoundWhenBusy registry value. (Yes, for some reason the initial s is lowercase. Go figure.) If you want Lync to keep quiet any time you’re Busy then set this value to 1. If it’s OK for Lync to make noise from time-to-time while you’re Busy then set this value to 0.

     

    All in all, pretty simple and straightforward.

     

    The following PowerShell script shows how you can retrieve the current value of suspendSoundWhenBusy from the local computer. If you'd prefer to retrieve that information from a remote computer, set the value of the variable $computer to the name of that remote computer. For example:

     

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

     

    That also seems pretty simple and straightforward, doesn't it?

     

    Here's the script that retrieves the suspendSoundWhenBusy value:

     

    $computer = "."

     

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

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

     

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

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

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

    Write-Host "Keep sounds to a minimum when my status is Busy: $value"

     

    And here's a script that lets you change that value. In this case, the script tells Lync to suspend sounds any time you're busy; that's done by setting suspendSoundWhenBusy to 1. To allow sounds to play even when you're busy, set suspendSoundWhenBusy to 0:

     

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

     

    Here's how you change the value:

     

    $computer = "."

     

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

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

     

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

     

     

     

  • Show photos of contacts

     

     

    Registry locations

    HKCU\Software\Microsoft\Communicator\ShowPhoto

    Allowed registry values

    ·         0: Photos of yourself and all your contacts are not displayed in Microsoft Lync

    ·         1: Photos of yourself and all your contacts are displayed in Microsoft Lync

    Registry value type

    REG_DWORD

    Default setting

    1: Photos of yourself and all your contacts are displayed in Lync

     

    One of the cool new features found in Microsoft Lync 2010 is the ability to show not only your picture, but pictures of all your contacts as well. Assuming you and your contacts have all decided to allow your pictures to be shown, an instance of Microsoft Lync will look something like this:

     

    Like we said: pretty cool.

     

    But one of the other cool new features in Microsoft Lync is this: Microsoft Lync gives you a considerable amount of control over the things you see (or don't see) in the user interface. For example, suppose you don't want to see everyone's picture (including your own) in the Contact List. That's fine; one of the settings available in the Options dialog box is the Show photos of contacts checkbox:

     

     

     

     

    If you clear this checkbox then neither your photo nor the photos of any of your contacts will be shown in Lync:

     

    It's entirely up to you.

     

    We should probably point out that this does not prevent other people from seeing your picture; if you want to do that, you need to go back into the Options dialog box and select the option Do not show my picture

     

     

     

    You can even configure things so that you can see everyone's picture except yours. To do that, select Do not show my picture and leave Show photos of contacts selected. After you've done all that, no one (including you) will see your photo. But you'll still be able to see everyone else's photo (unless they, too have selected Do not show my picture):

     

     

     

     

    Another way to enable/disable the showing of photos within Microsoft Lync is to modify the HKCU\SOFTWARE\Microsoft\Communicator\ShowPhoto value in the registry. Before we show you how to do that, however, let's first show you a script that retrieves that value from 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"

     

    Here's the script that lets you retrieve the value:

     

    $computer = "."

     

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

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

     

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

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

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

    Write-Host "Show photos of contacts: $value"

     

    And here's a script that sets the value of ShowPhoto. In this case, the script enables showing pictures of yourself and your contacts; that's done by setting ShowPhoto to 1. To suppress pictures of both yourself and your contacts, set ShowPhoto to 0:

     

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

     

    In other words:

     

    $computer = "."

     

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

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

     

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

     

     

     

  • Show the Menu Bar

     

     

    Registry locations

    HKCU\Software\Microsoft\Communicator\AlwaysShowMenu

    Allowed registry values

    ·         00 00 00 00 – The menu bar is not visible

    ·         01 00 00 00 – The menu bar is visible

    Registry value type

    REG_BINARY

    Default setting

    00 00 00 00: The menu bar is not visible

     

    Did you know that the Microsoft Lync user interface includes a menu bar? Well, don't feel bad; we didn't know that, either, at least not until we started looking at some of the options for configuring Microsoft Lync. By default, Lync doesn't display a menu bar; instead, you need to click the little arrow next to that thing that looks like a gear in order to get to the commands and options available in Microsoft Lync:

     

     

     

    Needless to say, there isn't anything wrong with that; if there was we wouldn't have made it the default behavior. On the other hand, if you'd prefer to see a good old-fashioned menu bar within Microsoft Lync, well, then just configure Lync to display a good old-fashioned menu bar like this one:

     

     

    Cool, huh? As it turns out, there are at least two ways to show (or to hide) the menu bar in Microsoft Lync. For one, you can click the little arrow next to the thing that looks like a gear and select Show Menu Bar.

     

     

    Alternatively, you can do the same thing by manipulating the HKCU\SOFTWARE\Microsoft\Communicator\AlwaysShowMenu registry value. The following PowerShell script shows you how you can retrieve the current value of the AlwaysShowMenu registry value 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 how you can retrieve that value:

     

    $computer = "."

     

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

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

     

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

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

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

    Write-Host "Show menu bar: $value"

     

    That's nice, but we did say something about manipulating this value, didn't we? Okey-doke. Our next script shows how you can configure the value of AlwaysShowMenu. In this case, the script displays the menu bar; that's done by setting AlwaysShowMenu to 1. To hide the menu bar, set AlwaysShowMenu to 0:

     

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

     

    Here's the script:

     

    $computer = "."

     

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

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

     

    $key.SetValue("AlwaysShowMenu",[byte[]]@(1,0,0,0),"Binary")

     

     

     

     

  • Show Lync in foreground when it starts

     

     

    Registry locations

    HKCU\Software\Microsoft\Communicator\AutoOpenMainWindowWhenStartup

    Allowed registry values

    ·         0 – The Contact List will not display onscreen when you logon to Windows

    ·         1 – The Contact List will display onscreen when you log on to Windows

    Registry value type

    REG_DWORD

    Default setting

    1: Lync is automatically brought to the foreground when it starts

     

    To be perfectly honest, when we first saw this option in the Office Communicator 2007 R2 user interface it didn’t make much sense to us. Back then the setting was labeled Automatically open the contact list when Communicator starts, and we didn't understand what that was supposed to mean: after all, wasn't the Contact List always open when you started Communicator?

     

    As it turns out, however, this option actually did make sense; you just had to know what it meant. (Fortunately the setting has been relabeled in Microsoft Lync 2010, which makes it much easier to understand.)  So what happens if this option is enabled? This happens: each time you start Lync the Contact List will appear on screen and in the foreground, something like this:

     

     

    And what happens if you don’t select this option? In that case, you won’t see the Contact List on screen; instead, all you’ll see is the Microsoft Lync icon running in the task bar or the Notification area:

     

     

     Either way, it’s up to you. Do you want to see Lync jump into the foreground every time it starts, or would you prefer to have it start unobtrusively in the background? To be honest, it makes no difference to us at all.

     

    Oh, good point: if it’s up to you to configure this option then how exactly do you configure this option? Well, one way is to select (or clear) the Show Lync in foreground when it starts checkbox. (We told you it had a much better label now than it did in 2007 R2.) That’s a checkbox you’ll find on the Personal tab of the Options dialog box:

     

     

    You can also programmatically control what happens to the Contact List each time you start Lync. If you’d like to actually see Microsoft Lync each time you start the application then all you need to do is set the HKCU\SOFTWARE\Microsoft\Communicator\AutoOpenMainWindowWhenStartup registry value to 1. Happy just to have the Lync icon appear in the task bar or Notification area? Then set the registry value to 0. Life doesn’t get any better than that, does it?

     

    And don’t worry: we’re about to show you exactly how to do that.

     

    For starters, here's a Windows PowerShell script that retrieves the current value of AutoOpenMainWindowWhenStartup from the local computer. If you'd rather 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"

     

    Here's the script for retrieving the value:

     

    $computer = "."

     

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

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

     

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

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

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

    Write-Host "Show Lync in foreground when it starts: $value"

     

    And here's a script that sets the value of AutoOpenMainWindowWhenStartup. In this case, the script causes Lync to open in the foreground; that's done by setting AutoOpenMainWindowWhenStartup to 1. To have Lync open up in the background, set AutoOpenMainWindowWhenStartup to 0:

     

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

     

    Here you go:

     

    $computer = "."

     

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

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

     

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

     

     

     

     

  • Show emoticons in instant messages

     

     

    Registry locations

    HKCU\Software\Microsoft\Communicator\ShowEmoticons

    Allowed registry values

    ·         0 – Emoticons are sent as text

    ·         1 – Emoticons are sent as graphics

    Registry value type

    REG_DWORD

    Default setting

    1: Emoticons are shown in instant messages

     

    Where would the world be without emoticons? Back in the dark ages of computing, the only way to add a "smiley face" to an instant message would be to use the typewritten equivalent, like so:

     

    :)

     

    Thank goodness that’s no longer the case, at least not with Microsoft Lync. Instead, with Microsoft Lync you can add a real smiley face to your instant messages:

     

     

    Progress is truly a wonderful thing, isn’t it?

     

    Historical note. The first known use of the classic smiley face emoticon: :-)? That dates all the way back to 1982 and the computer science department at Carnegie Mellon University. (As if anyone other than a computer science major at Carnegie Mellon University could have come up with the smiley face emoticon.)

     

    In Microsoft Lync you can enable the use of emoticons by checking the Show emoticons in instant messages checkbox:

     

     

    Once you do that, you can then insert any Lync emoticon into your instant messages and have that emoticon be sent as a graphic. Likewise, you can type an emoticon character equivalent and Lync will automatically convert that typewritten value to a graphic. For example, suppose you type the following into an instant message:

     

    8-|

     

    Do that, and Lync will convert that text to the following emoticon when the message is sent:

     

     

    Note. In case you’re wondering, the preceding emoticon is officially known as the “nerd smiley.”

     

    As if that wasn’t cool enough, this conversion also takes place for any emoticons (or their text equivalents) that get sent to you. For example, suppose someone types 8-| in an instant message sent to you. When you receive that message, Lync will automatically show you – that’s right, the beloved nerd smiley:

     

     

    This really is a wonderful age in which to be alive, isn't it?

     

    Of course, it’s always possible that you’d rather not use emoticons in your instant messages. (Killjoy.) In that case, all you have to do is clear the Show emoticons in instant messages checkbox in the Options dialog box. Do that, and Lync will no longer convert typed characters to their emoticon equivalents.

     

    And yes, in some ways that does take all the fun out of instant messaging. But in some organizations, fun might not be the overriding concern when it comes to sending and receiving instant messages.

     

    Go figure.

     

    And before you ask, yes, you can use Windows PowerShell to manage the use of emoticons; that's done by manipulating the registry value HKCU\SOFTWARE\Microsoft\Communicator\ShowEmoticons. For example, the following PowerShell script retrieves the current value of ShowEmoticons from 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"

     

    Here's the script we were just talking about:

     

    $computer = "."

     

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

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

     

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

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

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

    Write-Host "Show emoticons: $value"

     

    You can also use a script to set the value of ShowEmoticons. In the code we're about to show you, the script enables the use of emoticons in instant messages; that's done by setting ShowEmoticons to 1. To disable the use of emoticons, set ShowEmoticons to 0:

     

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

     

    You know, like this:

     

    $computer = "."

     

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

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

     

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

     

    One thing to keep in mind here is that there is also a client policy setting (DisableEmoticons) that can be used to regulate the use of emoticons in instant messages. If DisableEmoticons is set to anything other than a null value ($null) then users will not be able to use emoticons in their instant messages, and they won't be able to change that setting:

     

     

    And yes, oddly enough, it doesn't matter whether you set DisableEmoticons to True or to False; anything other than a null value will disable the use of emoticons in instant messages.

     

    That's what we said: go figure.

     

     

     

  • 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))

     

  • 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.

     

     

     

  • Prompt me before joining to confirm or select another audio source

     

     

    Registry locations

    HKCU\Software\Microsoft\Communicator\AllowOverridingDeviceAtJoinTime

    Allowed registry values

    0: Automatically join a meeting using the default audio source

    1: Prompt before joining or changing an audio source

    Registry value type

    REG_DWORD

    Default setting

    1: Prompt before joining or changing an audio source

     

    As a general rule, Microsoft Lync gives you as many opportunities as possible to decide for yourself how you want the software to work. For example, each time you join a meeting Lync shows you the following dialog box and asks you to select the audio source for the meeting:

     

     

    That's great. But suppose you always want to use Microsoft Lync as your audio source. In that case, it can be a bit of a hassle to have to dismiss the dialog box each time you join a meeting. Isn't there some way to keep this dialog box from popping up on screen?

     

    Actually, there are several ways to keep this dialog box from popping up on screen. For one, you can click the Don't show this again checkbox before clicking OK; that will ensure that the Join Meeting Audio dialog box won't appear the next time you join a meeting from Microsoft Lync. Alternatively, you can clear the Prompt me before joining to confirm or select another audio source setting from within the Options dialog box:

     

     

    If you clear that checkbox then the dialog box will not appear when you join a meeting. If you select that checkbox then the dialog box will appear when you join a meeting.

     

    And, of course, you can always use a script to change the registry value HKCU\SOFTWARE\Microsoft\Communicator\AllowOverridingDeviceAtJoinTime. Before we show you to do that, let's take a quick peek at a Windows PowerShell script that retrieves the current value of AllowOverridingDeviceAtJoinTime. If you'd rather get this value from a remote computer, hey, no problem: simply 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 AllowOverridingDeviceAtJoinTime value:

     

    $computer = "."

     

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

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

     

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

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

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

    Write-Host "Prompt me before joining to confirm or select another audio" `

        "source: $value"

     

    And here's a script that sets the value of AllowOverridingDeviceAtJoinTime. In this case, the script causes the dialog box to appear; that's done by setting AllowOverridingDeviceAtJoinTime to 1. To suppress the appearance of the dialog box, set AllowOverridingDeviceAtJoinTime to 0:

     

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

     

    In other words:

     

    $computer = "."

     

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

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

     

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

     

     

     

     

  • Display my Out of Office Information to contacts in my Friends and Family, Workgroup, and Colleagues privacy relationships

     

     

    Registry locations

    HKCU\Software\Microsoft\Communicator\AutoRetrieveOOFSettings

    Allowed registry values

    ·         0 – Out of Office information is not displayed to contacts with the Friends and Family, Workgroup, or Colleagues access level

    ·         1 – Out of Office information is displayed to contacts with the Friends and Family, Workgroup, or Colleagues access level

    Registry value type

    REG_DWORD

    Default setting

    1: Out of Office information is displayed to the appropriate contacts

     

    If you're using Microsoft Outlook then Microsoft Lync offers you a number of additional Outlook-related options. Like what, you ask? Well, here’s one: you can have Lync display your Out of Office message to any of your contacts who have the Friends and Family, Workgroup, or Colleagues access level.

     

    And just how do you do that, you say? Well, one way is to select the Display my Out of Office information to contacts in my Friends and Family, Workgroup, and Colleagues privacy relationships checkbox within Personal tab of the Options dialog box:

     

     

    If you enable this option then your Out of Office message will be integrated into the rest of your presence information:

     

     

    Another way to configure this behavior is to modify the SOFTWARE\Microsoft\Communicator\AutoRetrieveOOFSettings registry value. When this value is set to 1 your Out of Office information will be displayed to the appropriate contacts; when this value is set to 0 then Out of Office information won’t be displayed to anyone. Period.

     

    Oh and, needless to say, this setting has no effect if Outlook has not been configured as your personal information manager.

     

    Historical note. The OOF in AutoRetrieveOOFSettings is short for "Out of Office." Why is OOF (rather than OOO) short for Out of Office? From what we’ve been told, Microsoft’s original Xenix email system included a command – oof – that marked a user as “Out of Facility.” The acronym has simply been carried through to this day, even though the word "Facility" has been replaced by the word “Office.” And why did they call it "Out of Facility" in the first place? That’s a mystery that might never be solved.

     

    But we digress. The following Windows PowerShell script retrieves the current value of AutoRetrieveOOFSettings from 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"

     

    Here's the script for retrieving the AutoRetrieveOOFSettings value:

     

    $computer = "."

     

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

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

     

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

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

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

    Write-Host "Display my Out of Office information to contacts in my Friends" `

        "and Family, Workgroup, and Colleagues privacy relationships: $value"

     

    And here's a script that sets the value of AutoRetrieveOOFSettings. In this case, the script enables showing your Out of Office message to the appropriate contacts; that's done by setting AutoRetrieveOOFSettings to 1. To disable the display of your OOF message, set AutoRetrieveOOFSettings to 0:

     

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

     

    Here's how the whole thing looks:

     

    $computer = "."

     

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

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

     

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

     

    By the way, there's also a client policy property – the less than aptly-named DisablePresenceNote property – that can be used to manage the Out-of-Office setting. If you set DisablePresenceNote to anything other than a null value (that is, if you set it either to True or to False) then the Display my Out of Office information to contacts in my Friends and Family, Workgroup, and Colleagues privacy relationships setting will be disabled and users will not be able to enable it, regardless of how AutoRetrieveOOFSettings has been set in the registry:

     

     

    Just something to keep in mind.

     

  • Hide the Notification Balloon

     

     

    Registry locations

    HKCU\Software\Microsoft\Communicator\DSBkgndMode

    Allowed registry values

    ·         00 00 00 00 – A balloon alert will be displayed each time you close the main Lync window

    ·         01 00 00 00 – A balloon alert will not be displayed each time you close the main Lync window

    Registry value type

    REG_BINARY

    Default setting

    Not present (the notification balloon is shown)

     

    As you probably know, simply closing the Microsoft Lync window does not terminate the application; instead, Lync minimizes itself and continues to run as it awaits further instructions. To help lessen confusion about whether it's still running or not, Lync displays a balloon alert like this one each time it recedes into the Notification area or task bar:

     

     

    As we noted, this balloon alert appears each time you close the main Lync window.

     

    Unless, of course, you’d prefer that this alert doesn’t appear each time you close the main Lync window. How do you do that? Well, as you can see, one way is to click on the alert itself; that will suppress its display in the future, and the balloon will be gone forever.

     

    But you’re right: forever is a long time, isn’t it? So what happens if you miss that balloon, what happens if you'd like to see it again? As near as we can tell, you have two choices:

     

    • Build a time machine, then use that machine to go back in time and prevent yourself from clicking the alert.
    • Modify the HKCU\SOFTWARE\Microsoft\Communicator\DSBkgndMode registry value.

     

    Admittedly, building a time machine is slightly outside the scope of this article; therefore, we’ll focus our attention on modifying the DSBkgndMode registry value. If you set this value to 00 00 00 00 then the balloon alert will appear each time you close the main Lync window; if you set this value to 01 00 00 00 the balloon alert will not appear. Short of building a time machine, this is the only way we know of to toggle the appearance of the balloon alert. Clicking the alert will cause it to disappear, but we don’t know of any option in Lync’s user interface that will allow you to restore the alert.

     

    Note. Why not? Good question: we have no idea.

     

     

    On the other hand, who needs another option as long as you can use Windows PowerShell to modify the registry? The following PowerShell script retrieves the current value of the DSBkgndMode registry value on the local computer. If you'd like 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"

     

    And here's how you actually retrieve that value:

     

    $computer = "."

     

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

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

     

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

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

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

    Write-Host "Hide notification balloon: $value"

     

    Having done that, the next logical step would be to find a way to change the value of DSBkgndMode. In a minute, we'll show you a script that suppresses the appearance of the notification balloon; that's done by setting DSBkgndMode to 1,0,0,0. To get the balloon back, set DSBkgndMode to 0,0,0,0:

     

    $key.SetValue("DsBkgndMode",[byte[]]@(0,0,0,0),"Binary")

     

    And, as promised, here's how you suppress the notification balloon:

     

    $computer = "."

     

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

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

     

    $key.SetValue("DSBkgndMode",[byte[]]@(1,0,0,0),"Binary")

     

     

     

  • Keep sounds to a minimum when my status is Do Not Disturb

     

     

    Registry locations

    HKCU\Software\Microsoft\Communicator\suspendSoundWhenDND

    Allowed registry values

    ·         0 – Lync will not suppress sounds when your status is set to Do Not Disturb

    ·         1 – Lync will suppress sounds when your status is set to Do Not Disturb

    Registry value type

    REG_DWORD

    Default setting

    0: Sounds are not muted when your status  is set to Do Not Disturb

     

    Sometimes silence is golden. Like when? Like, say, when your status has been set to Do Not Disturb, a status you probably set because, well, because you don’t want to be disturbed. With that in mind you might want to configure Lync so that no sounds are played while your status is set to Do Not Disturb; that way you won’t hear a beep or a boop every time something happens on the order of, say, one of your tagged contacts logging on or off.

     

    One way to configure the Do Not Disturb setting is from within the Options dialog box; all you have to do is select (or deselect) the Keep sounds to a minimum when my status is Do Not Disturb checkbox:

     

     

    You can also configure the Do Not Disturb setting by modifying the HKCU\SOFTWARE\Microsoft\Communicator\suspendSoundWhenDND registry value. Set this value to 1 to ensure that no sounds are played when your status is set to Do Not Disturb; set this value to 0 if it’s OK for Lync to play sounds while your status is set to Do Not Disturb.

     

     

     

    Before we show you how to change that setting, let's show you how to retrieve the current value of suspendSoundWhenDND from the local computer. You say you'd rather retrieve this value from a remote computer? That's fine; 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 current value:

     

    $computer = "."

     

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

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

     

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

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

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

    Write-Host "Keep sounds to a minimum when my status is Do Not Disturb: $value"

     

    And now, at long last, here's a script that sets the value of suspendSoundWhenDND. In this example, the script suppresses the playing of sounds when your status is set to Do Not Disturb; that's done by setting suspendSoundWhenDND to 1. If you'd prefer to hear sounds even when your status is set to Do Not Disturb, well, hey, who are we to judge? In that case, just set suspendSoundWhenDND to 0:

     

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

     

    Like we were saying:

     

    $computer = "."

     

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

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

     

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