Build Constrained PowerShell Endpoint Using Configuration File

Doctor Scripto

Summary: Boe Prox teaches you how to build a constrained endpoint by using a configuration file.

Hey, Scripting Guy! Question Hey, Scripting Guy!, is there a better way to lock down my remote endpoint by using something other than a startup script?


Hey, Scripting Guy! Answer Hello SH, Honorary Scripting Guy, Boe Prox, here today filling in for my good friend, The Scripting Guy. This is the third part in a series of five posts about Remoting Endpoints. The series includes:

  1. Introduction to PowerShell Endpoints
  2. Build Constrained PowerShell Endpoint Using Startup Script
  3. Build Constrained PowerShell Endpoint Using Configuration File (today’s post)
  4. Use Delegated Administration and Proxy Functions
  5. Build a Tool that Uses Constrained PowerShell Endpoint

In yesterday’s post, I was able to restrict the commands that are available from a remote Windows PowerShell session by using a startup script to create a constrained endpoint. Today I am going to show you how to create a constrained endpoint by using a configuration file, which became available in Windows PowerShell 3.0.

Although startup scripts work great and were a necessity in Windows PowerShell 2.0, they are optional for configuring constrained remote endpoints since Windows PowerShell 3.0 because a session configuration file (.pssc) makes the process much easier to work with.

So what is a session configuration file and what does it look like? The .pssc file is used with Register-PSSessionConfiguration, and it is used in the Path parameter. After the session configuration has been registered, the file is copied to the C:\Windows\System32\WindowsPowerShell\v1.0\SessionConfig folder.

It is saved in the following format: SessionName_GUID.pssc. The GUID is the same as that in the .pssc file and the same as what you would see when you use Get-PSSessionConfiguration and view the GUID property. It is a text file that contains a hash table that allows you to specify various parts of the remote endpoint.

Image of command output

To building a session configuration file, we use the New-PSSessionConfigurationFile cmdlet. Looking at the Help file for this cmdlet, you can see that there are a lot of parameters, which cover all aspects of the configuration file.

Image of command output

You have a number of options for creating the file. You can specify the parameters you want to use and supply the proper arguments, build a hash file, and splat the parameters into the cmdlet. I plan to use splatting to build my file. But before that, I am going to run the cmdlet with only the Path parameter, which will create a default configuration file. Then I’ll edit it by using the ISE. This way I can show you everything that is available to edit.

Creating a blank session configuration file is as simple as running the following command:

New-PSSessionConfigurationFile -Path "ConstainedSession.pssc"

We can then open the file by using the ISE and view the contents of the empty configuration file.

Image of command output

Image of command output

As you can see, there is quite a bit of stuff here that you can adjust, based on your requirements. Only a few items are actually enabled by default (such as Language and SessionType) because of the need for the remote endpoint to work properly.

If you recall from yesterday’s post, Language is important to determine what you will allow for this remote endpoint. Its current setting of FullLanguage is not what I plan to use because it opens everything in the Windows PowerShell language. I want to stick with NoLanguage to restrict the use of variables and .NET types (to name a couple).

Now that we have that out of the way, I am going to build the configuration file:

New-PSSessionConfigurationFile -Path 'PrinterAuditSession.pssc' `

-SessionType RestrictedRemoteServer `

-LanguageMode NoLanguage `

-ModulesToImport PrintManagement, Microsoft.PowerShell.Management `

-VisibleCmdlets Get-Service `

-VisibleFunctions Get-Printer,Get-PrintJob

Let me break down some of this before I create the session:

Path  Name of the file that will be created from the cmdlet.

SessionType  Determines what commands will be made available when the session is started. By specifying RestrictedRemoteServer, I am allowing only the 7 proxy functions that are required for the remote session to work properly.

LanguageMode   By defining the language as NoLanguage, I ensure that whoever uses this session will not have access to the PowerShell language which includes no variables, .Net types, etc…

VisibileCmdlets   Besides the 7 proxy functions, I want to include a couple of other cmdlets that the user can make use of.

VisibleFunctions   Depending on the modules that I choose to import, some of the commands may be functions. I want to make sure that I allow functions which would be required for whoever connects to this endpoint.

ModulesToImport   By default, no modules are available nor can the user import modules while in this session. I can determine what modules will be made available and already imported using this. Note that only the cmdlets that I specify in VisibleCmdlets will be available in the constrained session.

Next is to actually create the session that will be made available to our users:

Register-PSSessionConfiguration -Name PrinterAudit -Path PrinterAuditSession.pssc –ShowSecurityDescriptorUI

I’ll type A to allow the services to restart and allow the session to be made available for user consumption.

I am removing the default groups and only allowing the PrinterAuditors group to have access to connect to this endpoint. They only need the Execute permissions, so this will be enough.

Image of command output

Let’s let them connect and try it out! I will connect with an account that has PrinterAuditors rights and see what I have access to do:

Enter-PSSession -ComputerName 'boe-pc' -ConfigurationName PrinterAudit

After some exploring, I see that I can check printers and services, but I cannot make any changes while I am connected to the remote endpoint.

[boe-pc]: PS>Get-Command

[boe-pc]: PS>Get-Printer

[boe-pc]: PS>Add-Printer

[boe-pc]: PS>Get-Service Spooler

[boe-pc]: PS>Stop-Service Spooler

Image of command output

With that, you can see what it takes to configure a constrained remote endpoint by using a pssession configuration file.

SH, that is all there is to customizing a constrained remote endpoint by using a configuration file. What happens if we want a user to have access to a command (or commands), but want to further limit what they can do? How about giving a user access to run that command on a system that they do not have access to without giving them the rights to that system? Stay tuned…

Remote Endpoint Week will continue tomorrow when I will show you how this can be done by creating a proxy function and using delegated administration on the remote endpoint.

I invite you to follow the Scripting Guys on Twitter and Facebook. If you have any questions, send email to me at, or post your questions on the Official Scripting Guys Forum. See you tomorrow.

Boe Prox, Honorary Scripting Guy


Discussion is closed.

Feedback usabilla icon