Documentation Index
Fetch the complete documentation index at: https://tally.wharflab.com/llms.txt
Use this file to discover all available pages before exploring further.
powershell/PSUseConstrainedLanguageMode is a PSScriptAnalyzer diagnostic emitted by tally for PowerShell snippets embedded in Dockerfiles.
| Property | Value |
|---|---|
| Severity | Warning |
| Category | PSScriptAnalyzer |
| Auto-fix | No |
Description
This rule identifies PowerShell patterns that are restricted or not permitted in Constrained Language Mode (CLM). Constrained Language Mode is a PowerShell security feature that restricts:- .NET types that can be used
- COM objects that can be instantiated
- Commands that can be executed
- Language features that can be used
- Application Control environments (Application Control for Business, AppLocker)
- Just Enough Administration (JEA) endpoints
- Secure environments requiring additional PowerShell restrictions
# SIG # Begin signature block) and adjusts checks
accordingly. Most restrictions don’t apply to signed scripts, but certain checks (dot-sourcing,
parameter types, manifest best practices) are always enforced.
[!IMPORTANT] The rule performs a simple text check for signature blocks and does NOT validate signature authenticity or certificate trust. Actual signature validation is performed by PowerShell at runtime.
Constrained Language Mode Restrictions
Unsigned Scripts (Full CLM Checking)
The following are flagged for unsigned scripts:- Add-Type - Code compilation not permitted
- Disallowed COM Objects - Only Scripting.Dictionary, Scripting.FileSystemObject, VBScript.RegExp allowed
- Disallowed .NET Types - Only ~70 allowed types (string, int, hashtable, pscredential, etc.)
- Type Constraints - On parameters and variables
- Type Expressions - Static type references like
[Type]::Method() - Type Casts - Converting to disallowed types
- Member Invocations - Methods/properties on disallowed types
- PowerShell Classes -
classkeyword not permitted - XAML/WPF - Not permitted
- Invoke-Expression - Restricted
- Dot-Sourcing - May be restricted depending on the file being sourced
- Module Manifest Wildcards - Wildcard exports not recommended
- Module Manifest .ps1 Files - Script modules ending with .ps1 not allowed
Signed Scripts (Selective Checking)
For scripts with signature blocks, only these are checked:- Dot-sourcing
- Parameter type constraints
- Module manifest wildcards (.psd1 files)
- Module manifest script modules (.psd1 files)
Configuration
Basic Configuration
Parameters
Enable: bool (Default value is $false)
Enable or disable the rule during ScriptAnalyzer invocation. This rule is disabled by default
because not all scripts need CLM compatibility.
IgnoreSignatures: bool (Default value is $false)
Control signature detection behavior:
$false(default): Automatically detect signatures. Signed scripts get selective checking, unsigned get full checking.$true: Bypass signature detection. ALL scripts get full CLM checking regardless of signature status.
IgnoreSignatures = $true when:
- Auditing signed scripts for complete CLM compatibility
- Preparing scripts for untrusted environments
- Enforcing strict CLM compliance organization-wide
- Development/testing to see all potential issues
How to Fix
Replace Add-Type
Use allowed cmdlets or pre-compile assemblies.Replace Disallowed COM Objects
Use only allowed COM objects (Scripting.Dictionary, Scripting.FileSystemObject, VBScript.RegExp) or PowerShell cmdlets.Replace Disallowed Types
Use allowed type accelerators ([string], [int], [hashtable], etc.) or allowed cmdlets instead
of disallowed .NET types.
Replace PowerShell Classes
UseNew-Object PSObject with Add-Member or hashtables instead of classes.
[!IMPORTANT]
[PSCustomObject]@{} syntax is NOT allowed in CLM because it uses type casting.
Avoid XAML
Don’t use WPF/XAML in CLM-compatible scripts.Replace Invoke-Expression
Use direct execution (&) or safer alternatives.
Replace Dot-Sourcing
Use modules with Import-Module instead of dot-sourcing when possible.Fix Module Manifests
- Replace wildcard exports (
*) with explicit lists. - Use
.psm1or.dllinstead of.ps1for RootModule/NestedModules. - Don’t use
ScriptsToProcess. These scripts are loaded in the caller’s scope and are blocked.
Examples
Example 1: Add-Type
Wrong
Correct
Example 2: COM Objects
Wrong
Correct
Example 3: Disallowed Types
Wrong
Correct
Example 4: PowerShell Classes
Wrong
Correct
Example 5: Module Manifests
Wrong
Correct
Example 6: Array Types
Wrong
Correct
Detailed Restrictions
1. Add-Type
Add-Type allows compiling arbitrary C# code and isn’t permitted in CLM.
Enforced For: Unsigned scripts only
2. COM Objects
Only three COM objects are allowed:Scripting.DictionaryScripting.FileSystemObjectVBScript.RegExp
3. .NET Types
Only ~70 allowed types including:- Primitives:
string,int,bool,byte,char,datetime,decimal,double, etc. - Collections:
hashtable,array,arraylist - PowerShell:
pscredential,psobject,securestring - Utilities:
regex,guid,version,uri,xml - Arrays:
string[],int[][], etc. (array of any allowed type)
- Parameter type constraints (always enforced, even for signed scripts)
- Variable type constraints
- New-Object -TypeName
- Type expressions (
[Type]::Method()) - Type casts (
[Type]$variable) - Member invocations on typed variables
4. PowerShell Classes
Theclass keyword is not permitted. Use New-Object PSObject with Add-Member or hashtables.
Note: [PSCustomObject]@{} is also not allowed because it uses type casting.
Enforced For: Unsigned scripts only
5. XAML/WPF
XAML and WPF are not permitted in CLM. Enforced For: Unsigned scripts only6. Invoke-Expression
Invoke-Expression is restricted in CLM.
Enforced For: Unsigned scripts only
7. Dot-Sourcing
Dot-sourcing (. $PSScriptRoot\script.ps1) may be restricted depending on source location.
Enforced For: ALL scripts (unsigned and signed)
8. Module Manifest Best Practices
Wildcard Exports
Don’t use* in: FunctionsToExport, CmdletsToExport, AliasesToExport, VariablesToExport
Use explicit lists for security and clarity.
Enforced For: ALL .psd1 files (unsigned and signed)
Script Module Files
Don’t use.ps1 files in: RootModule, ModuleToProcess, NestedModules
Use .psm1 (script modules) or .dll (binary modules) for better performance and compatibility.
Enforced For: ALL .psd1 files (unsigned and signed)
More Information
- About Language Modes
- PowerShell Constrained Language Mode and the Dot-Source Operator
- PowerShell Constrained Language Mode
- PowerShell Module Function Export in Constrained Language