PowerShell Web Access: Is It Practical ?

PowerShell Web Access: Is It Practical?

PowerShell has long been the standard tool for managing everything. It handles Windows Server, Exchange, Office 365, and Azure resources. More recently, it has added support for Linux and macOS via its PowerShell Core fork. With its robust language, automation, and remoting capabilities, PowerShell has proven invaluable to many IT professionals. It has therefore become increasingly important to ensure access to a PowerShell console whenever possible.

Using PowerShell in the browser isn’t anything new. In fact, this feature has been available for many years. Since Windows Server 2012, PowerShell Web Access has allowed us to run cmdlets and scripts on any device. That said, the PowerShell Web Access feature hasn’t received much love since its initial release. And while it’s still part of the Windows Server installation, there’s not much new to report.

So why am I writing about this now, six years later? Azure Cloud Shell is one reason. I had intended to compare the two, particularly for Office 365 management. After other announcements at this year’s Ignite show, I have a few more reasons to delve deeper into this topic. Let’s dive in.

PowerShell Web Access

Since PowerShell Web Access isn’t new, I won’t go into the details of installation and configuration. You can find this information in the official documentation or on numerous blog posts. However, I will briefly discuss how you can use it and the applications. 

To begin, you can use any browser to connect to the PSWA endpoint. This is the endpoint exposed internally within your organization or to the outside world. Internet Explorer will do, even versions as old as IE 8.0, although you shouldn’t use them. Most mobile browsers are fine too, provided they support JavaScript. As you might imagine, the tradeoff for this relaxed requirement is a less snappy interface. This screenshot also illustrates the attention Microsoft has paid to this feature over the past few years. Since I’m actually running on a Windows Server 2019 box, even though the webpage says Windows Server 2016.

PowerShell Web Access Screenshot

Supported Cmdlets

Once you’ve logged in to the PSWA page, you’ll find yourself in a terminal window. And you can start issuing cmdlets. Under the hood, PSWA uses remoting to connect to a given machine. That’s why the Computer Name parameter is required when logging in. Once logged in, you have access to a full-fledged PowerShell console, as the output of $PSVersionTable indicates. And you can do more than just run cmdlets. For example, you can invoke .NET classes and methods, such as the System.Environment class and its OSVersion property, which indicates the current server version/build. You can also invoke console applications such as ipconfig:

PowerShell Console Access Screenshot

You benefit from support for:

  • tab completion and execution history,
  • most of the other PowerShell features you know.

Finding and installing modules via cmdlets exposed by the PowerShellGet module is one example, provided you’re logged into a computer running a recent version of PowerShell. You can quickly download the MSOnline module if it’s not already present on the system. Once the module is installed, you can log in to Office 365 and begin managing users.

PowerShell Web Access Module

Limitations

You may have noticed that I used the -Credential switch for the Connect-MsolService cmdlet above. This causes a special OAuth flow to be used. This allows me to log in via Modern Authentication while bypassing the interactive login dialog. The reason is simple: since I’m running PowerShell in what is effectively a terminal, there’s no way to display the ADAL interactive dialog. This means that any module that requires interactive login won’t work. And PowerShell will inform you of this with an error message. Connecting to services that accept the $Credentials variable will work just fine, however, for example in the case of Exchange Online:

PowerShell Web Access Module Example Screenshot

In fact, I used my usual “Office 365 login” script in a browser session. And I am now able to perform (almost) all the operations I am used to performing on my desktop computer. Other modules, such as Microsoft Teams, will also work without any problem, provided you can pass the credentials directly. For modules that only support interactive login, you will opt for workarounds. For example, you will obtain an access token directly via ADAL and pass it to log in via Modern Authentication:

PowerShell Web Access EXO Screenshot

This isn’t the only limitation. For example, in a remote session, if you run PowerShell on a different host, no profile is available. Therefore, you cannot interactively connect remotely to another machine using Enter-PSSession. For example, to access a module installed on that machine. An alternative would be to reconnect to the PSWA gateway and choose the other machine instead. You can also use other methods, such as New-PSSession, Invoke-Command, or the -ComputerName parameter.

Balance sheet

Since you’re tied to the device, copying and pasting information can be a chore. As can viewing or editing files, transferring files is nearly impossible. Syntax highlighting, function keys, and persistent cmdlet history are also unavailable or limited. Overall, PSWA is a viable replacement for cases where you need to perform a specific PowerShell task from a tablet. How convenient is it? I’d rate it a solid 8/10 when viewed in the context of Office 365 tasks.

Azure Cloud Shell

While PSWA has seen little change, Microsoft has put a lot of effort into releasing and refining PowerShell Core. One such modality is Azure Cloud Shell, a browser-based PowerShell experience for managing Azure resources. Under the hood, Azure Cloud Shell is a web interface for a PowerShell Core instance. The latter runs on a Linux VM running on top of a Hyper-V host. Running on Linux allows Microsoft to minimize resource consumption and costs. And in fact, the only ACS charge is for the cloud storage account used to host the VM containing the file share.

Azure Cloud Shell is accessible from multiple access points. It is integrated into the Azure portal and also has a standalone website accessible via https://shell.azure.com. If you access ACS via the Azure portal login, you will be automatically logged in and have access to Azure PowerShell. If you access it via the ACS web page, you will need to authenticate and select the subscription. You can also select the shell type, either Bash or PowerShell.

For the purposes of this article, we’re, of course, focusing on PowerShell. The screenshot below reveals some basic information about the environment, such as:

  • the version of PowerShell used,
  • the operating system it runs on,
  • the fact that it runs in a Hyper-V VM,
  • the IP address of the machine.

Available modules

The currently available PowerShell modules are listed on the right, and additional modules can be added via Install-Module. Additionally, some of the environment variables are displayed, which will be important later.

PowerShell en accès Web

Since this is a PowerShell Core instance running on Linux, there are some limitations. For example, I can download, install, and import the MSOnline module without any problems. However, I can’t use it to connect to Azure AD due to an underlying dependency on ADAL binaries:

PowerShell en accès Web

The same goes for any other module that depends on ADAL, unless it has been ported to .Net Core. Fortunately, that’s exactly what Microsoft has done with Azure modules. This includes a (preview) version of the Azure AD module that you may have spotted in the Get-Module output above. Therefore, we can use it instead of the MSOnline module to manage our Office 365 objects. In fact, there are several methods you can use to connect to Azure AD, as shown below:

PowerShell en accès Web

Connecting to Azure-AD

The first method is to simply use the Connect-AzureADService function. This will populate the AccountId and TenantId values ​​based on the environmental variables and automatically log you in. You can also run the Connect-AzureAD cmdlet without any parameters. This will trigger the OAuth flow of the device code. This will allow you to complete the interactive authentication process from a different endpoint, thus bypassing the limitations of PowerShell Core. Another method is to pass an access token directly. Once the login is successful, you can run all the familiar AzureAD cmdlets without any issues. This is in contrast to running Azure AD cmdlets on PowerShell Core, which resulted in various errors.

Boundaries

For managing Exchange Online objects, PowerShell Core should do the trick, once authenticated. If you’re still using Basic Authentication, you’ll be fine. MFA isn’t compatible with the ADA-enabled ExO module. This is because the module hasn’t been ported to work on .NET Core yet. But you can still use various tricks, such as obtaining a token outside the module and passing it:

PowerShell en accès Web

Another nuisance of the Linux VM/PowerShell Core combination is also shown in the screenshot above. Namely, the rather annoying “ERROR_WSMAN_INVALID_SELECTORS” errors that you often encounter. Problems with other modules can be even more frustrating. For example, the MicrosoftTeams module fails to install due to a DLL dependency error. The SharePoint PnP module installs correctly but fails to connect due to a method dependency, etc.

Some of the drawbacks of using PowerShell in the browser have been addressed. A basic syntax highlighter is available, as well as execution history between sessions. Instead of using vi or emacs command-line utilities, we have a built-in script editor. Transferring files in and out of the environment is also possible. Finally, ACS also supports PowerShell profiles. The downside is that browser requirements are stricter, which could limit availability on some systems. Some of the remaining issues include:

  • function keys are unusable,
  • the escape key does not work,
  • copy-paste leaves something to be desired in terms of user-friendliness.

The case-sensitive file system can quickly get on your nerves when trying to use tab completion.

Balance sheet

End-user experience aside, ACS can present some administrative challenges. As part of the Azure portal, ACS is available anytime, on any device, from any location. However, it is possible to restrict access to ACS by blocking the endpoint on your network devices. If you whitelist locations from which users can authenticate, such as “named locations” for Conditional Access, you will need to whitelist entire Azure subnets, as the external IP used by the ACS environment is not static. ACS lacks the granularity of PSWA authorization rules and session configurations, or even basic branding controls outside of Azure AD login branding.

How convenient is Azure Cloud Shell when it comes to performing your daily Office 365-related tasks? If you’re only interested in Azure AD tasks, the experience is comparable to running PowerShell on the desktop. If you add Exchange tasks into the mix, only ase authentication works. Almost all other Office 365-related modules have issues running in an ACS environment. So if these modules are essential to you, I recommend waiting until a .NET Core version of the module is officially released by Microsoft.

Given the issues encountered, ACS deserves a rating of 6/10 in the context of Office 365 tasks. This rating is expected to improve in the coming months as Microsoft continues to develop the shell and port additional modules to PowerShell Core.

Summary and next steps for Office 365 PowerShell in the browser

In this article, we explored the viability of browser-based access to PowerShell in the context of Office 365. Our first stop was PowerShell Web Access. It’s a reliable gateway for connecting to PowerShell on an on-premises or cloud-based machine. While PSWA hasn’t evolved much and the interface is clunky, it still gets the job done in most scenarios.

The other option is Azure Cloud Shell, a PowerShell Core environment running on a Linux VM in Azure. While ACS offers a better overall experience, it falls short. This is because most of the relevant modules have not yet been ported to .NET Core. Microsoft is working on improving it, and a preview version of the Azure AD module is available and pre-installed in the ACS environment. Additionally, we know that the ExO module is also under development. This is evident from recent code changes to the CreateExOPSSession script. The script detects whether the script is running in ACS and dynamically updates the script parameters. A short snippet of the core is visible below:

PowerShell en accès Web

Yes, these are exactly the same environmental variables we saw in the previous section. And that’s how I know the module is being prepared for ACS.

New-DistributionGroup: A Misunderstood PowerShell Cmdlet

New-DistributionGroup: A Misunderstood PowerShell Cmdlet

PowerShell – An Introduction to the Basics

PowerShell – An Introduction to the Basics

Adapt your Exchange Online scripts to use Get-ExoMailbox

Adapt your Exchange Online scripts to use Get-ExoMailbox

Top 6 PowerShell Commands for Managing Office 365

Top 6 PowerShell Commands for Managing Office 365

Scroll to Top