PowerShell Constrained Language Mode limits syntax, not every command
Application control policies can force PowerShell into Constrained Language Mode. In that mode, PowerShell permits all cmdlets but restricts the language elements and object types that scripts can use. The behavior is a useful containment layer on managed Windows hosts, yet it is often described as if it blocked every dangerous action. The actual boundary is narrower and depends on the cmdlets and application control policy around it.
Microsoft documents that PowerShell automatically runs in Constrained Language Mode when it starts under a system application control policy. Windows App Control for Business and AppLocker can enforce that policy. The mode limits method invocation, property setters, and access to arbitrary types, while still allowing approved commands and a subset of the language. A script that only uses cmdlets may continue to read, write, or invoke services even when method calls fail.
This distinction matters during incident response. A blocked [System.IO.File]::WriteAllText() call does not prove that no file operation is possible. An allowed cmdlet can perform a file operation for the user. Review the effective language mode together with the script policy, the signed or approved files, the user's privileges, and the cmdlet surface available on the host.
Establish the enforcement path
Start by confirming which application control policy is active and which script rules apply. Microsoft notes that AppLocker can block a script while still causing PowerShell to run in Constrained Language Mode. Windows App Control for Business has its own script enforcement behavior. The resulting mode can vary with PowerShell version, policy, and whether the process is interactive or launched by an agent.
Check $ExecutionContext.SessionState.LanguageMode in a controlled session, then repeat from the launch paths that matter: an interactive administrator shell, a scheduled task, a management agent, and a service wrapper. A host can appear constrained in one path and full language in another. Record the executable path, version, user, parent process, and policy result for each test.
The policy should identify the scripts or publishers allowed to run in FullLanguage mode and keep that list small. A broad allow rule for a scripting host can defeat the intended control. Review signed script deployment, allowed publisher certificates, and the rules that govern removable or temporary paths. A valid signature is a supply-chain decision; it does not make a script's actions appropriate on every host.
Test the cmdlet surface
Constrained Language Mode is not a cmdlet allowlist. Enumerate the commands that remain available to the target user and assess the operations they expose. A management cmdlet that changes a service, schedules a task, edits a registry value, or retrieves credentials can still be powerful. The application control policy, PowerShell profiles, module paths, and Windows role configuration determine what is present.
Use a test account with the same group membership as production. Run harmless probes against each relevant command family and record the result. Do not test destructive operations on production. Review the audit log for the command and script block so that you know what evidence remains when a blocked expression fails. If the logging pipeline drops the event, the containment control becomes harder to investigate.
PowerShell's security features documentation calls the system application control policy a form of system lockdown. Treat that phrase as a policy relationship, not a guarantee. An approved script that runs a signed binary, loads a module from an allowed path, or invokes a remote management endpoint still needs its own review. CLM changes the language, not the authority of the cmdlet or the process token.
Measure drift and exceptions
Track the language mode reported by endpoints and alert when a host that should be constrained reports FullLanguage. A mode change can follow a policy edit, a PowerShell upgrade, a launch path outside the policy, or an unauthorized local change. Keep the expected mode per host role and compare it with the observed value.
Review exception processes. A temporary FullLanguage rule for a maintenance task should have an owner, an expiration, and a removal check. After the task, verify that the host returns to the constrained state and that the exception is no longer effective. Audit logs should show the policy change and the process that applied it.
Constrained Language Mode is strongest when it is one layer in a managed application control design. Pair it with least privilege, restricted module paths, code integrity, script logging, and a small set of approved administrative tools. The review question is not only whether PowerShell says ConstrainedLanguage; it is which commands, files, and services the remaining session can still reach.
Top comments (0)