Running Windows PowerShell from Your Smartphone
Imagine that you're on vacation with your family, enjoying the sunshine, when you receive an emergency call from your IT department colleague back at the office. It turns out one of your infrastructure servers is messed up, and the fix can be accomplished by running a single PowerShell pipeline.
The trouble is that you're on the beach with only your smartphone. Sure, you can walk through the PowerShell with your colleague, but the chances are good that he or she is PowerShell-phobic. Wouldn't it be awesome if you could just send that PowerShell instruction directly from your smartphone?
I'm leading you a bit, of course, because you absolutely can access a PowerShell console session from just about any desktop or mobile browser in the world that supports cookies, SSL/TLS, and JavaScript—which is the vast majority of them, of course.
In this article, you'll learn how to deploy a PowerShell Web Access (PSWA) gateway to support "PowerShell through a pinhole."
Understanding PowerShell Web Access (PSWA)
PowerShell Web Access (PSWA) is a built-in role in Windows Server 2012 and Windows Server 2012 R2. PSWA combines an Internet Information Services (IIS) web application with the magic of Windows PowerShell remoting to allow administrators to access the PowerShell console host (powershell.exe) from a web browser.
One common use case I've seen is employing the PSWA gateway as a "jump box." Imagine that you want to send PowerShell commands to one or more hosts located on a screened, protected subnet, and firewall/security rules prevent you from interacting with the secure hosts directly. As Figure 1 shows, as long as you have access to a PSWA jump box, and the jump box has permissions to the screened subnet, you can accomplish your goal.
Figure 1 PowerShell Web Access serves as an excellent jump box to manage hosts that are normally out of reach.
The best way to learn how PSWA works is to set it up and work with it. For this example, my environment uses the computers described in the following table.
Fully Qualified Host Name |
Computer Role |
cli1.company.pri |
Windows 10 administrative workstation. |
mem1.company.pri |
Windows Server 2012 R2 member server that will be our PSWA gateway. |
dc1.company.pri |
Windows Server 2012 R2 domain controller that is our ultimate management target. In other words, we'll tunnel through the PSWA gateway to get to dc1. |
Setting Up the PSWA Gateway
First the possibly bad news: Installing the PowerShell Web Access role involves a server restart if you don't have the IIS bits already installed. Once you get over that hump, mosey on over to your PSWA gateway box (mem1 in my example), start an elevated Windows PowerShell console session, and issue the following one-liner:
Install-WindowsFeature -Name WindowsPowerShellWebAccess -IncludeManagementTools -Restart
We'll use Install-PSWAWebApplication to provision our new IIS website. PSWA requires SSL/TLS, so you need to decide which way you'll address this requirement:
- Use a test certificate. Install-PSWAWebApplication can actually create a self-signed certificate and even automatically create the IIS binding for you.
- Use an internal certificate. This option is convenient if your business already has an internal public key infrastructure (PKI).
- Use a public certificate. This option is obviously the most expensive, but you get built-in public trust.
For a lab or demo environment, the test certificate is fine. Here we go:
Install-PSWAWebApplication -UseTestCertificate
We can open IIS Manager to verify what happened (shown in Figure 2).
Figure 2 Verifying the SSL certificate binding on the PSWA virtual directory.
Note that unless we override with the -WebSiteName parameter of the Install-PSWAWebApplication command, PowerShell Web Access uses the Default Web Site web application. Along the same lines, the gateway installs into a virtual directory named PSWA unless we override with the -WebApplicationName parameter.
Finally, if you're going to use your own SSL certificate, simply leave off the -UseTestCertificate switch parameter and create the IIS binding manually.
Securing the PSWA Gateway
Other than SSL, the PowerShell Web Access gateway denies all connection attempts. To demonstrate, fire up a web browser and attempt to load the gateway. In my environment, mem1 is my gateway, and I used the installation defaults:
https://mem1/pswa
Remember that mem1 is my own server, so you'll need to substitute the name of your machine.
Because I used an untrusted self-signed SSL certificate, I'll have to manually continue the page load as shown in Figure 3.
Figure 3 Self-signed SSL/TLS certificates are fine in development, but not in production.
Unless your user account is granted PSWA gateway access via an authorization rule (which we'll create next), you'll receive an authentication failure upon login. Figure 4 shows the user interface (UI).
Figure 4 You see this error if your user account isn't granted PSWA gateway access through an authorization rule.
If you run Get-PSWAAuthorizationRule, by default you should see no output. Change that result right now by using Add-PSWAAuthorizationRule to enforce your authorization rules. Here are mine:
- Only members of the Domain Admins global group can access the gateway.
- The gateway allows remote connections only to the host dc1.company.pri.
- We'll use the default (open) session configuration for now.
Here's the code:
Add-PSWAAuthorizationRule -UserGroupname 'company\domain admins' -ComputerName dc1.company.pri -ConfigurationName *
The asterisk (*) at the end of the command is a wildcard; I've used it here to denote any PowerShell remoting session configuration. Although the asterisk is fine in dev/test environments, in production you'll want to create granular authorization rules that subscribe to the IT security principle of least privilege.
Now let's run Get-PSWAAuthorizationRule to verify that the gateway accepted the changes:
PS C:\> Get-PswaAuthorizationRule Id RuleName User Destination ConfigurationName -- -------- ---- ----------- ----------------- 0 Rule 0 company\domain admins company\dc1 *
Testing Access
From my administrative workstation (cli1), I'll reopen my browser and connect to the PSWA gateway URL. Make it a habit to open the Optional Connection Settings (see Figure 5) and change the default session configuration if necessary. You can also specify alternate credentials.
Figure 5 Open the Optional Connection Settings to use alternate credentials or change the session configuration.
Finally we see the actual PSWA console, as shown in Figure 6. Notice in Figure 6 that $host returns the Server Remote Host. Although the PSWA console looks and behaves a lot like the traditional powershell.exe console host, it's actually a different environment, which operates under different security rules.
Figure 6 We're running Windows PowerShell from a web browser!
Remember that this PowerShell access is available from any web browser that supports HTTPS, browser cookies, and JavaScript. You could conceivably run remote PowerShell commands from your iPhone or Android smartphone from anywhere in the world!
Remember that our authorization rules control the default connection (dc1 in my example). Attempting to connect to any other machine should cause an error.
To ensure that result, we can edit the PSWA authorization rules. In fact, let's quickly look up all the PSWA PowerShell commands related to authorization rules:
PS C:\> Get-Command -Name *authorizationrule* CommandType Name ModuleName ----------- ---- ---------- Cmdlet Add-PswaAuthorizationRule PowerShellWebAccess Cmdlet Get-PswaAuthorizationRule PowerShellWebAccess Cmdlet Remove-PswaAuthorizationRule PowerShellWebAccess Cmdlet Test-PswaAuthorizationRule PowerShellWebAccess
It strikes me as inconsistent and wonky that Microsoft forces us to redefine our authorization rules instead of modifying them in place (with a Set- verb, for instance), but we don't have a choice. Take a look:
Add-PswaAuthorizationRule -ComputerGroupName 'company\secureservers' -ConfigurationName * -RuleName mem1-dc1 - UserGroupName 'company\domain admins' -Verbose
Thanks to the -RuleName parameter, the auth rule now has a friendly name. For this example, I put dc1 and mem1 in a global computer group named SecureServers and used the -ComputerGroupName parameter to bring them into my previously established authorization rule.
To delete a rule, simply use the pipeline:
Get-PSWAAuthorizationRule -Rule 'mem1-dc1' | Remove-PSWAAuthorizationRule -Force
Next Steps
In my opinion, your next step is to deep-dive into session configuration files so you can get a handle on how to limit a remote user's capability in a session. For example, you might give domain administrators full access to all infrastructure servers, but only allow junior administrators to run Get- commands against specific servers.
To learn how to control session configuration, check any of the following references:
- Windows PowerShell conceptual help: session configuration files
- Microsoft TechNet: authorization rules
- Sams Teach Yourself Windows PowerShell 5 in 24 Hours: Hour 11, "Implementing One-to-Many Windows PowerShell Remoting"
Thanks for reading, and happy PowerShelling!