JEA
JEA copied to clipboard
'VisibleCmdlets' and 'VisibleFunctions' break internal functions usage
With the following PowerShell version:
Name Value
---- -----
PSVersion 5.1.14409.1012
PSEdition Desktop
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0...}
BuildVersion 10.0.14409.1012
CLRVersion 4.0.30319.42000
WSManStackVersion 3.0
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
If I use VisibleCmdlets or VisibleFunctions in a RoleCapability file, module functions are no more available for other functions.
How to reproduce
A PSSessionConfiguration file, 'Test-JEA.pssc':
@{
GUID = 'd919b726-67f7-4f43-b340-3e1240375d90'
SessionType = 'RestrictedRemoteServer'
RunAsVirtualAccount = $true
RoleDefinitions = @{ 'UNDISLAB\Administrator' = @{ RoleCapabilities = 'Test-JEA' } }
}
Registered with the command:
Register-PSSessionConfiguration -Path .\Test-JEA.pssc -Name Test-JEA
A RoleCapability file, 'Test-JEA.psrc' in the folder 'C:\Program Files\WindowsPowerShell\Modules\Test-JEA\RoleCapabilities':
@{
GUID = 'c847874d-614a-4eca-afeb-a913b82d77a2'
FunctionDefinitions = @(
@{Name = 'GetUtilityCommand'; ScriptBlock = { Get-Command | Where-Object { $_.Source -eq 'Microsoft.PowerShell.Utility' }}}
@{Name = 'TestGuid'; ScriptBlock = { New-Guid}}
)
}
If I enter in the Test-JEA PSSession, TestGuid function works and GetUtilityCommand returns a list of functions and cmdlets from the Microsoft.PowerShell.Utility module:
PS C:\Users\administrator.UNDISLAB\Desktop> Enter-PSSession -ComputerName localhost -ConfigurationName Test-JEA
[localhost]: PS>Get-Command
CommandType Name Version Source
----------- ---- ------- ------
Function Clear-Host
Function Exit-PSSession
Function Get-Command
Function Get-FormatData
Function Get-Help
Function GetUtilityCommand
Function Measure-Object
Function TestGuid
Function Out-Default
Function Select-Object
[localhost]: PS>TestGuid
Guid
----
ac4de845-0977-4604-a6ea-714ee6e916ed
[localhost]: PS>getutilitycommand
CommandType Name Version Source
----------- ---- ------- ------
Function ConvertFrom-SddlString 3.1.0.0 Microsoft.PowerShell.Utility
Function Format-Hex 3.1.0.0 Microsoft.PowerShell.Utility
Function Get-FileHash 3.1.0.0 Microsoft.PowerShell.Utility
Function Import-PowerShellDataFile 3.1.0.0 Microsoft.PowerShell.Utility
Function New-Guid 3.1.0.0 Microsoft.PowerShell.Utility
Function New-TemporaryFile 3.1.0.0 Microsoft.PowerShell.Utility
Cmdlet Add-Member 3.0.0.0 Microsoft.PowerShell.Utility
Cmdlet Add-Type 3.0.0.0 Microsoft.PowerShell.Utility
Cmdlet Clear-Variable 3.0.0.0 Microsoft.PowerShell.Utility
...
Now if I want to allow the Clear-Variable cmdlet, in the 'Test-JEA.psrc' file:
@{
GUID = 'c847874d-614a-4eca-afeb-a913b82d77a2'
VisibleCmdLets = 'Clear-Variable'
VisibleFunctions = 'GetUtilityCommand', 'TestGuid'
FunctionDefinitions = @(
@{Name = 'GetUtilityCommand'; ScriptBlock = { Get-Command | Where-Object { $_.Source -eq 'Microsoft.PowerShell.Utility' }}}
@{Name = 'TestGuid'; ScriptBlock = { New-Guid}}
)
}
The Clear-Variable CmdLet is available, GetUtilityCommand and TestGuid functions are available too. But function TestGuid doesn't work as the New-Guid function is no more available. GetUtilityCommand now only returns cmdlets; functions have disappeared from Microsoft.PowerShell.Utility module:
PS C:\Users\administrator.UNDISLAB\Desktop> Enter-PSSession -ComputerName localhost -ConfigurationName Test-JEA
[localhost]: PS>Get-Command
CommandType Name Version Source
----------- ---- ------- ------
Function Clear-Host
Function Exit-PSSession
Function Get-Command
Function Get-FormatData
Function Get-Help
Function GetUtilityCommand
Function Measure-Object
Function TestGuid
Function Out-Default
Function Select-Object
Cmdlet Clear-Variable 3.0.0.0 Microsoft.PowerShell.Utility
[localhost]: PS>TestGuid
New-Guid : The term 'New-Guid' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:2
+ New-Guid
+ ~~~~~~~~
+ CategoryInfo : ObjectNotFound: (New-Guid:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
[localhost]: PS>GetUtilityCommand
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Add-Member 3.0.0.0 Microsoft.PowerShell.Utility
Cmdlet Add-Type 3.0.0.0 Microsoft.PowerShell.Utility
Cmdlet Clear-Variable 3.0.0.0 Microsoft.PowerShell.Utility
...
Using only VisibleCmdLets or VisibleFunctions do the same result.
Expected behavior
The expected behavior is that VisibleCmdlets or VisibleFunctions only affect 'Visible' cmdlet or function but not available functions for internal use
Impact
This is a huge problem as VisibleCmdlets is a main feature of JEA and many modules or custom scripts use functions. In our use case, we would-like to expose Pester based custom functions for monitoring purpose, but Pester cannot load without functions.
Can you try adding Microsoft.PowerShell.Utility to ModulesToImport in your PSRC? JEA can get funny with dependencies because the module discovery and auto-loading doesn't work the same as it does in a full language session. We generally recommend adding any modules called inside custom scripts or functions to ModulesToImport to ensure they're pre-loaded into the session. You can also try fully qualifying the cmdlet name in your function definition: Microsoft.PowerShell.Utility\Clear-Variable
Unfortunately it's exactly the same. We tried many different workarounds and never got back functions :-/
@PaulHigin Any tips for Julien? I'm not sure why the built-in commands would stop working inside custom functions.
I provided some workarounds on this page: https://jnury.github.io/JEA_term_not_recognized_name_cmdlet/
By the way, I only found 6 functions affected:
- ConvertFrom-SddlString
- Format-Hex
- Get-FileHash
- Import-PowerShellDataFile
- New-Guid
- New-TemporaryFile
These functions are all provided by the Microsoft.PowerShell.Utility module
I'll take a look.
@jnury Thanks for reporting this. I am able to reproduce the problem. This is old endpoint configuration code that imports core modules into the restricted session through "snapins". The Microsoft.PowerShell.Utility module consists of binary and script components but snapins only deal with the binary component and leave the script out, which is why the script functions are not available.
I think this is just old legacy code that should be re-written to use module loading rather than snapins. Can you create an issue on https://github.com/powershell/powershell? I believe the fix is to re-write how core modules are loaded in the InitialSessionState.CreateRestrictedForRemoteServer() method.
Thank-you @PaulHigin ! I found this issue on UserVoice: https://windowsserver.uservoice.com/forums/301869-powershell/suggestions/17852350-wmf-5-1-restrictedremoteserver-session-type-fails so just voted and commented on it. If i can reproduce the behaviour on Powershell Core, I'll open an issue on GitHub.