Script: Install-OfficeWebAppsLanguagePacks.ps1 – Easier Installation of Selected Language Packs

March 7th, 2015 No comments

PowerShell-logo-128x84Description

I was working with a global customer lately who has datacenters in various global regions (as most global orgs do). The customer had not decided, and basically, hadn’t even thought about what language packs to install on their Office Web Apps Servers (OWAS). I suggested that there are 49 language packs including the English pack that I install by default on every OWAS server. Those languages are:

Azeri (Latin)
Basque
Bosnian (Latin)
Bulgarian
Catalan
Chinese (Simplified)
Chinese (Traditional)
Croatian
Czech
Danish
Dari
Dutch
English
Estonian
Finnish
French
Galician
German
Greek
Hebrew
Hindi
Hungarian
Indonesian
Irish – Ireland
Italian
Japanese
Kazakh
Korean
Latvian
Lithuanian
Macedonian (FYROM)
Malay (Malaysia)
Norwegian (Bokmal)
Polish
Portuguese (Brazil)
Portuguese (Portugal)
Romanian
Russian
Serbian (Cyrillic)
Serbian (Latin)
Slovak
Slovenian
Spanish
Swedish
Thai
Turkish
Ukranian
Vietnamese
Welsh

The customer decided on which language packs to install.

If you’ve ever tried to install these, you know you go to the language pack download page, and pick your desired language. When the next page comes up, you notice that it’s in the language of the desired language pack. You hope you’re clicking on the right link, download the file, then run the installer, which is mostly in the desired language, and go from there. It can be somewhat confusing, but extremely repetitive – especially if you’re installing a lot of language packs. It got me thinking that this was an area ripe for automation (what area isn’t?).

Well, as I’ve mentioned on this blog before, I’m lazy (as most coders are). So I wrote this script to make my life easier, and as a result, you gain from it. Here’s what the script does:

  1. Detects which (if any) language packs are installed on the local machines. This is accomplished by looking for the correct GUID in the Uninstall branch of the registry.
  2. Displays a grid list of the language packs that are available and not already installed on the machine (see image below). You can select one or more language packs to install and click “Ok”.
  3. The script will download the language pack(s)
  4. It will mount (if they are an .img file), or extract (if an .exe).
  5. It will silently install the language pack
  6. It will clean up after itself (unmount or clean up extracted files)

Here is the selection list presented. Notice that English is not in the list as that language pack is already installed.

OWAS language pack selection

Once installation is completed, you’re left with your language packs installed and a nice little log file.

OWAS post installation

Extract the files to any folder. The script and the .csv file MUST be in the same folder. Run it by calling Install-OWASLanguagePack.ps1 and it will default to using the following path structure (which it will create if it doesn’t already exist):

Path Purpose 
 c:\_Install  Root working folder. Can be changed using -TargetFolder when calling the script.
 c:\_Install\logs  Log files from the script are stored here
 c:\_Install\OWASLanguagePacks Downloaded language pack files are stored here. Folder name can be changed using -OWASLanguagePackFolder. Language packs are placed in sub folders of this folder. The sub folders match the language of the language pack.

A little bit of a rant. I *REALLY* wish the language packs were an MSI file that supported silent install instead of an .img file that must be mounted or an .exe that must be extracted, and then each called with complex syntax.

Syntax

Install-OWASLanguagePacks.ps1 [[-TargetFolder] <object width="300" height="150">][[-OWASLanguagePackFolder] <object>] [-WhatIf] [-Confirm] [-IncludeTotalCount] [-Skip <uint64>] [-First <uint64>][<commonparameters>]</commonparameters></uint64></uint64></object>

Installation

Execution Policy: Third-party PowerShell scripts may require that the PowerShell Execution Policy be set to either AllSigned, RemoteSigned, or Unrestricted. The default is Restricted, which prevents scripts – even code signed scripts – from running. For more information about setting your Execution Policy, see Using the Set-ExecutionPolicy Cmdlet.

Assumptions

None

Download

v1.0 – 03-07-2015 – Install-OWASLanguagePacks.v1.0.zip

Changelog

See the changelog for information on what’s changed/included in each version.

Changelog: Install-OfficeWebAppsLanguagePacks.ps1

March 7th, 2015 No comments

This is the changelog page for Script: Install-OfficeWebAppsLanguagePacks.ps1 – Easier Installation of Selected Language Packs. You will find a complete list of released versions, their dates, and the features and issues addressed in each. Please refer to the script’s main page for more information including download links, installation details, and more.

v1.0 – 03-07-2015

  1. Initial version
Categories: PowerShell Tags:

One Liner: Set-TaskbarGrouping – Configure Desktop Taskbar Grouping

February 18th, 2015 No comments

In One Liner: Configuring Shutdown Tracker in Windows Server I mentioned that it’s often preferable to quickly configure some server settings when building servers. As a consultant, I like to set up my server profile when building servers in a manner that’s efficient and convenient for me. One thing that drives me completely insane is the default taskbar group setting. Taskbar grouping is how Windows groups common items together on the taskbar. By default, all similar items are lumped together, i.e. all Internet Explorer windows. So to go back to an IE window could take two mouse clicks instead of one. Let’s take a look at streamlining this configuration for Server 2012 and Server 2012 R2.

Taskbar grouping has three settings. The default “always combine” mentioned previously, “combine when taskbar full” which doesn’t start grouping until there are enough items to fill the taskbar, and my favorite, “never combine”. As you can probably guess, “never combine” doesn’t group taskbar items at all. Since I usually don’t have more than 4 or 5 apps open when building servers, this suits my style.

Just like the shutdown tracker, this setting is stored in the registry. A one liner for this would look like this:

Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name TaskbarGlomLevel -Value 0

0 is the value for “always combine”, 1 for “combine when taskbar full” and 2 for “never combine”. In order for the setting to take effect, one of two things has to happen. Either log off/restart, or restart the explorer.exe process. The later can be performed by running the following:

Stop-Process -ProcessName explorer -force

If you’d like to use a function for this, we can use something like the code below in our server build script:

function Set-TaskbarGrouping {
	[CmdletBinding(SupportsShouldProcess = $True, SupportsPaging = $True, DefaultParameterSetName = "NeverCombine")]
	param(
		# Always combines similar shortcuts into groups
		[Parameter(ValueFromPipeline = $False, ValueFromPipelineByPropertyName = $True, ParameterSetName = "AlwaysCombine")]		
		[switch] $AlwaysCombine,
		
		# Combines similar shortcuts into groups only when the taskbar is full
		[Parameter(ValueFromPipeline = $False, ValueFromPipelineByPropertyName = $True, ParameterSetName = "CombineWhenTaskbarFull")]
		[switch] $CombineWhenTaskbarFull,
		
		# Never combines similar shortcuts into groups
		[Parameter(ValueFromPipeline = $False, ValueFromPipelineByPropertyName = $True, ParameterSetName = "NeverCombine")]
		[switch] $NeverCombine,
		
		# Restarts explorer in order for the grouping setting to immediately take effect. If not specified, the change will take effect after the computer is restarted
		[switch] $NoReboot
	)
	switch ($PsCmdlet.ParameterSetName) {
		"AlwaysCombine" {
			Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name TaskbarGlomLevel -Value 0
		}
		"CombineWhenTaskbarFull" {
			Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name TaskbarGlomLevel -Value 1
		}
		"NeverCombine" {
			Set-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced" -Name TaskbarGlomLevel -Value 2
		}
	}
	if ($NoReboot){
		Stop-Process -ProcessName explorer -force
	}else{
		Write-Verbose "Change will take effect after the computer is restarted"
	}
} # end function Set-TaskbarGrouping

I use parameter set names so that only one of the parameters can be used when the function is called. The three options are “NeverCombine” “CombineWhenTaskbarFull” and “AlwaysCombine”. But since I define the parameters in a param block, you get tab completion. So no need to even remember the options. For example:

Set-TaskbarGrouping -NeverCombine

If you also include the -NoReboot parameter when calling the function, it will restart explorer.exe to avoid the need to log off/restart.

One Liner: Configuring Shutdown Tracker in Windows Server

February 17th, 2015 1 comment

When you spend time building servers, there are often some minor tweaks that you use to make life easier. In many environments, Group Policy Objects (GPOs) are used to configure these settings. But in a lot of environments, that’s not the case. If you build a lot of servers, you may have some scripts to help streamline the process. I often see this being the case among consultants who are engaged to deploy a solution. If you’ve followed my blog for a while, you know that’s what I do. And I look for many ways to streamline the deployment. Many solutions I write are all about the actual deployment, whereas this particular post is about the working environment I’ll be spending time in.

One thing that always drives me nuts is the Shutdown Tracker. That’s the little dialog box that pops up when you want to restart or shutdown a server. You’re presented with a prompt to pick the reason why you’re restarting or shutting down. While this can certainly have its place in an enterprise environment, it’s not generally needed during a deployment. And it’s not likely needed in a lab environment where you might be testing various configurations and restarting often. So let’s gag that annoying prompt.

To disable Shutdown Tracker, open an elevated PowerShell prompt and enter the following one line:

Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Reliability" -Name ShutdownReasonOn -Value 0

This will take care of the problem. If you later want to enable the Shutdown Tracker, you can simply run it again, specifying a 1 for the value.

We can make this a little more flexible by creating a function to let us enable or disable as needed.

function Set-ShutdownTracker {
	[CmdletBinding(SupportsShouldProcess = $True, SupportsPaging = $True, DefaultParameterSetName = "disabled")]
	param(
		# Disable the shutdown tracker
		[Parameter(ValueFromPipeline = $False, ValueFromPipelineByPropertyName = $True, ParameterSetName = "disabled")]
		[switch] $Disabled,
		
		# Enable the shutdown tracker
		[Parameter(ValueFromPipeline = $False, ValueFromPipelineByPropertyName = $True, ParameterSetName = "enabled")]
		[switch] $Enabled
	)
	switch ($PsCmdlet.ParameterSetName) {
		"enabled" {
			Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Reliability" -Name ShutdownReasonOn -Value 1
		}
		"disabled" {
			Set-ItemProperty -Path "HKLM:\SOFTWARE\Policies\Microsoft\Windows NT\Reliability" -Name ShutdownReasonOn -Value 0
		}
	}
} # end function Set-ShutdownTracker

And the script can be called with either the -Enabled or -Disabled parameters.

Adding the one liners or the function to your deployment scripts might make life a little easier.

Creating Desktop Shortcuts to Run PowerShell Scripts

February 16th, 2015 No comments

PowerShell-logo-128x84There are some really helpful scripts out there. Not just for Lync and Exchange. But many other apps and administrative tasks. Sometimes, however, the people who need to run them aren’t well versed in PowerShell. This makes is cumbersome for them to open PowerShell, navigate to a folder containing a script, and execute it with the correct parameters. This often leads to complaints about the difficulty of the process, or those admins just not using that tool. As not all admins have our PowerShell prowess, we can create a desktop shortcut that will allow an admin to simply double-click on it to execute it. Let’s see an example.

For this example, I’m going to use Johan Veldhuis’ very slick sefautil GUI, a wrapper for the Lync sefautil.exe program. Sefautil is a resource kit utility that allows an admin to set things like delegates, call forwarding, and other settings, on behalf of users. Sefautil has some really painful syntax, and a complete lack of error reporting. Using it is often frustrating. Johan’s GUI for it makes life SO much easier, that I found myself using it a LOT.

Let’s say, for the sake of this example, that the script, called sefautil_gui.ps1, is in a folder called c:\_scripts. When you execute Johan’s script, you must pass it a front end pool name using the “-pool” parameter. Normally running it would require something like the following:

.\sefautil_gui.ps1 -pool pool01.contoso.com

With a shortcut, we need to tell it to launch PowerShell, and call the script along with the parameters. The syntax is the full path to powershell.exe, along with the “-command” parameter and the syntax used for the script. The syntax is wrapped in quotes, and prefixed with an ampersand. PowerShell resides at C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe

  1. Right click on the desktop, and choose New>Shortcut.
  2. Enter a path for the shortcut. For our example, we’ll use
    C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -command “& c:\_scripts\sefautil_gui.ps1 -pool pool01.contoso.com”
  3. Click Next.
  4. Give the shortcut a name. We’ll call it “sefautil GUI”. Then click Finish.

Let’s set the starting path. Right click on the newly created shortcut, and click Properties. Click on the Shortcut tab. In the “Start In” field, let’s set it to “C:\windows\system32\WindowsPowerShell\v1.0″.

You may have noticed that the shortcut has the PowerShell icon. While that’s all fine and damn sexy, we might want to change that. That’s simple enough since we’re already on the Shortcut tab, click the Change Icon at the bottom and choose whichever icon you’d like. For mine, I chose the Deployment Wizard icon. This is available by browsing to %ProgramFiles%\Microsoft Lync Server 2013\Deployment and choosing Bootstrapper.exe.

While Johan’s script is a GUI based script, many are not. If that’s the case, we can tweak the session settings a little further. On the Options tab of the shortcut, you can tailor settings like Quick Edit mode, which makes selecting, copying, and pasting easier. Obviously, the Font, Layout, and other tabs provide further control over the experience.

Also note that non-GUI scripts will close the PowerShell window when they are done running, so a script might need to be tweaked to pause before closing. YMMV.

Once you’re done, click Ok. Viola!

sefautil GUI shortcut

Now, simply double clicking on our new shortcut launches the script.

sefautil GUI

 

I often do this for many 3rd party administrative tools, including Lync Call Pickup Group Manager, Lync RGS Holiday Set Editor, Centralized Logging Tool, and more.

Categories: PowerShell Tags: ,

One Liner – See Number Of Connected Users, Endpoints On A Lync Front End Server

January 22nd, 2015 2 comments

A question went around an internal DL at work today asking if anyone knew off the top of their head the name of performance counters that show connected users and endpoints. While digging up the answer, I started thinking – this would be a great little one liner.

My esteemed colleague Ron Cook (@roncook925) beat me to supplying the answer to the DL question. The two counters are:

LS:USrv – Endpoint Cache\USrv – Active Registered Endpoints
LS:USrv – Endpoint Cache\USrv – Active Registered Users

Endpoints is always higher than users, in my experience. There are always some users who are connected via mobile devices and rich client, or via OWA, or LPE. So I like to query both.

PowerShell has a great cmdlet called Get-Counter which, as you can guess, can query performance counters. There’s a pretty good tutorial on how to retrieve perfmon counter data for Lync related counters by the Lync PowerShell group at Microsoft in How Do We Love Performance Counters” Let Us Count the Ways. So let’s take a look at how we can get the data we need.

In this case, we’ll query the two counters mentioned above with one line. This is supported in Get-Counter by just separating the counters with a comma. We’ll select an expanded property called CounterSamples, which holds the data we need (among other info). And lastly, we’ll output the path (counter name), and something called the CookedValue, which is the actual counter value contained within CounterSamples. I know, CookedValue sounds like it could be just made up numbers, like those you get from a shifty accountant. But it is truly the value we want.

Plug this into your console as one long line:

Get-Counter "\LS:USrv - Endpoint Cache\USrv - Active Registered Endpoints","\LS:USrv - Endpoint Cache\USrv - Active Registered Users" | Select-Object -ExpandProperty CounterSamples | Format-Table Path,CookedValue -Auto

That will give you a quick point-in-time snapshot of the number of users and endpoints connected to the front end, as shown below.

perfmon

The blurred text is just the front end name. If you’d like to query a remote front end, just tack on the ComputerName parameter, such as:

Get-Counter "\LS:USrv - Endpoint Cache\USrv - Active Registered Endpoints","\LS:USrv - Endpoint Cache\USrv - Active Registered Users" -ComputerName frontend.contoso.com | Select-Object -ExpandProperty CounterSamples | Format-Table Path,CookedValue -Auto

For those wondering why I’m using Format-Table and the -Auto parameter, it’s because the counter path value is so long that it would otherwise get truncated short enough to where you wouldn’t know which counter was tied to which value.

One Liners: Finding Elevated Accounts That Are Enabled For Lync

November 18th, 2014 No comments

Lync 2013 logo 128x128One thing I see while doing Lync environmental health checks for some customers is some elevated accounts that are enabled for Lync. An example is members of the Domain Admins group. This can be somewhat problematic, especially for administration of those elevated accounts. For security reasons, it is not recommended to enable members of Domain Administrators group for Lync.

You cannot use Lync Server Control Panel to manage users who are members of the Domain Admins Active Directory group. For Domain Admins users, you can use Lync Server Control Panel only to perform read-only search operations. Attempting to perform write operations (such as enable or disable for Lync Server Control Panel, change pool or assigned policies, telephony settings, SIP address) on an elevated user will yield an “Access Denied” error. To perform write operations on a member of Domain Admins, you must use Lync Server Management Shell (PowerShell) cmdlets while logged on as a member of Domain Admins.

For more information please refer to this Microsoft page: User accounts enabled for Lync Server 2013

To query an elevated group, such as Domain Admins, for Lync enabled users, use the following:

(Get-ADGroupMember "Domain Admins").DistinguishedName | Get-CsUser -ErrorAction SilentlyContinue | Format-Table DisplayName,SipAddress

You can replace the “Domain Admins” with the name of any group, really. When you run it, you’ll end up with something like:

PS C:\> (Get-ADGroupMember "Domain Admins").DistinguishedName | Get-CsUser -ErrorAction SilentlyContinue | Format-Table DisplayName,SipAddress

DisplayName                                                 SipAddress
-----------                                                 ----------
Services                                                    sip:services@contoso.com
Dan Giles                                                   sip:dan.giles@contoso.com
Neil Armstrong                                              sip:neil.armstrong@contoso.com
Dawn Lopes                                                  sip:dawn.lopez@contoso.com
Bob Seger                                                   sip:bob.seger@contoso.com
Gail O'Grady                                                sip:gail.ogrady@contoso.com
Troy Dallas                                                 sip:Troy.Dallas@contoso.com
Steve Carrell                                               sip:steve.carrell@contoso.com

You can Lync disable these users for Lync, using the Disable-CsUser cmdlet. This can be done either individually using the -Identity parameter, or everyone at once by pipeline, with something like:

(Get-ADGroupMember "Domain Admins").DistinguishedName | Disable-CsUser -ErrorAction SilentlyContinue

If you have some accounts that were previously members of an elevated group like Domain Admins, but no longer are, then the AdminCount parameter on their account may still be set. This will cause the Access Denied issue to continue. You can manually change this on the user object using ADSIEDIT, or via a script such as Set-AdminUser.

Quality of Service (QoS) Calculator – Plan Your Network, GPO, and Lync Config More Easily

November 5th, 2014 4 comments

Description

When deploying Microsoft Lync Server, network health and configuration can be crucial.

The QoS Calculator allows you to pick and choose what components and clients will be used in your environment as well as which specific clients. You’re also able to pick a starting port number, port count, and DSCP value for each modality. The calculator will ensure that port ranges are consecutive, and that they don’t extend past 65535. The calculator will list all relevant Group Policy Object (GPO) settings, as well as the PowerShell commands needed to configure Lync Server. Clients available for configuration include Lync 2010 and Lync 2013 full client, Lync 2010 Attendant and Landis Computer’s Attendant Pro attendant clients, Windows Store App client, Lync Phone Edition, and more. Server side options include A/V conferencing, application sharing, Response Group Service applications, Conference Announcement service, Call Park, UCMA apps, PSTN audio, A/V Edge services, Exchange UM, and the VDI client.

To start with, go to the INPUT tab. Any of the green cells can be changed. Reset buttons allow you to set port and port count settings back to their original values. Future releases will also reset the DSCP values as well (just need to figure out how to do that in Office VBA). Red cells indicate an error (missing or incorrect data).

1

Enter your Front End and Edge pool FQDNs. If you have a separate mediation pool, enter that name as well. The values defined here are used to compose the PowerShell commands needed to configure Lync Server.

2

You can show/hide different policy types using the appropriate checkboxes.

qoscalculator3

If your Mediation role is collocated with your Front End servers, check the box. This will combine the appropriate GPO policies together.

qoscalculator4

Changes to green cells are immediately reflected elsewhere in the calculator.

Once you have the values entered/verified, go to the POLICIES tab to see a list of GPO settings needed. Check out Elan Shudnow’s awesome Enabling QoS for Lync Server 2013 and Various Clients and Jeff Schertz’s Lync Quality of Service Behavior for a deep dive into setting up QoS.

Next, go to the POWERSHELL-LYNC tab, and you’ll see the relevant Lync Management Shell commands to configure the server side based on the info you supplied. Copy and paste each into Lync Server Management Shell.

Lastly, go to the POWERSHELL-GPO tab, and you can copy and past PowerShell code into a PowerShell console on a domain controller to automatically create and configure the Group Policy Objects for server and client machines. Note that if your edge servers are not domain joined, the local security policy on the edge servers is used to configure QoS.

I have tons of ideas for more features and functionality. Feel free to comment below on things you’d like to see in future versions.

Syntax

None

Installation

None. Just open the file in Excel. As this is a macro based file, you’ll need to enable content when prompted.

Assumptions

None

Download

v1.2 – 02-27-2015 – Lync 2013 QoS Calculator v1.2.xksm

v1.1 – 01-26-2015 – Lync 2013 QoS Calculator v1.1.xslm

v1.0 – 11-5-2014 – Lync 2013 QoS Calculator v1.0.xlsm

Changelog

See the changelog for information on what’s changes/included in each version.

Changelog: QoS Calculator

November 5th, 2014 No comments

This is the changelog page for QoS Calculator. You will find a complete list of released versions, their dates, and the features and issues addressed in each. Please refer to the script’s main page for more information including download links, installation details, and more.

v1.1 – 01-26-2015

  1. Fixed server app sharing end port calculation. It was incorrectly showing an end port that was 1 higher than the correct amount.
  2. Moved edge server port definitions to destination instead of source
  3. Added fields to define trusted app ports, and SDN port. This will be used in the future to ensure there is no conflict in port assignments.
  4. Added configuration verification commands to PowerShell tab
  5. Fixed typo in PowerShell code for mediation server. Thanks to Andy.

v1.0 – 11-05-2014

  1. Initial version
Categories: Lync Server Tags:

Norway, Here I Come!

October 3rd, 2014 No comments

One of the great things about being involved in The UC Architects is all the people we meet. I’m part of a team of 15 of some really smart UC guys with TONS of experience. Nearly all are MVPs, some are MCMs, and all have a great deal of knowledge. With the collective reach of the individuals, we’ve made some amazing contacts.

So I was really excited (and honored) when I was invited to attend & host an episode at Norwegian Lync day on October 14. The Norwegian Lync Day will take place in Oslo, Norway, a locale I’ve yet to visit. It’s a one day conference with two tracks of sessions around Lync. Everything from Wi-Fi and BYOD, analytics and validation, to topics such as Hybrid, Skype, telephony and mobility. See the full session list in English here. With the exception of the keynote, everything else will be presented in English, which is good, because my Norwegian is pretty sad.

A pile of MVPs will be there, from fellow UC Architects host Steve Goodman and fellow Modality Systems colleague Tom Arbuthnot, to others including Martin Lidholm, Ståle Hansen, Tommy Clarke, Johan Delimon, and Adam Gent. MVPs will be participating in an Ask The Experts style event that will include Q&A, white boarding, etc. There will be tons of vendors there, so you can check out hardware, software, and services that are compatible with Lync.

My MVP and UC Architects colleague Stale Hansen has done a great video describing the event. Check it out below.

If you’re attending Norwegian Lync Day, stop by our live recording at 1600 and say hi! Or find me. I’ll be wearing a UC Architects t-shirt.

See you there!