Improve security with PowerShell’s constrained language mode

History has conclusively demonstrated that cyberattackers will take advantage of any perceived weakness in a system in order to gain access to a system. Although some have downplayed the idea that PowerShell can be used as a tool for attacking a system, there have been quite a few documented instances of attackers doing just that. Since PowerShell can sometimes be of interest to those who have bad intent, it is a good idea to harden PowerShell whenever possible in an effort to prevent it from being exploited. One option for doing so is to enable constrained language mode within your PowerShell sessions.

What is constrained language mode?

So what is the constrained language mode? Simply put, the mode is a tool that can be used to limit the types of commands that can be executed within a PowerShell session. Let me give you a really simple example.

If you look at the figure below, you can see that I have opened two separate PowerShell windows. The top window is completely normal. As you can see, I entered a mathematical expression into this window. This expression asks for the square root of 64. PowerShell returned a value of 8, which is the correct answer. The figure’s lower PowerShell window has the constrained language mode enabled. I entered exactly the same mathematical expression into this window, but received an error message telling me that PowerShell was unable to invoke the method.

OK, so what’s really going on here? How come the command failed in one window, but succeeded in another? The simple explanation is that constrained language mode allows you to continue using basic PowerShell cmdlets but blocks commands that can be used to interact with various APIs. The reason why the mathematical expression shown in the previous figure produced an error is because I was attempting to use .NET. Had I entered a simpler expression such as 2+2, the operation would have been allowed.

There is a long list of items that PowerShell either limits or blocks when constrained language mode is enabled. I won’t bore you with the full list, but some of the more noteworthy items include:

• COM objects
• Unapproved .NET types
• XAML based workflows
• PowerShell classes

Setting PowerShell’s constrained language mode

If you want to determine which language mode PowerShell is currently using, enter this command:


As you can see in the screenshot below, PowerShell is set to use full language mode, which means that constrained language mode is not enabled.

If you decide that you want to enable constrained delegation, you can do so by using a variation of the command shown above. Simply enter the command as before, but append =”ConstrainedLanguage”. The full command looks like this:

$ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage"

You can see what a switch from full language to constrained language looks like in the screenshot below.

PowerShell’s Achilles’ heel

The problem with using constrained delegation as a security feature is that depending on how it is implemented, it can be relatively easy for an attacker to get around it. The reason for this is that PowerShell’s language mode is session specific. Let me show you what I mean.

If you look at the screenshot below, you can see that I have two PowerShell windows open. I set the language mode of the window on the left to Constrained Language. I then verified the language mode to make sure that PowerShell really had been properly set to use constrained language. Next, I opened up the window on the right and checked PowerShell’s language mode. The PowerShell session running in that window is using full language, even though the session within the window on the left remains limited to using constrained language. In other words, if an attacker wants to gain access to the full language, then they need only to open another PowerShell session.

Two problems

Although constrained language mode can improve security, its use presents two big problems. First, as previously noted, constrained language mode is easy to circumvent because it is session specific. If an attacker wants to avoid constrained language mode, they can simply launch a new PowerShell session.

The second problem with using constrained language mode is that it can break your existing PowerShell scripts. I showed you an example earlier of a mathematical expression that could not be evaluated because doing so required the use of .NET. Just imagine if that expression had been a part of a script.

The trick to making the use of constrained language practical is to accept the idea that constrained language mode is not designed to be used by itself. Instead, constrained language mode is designed to be used in conjunction with Device Guard User Mode Code Integrity (UMCI).

For those who might not be familiar with UMCI, it is a tool that allows administrators to set policies describing the code that is allowed to run on the system. Because Device Guard runs on a system wide basis, it is ideal for enforcing the use of constrained language mode. An attacker will not be able to circumvent constrained language mode by opening a new PowerShell session, because Device Guard policies apply to the system as a whole, not solely to the current PowerShell session.

A powerful tool

Constrained language mode can be a very powerful tool for locking down PowerShell in an effort to prevent it from being used for nefarious purposes. Even so, it is completely ineffective by itself, because an attacker could bypass it by launching another PowerShell session, or simply disable it by entering a single command. In spite of its weaknesses however, constrained language mode can greatly enhance PowerShell’s security when it is used in conjunction with Device Guard User Mode Code Integrity.

Featured image: Shutterstock

Brien Posey

Brien Posey is a freelance technology author and speaker with over two decades of IT experience. Prior to going freelance, Brien was a CIO for a national chain of hospitals and healthcare facilities. He has also served as a network engineer for the United States Department of Defense at Fort Knox. In addition, Brien has worked as a network administrator for some of the largest insurance companies in America. To date, Brien has received Microsoft’s MVP award numerous times in categories including Windows Server, IIS, Exchange Server, and File Systems / Storage. You can visit Brien’s Website at:

Published by
Brien Posey
Tags Powershell

Recent Posts

Find what you need: Using PowerShell to parse Windows log files

There’s a lot of information in log files. Maybe too much information. Use PowerShell to…

12 hours ago

How to quickly check the status of all your Azure services

Error messages don’t always tell you what caused the problem with Azure.. Azure services status…

16 hours ago

Future-proofing operations with AI-powered predictive analytics

Is your organization faced with making tough decisions about staffing, remote work, and other matters?…

19 hours ago

3 startups leveraging the power of AI to modernize enterprises

With artificial intelligence, there’s no looking back. And these forward-looking startups are at the leading…

2 days ago

Mental health patients blackmailed following major hack in Finland

There are fewer things more evil than blackmailing patients of a psychotherapy clinic. But this…

2 days ago

Attracting IT pros with great tech talent in the time of COVID-19

COVID-19 has forced many to shelter-in-place — including IT pros who might otherwise look for…

2 days ago