Add Optional PSUseConstrainedLanguageMode rule#2165
Add Optional PSUseConstrainedLanguageMode rule#2165joshcorr wants to merge 13 commits intoPowerShell:mainfrom
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new optional ScriptAnalyzer rule (PSUseConstrainedLanguageMode) to detect PowerShell patterns that are incompatible with Constrained Language Mode (CLM), along with tests and documentation so users can opt into CLM-focused linting.
Changes:
- Added
UseConstrainedLanguageModerule implementation to detect multiple CLM-incompatible patterns, with special handling for signature blocks. - Added a comprehensive Pester test suite for the new rule.
- Added end-user documentation and new localized resource strings for diagnostics.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
Rules/UseConstrainedLanguageMode.cs |
Implements the new rule logic (CLM checks, signature-block detection, manifest checks). |
Tests/Rules/UseConstrainedLanguageMode.tests.ps1 |
Adds tests covering the new rule’s detections and signature behavior. |
docs/Rules/UseConstrainedLanguageMode.md |
Documents what the rule flags, signed vs unsigned behavior, and configuration. |
Rules/Strings.resx |
Adds diagnostic strings used by the new rule (and updates file header/encoding). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Rules/UseConstrainedLanguageMode.cs
Outdated
| /// When true, ignores script signatures and runs all CLM checks regardless of signature status. | ||
| /// When false (default), scripts with valid signatures are treated as having elevated permissions | ||
| /// and only critical checks (dot-sourcing, parameter types, manifests) are performed. | ||
| /// Set to true to enforce full CLM compliance even for signed scripts. |
| // Check if the variable was declared with a type constraint elsewhere | ||
| // Look for assignment statements with type constraints | ||
| var assignmentWithType = FindTypedAssignment(varExpr); | ||
| if (assignmentWithType != null) | ||
| { |
Rules/Strings.resx
Outdated
| @@ -1,17 +1,17 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| Context "Informational severity" { | ||
| It "Should have Information severity" { |
Rules/Strings.resx
Outdated
| <value>Module manifest field '{0}' uses wildcard ('*') which is not recommended for Constrained Language Mode. Explicitly list exported items instead.</value> | ||
| </data> | ||
| <data name="UseConstrainedLanguageModeScriptModuleError" xml:space="preserve"> | ||
| <value>Module manifest field '{0}' contains script file '{1}' (.ps1). Use binary modules (.psm1 or .dll) instead for Constrained Language Mode compatibility.</value> |
|
|
||
| Use `New-Object PSObject` with `Add-Member` or hashtables instead of classes. | ||
|
|
||
| **Important**: `[PSCustomObject]@{}` syntax is NOT allowed in CLM because it uses type casting. |
|
👋 @joshcorr, I wonder if Perhaps something like |
PR Summary
This PR adds a new rule PSUseConstrainedLanguageMode that identifies PowerShell patterns incompatible with Constrained Language Mode, helping developers ensure scripts work in restricted environments. This rule is a Warning, but is optional and not enabled by default.
New files:
Rules/UseConstrainedLanguageMode.cs- Implements 14 CLM restriction checksTests/Rules/UseConstrainedLanguageMode.tests.ps1- Adds 46 comprehensive testsdocs/Rules/UseConstrainedLanguageMode.md- Provides complete user documentationModified files;
Rules/strings.resx- Adds 16 new diagnostic message stringsFeatures
Detects CLM Violations:
Signature Awareness:
Array Type Support:
Configuration:
Testing:

PR Checklist
.cs,.ps1and.psm1files have the correct copyright headerWIP:to the beginning of the title and remove the prefix when the PR is ready.