Have you ever wanted to delegate a task, but found that the necessary permits may be too risky to hand out? Or have you wanted to block things like creating groups in AD to enforce naming conventions for groups?
JEA can help you with that and much more. In this post, we will see how you can delegate your already created scripts with PowerShell 5.1.
What is JEA?
JEA is a Microsoft PowerShell solution that can restrict users (and administrators) so they can only perform specific tasks in a specific PowerShell session, even if they require a local administrator on said resource. At the same time, can be extremely specific. Only the commands you specify can be run, you can enable only specific parameter values and parameter values that match a specific pattern.
As an example, you can enable Servicedesk to only restart a specific service with Restart-Service
, or just add groups to AD according to a specific naming convention. You can do all of this without giving them explicit permissions on a server or in AD. It is a tool that can save you an enormous amount of time and protect your environment. Let's start by wrapping our script in a function.
Paso 1: creating a function from your script
The first step, if you haven't done it yet, is to create a function from your script. This is pretty straightforward, assuming you already have your parameters
set up. Next, I have wrapped my simple script “New-FolderAndShare” in a function:
Function New-FolderAndShare {
[cmdletbinding()]
param(
# Name of the share
[parameter(Mandatory)]
[ValidatePattern("^(Project d{5}|Team (Finance|HR|IT|Multi) [a-z ]+)$")]
[string]$ShareName,
# Directory of the new share folder locally
[parameter(Mandatory)]
[ValidatePattern("^(D|E|F):Shares$")]
[string]$Path,
# Who to have full access
[parameter(Mandatory)]
[ValidateSet("^CONTOSO")]
[string]$FullAccess
)
$FullPath = Join-Path $Path $ShareName
New-Item -ItemType Directory -Path $FullPath
New-SmbShare -Path $FullPath -Name $ShareName -FullAccess $FullAccess
}
Validate the parameters with ValidatePattern in function, but if this were part of a module, you could do it in the RoleCapabilities file instead with Visible functions.
Making the script a function gives us greater control of the parameters allowed in JEA and facilitates the export.
Paso 2: role-building capacity building
The RoleCapabilities file decides what a specific role is allowed to do (defined in the next step). This includes what commands they can run, what parameters can they use and what modules to import.
Although RoleCapabilities can be created manually, it is recommended to use the New-PSRoleCapabilityFile
PowerShell built-in command 5.1. It is also in this file that it will load in the function that we created in the previous step.
The following script creates a file called FileShareCreator.psrc and add the New-FolderAndShare
function (which should be loaded in the current session):
# RUN THIS IN THE SERVER THAT WILL BE THE JEA ENDPOINT
$RoleCapabilitiesParam = @{
# Establece a function that will be available in the cmdlet
FunctionDefinitions = @{
Name="New-FolderAndShare"
# Import the code of the function
ScriptBlock = [ScriptBlock]::Create(
(Get-Command New-FolderAndShare).Definition
)
}
# Modules used in the function needs to be explicity imported
ModulesToImport = @(
"SmbShare",
"Microsoft.PowerShell.Management"
)
Path = ".FileShareCreator.psrc"
}
New-PSRoleCapabilityFile @RoleCapabilitiesParam
To use Get-Command
to find the function in the FunctionDefinitions
-parameter. Additionally you can add the raw script with parameters.
It also specifies how you are enabled to use the function in the VisibleCmdlet
parameter. For this, specify the name of the function and its parameters along with a regular expression.
With this, you can create extremely granular control of what a user can and cannot do. But there is a caveat to make this work: you need to add psrc file in a module.
Paso 3: creating a module for the RoleCapability file
Time to create a module in which you can put your role capabilities. JEA finds the role capabilities by the name of the psrc files without their extension, therefore avoid duplicates if you are creating more role capabilities later.
The following script is a modified version of what you find in the Official JEA documentation. Create a new module in the module directory, create the necessary files and folders and copy the psrc file you created in step 2 at:
# RUN THIS IN THE SERVER THAT WILL BE THE JEA ENDPOINT
# Create a folder for the module
$modulePath = Join-Path $env:ProgramFiles "WindowsPowerShellModulesFileShareJEA"
New-Item -ItemType Directory -Path $modulePath
# Create an empty script module and module manifest.
# At least one file in the module folder must have the same name as the folder itself.
New-Item -ItemType File -Path (Join-Path $modulePath "FileShareJEA.psm1")
New-ModuleManifest -Path (Join-Path $modulePath "FileShareJEA.psd1") -RootModule "FileShareJEA.psm1"
# Create the RoleCapabilities folder and copy in the PSRC file
$rcFolder = Join-Path $modulePath "RoleCapabilities"
New-Item -ItemType Directory $rcFolder
Copy-Item -Path .FileShareCreator.psrc -Destination $rcFolder
You have now created a role capability and a role to be used in JEA. What remains to be done now is to create a PowerShell session configuration to allocate AD groups to the roles you just created.
Paso 4: Definition of roles
In this step, will create a PowerShell session configuration file that establishes which roles will be assigned which capabilities (from the.psrc file we created in step 2).
Here you will also create the AD group and the transcripts directory.
# Create directory to store logs
New-Item -ItemType Directory -Path 'C:ProgramDataJEAConfigurationTranscripts' -Force
# Create AD group (you might need to do it on another server)
New-ADGroup -Path "OU=Groups,DC=contoso,DC=com" -Name 'JEA_FILESHARE_CREATOR' -GroupScope DomainLocal
# RUN THIS IN THE SERVER THAT WILL BE THE JEA ENDPOINT
# Establece parameters for New-PSSessionConfigurationFile
$PSSessionConfigurationParams = @{
# Run as a temporary account
RunAsVirtualAccount = $True
# That is a local administrator
RunAsVirtualAccountGroups = @(
"administrators"
)
# Path where to save log files of what connected users are doing
TranscriptDirectory = 'C:ProgramDataJEAConfigurationTranscripts'
# Map an active directory group to the capability we created
RoleDefinitions = @{
'CONTOSOJEA_FILESHARE_CREATOR' = @{
RoleCapabilities="FileShareCreator"
}
}
# Path of the PSSC file
Path = ".SessionConfiguration.pssc"
}
# Create the PSSC file
New-PSSessionConfigurationFile @PSSessionConfigurationParams
Paso 5: create a PowerShell session
In this step, will read in the SessionConfiguration.pssc file you created in the previous step. This enables members of JEA_FILESHARE_CREATOR to connect via PowerShell to the server:
PS51> Register-PSSessionConfiguration -Path .SessionConfiguration.pssc -Name 'JEAFileShare' -Force
PSPath : Microsoft.WSMan.ManagementWSMan::localhostPluginJEAFileShare
PSParentPath : Microsoft.WSMan.ManagementWSMan::localhostPlugin
PSChildName : JEAFileShare
PSDrive : WSMan
PSProvider : Microsoft.WSMan.ManagementWSMan
PSIsContainer : True
Keys : {Name=JEAFileShare}
Name : JEAFileShare
TypeNameOfElement : Container
Type : Container
Ready! Add a user to JEA_FILESHARE_CREATOR that you do not have access to the server by normal means and test it as that user by typing:
PS51> Enter-PSSession -ComputerName fs02.contoso.com -ConfigurationName JEAFileShare
PS51> New-FolderAndShare -ShareName "Project 12345" -Path D:Share
Now you can run the command as a temporary local administrator which is locked and only enabled to run some default commands (visible with Get-Command
during the session) and the New-FolderAndShare
function added in functions functions file.
If you want to see the account that was created temporarily, add VisibleExternalCommands @('c:windowssystem32whoami.exe')
to your RoleCapabilities parameters in Step 2. You can run whoami and see the name of the local administrator:
PS51 >whoami
winrm virtual userswinrm va_1_contoso_joe_helpdesk
Summary
Using JEA can be an amazing and easy way to delegate tasks and protect your environment. This doesn't just include your own scripts, but also the integrated modules and the installed modules. Even though JEA can be a great added value, be careful! You can create great risk to your environment if you delegate the wrong commands or specify the wrong parameters to unexpected people.