5.3 Just Enough Administration (JEA) for Constrained PowerShell Endpoints
Key Takeaways
- JEA requires two files: a role capability file (.psrc) listing permitted cmdlets, functions and parameter values, and a session configuration file (.pssc) mapping security groups to those roles.
- RunAsVirtualAccount grants the session local administrative privilege for the duration of the connection, so the connecting user needs no standing administrative rights.
- Role capability files must live in a RoleCapabilities folder inside a valid PowerShell module for the .pssc to resolve them by name.
- Register-PSSessionConfiguration publishes the endpoint, and clients reach it with the -ConfigurationName parameter rather than the default Microsoft.PowerShell endpoint.
- TranscriptDirectory writes a per-session transcript, which is the audit evidence that a delegated help-desk action actually took place.
Just Enough Administration (JEA) for Constrained PowerShell Endpoints
PowerShell Remoting as configured so far is all-or-nothing: a user who can enter a session on a server generally does so with the full rights of their account. That is unacceptable for help-desk delegation, where the requirement is "restart the print spooler on any file server" and nothing more. Just Enough Administration (JEA) solves it by constraining what a connected user may run, and by supplying the privilege from a temporary virtual account rather than from the user.
1. Just Enough Administration (JEA) Architecture & Configuration
Just Enough Administration (JEA) is a role-based security technology built into PowerShell that enforces the principle of least privilege. JEA locks down a remote PowerShell endpoint so that non-administrative users (such as Help Desk or junior operators) can perform specific administrative tasks without being members of the Local Administrators or Domain Admins security groups.
+-----------------------------------------------------------------------------------------+
| JEA ARCHITECTURE & PIPELINE |
| |
| [Connecting User: HelpDesk_User] (Has NO Admin Rights on Target) |
| | |
| | 1. Enter-PSSession -ComputerName Srv01 -ConfigurationName 'HelpDeskOps' |
| v |
| +-----------------------------------------------------------------------------------+ |
| | JEA ENDPOINT ('HelpDeskOps') | |
| | | |
| | +-----------------------------------------------------------------------------+ | |
| | | [Session Configuration File: (.pssc)] | | |
| | | - SessionType = 'RestrictedRemoteServer' (No-Language Mode) | | |
| | | - RunAsVirtualAccount = $true (Spawns temporary Local System Virtual Admin) | | |
| | | - TranscriptDirectory = 'C:\ProgramData\JEA\Transcripts' (Auditing) | | |
| | | - RoleDefinitions = @{ 'CORP\HelpDeskGroup' = @{ RoleCapabilities = 'DNS' }}| | |
| | +-----------------------------------------------------------------------------+ | |
| | | | |
| | v Maps to Role Capability | |
| | +-----------------------------------------------------------------------------+ | |
| | | [Role Capability File: (.psrc)] | | |
| | | - VisibleCmdlets = 'Restart-Service', @{ Name='Get-Service'; Parameters=..} | | |
| | | - VisibleFunctions = 'Clear-DnsClientCache' | | |
| | | - VisibleAliases = 'gsv' | | |
| | +-----------------------------------------------------------------------------+ | |
| +-----------------------------------------------------------------------------------+ |
+-----------------------------------------------------------------------------------------+
The Two JEA Configuration Files:
- Role Capability File (
.psrc): Defines what an authorized user can do. It specifies allowed cmdlets, functions, external executables, and parameter restrictions (e.g., allowingRestart-Serviceonly when-Nameequals'Spooler'). Role capability files reside inside aRoleCapabilitiesfolder within a PowerShell module path. - Session Configuration File (
.pssc): Defines who can connect and how the session executes. It maps Active Directory security groups to specific Role Capabilities, enables virtual administrative accounts (RunAsVirtualAccount = $true), and configures over-the-shoulder transcript auditing (TranscriptDirectory).
Step-by-Step JEA Authoring & Registration
Step 1: Create the Role Capability File (.psrc)
# Create directory inside module path
$ModulePath = "C:\Program Files\WindowsPowerShell\Modules\JEARoles\RoleCapabilities"
New-Item -ItemType Directory -Path $ModulePath -Force
# Author Role Capability File
New-PSRoleCapabilityFile -Path "$ModulePath\HelpDeskMaintenance.psrc" `
-VisibleCmdlets @(
'Get-Service',
@{ Name = 'Restart-Service'; Parameters = @{ Name = 'Name'; ValidateSet = @('Spooler', 'W32Time') } }
) `
-VisibleFunctions @('Get-ProcessInfo') `
-FunctionDefinitions @(
@{ Name = 'Get-ProcessInfo'; ScriptBlock = { Get-Process | Sort-Object CPU -Descending | Select-Object -First 10 } }
)
Step 2: Create the Session Configuration File (.pssc)
# Author Session Configuration File
New-PSSessionConfigurationFile -Path "C:\JEA\HelpDeskEndpoint.pssc" `
-SessionType 'RestrictedRemoteServer' `
-RunAsVirtualAccount `
-TranscriptDirectory 'C:\JEA\Transcripts' `
-RoleDefinitions @{
'CORP\Tier1-HelpDesk' = @{ RoleCapabilities = 'HelpDeskMaintenance' }
}
Step 3: Register the JEA Configuration
# Register the endpoint on the target server
Register-PSSessionConfiguration -Name 'HelpDeskOps' -Path "C:\JEA\HelpDeskEndpoint.pssc" -Force
# Test connection from non-admin client
Enter-PSSession -ComputerName 'SRV-FILE-01' -ConfigurationName 'HelpDeskOps'
2. Virtual Accounts, Group-Managed Service Accounts and Session Types
The identity a JEA session runs under is the reason the model is secure, and it is chosen in the .pssc:
| Setting | Runs commands as | Use when |
|---|---|---|
RunAsVirtualAccount = $true | A temporary machine-local administrator account created for the session | The delegated tasks are local to the target server — the common case |
GroupManagedServiceAccount = 'CORP\gMSA-JEA$' | A gMSA with a domain identity | The delegated tasks reach other machines, where a machine-local virtual account has no rights |
| Neither specified | The connecting user | Rarely useful — it defeats the purpose of JEA |
RunAsVirtualAccountGroups narrows the virtual account further: instead of local Administrators, the account is placed only in the groups you list, such as Network Configuration Operators.
The SessionType value is equally consequential. RestrictedRemoteServer is the JEA session type: it starts with the language mode set to NoLanguage and exposes only Exit-PSSession, Get-Command, Get-FormatData, Get-Help, Measure-Object, Out-Default and Select-Object. Everything else a user is allowed to run must be added explicitly by a role capability. NoLanguage mode is what prevents a delegated operator from escaping the constraint through an expression such as Invoke-Expression or a script block.
Constraining Parameters, Not Just Cmdlets
Allowing Restart-Service outright still lets a help-desk operator restart NTDS on a domain controller. Role capabilities can pin parameter values:
# Inside the .psrc — allow only these three services to be restarted
VisibleCmdlets = @(
@{ Name = 'Restart-Service'; Parameters = @{ Name = 'Name'; ValidateSet = 'Spooler','W3SVC','BITS' } },
@{ Name = 'Get-Service' },
'Get-EventLog'
)
# Expose a purpose-built function instead of the underlying cmdlet
VisibleFunctions = @(
@{ Name = 'Repair-BranchPrintQueue'; ScriptBlock = { Restart-Service -Name Spooler -Force } }
)
[!IMPORTANT] A role capability file is only discovered if it sits in a
RoleCapabilitiesfolder inside a valid PowerShell module on the target server — for exampleC:\Program Files\WindowsPowerShell\Modules\JEAHelpDesk\RoleCapabilities\HelpDeskMaintenance.psrc. Placing the.psrcnext to the.psscand referencing it by name is the most common JEA registration failure.
3. Operating, Auditing and Removing a JEA Endpoint
# What endpoints exist on this server, and what does this one expose to me?
Get-PSSessionConfiguration | Format-Table Name,PSVersion,Permission
Invoke-Command -ComputerName 'SRV-FILE-01' -ConfigurationName 'HelpDeskOps' -ScriptBlock { Get-Command }
# Validate a configuration file before registering it
Test-PSSessionConfigurationFile -Path 'C:\JEA\HelpDeskEndpoint.pssc'
# Remove an endpoint (WinRM restart is required for the change to take effect)
Unregister-PSSessionConfiguration -Name 'HelpDeskOps' -Force
Restart-Service WinRM
Because TranscriptDirectory was set at registration, every session writes a transcript recording the connecting user, the virtual account used, and each command executed. Those transcripts, not the Security event log, are the primary audit artefact for delegated JEA administration — collect them centrally, because they are written on the target server and a local administrator can delete them.
You are designing a Just Enough Administration (JEA) endpoint to allow Tier 1 help desk technicians to restart the Print Spooler service on print servers without granting them local administrative privileges. Which configuration architecture correctly implements this requirement?
A JEA endpoint is registered with SessionType RestrictedRemoteServer and a role capability that makes Restart-Service visible. A help-desk operator connects and restarts the NTDS service on a domain controller. How should the role capability have been written?