Cloud Computing

Enabling HTTPS for PowerShell Remoting in Windows Server 2012 R2

powershell hero

In today’s Ask the Admin, I’ll kill two birds with one stone by showing you how to enable secure PowerShell Remoting in Azure virtual machines (VMs) and on-premises servers running Windows Server 2012 R2.

PowerShell Remoting uses encryption to secure communications between devices, regardless of whether HTTPS is deployed as the transport. But outside of a domain environment where the Kerberos authentication protocol provides a trust relationship between computers, PowerShell Remoting could be subject to man-in-the-middle attacks. To thwart these kinds of threats, Microsoft recommends using HTTPS as the transport for PowerShell Remoting when a session is initiated from a workgroup device.

Azure VMs deployed using the classic deployment model have PowerShell Remoting enabled and are securely configured by default. With that model, you could download a certificate from the management portal, install it on your device and then make a secure connection to an Azure VM.

Sponsored Content

What is “Inside Microsoft Teams”?

“Inside Microsoft Teams” is a webcast series, now in Season 4 for IT pros hosted by Microsoft Product Manager, Stephen Rose. Stephen & his guests comprised of customers, partners, and real-world experts share best practices of planning, deploying, adopting, managing, and securing Teams. You can watch any episode at your convenience, find resources, blogs, reviews of accessories certified for Teams, bonus clips, and information regarding upcoming live broadcasts. Our next episode, “Polaris Inc., and Microsoft Teams- Reinventing how we work and play” will be airing on Oct. 28th from 10-11am PST.

But that’s no longer the case for VMs deployed using Azure Resource Manager (ARM), where only RDP connections are permitted by default. In this article, I’ll show you how to generate a self-signed certificate for the purposes of establishing SSL connections. While self-signed certificates are useful in lab environments, if you need HTTPS in a production environment, certificates should either be issued by your own Certification Authority (CA) or by a public CA.

Add a Rule to an Azure Network Security Group

If the Azure VM you want to manage was deployed using the Resource Manager deployment model in the management portal, you’ll need to start by adding a rule to the Network Security Group (NSG) to allow inbound connections on port 5986. If you deployed the VM using Resource Manager, but using PowerShell ARM cmdlets or a JSON template, it may be that no NSG exists, in which case you can skip this section. If you want to manage an on-premises server using a device on the Internet, you’ll need to add an inbound rule to your network-edge firewall.

Add a rule to an Azure Network Security Group (NSG) (Image Credit: Russell Smith)
Add a rule to an Azure Network Security Group (NSG) (Image Credit: Russell Smith)

If you haven’t yet installed Azure PowerShell 1.0 (or higher), read Install Azure PowerShell 1.0 Preview on Petri. Open Windows PowerShell ISE, and log in to your Microsoft account using the Login-AzureRmAccount cmdlet.

Login-AzureRmAccount

# Select a subscription

$subscriptionId = (Get-AzureRmSubscription | Out-GridView -Title 'Select Azure Subscription:' -PassThru).SubscriptionId
Select-AzureRmSubscription -SubscriptionId $subscriptionId

# Select a Resource Group

$rgName = (Get-AzureRmResourceGroup | Out-GridView -Title 'Select Azure Resource Group:' -PassThru).ResourceGroupName

Run the rest of the code above, and select the Azure subscription and Resource Group where your VM is located.

Next, I’ll define a variable with the name of the NSG that I want to modify. NSGs are most commonly used to control inbound and outbound network traffic to subnets. The Get-AzureRmNetworkSecurityGroup, Add-AzureRmNetworkSecurityRuleConfig, and Set-AzureRmNetworkSecurityGroup cmdlets are then used to add a new rule and update the NSG. You can see that the rule specified in the Add-AzureRmNetworkSecurityRuleConfig cmdlet allows inbound TCP traffic on port 5986 from any device.

# Set the NSG name

$nsgName = 'NSG1'

# Add rule to existing NSG

$nsg = Get-AzureRmNetworkSecurityGroup -Name $nsgName -ResourceGroupName $rgName
$nsg | Add-AzureRmNetworkSecurityRuleConfig -Name 'default-winrm-https' -Direction Inbound -Priority 1001 -Access Allow -SourceAddressPrefix '*'  -SourcePortRange '*' -DestinationAddressPrefix '*' -DestinationPortRange 5986 -Protocol Tcp 
$nsg | Set-AzureRmNetworkSecurityGroup

# Display custom security rules

(Get-AzureRmNetworkSecurityGroup -Name $nsgName -ResourceGroupName $rgName).SecurityRules

List the security rules in an Azure Network Security Group (Image Credit: Russell Smith)
List the security rules in an Azure Network Security Group (Image Credit: Russell Smith)

For confirmation, I use the Get-AzureRmNetworkSecurityGroup cmdlet once more to display the custom security rules for the NSG. You should see the new rule in the output.

Generate and Install a Self-Signed Certificate

Now I need to RDP to the server and install a certificate. This process is the same for local and Azure-based VMs. Open a PowerShell prompt with local administrator privileges on the server and run the code block below.

Create a self-signed certificate using PowerShell (Image Credit: Russell Smith)
Create a self-signed certificate using PowerShell (Image Credit: Russell Smith)

# Run on the remote server with admin privileges

mkdir C:\temp
$Cert = New-SelfSignedCertificate -CertstoreLocation Cert:\LocalMachine\My -DnsName adVM.ad.contoso.com
Export-Certificate -Cert $Cert -FilePath C:\temp\cert

Here I use the New-SelfSignedCertificate cmdlet (PowerShell 4.0 and later) to generate and install the certificate on the server. Note that the -DnsName parameter should contain the name that will be resolved by DNS when initiating a remote connection to the server. This usually means specifying the server’s Fully Qualified Domain Name (FQDN). Export-Certificate is then used to export the certificate as a file to the temp directory. You’ll need to copy this file and import it on the device where you’ll initiate PowerShell Remoting sessions to the server.

Create a WinRM HTTPS Listener

Now that we have a certificate, all that’s left to do is use the New-Item cmdlet to create an HTTPS listener and the New-NetFirewallRule cmdlet to open port 5986 in Windows Firewall to allow inbound connections for PowerShell Remoting.

Create a WinRM HTTPS listener and new Windows Firewall rule (Image Credit: Russell Smith)
Create a WinRM HTTPS listener and new Windows Firewall rule (Image Credit: Russell Smith)

# Set up WinRM HTTPS listener

New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint –Force
New-NetFirewallRule -DisplayName 'Windows Remote Management (HTTPS-In)' -Name 'Windows Remote Management (HTTPS-In)' -Profile Any -LocalPort 5986 -Protocol TCP

Remove HTTP Listeners

If you want to ensure that only HTTPS can be used for Windows Remote Management (WinRM), you should remove any existing HTTP listeners. You can use the winrm command to enumerate the listeners configured on the device. Here I use Get-ChildItem cmdlet to enumerate and remove all HTTP listeners. You might also want to remove firewall or NSG rules created for WinRM HTTP if they exist.

# Remove HTTP listener (optional)

Winrm enumerate winrm/config/listener
Get-ChildItem WSMan:\Localhost\listener | Where -Property Keys -eq 'Transport=HTTP' | Remove-Item -Recurse

Import the Certificate and Establish a Remote Connection

Now that the server is configured, use the Import-Certificate cmdlet to copy and import the certificate file (cert) generated in the steps above to the device where you’ll initiate PowerShell Remoting sessions. You’ll need to run a PowerShell prompt with local administrator privileges to import the certificate and make it available for all users of the device.

Import the self-signed certificate on the management PC (Image Credit: Russell Smith)
Import the self-signed certificate on the management PC (Image Credit: Russell Smith)

# Copy the cert file to the local PC and run commands below with admin privileges

Import-Certificate -Filepath 'C:\temp\cert' -CertStoreLocation 'Cert:\LocalMachine\Root'

# Skip Certification Authority (CA) check

$so = New-PsSessionOption –SkipCACheck

# Establish a POSH Remoting session

Enter-PSSession -Computername adVM.ad.contoso.com -Credential (Get-Credential) -UseSSL -SessionOption $so

Finally, use the Enter-PSSession cmdlet to establish a remote connection to the server. I skip the CA check because the imported certificate is self-signed and as such isn’t trusted by the device because it wasn’t issued by a known CA. Note also the use of the -UseSSL parameter to force the use of HTTPS.

Establish a PowerShell Remoting session over HTTPS (Image Credit: Russell Smith)
Establish a PowerShell Remoting session over HTTPS (Image Credit: Russell Smith)

If the PowerShell Remoting session is established successfully, you should see the prompt change in the console window to indicate that you are now connected to a session running on the remote server.

 

Related Topics:

BECOME A PETRI MEMBER:

Don't have a login but want to join the conversation? Sign up for a Petri Account

Register
Comments (0)

Leave a Reply

IT consultant, Contributing Editor @PetriFeed, and trainer @Pluralsight. All about Microsoft, Office 365, Azure, and Windows Server.
External Sharing and Guest User Access in Microsoft 365 and Teams

This eBook will dive into policy considerations you need to make when creating and managing guest user access to your Teams network, as well as the different layers of guest access and the common challenges that accompany a more complicated Microsoft 365 infrastructure.

You will learn:

  • Who should be allowed to be invited as a guest?
  • What type of guests should be able to access files in SharePoint and OneDrive?
  • How should guests be offboarded?
  • How should you determine who has access to sensitive information in your environment?

Sponsored by: