← All posts

Just Enough Administration (JEA): Constraining PowerShell Remoting to Least-Privilege Endpoints

Standing local-admin on every box is a lateral-movement gift. JEA lets you expose only the exact PowerShell commands an admin needs, run under a virtual account, with full transcription.

Most Windows environments hand out administrative access like a hotel keycard: one credential opens every door. A help-desk tech who only ever restarts a stuck print spooler is a full local admin. A junior sysadmin who patches a line-of-business app has Domain Admins because that was the fastest way to make the deployment work. Every one of those accounts is a complete lateral-movement path for anyone who phishes the user or dumps the credential from memory. Just Enough Administration (JEA) is Microsoft's built-in answer, and it ships free in Windows — no agent, no licence, no cloud dependency.

What JEA actually does

JEA is a feature of PowerShell Remoting (WinRM). Instead of letting a connecting user land in a full, unrestricted PowerShell session, you register a constrained endpoint — a session configuration — that:

The result: the help-desk tech can run Restart-Service Spooler on a server where they have no standing rights at all, and literally nothing else.

The two files that define a role

A JEA configuration is just two artifacts. A Role Capability file (.psrc) describes what a role may do, and a Session Configuration file (.pssc) maps AD groups to those roles and sets the run-as identity.

# HelpDesk.psrc — what this role can touch
New-PSRoleCapabilityFile -Path .\HelpDesk.psrc `
  -VisibleCmdlets 'Get-Service',
    @{ Name = 'Restart-Service'; Parameters = @{ Name = 'Name'; ValidateSet = 'Spooler','W32Time' } },
    'Get-EventLog'

# JeaEndpoint.pssc — who maps to it, and as whom it runs
New-PSSessionConfigurationFile -Path .\JeaEndpoint.pssc `
  -SessionType RestrictedRemoteServer `
  -RunAsVirtualAccount `
  -TranscriptDirectory 'C:\ProgramData\JEATranscripts' `
  -RoleDefinitions @{ 'CONTOSO\HelpDesk' = @{ RoleCapabilities = 'HelpDesk' } }

Register-PSSessionConfiguration -Name 'HelpDesk' -Path .\JeaEndpoint.pssc

Note the ValidateSet on Restart-Service: the tech can restart the Spooler and the Time service and nothing else. Not the antivirus service, not the EDR agent, not WinRM itself. That parameter-value constraint is where JEA pulls ahead of plain RBAC.

Why this beats local-admin groups

If an attacker steals a JEA user's credential, they inherit the user's constrained endpoint — a handful of parameter-locked cmdlets — not a SYSTEM shell.

Compare the blast radius. A compromised standing-admin account means credential theft from LSASS, token impersonation, scheduled-task persistence, and free lateral movement. A compromised JEA-only account means the attacker can connect and run Get-Service. There is no interactive logon, no second-hop credential to harvest (the virtual account's secret never leaves the box), and every action is transcribed. You have converted an identity problem into a very small, very auditable surface.

Operational guardrails that matter

  1. Never expose cmdlets that can escape. Invoke-Expression, Start-Process, New-Service, Add-LocalGroupMember, and anything that writes to HKLM can be used to break out. Audit your VisibleCmdlets list as if it were a firewall ruleset.
  2. Prefer custom functions over raw cmdlets. Wrap the operation (“restart the app pool for site X”) in a function that takes a validated argument, rather than exposing the underlying cmdlet with broad parameters.
  3. Protect the transcript directory. Put transcripts somewhere the JEA roles themselves cannot write arbitrarily or delete — ideally forwarded off-box with Windows Event Forwarding.
  4. gMSA over virtual accounts when a role needs to touch network resources (e.g. a remote SQL instance), so the run-as identity is a managed, rotating, auditable account rather than the local machine.

Where WinSentinel fits

JEA only reduces risk if it is actually deployed and hasn't drifted. On a single machine, the free WinSentinel agent audits the full remoting posture: it flags endpoints still running SessionType Default (unconstrained), configurations that grant RunAsVirtualAccount to overly broad groups, roles that expose breakout cmdlets, and WinRM itself accepting unconstrained sessions from the network. All 64 modules run locally with no limits — you get the complete remoting and privilege-escalation audit on one box for free.

Across an organization, the Pro tier adds fleet orchestration: the central node rolls those JEA findings up across every endpoint, flags the one server where someone re-registered the default Microsoft.PowerShell endpoint after a reboot, and raises a drift alert when a role capability file is edited to add a dangerous cmdlet. That's the difference between auditing one machine and continuously enforcing least-privilege remoting across hundreds — centralized agent management, compliance rollups, and drift detection that no per-box check can give you.

Start small

You do not need to re-architect every admin workflow at once. Pick the single most common privileged task your team performs over remoting — a service restart, a log pull, an IIS recycle — and build one JEA endpoint for it. Point the relevant AD group at it, revoke the standing local-admin rights that task used to require, and watch the transcripts. Each endpoint you add is one more credential that stops being a skeleton key.