Determining Language Packs (Part 1)

by Jul 21, 2022

Let’s assume you need to find the installed language packs for a Windows machine. In this three-part series, we use PowerShell’s features to tackle this problem.

In part 1, we simply try and solve the issue by looking for a native non-PowerShell command that we could utilize.

As it turns out, the command dism.exe can find out that information for you. However, as with so many binary console commands, the results are (a) localized, (b) string data and (c) often require Administrator privileges.

If we had no other choice, as an Admin you can run this:

DISM.exe /Online /Get-Intl /English

Next, you can use PowerShell features to filter and track down the information until you find what you need.

For example, use Select-String to select only those lines that are interesting for your task:

DISM.exe /Online /Get-Intl /English |
  Select-String -SimpleMatch 'Installed language(s)'

The result looks like this now:

Installed language(s): de-DE
Installed language(s): en-US
Installed language(s): fr-FR  

Next, use PowerShell pipeline mechanism to “polish” each result and extract the info you really need:

DISM.exe /Online /Get-Intl /English |
  Select-String -SimpleMatch 'Installed language(s)' |
  ForEach-Object { $_.Line.Split(':')[-1].Trim() } 

Here, each line is taken, then splitted by the colon, then the last (right) part taken and all whitespace eliminated. That’s cumbersome but at the end gets you the results from the raw string data.

In fact, Select-String really uses a regular expression pattern so if you understand regular expressions, you could have as well queried for the required information right away:

DISM.exe /Online /Get-Intl /English |
  Select-String -Pattern 'Installed language\(s\):\s(.*?)$' |
  ForEach-Object { $_.Matches[0].Groups[1].Value }

Note how in the code example we used -Pattern and omitted -SimplePattern, thus telling Select-String that we are using full regular expressions. The search pattern now uses “\” to escape all special characters and defines a set of parentheses to define the value we are looking for, located after the search text and the end of line “$”).

Select-String then returns regular expression matches in its property “Matches”, so from here we can access the found matches and groups in an object-oriented manner. The information we were looking for was in the first match (per line, index 0), and here in the second group (index 0 is the entire match, index 1 is the match inside the first parenthesis).

If this is all too low-level for you, wait for our next tip!

Twitter This Tip! ReTweet this Tip!