PowerShell Web Access is great new feature, that allows us run PowerShell inside web browser. So far I was thinking of it as something that is either save but slightly inconvenient (when we have to connect to constrained endpoint running with RunAs credentials) or slightly insecure with cool features like tab completion and full cmdlet coverage, including all *-Object cmdlets (if we connect with more privileged account to “normal” endpoint). Either – or. But last Friday I came up with idea that can give us a little bit of both. Idea, that I would like to share.
I have mentioned it several times, and I will repeat it again: in my opinion constrained endpoints are perfect for delegation, but are useful only when we import them into current session, using implicit remoting. When we are forced to use them directly in web browser it becomes painful: even more painful than in “normal” console, where we have many other tools that can support us, like script pane in PowerShell ISE. In PowerShell Web Access, especially when used on mobile devices, things that save typing and reduce typos are very important. The question I was asking myself was: how to do that without opening delegated endpoint too much?
How it works (easy way)
As you may know already PowerShell Web Access is just a gateway between browser and remoting endpoints. First of all – you need to be able to authenticate to the web page. But once you authenticate, there is second step involved – authorization rules. These rules decide if you are allowed to connect to given computer, with given configuration. This is where gateway connects to remote server on your behalf. You have to be able to connect to the endpoint too, which may require alternate set of credentials. Unfortunately, there is no separation between those two steps: you have to give it all in single step. One of things I would love to see in next version would be this separation. Until than – we have to provide everything on login page:
“Destination computer” is the part where we can constrained things. We want to run this beast (and type in password) on many different devices, some of them may be considered less secure. Consider typing in your Enterprise Admin password on smartphone without antivirus. Looks like asking for trouble if you would ask me… SSL will protect traffic from device to the gateway, but if there is something sitting on the device itself – we are doomed. If we mix delegation with constrains it looks a lot more secure. We can, obviously, prepare such configuration pretty easily:
There can be more Endpoints, but when connecting to them – we would need to re-connect (or run another instances of web browser – separate tab in my experience is not enough). Each time we need to provide credentials and make sure there is authorization rule in place that would allow users connect to created endpoint. Also, working with constrained endpoint this way requires usually to type in whole command (without TAB support) and won’t let you use cmdlets that make working with data a lot easier (Select-Object, Where-Object, Foreach-Object to start with). This is were my puzzle started. So how in my opinion we can solve it?
Triple-Hop
First question you can ask yourself: how can I run PowerShell console and feel save about it? Easiest answer: this console should run as less privileged account. This can be done with “normal” endpoint (but than we walk into issues with double-hop), or with delegated endpoint that runs with non-admin (RunAs creds, server trusted for delegation, CredSSP). For easier configuration, let’s try with RunAs credentials first. It means that you will connect remotely to the box, but even than – you won’t be able to do anything destructive. All cmdlets that are useful for filtering and displaying data are there, tab completion works, all is great. But that won’t help us with delegating credentials and performing tasks that require admin rights. And that’s moment when our good friend implicit remoting comes into the picture.
Rather than connect to remote box(es) – we can simply create remote sessions and import them into our “local” session. This is probably best done with StartupScript. Let say we want to configure single endpoint with low privileges on our server as a “wrapper” around several connections to other servers, each with delegated constrained endpoint running as privileged user and with ACL configured in a way, that our initial user can connect to it. Something like this:
Example StartupScript script may look like this:
$EndpointList = @' Name,Config,Prefix Delegated-DC,DC,DC Delegated-File,File,FL Delegated-DB,DB,DB Endpoint,PSWA,PSWA '@ | ConvertFrom-Csv foreach ($Endpoint in $EndpointList) { $ParamsNew = @{ ComputerName = $Endpoint.Name ConfigurationName = $Endpoint.Config ErrorAction = 'Ignore' } $Session = New-PSSession @ParamsNew if ($Session) { $ParamsImport = @{ Prefix = $Endpoint.Prefix Session = $Session ErrorAction = 'Ignore' } Import-PSSession @ParamsImport | Out-Null } }
Lets save it in known location and configure our endpoint:
$Konfig = 'C:\ProgramData\Microsoft\PowerShell\Config.ps1' $ParamsRegister = @{ Name = 'Full' StartupScript = $Konfig SecurityDescriptorSddl = $SDDL RunAsCredential = $WebCreds Force = $true } Register-PSSessionConfiguration @ParamsRegister
Once it is done we can run code that would normally requires admin rights, but if we need to process it – we now can (with cmdlets that will run locally, as “safe” account). Any neat features that PowerShell Web Access offers (like tab completion) will work. And we won’t be able to cause (ourselves or the system) any harm (mind PSWAPswa in first command):
This is just sketch of final configuration – but I think it may help few people who are still fighting with thoughts and are not sure if they should use PSWA or not. Also – this is extension to chapter I’ve written for PowerShell Deep Dives book available in MEAP (any feedback more than welcome). Chapter is more descriptive when it comes to configuration both on endpoint and PSWA side. Here – I just wanted to share idea how to make it more user-friendly. I wish I came up with it before I wrote the chapter…