Skip to content
This repository has been archived by the owner on Dec 11, 2020. It is now read-only.

'VisibleCmdlets' and 'VisibleFunctions' break internal functions usage #42

Open
jnury opened this issue Mar 9, 2018 · 7 comments
Open

Comments

@jnury
Copy link
Contributor

jnury commented Mar 9, 2018

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.

@rpsqrd
Copy link
Collaborator

rpsqrd commented Mar 9, 2018

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

@jnury
Copy link
Contributor Author

jnury commented Mar 9, 2018

Unfortunately it's exactly the same. We tried many different workarounds and never got back functions :-/

@rpsqrd
Copy link
Collaborator

rpsqrd commented Mar 9, 2018

@PaulHigin Any tips for Julien? I'm not sure why the built-in commands would stop working inside custom functions.

@jnury
Copy link
Contributor Author

jnury commented Mar 11, 2018

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

@PaulHigin
Copy link

I'll take a look.

@PaulHigin
Copy link

@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.

@jnury
Copy link
Contributor Author

jnury commented Apr 25, 2018

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.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants