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
· Automatically start Lync when I log on to Windows
· Hide the Notification Balloon
· Keep sounds to a minimum when my status is Busy
· Keep sounds to a minimum when my status is Do Not Disturb
· 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)
· 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
· 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!
Comments
- Anonymous
January 01, 2003
Thanks for your example. With a few changes you could make it a lot more flexible/useful.
- Currently your output is not PowerShell friendly. By that I mean it doesn't output an object, it just writes directly to the host, which you can't capture. If you embed the results you get back as properties in an object, it makes it more flexible. Get-LyncReg | Export-CSV C:LyncRegSessings.csv
- Use ComputerName in output object. If you have to gather data from multiple clients having the name of the computer in the output is useful.
- Use True/False instead of Yes/No. PowerShell can easily filter on True/False whereas Yes/No takes work. Get-LyncReg Computer3 | ? { $_.ShowEmoticons }
- Don't hardcode language codes. In this case it's already in .Net, so once you know where it is, it's easy to use. [System.Globalization.CultureInfo]::GetCultureInfo(1025).DisplayName. Results in "Arabic (Saudi Arabia)"
- Make it into a function/script that takes ComputerName as a parameter. This makes it easier to reuse. Here's a version that should do these things and a few more. I've included one additional example to give you an idea of some more things you can do with it. Unfortunately, I'm guessing the formatting of this is going to get messed up, but it hopefully still be useful. 'Computer1', 'Computer2', 'Computer3' | Get-LyncReg | ? { $_.ShowEmoticons}| Export-CSV C:LyncWithShowEmoticons.csv function Get-LyncReg { param( [Parameter(ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)][string]$ComputerName = $ENV:COMPUTERNAME ) process { $Registry = [Microsoft.Win32.RegistryKey]::OpenRemoteBaseKey("CurrentUser", $ComputerName) $Key = $Registry.OpenSubKey("SOFTWAREMicrosoftCommunicator", $True) New-Object PSObject -Property @{ "ComputerName" = $ComputerName "ShowEmoticons" = [bool]$Key.GetValue("ShowEmoticons",$null) "ShowColorBand" = [bool]$Key.GetValue("ShowColorBand",$null) "CEIPEnabled" = [bool]$Key.GetValue("CEIPEnabled",$null) "EnableTracing" = [bool]$Key.GetValue("EnableTracing",$null) "EnableEventLogging" = [bool]$Key.GetValue("EnableEventLogging",$null) "MinimizeWindowToNotificationArea" = [bool]$Key.GetValue("MinimizeWindowToNotificationArea",$null) "AutoRunWhenLogonToWindows" = [bool]$Key.GetValue("AutoRunWhenLogonToWindows",$null) "AutoOpenMainWindowWhenStartup" = [bool]$Key.GetValue("AutoOpenMainWindowWhenStartup",$null) "AutoRetriveOOFSettings" = [bool]$Key.GetValue("AutoRetriveOOFSettings",$null) "ShowPhoto" = [bool]$Key.GetValue("ShowPhoto",$null) "IdleMinutes" = $Key.GetValue("IdleThreshold",$null) "AwayThreshold" = $Key.GetValue("AwayThreshold",$null) "EnableTTY" = [bool]$Key.GetValue("EnableTTY",$null) "AllowOverridingDeviceAtJoinTime" = [bool]$Key.GetValue("AllowOverridingDeviceAtJoinTime",$null) "PlaySoundFeedback" = [bool]$Key.GetValue("PlaySoundFeedback",$null) "suspendSoundWhenConversationWindowInForeground" = [bool]$Key.GetValue("suspendSoundWhenConversationWindowInForeground",$null) "suspendSoundWhenBusy" = [bool]$Key.GetValue("suspendSoundWhenBusy",$null) "suspendSoundWhenDND" = [bool]$Key.GetValue("suspendSoundWhenDND",$null) "AlwaysOnTop" = [bool]$Key.GetValue("AlwaysOnTop",$null) "DsBkgndMode" = [bool]$Key.GetValue("DsBkgndMode",$null) "AlwaysShowMenu" = [bool]$Key.GetValue("AlwaysShowMenu",$null) "JoinAudioConferenceFrom" = [bool]$Key.GetValue("JoinAudioConferenceFrom",$null) "FtReceiveFolder" = $Key.GetValue("FtReceiveFolder",$null) "LastDialedNumber" = $Key.GetValue("LastDialedNumber",$null) "ProductVersion" = $Key.GetValue("ProductVersion",$null) "Language" = [System.Globalization.CultureInfo]::GetCultureInfo( ([int]$Key.GetValue("Language",$null)) ).DisplayName } } }
Anonymous
January 01, 2003
@Cosmin, There isn't a cmdlet or registry setting that will get you this info. You can get some of that info by using the Lync API (this article can get you started: blogs.technet.com/.../howtoretrievecontactavailability.aspx), but in that case it would only be for the contacts of the currently logged on Lync user.Anonymous
January 01, 2003
Hey Stephen, Thanks so much for the feedback! As usual, there are a lot of different ways to do a single thing in PowerShell. Your solution is pretty nice. And your ideas for ways to expand on the script are great, too. Thanks for sharing!Anonymous
June 23, 2011
Is there a way to modify the meet-Website? I want to write a short text for our external users, that join a link conference. I know how to make the attendee client available to them, but I´d also want to tell them to use it instead of the web app. A way to hide the web app would work for me, too. Thanks in advanceAnonymous
July 28, 2011
Thank you - I'm using this for a Citrix XenDesktop deployment... Very helpful!Anonymous
August 18, 2011
How I can retrieve the Away time of a user?Anonymous
September 08, 2011
Under Lync Tools/Options/Personal, there is an option to save instant message conversations in my email Conversation History folder. It is grayed out.Is there someway using PShell that I can run to enable it on that PC?Anonymous
September 12, 2011
Hi, Usually Lync shows once status as "Away" and also it will display the time for which the person is away..like "Name Away 55 Minutes". MY question is that, "Is there any way I can hide that time, i.e. if Im away then my status should show just "Away" and not the minutes/hours. One of my colleague has setup somehow to make it appear that way. Please let me know how to hide "minutes/ours" part in my status. Thanks in advance for your help.Anonymous
October 12, 2011
Steven: Did you ever get an answer? BKAnonymous
October 24, 2011
Kumar - Did you get any answer? MKAnonymous
November 02, 2011
How do you stop the disclaimer appearing in the Conversation Window each time you participate in a new instant messaging session?Anonymous
December 13, 2011
Hi. Do you know how to hide the "What's happening today" field?. Some users use this field to publish inappropiate comments. ThanksAnonymous
December 21, 2011
Any answers on the Archiving Conversation History question? Need the functionality badly. Thanks!Anonymous
January 06, 2012
Hi, I didn't see that Kumar's question above was answered. I have the same question. Is there any way I can hide the time away? ..i.e. if I'm away then my status should show just "Away" and not the minutes/hours.Anonymous
January 11, 2012
Please can somone answer Kumar's and Jeff's question on how to hide the time for which the user has been AwayAnonymous
February 01, 2012
Estiamtes, Kumar y Jeff any news?Anonymous
June 06, 2012
Kumar & Jeff - This is resolved with an update released in April: support.microsoft.com/.../2684128Anonymous
June 12, 2012
Hi Microsoft has released an update to remove the LastActive from the presence state, that should do the trick support.microsoft.com/.../en-us Jonatan