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

Exchange 2019: Peaceful coexistence with Exchange 2016

Exchange coexistence has been around for a long time. This can be having Exchange 2010…

1 hour ago

How to check the VM sizes available on your Azure Region

If you want to check VM sizes available to any given region, Azure Portal is…

4 hours ago

Cybersecurity 101: Close the door on open network shares

If you have open network shares on your network, you are opening the door to…

21 hours ago

Spear-phishing email results in U.S. gas pipeline ransomware attack

A spear-phishing email has resulted in a U.S. gas pipeline ransomware attack. Making the attack…

1 day ago

Planning your Azure reserved instances and flexibility groups

To really lower your Azure costs, you need actionable information. Get info on flexibility groups…

1 day ago

MGM Resorts customer data breach still being utilized by hackers

Data stolen from breaches often live on forever, as appears to be the case with…

2 days ago