Add support for new WLDP setting EnableFileOnlyEntry#26752
Add support for new WLDP setting EnableFileOnlyEntry#26752SeeminglyScience wants to merge 8 commits intoPowerShell:masterfrom
EnableFileOnlyEntry#26752Conversation
There was a problem hiding this comment.
Pull request overview
This pull request adds support for a new Windows Lockdown Policy (WLDP) setting called FileOnlyEntry that restricts PowerShell to only execute when a file is specified via the -File parameter and -NoExit is not present. This is intended for managed systems where interactive or ad-hoc PowerShell usage should be prevented.
Changes:
- Adds WLDP API integration to query the
FileOnlyEntrysetting with environment variable fallback for testing - Implements command-line parameter validation to enforce the policy across multiple entry points
- Provides test infrastructure and initial test cases for the new functionality
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 8 comments.
Show a summary per file
| File | Description |
|---|---|
| src/System.Management.Automation/security/wldpNativeMethods.cs | Adds P/Invoke declaration for WldpGetApplicationSettingBoolean, implements IsFileOnlyEntryEnabled() with caching and environment variable fallback, and provides reusable TestBooleanWldpSetting() helper method |
| src/Microsoft.PowerShell.ConsoleHost/host/msh/CommandLineParameterParser.cs | Adds FileOnlyEntry checks at multiple points: empty args, -NoExit, -Command/-EncodedCommand/-CommandWithArgs, -File -, and a final catch-all check |
| src/Microsoft.PowerShell.ConsoleHost/resources/CommandLineParameterParserStrings.resx | Adds error message string for FileOnlyEntry policy violations |
| test/tools/Modules/HelpersSecurity/HelpersSecurity.psm1 | Adds SetFileOnlyEntry and RevertFileOnlyEntry parameters to test cmdlet for setting/clearing the environment variable |
| test/powershell/Modules/Microsoft.PowerShell.Security/FileOnlyEntry.Tests.ps1 | Adds new test file with negative test cases for -NoExit -Command, -Command, -NoExit -File, and -File - scenarios |
test/powershell/Modules/Microsoft.PowerShell.Security/FileOnlyEntry.Tests.ps1
Show resolved
Hide resolved
test/powershell/Modules/Microsoft.PowerShell.Security/FileOnlyEntry.Tests.ps1
Show resolved
Hide resolved
| } | ||
| } | ||
|
|
||
| if (_error is null && (ParametersUsed & ParameterBitmap.File) is 0 && SystemPolicy.IsFileOnlyEntryEnabled()) |
There was a problem hiding this comment.
The FileOnlyEntry check at line 1278 will incorrectly reject informational commands like -Version and -Help, which don't execute any user code and should be allowed even when FileOnlyEntry is enabled. The check should exclude these scenarios. Consider modifying the condition to:
if (_error is null && !_showVersion && !_showHelp && (ParametersUsed & ParameterBitmap.File) is 0 && SystemPolicy.IsFileOnlyEntryEnabled())This ensures that -Version and -Help work even when the policy is enabled, since they only display information and don't execute scripts or commands.
| if (_error is null && (ParametersUsed & ParameterBitmap.File) is 0 && SystemPolicy.IsFileOnlyEntryEnabled()) | |
| if (_error is null && !_showVersion && !_showHelp && (ParametersUsed & ParameterBitmap.File) is 0 && SystemPolicy.IsFileOnlyEntryEnabled()) |
| $PwshParameterTestCases = @( | ||
| MakeTestCase -NoExit -Command Get-ChildItem | ||
| MakeTestCase -Command Get-ChildItem | ||
| # File validation should come after `FileOnlyEntry` check, so | ||
| # this file should not need to exist for us to get the error | ||
| # we expect. | ||
| MakeTestCase -NoExit -File this_file_does_not_exist.ps1 | ||
| MakeTestCase -File - | ||
| ) |
There was a problem hiding this comment.
The test suite should include test cases to verify that informational commands like -Version and -Help are still allowed when FileOnlyEntry is enabled, since they don't execute any user code. Consider adding test cases like:
pwsh -Versionshould succeed and display versionpwsh -Helpshould succeed and display helppwsh -?should succeed and display help
| Describe "File Only Entry throws for interactive or non-file scenarios" -Tags 'CI','RequireAdminOnWindows' { | ||
|
|
||
| BeforeAll { | ||
| function MakeTestCase { | ||
| param([Parameter(ValueFromRemainingArguments)] [string[]] $ArgumentList) | ||
| end { | ||
| @{ | ||
| Arguments = $ArgumentList | ||
| TestName = 'With args "{0}"' -f ($ArgumentList -join ' ') | ||
| } | ||
| } | ||
| } | ||
|
|
||
| [SuppressMessage('PSUseDeclaredVarsMoreThanAssignments', 'PwshParameterTestCases')] | ||
| $PwshParameterTestCases = @( | ||
| MakeTestCase -NoExit -Command Get-ChildItem | ||
| MakeTestCase -Command Get-ChildItem | ||
| # File validation should come after `FileOnlyEntry` check, so | ||
| # this file should not need to exist for us to get the error | ||
| # we expect. | ||
| MakeTestCase -NoExit -File this_file_does_not_exist.ps1 | ||
| MakeTestCase -File - | ||
| ) | ||
| } | ||
|
|
||
| It "<TestName>" -TestCases $PwshParameterTestCases { | ||
| param($Arguments) | ||
|
|
||
| $results = $null | ||
| try { | ||
| Invoke-LanguageModeTestingSupportCmdlet -SetFileOnlyEntry | ||
| if ($Arguments[-1] -eq '-') { | ||
| $results = 'Get-ChildItem' | & "$PSHOME\pwsh.exe" @Arguments 2>&1 | ||
| } else { | ||
| $results = & "$PSHOME\pwsh.exe" @Arguments 2>&1 | ||
| } | ||
| } finally { | ||
| Invoke-LanguageModeTestingSupportCmdlet -RevertFileOnlyEntry | ||
| } | ||
|
|
||
| $results.Exception.Message | Should -Be 'The parameter "-File" is required by policy.' | ||
| } | ||
| } |
There was a problem hiding this comment.
The test suite only covers negative test cases (scenarios that should be rejected). There should also be at least one positive test case to verify that legitimate file-based execution is still allowed when FileOnlyEntry is enabled. For example, a test that verifies pwsh.exe -File valid_script.ps1 succeeds when the policy is enabled.
PR Summary
Setting will ensure that managed systems will only launch PowerShell when a file to execute is specified and
-NoExitis not present. For use in systems where interactive or ad-hoc usage is not expected.PR Context
PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright header