PowerShell Session Configuration Files - TechNet Gallery

advertisement
Just Enough Administration (JEA) Infrastructure: An Introduction
By John Slack
Version 0.4
Table of Contents
After reading this document, you should be able to author, deploy, use, maintain, and audit a Just
Enough Administration (JEA) deployment on Windows Server 2016 PP1. Here are the topics we will
cover:
1.
2.
3.
4.
5.
6.
7.
8.
9.
Introduction: Briefly review why you should care about JEA.
Prerequisites: Set up your environment
Using JEA: Start by understanding the operator experience of using JEA.
Remake the Demo: Create a JEA Session Configuration from scratch.
Role Capabilities: Learn about how to customize JEA capabilities with Role Capability Files.
End to End - Active Directory: Make a whole new endpoint for managing Active Directory
Multi-machine: Discover how deployment and authoring changes with scale
Reporting on JEA: Discover how to audit and report on all JEA actions and infrastructure.
Appendix: Important skills and discussion points
Introduction
Motivation
When you grant someone privileged access to your systems, you extend your trust boundary to that
person. This is a risk; administrators are an attack surface. Insider attacks and stolen credentials are
both real and common.
This is not a new problem. You are probably very familiar with the principle of least privilege, and you
might use some form of role based access control (RBAC) with applications that provide it. However,
limited scope and large grained control limit the effectiveness and manageability of these solutions.
Furthermore, there are gaps in RBAC coverage. For example, in Windows, privileged access is largely a
binary switch, forcing you to give unnecessary permissions when adding users to the Administrator
group.
Just Enough Administration (JEA) provides a RBAC platform through Windows PowerShell. It allows
specific users to perform specific administrative tasks on servers without giving them administrator
rights. This allows you to fill in the gaps between your existing RBAC solutions, and simplifies
management of those settings.
Scope of this Guide
The initial release of JEA, called xJEA, consisted of experimental DSC resources. Our experiences with xJEA
helped us refine the JEA concept. Now, many of the capabilities from xJEA are moving into the underlying
PowerShell infrastructure. Instead of building JEA on top of PowerShell Session Configurations, we are
building JEA capabilities into PowerShell Session Configurations. Windows Server 2016 PP1 marks the
first release of these new capabilities. This experience guide is solely concerned with this new underlying
infrastructure.
Prerequisites
Initial State
Before starting this section, please ensure the following:
1) You have either:
a. An instance of Windows Server 2016 TP4 instance running
b. An instance of Windows Server 2012 or 2012R2 with WMF 5.0 RTM
2) You have administrative rights on the server
3) The server is domain joined. See the Creating a Domain Controller section for instructions on
creating a standalone domain.
Enable PowerShell Remoting
Management with JEA occurs through PowerShell Remoting. Run the following in an Administrator
PowerShell window to ensure that this process is set up.
Enable-PSRemoting
Identify Your Users or Groups
To show JEA in action, you need to identify the non-administrator users and groups you are going to use
throughout this guide.
If you’re using an existing domain, please identify or create some non-administrator users and groups.
You will give these non-administrators access to JEA. Anytime you see the $NonAdministrator variable
at the top of a script, assign it to your selected non-administrator users or groups.
If you created a new domain from scratch, it’s much easier. Please use the Set Up Users and Groups
section in the appendix to create a non-administrator users and groups. The default values of
$NonAdministrator will be the groups created in that section.
Set Up Maintenance Role Capability File
Run the following commands to create the demo “role capability” file we will be using for the next
section. Later in this guide, you will learn about what this file does.
$powerShellPath = "$env:SystemRoot\System32\WindowsPowerShell\v1.0"
# Fields in the role capability
$MaintenanceRoleCapabilityCreationParams = @{
Author =
"Contoso Admin"
ModulesToImport=
"Microsoft.PowerShell.Core"
VisibleCmdlets=
"Restart-Service"
CompanyName=
"Contoso"
FunctionDefinitions = @{ Name = 'Get-UserInfo'; ScriptBlock = {$PSSenderInfo}}
}
# Create the demo module, which will contain the demo Role Capability File
New-Item -Path “$env:ProgramFiles\WindowsPowerShell\Modules\Demo_Module” -ItemType
Directory
New-ModuleManifest -Path
“$env:ProgramFiles\WindowsPowerShell\Modules\Demo_Module\Demo_Module.psd1"
New-Item -Path
“$env:ProgramFiles\WindowsPowerShell\Modules\Demo_Module\RoleCapabilities” -ItemType
Directory
# Create the Role Capability file
New-PSRoleCapabilityFile -Path
“$env:ProgramFiles\WindowsPowerShell\Modules\Demo_Module\RoleCapabilities\Maintenance.
psrc" @MaintenanceRoleCapabilityCreationParams
Create and Register Demo Session Configuration File
Run the following commands to create and register the demo “session configuration” file we will be
using for the next section. Later in this guide, you will learn about what this file does.
#Determine domain
$domain = (Get-CimInstance -ClassName Win32_ComputerSystem).Domain
#Replace with your non-admin group name
$NonAdministrator = "$domain\JEA_NonAdmin_Operator"
$JEAConfigParams = @{
SessionType= "RestrictedRemoteServer"
RunAsVirtualAccount = $true
RoleDefinitions = @{ $NonAdministrator = @{RoleCapabilities = 'Maintenance'}}
TranscriptDirectory = "$env:ProgramData\JEAConfiguration\Transcripts”
}
if(-not (Test-Path "$env:ProgramData\JEAConfiguration"))
{
New-Item -Path "$env:ProgramData\JEAConfiguration” -ItemType Directory
}
$sessionName = "JEA_Demo"
if(Get-PSSessionConfiguration -Name $sessionName -ErrorAction SilentlyContinue)
{
Unregister-PSSessionConfiguration -Name $sessionName -ErrorAction Stop
}
New-PSSessionConfigurationFile -Path "$env:ProgramData\JEAConfiguration\JEADemo.pssc"
@JEAConfigParams
#endregion
#region Register the session configuration
Register-PSSessionConfiguration -Name $sessionName -Path
"$env:ProgramData\JEAConfiguration\JEADemo.pssc"
Restart-Service WinRM
#endregion
[Optional] Enable PowerShell Module Logging
This enables logging for all PowerShell actions on your system. You don’t need to enable this for JEA to
work, but it will be useful in the Reporting on JEA section.
STEP 1: Open the local group policy editor.
STEP 2: Navigate to “Computer Configuration\Administrative Templates\Windows
Components\Windows PowerShell”
STEP 3: Double Click on “Turn on Module Logging”
STEP 4: Click “Enabled”
STEP 5: In the Options section, click on “Show” next to Module Names
STEP 6: Type “*” in the pop up window. This means PowerShell will log commands from all modules.
STEP 7: Click OK and apply the policy.
Note: you can also enable system-wide PowerShell transcription through Group Policy.
Congratulations, you have now configured your server and are ready to get started with JEA!
Using JEA
This section focuses on understanding the end user experience of using JEA. In the prerequisites
section, you created a demo JEA endpoint. We will use this demo to show JEA in action. In later
sections, the guide will work backwards -- introducing the actions and files that made that end user
experience possible.
Using JEA as a Non-Administrator
STEP 1: To show JEA in action, you will need to use PowerShell remoting as though you were a nonadministrator user. Run the following command in a new PowerShell window:
$NonAdminCred = Get-Credential
Enter the credentials for your non-administrator account when prompted. If you followed the Set Up
Users and Groups section, they will be this:
 Username = “OperatorUser”
 Password = “pa$$w0rd”
This creates and saves a PSCredential object for an unprivileged user that was created in the
prerequisites section.
STEP 2: Run the following command in your PowerShell window:
Enter-PSSession -ComputerName . -ConfigurationName JEA_Demo -Credential $NonAdminCred
You have now entered an interactive remote PowerShell session against the local machine. By using the
“Credential” parameter, you have connected as though you were NonAdminUser. The change in the
prompt indicates that you are operating against a remote session.
STEP 3: Run the following in your remote command prompt:
Get-Command
This shows the commands that are available to the operator connecting this JEA endpoint. As you can
tell, this is a very limited subset of the command available in a normal PowerShell window (over 1520
commands on my machine).
STEP 4: Run the following command in the remote session:
Get-UserInfo
This custom command shows the “ConnectedUser” as well as the “RunAsUser.” The connected user is
the account that connected to the remote session (e.g. your account). The connected user does not
need to have administrator privileges. The “Run As” account is the account actually performing the
privileged actions. By connecting as one user, and running as a privileged user, we allow non-privileged
users to preform specific administrative tasks without giving them administrative rights.
STEP 5: Run the following command in the remote session:
Restart-Service -Name Spooler -Verbose
Restart-Service is one of the commands listed in the above configuration. Normally, this command
requires administrator privileges to run.
STEP 6: Try to run a PowerShell command that was not listed in STEP 3, such as:
Restart-Computer
JEA restricts which commands can be run as a privileged user. The operator is restricted to only those
commands listed in STEP 3.
STEP 7: Run the following command in the remote session:
Exit-PSSession
This disconnects you from the remote PowerShell session.
Key Concepts
PowerShell Remoting: PowerShell remoting allows you to run PowerShell commands against remote
machines. You can operate against one or many computers, and use either temporary or persistent
connections. In this demo, you remoted into your local machine with an interactive session. JEA
restricts the functionality available through PowerShell remoting. For more information about
PowerShell remoting, run the following command:
Get-Help about_Remote
“RunAs” User: When using JEA, a non-administrator “runs as” a privileged “Virtual Account.” The
Virtual Account only lasts the duration of the remote session. That is to say, it is created when a user
connects to the endpoint, and destroyed when the user ends the session. By default, the Virtual
Account is a member of the local administrators group. On a domain controller, it is also a member of
Domain Administrators.
“Connected” User: The non-administrator user who runs as the “RunAs” user through PowerShell
remoting.
Remake the Demo Endpoint
In this section, you will learn how to generate an exact replica of the demo endpoint you used in the
above section. This will introduce core concepts that are necessary to understand JEA, including
PowerShell Session Configurations.
PowerShell Session Configurations
When you used JEA in the above section, you started by running the following command:
Enter-PSSession -ComputerName . -ConfigurationName JEA_Demo -Credential $NonAdminCred
While most of the parameters are self-explanatory, the “ConfigurationName” parameter may seem
confusing at first. That parameter specified the PowerShell Session Configuration, or Endpoint, to
which you were connecting.
PowerShell Session Configuration is a fancy term for PowerShell Endpoint. It is the figurative “place”
where users connect and get access to PowerShell functionality. Based on how you set up a Session
Configuration, it can provide different functionality to connecting users. For JEA, we use Session
Configurations to restrict PowerShell to a limited set of functionality and to “RunAs” a privileged Virtual
Account.
You already have several registered PowerShell Session Configurations on your machine, each set up
slightly differently. Most of them come with Windows, but the “JEADemo” Session Configuration was
set up in the Prerequisites section. You can see all registered Session Configurations by running the
following command in an Administrator PowerShell prompt:
Get-PSSessionConfiguration
PowerShell Session Configuration Files
You can make new Session Configurations by registering new PowerShell Session Configuration Files.
Session Configuration Files have “.pssc” file extensions. You can generate Session Configuration Files
with the New-PSSessionConfigurationFile command.
Next, you are going to create and register a new Session Configuration for JEA.
Generate and Modify your PowerShell Session Configuration
STEP 1: Run the following script to generate a blank PowerShell Session Configuration file.
New-PSSessionConfigurationFile -Path "$env:ProgramData\JEAConfiguration\JEADemo2.pssc"
This generates a blank Session Configuration File called “JEADemo2.pssc”
STEP 2: Open it in PowerShell ISE, or your favorite text editor.
ise "$env:ProgramData\JEAConfiguration\JEADemo2.pssc"
STEP 3: You need to set the certain fields to make this Session Configuration File define a JEA Endpoint.
Specifically, please set the following lines to the following values (replace this with the name of your
non-administrator group):
Line #
Old Value
New Value
16
SessionType = 'Default'
19
# TranscriptDirectory =
'C:\Transcripts\'
22
# RunAsVirtualAccount = $true
# RoleDefinitions = @{
'CONTOSO\SqlAdmins' = @{
RoleCapabilities =
'SqlAdministration' };
'CONTOSO\ServerMonitors' = @{
VisibleCmdlets = 'Get-Process' } }
SessionType = 'RestrictedRemoteServer'
TranscriptDirectory =
“C:\ProgramData\JEAConfiguration\Trans
cripts”
RunAsVirtualAccount = $true
31
RoleDefinitions =
@{'Contoso\JEA_NonAdmin_Operator' = @{
RoleCapabilities = 'Maintenance' }}
Here is what each of those entries mean:
1. The SessionType field defines preset default settings to use with this endpoint.
RestrictedRemoteServer defines the minimal settings necessary for remote management. By
default, a RestrictedRemoteServer endpoint will expose Get-Command, Get-FormatData,
Select-Object, Get-Help, Measure-Object, Exit-PSSession, Clear-Host, and Out-Default. It will set
the ExecutionPolicy to RemoteSigned, and the LanguageMode to NoLanguage. The net effect
of these settings is a secure and minimal starting point for configuring your endpoint.
2. The RoleDefinitions field gives RoleCapabilities to specific groups. It defines who can do what
as a privileged account. With this field, you can specify the functionality available to any
connecting user based on group membership. This is the core of JEA’s RBAC functionality. In
this example, you are exposing the pre-made “Demo” RoleCapability to members of the
“Contoso\JEA_NonAdmin_Operator” group.
3. The RunAsVirtualAccount field indicates that PowerShell should “run as” a Virtual Account at
this endpoint. By default, the Virtual Account is a member of the built in Administrators group.
On a domain controller, it is also a member of the Domain Administrators group by default.
Later in this guide, you will learn how to customize the privileges of the Virtual Account.
4. The TranscriptDirectory field defines where “over-the-shoulder” PowerShell transcripts are
saved after each remote session. These transcripts allow you to inspect the actions taken in
each session in a readable way. For more information about PowerShell transcripts, check out
this blog post. Note: regular Windows Eventing also captures information about what each user
ran with PowerShell. Transcripts are just a bit more readable.
STEP 4: Save JEADemo2.pssc
Apply the PowerShell Session Configuration
To create a Session Configuration from a Session Configuration file, you need to register the file. This
requires a few pieces of information:
1. The path to the Session Configuration File.
2. The name of your registered Session Configuration. This is the argument users provide to the
“ConfigurationName” parameter when they connect to your endpoint.
3. [Optional] A custom SDDL that defines access conditions for this Session Configuration. This is
only required for scenarios like two factor authentication. Otherwise, PowerShell uses the
“RoleDefinitions” field to determine access. See this section in the appendix for more
information.
To register the Session Configuration on your local machine, run the following command:
Register-PSSessionConfiguration -Name JEADemo2 -Path
"$env:ProgramData\JEAConfiguration\JEADemo2.pssc"
Congratulations! You have set up your first JEA endpoint.
Test Out Your Endpoint
Re-run the steps listed in the “Using JEA” section against your endpoint to confirm that your endpoint is
operating as intended.
To ensure you are operating against your new endpoint, run the following command instead of STEP 2:
Enter-PSSession -ComputerName . -ConfigurationName JEADemo2 -Credential $NonAdminCred
Key Concepts
PowerShell Session Configuration: Sometimes referred to as PowerShell Endpoint, the figurative
“place” where users connect and get access to PowerShell functionality. You can list the registered
Session Configurations on your system by running Get-PSSessionConfiguration. When configured
in a specific way, a PowerShell Session Configuration can be called a JEA Endpoint.
PowerShell Session Configuration File (.pssc): A file that, when registered, defines settings for a
PowerShell Session Configuration. It contains specifications for user roles that can connect to the
endpoint, the “run as” Virtual Account, and more.
Role Definitions: The field in a Session Configuration File that defines the Role Capabilities granted to
connecting users. It defines who can do what as a privileged account. This is the core of JEA’s RBAC
capabilities.
SessionType: A field in a Session Configuration File that represents default settings for a Session
Configuration. For JEA Endpoints, this must be set to RestrictedRemoteServer.
Security Descriptor Definition Language (SDDL): The SDDL defines who has access to an Endpoint, and is
set when an Endpoint is registered. By default, access to an endpoint is limited to the groups listed in
Role Definitions.
PowerShell Transcript: A file containing an “over-the-shoulder” view of a PowerShell session. You can
set PowerShell to generate transcripts for JEA sessions using the TranscriptDirectory field. For more
information on transcripting, check out this blog post.
Role Capabilities
Overview
In the above section, you learned that the RoleDefinitions field defined which groups had access to
which Role Capabilities. You may have wondered, “What are Role Capabilities?” This section will
answer that question.
Introducing PowerShell Role Capabilities
PowerShell Role Capabilities define “what” a user can do at a JEA endpoint. They detail a whitelist of
things like visible commands, visible applications, and more. Role Capabilities are defined by files with a
“.psrc” extension.
Role Capability Contents
We will start by examining and modifying the demo Role Capability file you used before. Imagine you
have deployed your Session Configuration across your environment, but you have gotten feedback that
you need to change the capabilities exposed to users. Operators need the ability to restart machines,
and they also want to be able to get information about network settings. In addition, the security team
has told you that allowing users to run “Restart-Service” without any restrictions is not acceptable. You
need to restrict the services that operators can restart.
STEP 1: Using PowerShell ISE running as an Administrator, open the following file:
“C:\Program Files\WindowsPowerShell\Modules\Demo_Module\RoleCapabilities\Maintenance.psrc”
STEP 2: You need to set the certain fields implement the changes you want to make:
Line #
Old Value
New Value
VisibleCmdlets = 'RestartService'
VisibleCmdlets =
'Restart-Computer’,
@{ Name = ‘Restart-Service';
Parameters = @{ Name = 'Name';
ValidateSet = 'Spooler’ }},
‘NetTCPIP\Get-*'
# VisibleExternalCommands =
'Item1', 'Item2'
VisibleExternalCommands =
‘C:\Windows\system32\ipconfig.exe’
25
32
This contains a few interesting examples:
1.
You have restricted Restart-Service. Operators will only be able to use Restart-Service with the
-Name parameter, and they will only be allowed to provide “Spooler” as an argument to that
parameter. If you wanted to, you could also restrict the arguments using a regular expression
using a “ValidatePattern”.
2. You have exposed all commands with the “Get” verb from the NetTCPIP module. Because “Get”
commands typically don’t change system state, this is a relatively safe action. That being said,
we strongly encourage examining every command you expose through JEA.
3. You have expose an executable (ipconfig) using VisibleExternalCommands. You can also expose
scripts with this field.
STEP 3: Save the file.
STEP 4: Re-run the steps listed in the “Using JEA” section against your endpoint to confirm that your
endpoint is operating as intended.
Because you only modified the Role Capability file, you do not need to re-register the Session
Configuration. This is an important point to make; PowerShell will find your updated Role Capability
when a user connects.
To ensure you are operating against your new endpoint, run the following command instead of STEP 2:
Enter-PSSession -ComputerName . -ConfigurationName JEADemo2 -Credential $NonAdminCred
STEP 5: Confirm that you can restart the computer by running Restart-Computer with the -WhatIf
parameter (unless you actually want to restart the computer).
Restart-Computer -WhatIf
STEP 6: Confirm that you can run “ipconfig”
ipconfig
STEP 7: Confirm that Restart-Service only works for the Spooler service.
Restart-Service Spooler #this should work
Restart-Service WSearch #this should fail
STEP 8: Exit the session as before.
Exit-PSSession
Role Capability Creation
In the next session, you will create a Session Configuration for AD Help Desk users. To prepare, we will
create a blank Role Capability file to fill in for that section. In order to make this work, you will create a
new module that will contain the role capability. In order for PowerShell to detect Role Capabilities
automatically, you must put them in a “RoleCapabilities” folder in this module.
PowerShell Modules are essentially packages of PowerShell functionality. They can contain PowerShell
functions, cmdlets, DSC Resources, Role Capabilities, and more.
STEP 1: Create a “Contoso_AD_Module” folder the modules directory.
New-Item -Path “C:\Program Files\WindowsPowerShell\Modules\Contoso_AD_Module” -ItemType
Directory
STEP 2: Create a blank module manifest. This module manifest will contain metadata about the module
you are creating.
New-ModuleManifest -Path ‘C:\Program
Files\WindowsPowerShell\Modules\Contoso_AD_Module\Contoso_AD_Module.psd1’ -RootModule
Contoso_AD_Module.psm1
STEP 3: Create a blank script module. You’ll use this file for custom functions in the next section.
New-Item -Path “C:\Program
Files\WindowsPowerShell\Modules\Contoso_AD_Module\Contoso_AD_Module.psm1” -ItemType
File
STEP 4: Create a RoleCapabilities folder in the AD_Module folder. PowerShell can only automatically
discover Role Capabilities that are located in a “RoleCapabilities” folder within a module.
New-Item -Path “C:\Program
Files\WindowsPowerShell\Modules\Contoso_AD_Module\RoleCapabilities” -ItemType
Directory
STEP 5: Create a blank Role Capability in your RoleCapabilities folder. Running this command without
any additional parameters just creates a blank template.
New-PSRoleCapabilityFile -Path ‘C:\Program
Files\WindowsPowerShell\Modules\Contoso_AD_Module\RoleCapabilities\ADHelpDesk.psrc’
Congratulations, you have created a blank Role Capability File. It will be used in the next section.
Key Concepts
Role Capability (.psrc): A file that define “what” a user can do at a JEA endpoint. It details a whitelist of
things like visible commands, visible applications, and more. In order for PowerShell to detect Role
Capabilities automatically, you must put them in a “RoleCapabilities” folder in a valid PowerShell
module.
PowerShell Module: A package of PowerShell functionality. It can contain PowerShell functions,
cmdlets, DSC Resources, Role Capabilities, and more. In order to be automatically loaded, PowerShell
Modules must be located on $env:PSModulePath.
End to End: Active Directory
Imagine the scope of your program has increased. You are now responsible for adding JEA to Domain
Controllers to perform Active Directory actions. The help desk people are going to use JEA to unlock
accounts, reset passwords, and do other similar actions.
You need to expose a completely new set of commands to a different group of people. On top of that,
you have a bunch of existing active directory scripts you need to expose. This section will walk through
how to author a Session Configuration and Role Capability for this task.
Prerequisites
To follow this section step-by-step, you’ll need to be operating on a domain controller. If you don’t have
access to your domain controller, don’t worry. Try to follow along with by working against some other
scenario or role with which you are familiar.
Steps to Making a New Role Capability and Session Configuration
Making a new role capability can seem daunting at first, but it’s can be broken into fairly simple steps:
1.
2.
3.
4.
5.
Identify the tasks you need to enable
Restrict those tasks as necessary
Confirm they work with JEA
Put them in a Role Capability File
Register a Session Configuration that exposes that Role Capability
Step 1: Identify What Needs to Be Exposed
Before you make a new Role Capability or Session Configuration, you need to identify all of the things
users will need to do through the JEA endpoint, as well as how to do them through PowerShell. This will
involve a fair amount of requirement gathering and research.
How you go about this process will be dependent on your organization and goals. It is important to call
out requirement gathering and research as a critical part of the real world process. This may be the
most difficult step in the process of adopting JEA.
Find Resources
Here is a set of online resources that might have come up in your research on creating an Active
Directory Toolkit:


Active Directory PowerShell Overview
CMD to PowerShell Guide for Active Directory
Make a List
Here is a set of ten actions that you will be working from in the remainder of this section. Keep in mind
this is simply an example, your organizations requirements may be different:
Action
Account Unlock
Password Reset
Change a User’s Title
PowerShell Command
Unlock-ADAccount
Set-ADAccountPassword and
Set-ADUser -ChangePasswordAtLogon
Set-ADUser -Title
Find AD Accounts that are locked out,
disabled, inactive, etc.
Add User to Group
Remove User from Group
Enable a user account
Disable a user account
Search-ADAccount
Add-ADGroupMember -Identity (with whitelist) -Members
Remove-ADGroupMember -Identity (with whitelist) -Members
Enable-ADAccount
Disable-ADAccount
Step 2: Restrict Tasks as Necessary
Now that you have your list of actions, you need to think through the capabilities of each command.
There are two important reasons to do this:
1. It is easy to expose give users more capabilities than you intend. For example, Set-ADUser is an
incredibly powerful and flexible command. You may not want to expose everything it can do to
help desk users.
2. Even worse, it’s possible to expose commands that allow users to escape JEA’s restrictions. If
this happens, JEA ceases to function as a security boundary. Please be careful when selecting
commands. For example, Invoke-Expression will allow users to run unrestricted code. For more
discussion on this topic, check out the Considerations When Restricting Commands section.
After reviewing each command, you decide to restrict the following:
1. Set-ADUser should only be allowed to run with the “-Title” parameter
2. Add-ADGroupMember and Remove-ADGroupMember should only work with certain groups
Step 3: Confirm the Tasks Work with JEA
Actually using those cmdlets may not be straightforward in the restricted JEA environment. JEA runs in
No Language mode which, among other things, prevents users from using variables. In order to ensure
that end users have a smooth experience, it’s important to check for a few things.
As an example, consider Set-ADAccountPassword. The -NewPassword parameter requires a secure
string. Most of the time, I would create a secure string and pass it in as a variable (as below):
$newPassword = (Read-Host -Prompt "Provide New Password" -AsSecureString)
Set-ADAccountPassword -Identity mollyd -NewPassword $newPassword -Reset
However, No Language mode prevents the usage of variables. You can get around this restriction in two
ways:
1. You can require users run the command without assigning variables. This is easy to configure,
but can be painful for the operators using the endpoint. Who wants to type this out every time
you reset a password?
Set-ADAccountPassword -Identity mollyd -NewPassword (Read-Host -Prompt "Provide
New Password" -AsSecureString) -Reset
2. You can wrap the complexity in a script or a function that you expose to end users. Scripts and
functions that you expose run in an unrestricted context; you can write functions that use
variables and call several other commands without any issue. This approach simplifies the end
user experience, prevents errors, reduces required PowerShell knowledge, and reduces
unintentionally exposing excess functionality. The only downside is the cost of authoring and
maintaining the function.
Aside: Adding a Function to Your Module
Taking approach #2, you are going to write a PowerShell function called Reset-ContosoUserPassword.
This function is going to do everything that needs to happen when you reset a user’s password. In your
organization, this may involve doing fancy and complicated things. Because this is just an example, your
command will just reset the password and require the user change the password at logon. We will put it
in the Contoso_AD_Module module you made in the last section.
STEP 1: In PowerShell ISE, open “Contoso_AD_Module.psm1”
ISE ‘C:\Program
Files\WindowsPowerShell\Modules\Contoso_AD_Module\Contoso_AD_Module.psm1'
STEP 2: Press Crtl+J to open the snippets menu.
STEP 3: Key down until you find “function” and press enter. This puts up a super basic skeleton of a
function.
STEP 4: Rename the function “Reset-ContosoUserPassword”.
STEP 5: Rename one of the parameters “Identity” and delete the second.
STEP 6: Copy the following into the body of the function.
# Get the new password
$NewPassword = Read-Host -Prompt "Provide New Password" -AsSecureString
# Reset the password
Set-ADAccountPassword -Identity $Identity -NewPassword $NewPassword -Reset
# Require the user to reset at next logon
Set-ADUser -Identity $Identity -ChangePasswordAtLogon
STEP 7: Save the file. You should end up with something that looks like this:
function Reset-ContosoUserPassword ($Identity)
{
# Get the new password
$NewPassword = Read-Host -Prompt "Provide New Password" -AsSecureString
# Reset the password
Set-ADAccountPassword -Identity $Identity -NewPassword $NewPassword -Reset
# Require the user to reset at next logon
Set-ADUser -Identity $Identity -ChangePasswordAtLogon
}
Congratulations, you now have a bare bones function that gets the job done!
Step 4: Edit the Role Capability File
In the Role Capability Creation section, you created a blank Role Capability file. In this section, you will
fill in the values in that file.
STEP 1: Open the role capability file in ISE.
ISE 'C:\Program
Files\WindowsPowerShell\Modules\Contoso_AD_Module\RoleCapabilities\ADHelpDesk.psrc'
STEP 2: Please set the following fields:
Line #
19
28
Value
# ModulesToImport =
'MyCustomModule', @{ ModuleName
= 'MyCustomModule2';
ModuleVersion = '1.0.0.0'; GUID
= '4d30d5f0-cb16-4898-812df20a6c596bdf' }
ModulesToImport = 'Contoso_AD_Module',
'ActiveDirectory'
# VisibleFunctions = 'InvokeFunction1', @{ Name = 'InvokeFunction2'; Parameters = @{ Name
= 'Parameter1'; ValidateSet =
'Item1', 'Item2' }, @{ Name =
'Parameter2'; ValidatePattern =
'L*' } }
VisibleFunctions = 'Reset-ContosoUserPassword'
25
# VisibleCmdlets = 'InvokeCmdlet1', @{ Name = 'InvokeCmdlet2'; Parameters = @{ Name =
'Parameter1'; ValidateSet =
'Item1', 'Item2' }, @{ Name =
'Parameter2'; ValidatePattern =
'L*' } }
VisibleCmdlets = 'Unlock-ADAccount',
@{ Name = 'Set-ADUser'; Parameters = @{
Name = 'Title'; ValidateSet = 'Manager',
'Engineer' }},
'Search-ADAccount',
@{ Name = 'Add-ADGroupMember'; Parameters
=
@{Name = 'Identity';
ValidateSet = 'TestGroup'},
@{Name = 'Members'}},
@{ Name = 'Remove-ADGroupMember';
Parameters =
@{Name = 'Identity';
ValidateSet = 'TestGroup'},
@{Name = 'Members'}},
'Enable-ADAccount',
'Disable-ADAccount'
There are a few things to note about the above:
1. Listing the modules, you are using in ModulesToImport is not mandatory, but is considered a
best practice. Without it, PowerShell will auto-load modules for commands found in
VisibleCmdlets and VisibleFunctions.
2. If you aren’t sure if a command is a cmdlet or a function, run Get-Command and look at the
“CommandType.”
3. The ValidatePattern allows you to use a regular expression to restrict parameter arguments.
Step 5: Register a New Session Configuration
Next, you will create a new session configuration file that will expose your new role capability to
members of the JEA_NonAdmin_HelpDesk group.
STEP 1: Create and open a new blank Session Configuration File in PowerShell ISE.
New-PSSessionConfigurationFile -Path
"$env:ProgramData\JEAConfiguration\HelpDeskDemo.pssc"
ISE "$env:ProgramData\JEAConfiguration\HelpDeskDemo.pssc"
STEP 2: Modify the following fields to the following values. If you are working in your own environment,
replace this with your own non-administrator user or group:
Line #
Old Value
New Value
13
# Description = ''
Description = 'An endpoint for active
directory tasks.'
16
19
22
31
SessionType = 'Default'
# TranscriptDirectory =
'C:\Transcripts\'
# RunAsVirtualAccount = $true
SessionType = 'RestrictedRemoteServer'
TranscriptDirectory =
“C:\ProgramData\JEAConfiguration\Transcripts”
RunAsVirtualAccount = $true
# RunAsVirtualAccountGroups = 'Remote
Desktop Users', 'Remote Management
Users'
RunAsVirtualAccountGroups
# RoleDefinitions = @{
'CONTOSO\SqlAdmins' = @{
RoleCapabilities =
'SqlAdministration' };
'CONTOSO\ServerMonitors' = @{
VisibleCmdlets = 'Get-Process' } }
RoleDefinitions =
@{'Contoso\JEA_NonAdmin_HelpDesk' = @{
RoleCapabilities = 'ADHelpDesk' }}
STEP 3: Save and Register the Session Configuration
Register-PSSessionConfiguration -Name ADHelpDesk -Path
"$env:ProgramData\JEAConfiguration\HelpDeskDemo.pssc"
Test It Out!
STEP 1: Get your non-administrator user credentials.
$HelpDeskCred = Get-Credential
If you followed the Set Up Users and Groups section, they will be this:
 Username = “HelpDeskUser”
 Password = “pa$$w0rd”
STEP 2: Remote into the machine as you did before.
Enter-PSSession -ComputerName . -ConfigurationName ADHelpDesk -Credential
$HelpDeskCred
STEP 3: Use Set-ADUser to reset a user’s title.
Set-ADUser -Identity OperatorUser -Title Engineer
STEP 4: Verify that the title has changed.
Get-ADUser -Identity OperatorUser -Property Title
STEP 5: Use Add-ADGroupMember to add a user to the TestGroup. Note: make sure you’ve created the
TestGroup beforehand.
Add-ADGroupMember TestGroup -Member OperatorUser -Verbose
STEP 6: Exit the session:
Exit-PSSession
Key Concepts
NoLanguage Mode: When PowerShell is in “NoLanguage” mode, users may only run commands; they
cannot use any language elements. For more information, run Get-Help about_Language_Modes.
RunAsVirtualAccountGroups: You can use this element to set the permissions of the “RunAs” Virtual
Account. The token created for the Virtual Account will appear to
PowerShell Functions: PowerShell functions are bits of PowerShell code that you can call by name. For
more information, run Get-Help about_Functions.
ValidateSet/ValidatePattern: When exposing a command, you can restrict valid arguments for specific
parameters. A ValidateSet is a specific list of valid commands. A ValidatePattern is a regular expression
that the arguments for that parameter must match.
Multi-machine Deployment and Maintenance
At this point, you have deployed JEA to local systems several times. Because your production
environment probably consists of more than one machine, it’s important to walk through the critical
steps in the deployment process.
High Level Steps:
1.
2.
3.
4.
Copy your modules (with role capabilities) to each node.
Copy your session configuration files to each node.
Run Register-PSSessionConfiguration with your session configuration.
Keep a copy of your session configuration and toolkits in a secure location. As you make
modifications, it’s good to have a “single source of truth.”
Example Script
Here’s an example script for deployment. To use it in your environment, you’ll have to use the
names/paths of real file shares and modules.
# First, copy the session configuration and modules (containing role capability files)
onto a file share you have access to.
Copy-Item -Path 'C:\Demo\Demo.pssc' -Destination '\\FileShare\JEA\Demo.pssc'
Copy-Item -Path 'C:\Program Files\WindowsPowerShell\Modules\SomeModule\' -Recurse Destination '\\FileShare\JEA\SomeModule'
# Second, author a setup script (C:\JEA\Deploy.ps1) to run on each individual node
# Contents of C:\JEA\Deploy.ps1
New-Item -ItemType Directory -Path C:\JEADeploy
Copy-Item -Path '\\FileShare\JEA\Demo.pssc' -Destination 'C:\JEADeploy\'
Copy-Item -Path '\\FileShare\JEA\SomeModule' -Recurse -Destination 'C:\Program
Files\WindowsPowerShell\Modules' # Remember, Role Capability Files are found in
modules
if(Get-PSSessionConfiguration -Name JEADemo -ErrorAction SilentlyContinue)
{
Unregister-PSSessionConfiguration -Name JEADemo -ErrorAction Stop
}
Register-PSSessionConfiguration -Name JEADemo -Path 'C:\JEADeploy\Demo.pssc' SecurityDescriptorSddl 'SDDL From Single Machine Deployment Here'
Restart-Service 'WinRM'
Remove-Item -Path 'C:\JEADeploy' #Don't forget to clean up!
# Third, invoke the script on all of the target machines.
# Note: this requires PowerShell Remoting be enabled on each machine. Enabling
PowerShell remoting is a requirement to use JEA as well.
Invoke-Command –ComputerName 'Node1', 'Node2', 'Node3', 'NodeN' -FilePath
'C:\JEA\Deploy.ps1'
# Finally, delete the session configuration and role capability files from the file
share.
Remove-Item -Path '\\FileShare\JEA\Demo.pssc'
Remove-Item -Path '\\FileShare\JEA\SomeModule' -Recurse
Modifying Capabilities
When dealing with many machines, it’s important that modifications are rolled out in a consistent
manner. Once JEA has DSC Resources, this will help ensure your environment is in sync. Until that time,
we highly recommend you keep a master copy of your session configurations and redeploy each time
you make a modification.
Removing Capabilities
To remove JEA from your systems, use the following command on each machine:
Unregister-PSSessionConfiguration -Name JEADemo
Reporting on JEA
Because JEA allows non-privileged users to run in a privileged context, logging and auditing are
extremely important. In this section, we’ll run through the tools you can use to help you with logging
and reporting.
Reporting on JEA Actions
Over-the-Shoulder Transcription
One of the quickest ways to get a summary of what’s happening in a PowerShell session is to look over
the shoulder of the person typing. You see their commands, the output of those commands, and all is
well. Or it’s not, but at least you’ll know. PowerShell Transcription is designed to give you a similar view
after the fact.
When using the “TranscriptDirectory” field in your session configuration, PowerShell will automatically
record a transcript of all actions taken in a given session. You can find transcripts from your sessions in
this document here: "$env:ProgramData\JEAConfiguration\Transcripts”
As you can tell, the transcript records information about the “Connected” user, the “Run As” user, the
commands run in the session, and more. For more information about PowerShell transcription, check
out this blog post.
PowerShell Event Logs
When you have module logging turned on, all PowerShell actions are also recorded in regular Windows
Event logs. This is slightly messier to deal with when compared to transcripts, but the level of detail it
gives you can be useful.
In the “PowerShell” operational log, Event ID 4104 will record each command invoked if you have
enabled module logging.
Other Event Logs
Unlike PowerShell logs and transcripts, other logging mechanisms will not capture the “Connected
User”. You will need to do some correlation between other logs and PowerShell logs to match up
actions taken.
In the “Windows Remote Management” operational log, Event ID 193 will record the Connecting User’s
SID and Name, as well as the RunAs Virtual Account’s SID to assist with this correlation. You may have
also noticed that the name of the RunAs Virtual Account
Reporting on JEA Configuration
Get-PSSessionConfiguration
In order to accurately report on the state of your environment, it’s critical that you be able to report on
the number of JEA endpoints you have set up. “Get-PSSessionConfiguration” does this on each
machine.
Get-PSSessionCapability
Manually reporting on the capabilities of any given user through a JEA endpoint can be quite complex.
You would potentially need to inspect several role capabilities. Fortunately, the “GetPSSessionCapability” cmdlet does this.
To test this out, run the following command from an administrator PowerShell prompt:
Get-PSSessionCapability -Username OperatorUser -ConfigurationName JEADemo2
Conclusion
After completing this guide, you should have the tools and vocabulary to create your own JEA endpoint.
Thanks for reading!
Appendix
Creating a Domain Controller
This document assumes that your machine is domain joined. If you currently don’t
In the Making a Toolkit section, you will explore creating an Active Directory toolkit as an example. In
the first few sections, you will grant unprivileged users capabilities based on AD group membership.
Both of these require your machine a domain controller. The rest of this document assumes that your
machine is the domain controller of a “Contoso” domain.
There are many ways to set up a domain. For example, you could use Server Manager. Below are some
instructions on how to do it with PowerShell Desired State Configuration (DSC).
Prerequisites
1. The machine is on an internal network
2. The machine is not joined to an existing domain
3. The machine has the “xActiveDirectory” module installed (install instructions here)
DSC Instructions
Copy the following script in PowerShell to make your machine a Domain Controller in a new domain.
AUTHORS NOTE: THERE IS A KNOWN ISSUE WITH THE CREDENTIALS PROVIDED NOT BEING USED. TO
BE SAFE, DON’T FORGET YOUR LOCAL ADMIN PASSWORD.
Set-Item WSMan:\localhost\Client\TrustedHosts -Value $env:COMPUTERNAME -Force
# This "MetaConfiguration" sets the DSC Engine to automatically reboot if required
[DscLocalConfigurationManager()]
Configuration MetaConfiguration
{
Node $env:Computername
{
Settings
{
RebootNodeIfNeeded = $true
}
}
}
MetaConfiguration
# Apply the MetaConfiguration
Set-DscLocalConfigurationManager .\MetaConfiguration
# Configure a domain controller of a new "Contoso" domain
configuration DomainController
{
param
(
$node,
$cred
)
Import-DscResource -ModuleName xActiveDirectory
Node $node
{
WindowsFeature ADDS
{
Ensure = 'Present'
Name = 'AD-Domain-Services'
}
xADDomain Contoso
{
DomainName = 'contoso.com'
DomainAdministratorCredential = $cred
SafemodeAdministratorPassword = $cred
DependsOn = '[WindowsFeature]ADDS'
}
file temp
{
DestinationPath = 'C:\temp.txt'
Contents = 'Domain has been created'
DependsOn = '[xADDomain]Contoso'
}
}
}
$ConfigData = @{
AllNodes = @(
@{
NodeName = $env:Computername
PSDscAllowPlainTextPassword = $true
}
)
}
# Enter your desired password for the domain administrator (note, this will be stored
as plain text)
DomainController -cred (Get-Credential -Message "Enter desired credential for domain
administrator") -node $env:Computername -configurationData $ConfigData
# Apply the configuration to create the domain controller
Start-DSCConfiguration -path .\DomainController -ComputerName $env:Computername -Wait
-Force -Verbose
Your machine will restart a few times. You will know the process is complete once you see a file called
“C:\temp.txt” containing “Domain has been created.”
How to Install xActiveDirectory
If your machine has an active internet connection, run the following command in an Administrator
PowerShell window:
Install-Module xActiveDirectory -Force
If you do not have an internet connection, install xActiveDirectory to another machine and then copy
the xActiveDirectory folder to the “C:\Program Files\WindowsPowerShell\Modules” folder on your TP3
machine.
To confirm the installation, run the following command:
Get-Module xActiveDirectory -ListAvailable
Set up Users and Groups
If you created a domain from scratch (as per the Creating a Domain Controller section), you can use this
section to create a few non-administrator groups and users.
#Make Groups
$NonAdminOperatorGroup = New-ADGroup -Name "JEA_NonAdmin_Operator" -GroupScope
DomainLocal -PassThru
$NonAdminHelpDeskGroup = New-ADGroup -Name "JEA_NonAdmin_HelpDesk" -GroupScope
DomainLocal -PassThru
$TestGroup = New-ADGroup -Name "Test_Group" -GroupScope DomainLocal -PassThru
#Make Users
$OperatorUser = New-ADUser -Name "OperatorUser" -AccountPassword (ConvertToSecureString "pa`$`$w0rd" -AsPlainText -Force) -PassThru
Enable-ADAccount -Identity $OperatorUser
$HelpDeskUser = New-ADUser -name "HelpDeskUser" -AccountPassword (ConvertToSecureString "pa`$`$w0rd" -AsPlainText -Force) -PassThru
Enable-ADAccount -Identity $HelpDeskUser
#Add Users to Groups
Add-ADGroupMember -Identity $NonAdminOperatorGroup -Members $OperatorUser
Add-ADGroupMember -Identity $NonAdminHelpDeskGroup -Members $HelpDeskUser
New-ADGroup TestGroup -GroupScope DomainLocal
On Blacklisting
After playing around with JEA, many customers ask about blacklisting commands. This is an
understandable request, but it is not going to happen anytime soon. There are three primary reasons
for this.
1. We designed JEA to limit operators to only the actions they need to do. A blacklist is the
opposite.
2. PowerShell command authors did not design PowerShell commands with the JEA in mind. On a
fresh install of Windows Server 2016 TP3, there are about 1520 commands immediately
available. The threat models for these commands did not include the possibility that a user
would be running commands as a more privileged account. For example, certain commands
allow for code injection by design (e.g. Add-Type and Invoke-Command in the core PowerShell
module). JEA can warn you when you expose the specific commands we know about, but we
have not re-assessed every other command in Windows based on the new threat model. You
must understand the capabilities of the commands you exposing through JEA.
3. Furthermore, even if JEA blocked all commands with code-injection vulnerabilities, there is no
guarantee that a malicious user would not be able to carry out a blacklisted action with another
related command. Unless you understand all of the commands that you are exposing – it is
impossible for you to guarantee that a certain action is not possible.
The burden is on you to understand what commands you are exposing, whether they are using a
whitelist or a blacklist. The number of commands a blacklist would expose is unmanageable, so JEA
does not allow blacklists.
On SDDL Generation and Maintenance
By default, PowerShell will only allow to users or groups access to an endpoint if they are listed in
“RoleDefinitions” in the session configuration file. It does this by auto-generating a SDDL that defines
access to the endpoint. This works well, until you consider situations like Multi-Factor Authentication. In
those situations, you might want to put additional conditions on those users and groups. For example,
they might need to be a member of a security group representing smart card verification.
For these advanced scenarios, you can still use JEA. You’ll just need to create the SDDL yourself. To do
this use the “-ShowSecurityDescriptorUI” parameter of Register-PSSessionConfiguration. Then follow
these steps:
1.
2.
3.
4.
5.
6.
7.
Click on the “Advanced” button
Remove the two default groups.
Click the “Add” button.
Click “Select a Principle” and choose the user or group you want to give access.
Click “Add a Condition” with whatever condition you wish to add.
Click Okay.
Repeat steps 3-6 for each user/group that needs access to the endpoint
The registered endpoint will have a customized SDDL that restricts access in a conditional way. To
actually see that SDDL, just run:
(Get-PSSessionConfiguration -Name ConfigurationName).SecurityDescriptorSddl
To use that same SDDL on other endpoints, you can provide it as an argument to RegisterPSSessionConfiguration:
Register-PSSessionConfiguration -Name UsingSDDL -SecurityDescriptorSddl "<Your SDDL
Here>"
Signing PSSC and PSRC Files
Considerations When Limiting Commands
There is one important point to make about this step. It is critical that all capabilities exposed through
JEA are located in administrator-restricted areas. Non-administrator users should not have the
capability to modify the scripts used through JEA endpoints. In this example, I placed the scripts within
the module so that you could deploy both in a single step.
On a related note, it is critical that you do not give JEA users the ability to overwrite these scripts
through JEA Endpoints. Be extremely careful with exposing commands like Copy-Item!
Common Role Capability Pitfalls
You may run into a few common pitfalls into you go through this process yourself. Here is a quick guide
explaining how to identify and remediate these issues when modifying or creating a new toolkit.
Functions vs. Cmdlets
PowerShell commands written in PowerShell are PowerShell Functions. PowerShell commands written
as specialed .NET classes are PowerShell Cmdlets. Typically, built in commands are Cmdlets, but it is
best to check the command type by running Get-Command.
VisibleProviders
You will need to expose the providers your command need. The most common is the FileSystem
provider, but you may also need to expose others, like the Registry provider. For an introduction to
providers, I recommend this Hey, Scripting Guy blog post:
http://blogs.technet.com/b/heyscriptingguy/archive/2015/04/20/find-and-use-windows-powershellproviders.aspx
Download