PowerShell function to enable WinRM over HTTPS on an Azure Resource Manager VM

You may have seen my previous posts detailing how to enable WinRM over HTTPS on an Azure Resource Manager VM. I have now collated all the different bits of script and creates a single PowerShell function. The function is called Configure-WinRMHTTPS, and is as follows:

function Configure-AzureWinRMHTTPS {
  Configure WinRM over HTTPS inside an Azure VM.
  1. Creates a self signed certificate on the Azure VM.
  2. Creates and executes a custom script extension to enable Win RM over HTTPS and opens 5986 in the Windows Firewall
  3. Creates a Network Security Rules for the Network Security Group attached the the first NIC attached the the VM allowing inbound traffic on port 5986
   Configure-AzureWinRMHTTPS -ResourceGroupName "TestGroup" -VMName "TestVM"
  Give another example of how to use it
  .PARAMETER ResourceGroupName
  Name of the resource group that the VM exists in
  The name of the virtual machine you wish to enable Win RM on.
  DNS name you will use to connect to the VM. If not provided defaults to the computer name.
  .PARAMETER SourceAddressPrefix
  Provide an CIDR value to restrict connections to a specific IP range


            $DNSName = $env:COMPUTERNAME,
            $SourceAddressPrefix = "*"


# define a temporary file in the users TEMP directory
$file = $env:TEMP + "\ConfigureWinRM_HTTPS.ps1"
#Create the file containing the PowerShell



# Ensure PS remoting is enabled, although this is enabled by default for Azure VMs
Enable-PSRemoting -Force
# Create rule in Windows Firewall
New-NetFirewallRule -Name "WinRM HTTPS" -DisplayName "WinRM HTTPS" -Enabled True -Profile Any -Action Allow -Direction Inbound -LocalPort 5986 -Protocol TCP
# Create Self Signed certificate and store thumbprint
$thumbprint = (New-SelfSignedCertificate -DnsName $DNSName -CertStoreLocation Cert:\LocalMachine\My).Thumbprint
# Run WinRM configuration on command line. DNS name set to computer hostname, you may wish to use a FQDN
$cmd = "winrm create winrm/config/Listener?Address=*+Transport=HTTPS @{Hostname=""$DNSName""; CertificateThumbprint=""$thumbprint""}"
cmd.exe /C $cmd
}  | out-file $file -force

# Get the VM we need to configure
$vm = Get-AzureRmVM -ResourceGroupName $ResourceGroupName -Name $VMName

# Get storage account name
$storageaccountname = $vm.StorageProfile.OsDisk.Vhd.Uri.Split('.')[0].Replace('https://','')
# get storage account key
$key = (Get-AzureRmStorageAccountKey -Name $storageaccountname -ResourceGroupName $ResourceGroupName).Key1
# create storage context
$storagecontext = New-AzureStorageContext -StorageAccountName $storageaccountname -StorageAccountKey $key
# create a container called scripts
New-AzureStorageContainer -Name "scripts" -Context $storagecontext
#upload the file
Set-AzureStorageBlobContent -Container "scripts" -File $file -Blob "ConfigureWinRM_HTTPS.ps1" -Context $storagecontext -force

# Create custom script extension from uploaded file
Set-AzureRmVMCustomScriptExtension -ResourceGroupName $ResourceGroupName -VMName $VMName -Name "EnableWinRM_HTTPS" -Location $vm.Location -StorageAccountName $storageaccountname -StorageAccountKey $key -FileName "ConfigureWinRM_HTTPS.ps1" -ContainerName "scripts" -RunFile "ConfigureWinRM_HTTPS.ps1" -Argument $DNSName
# Get the name of the first NIC in the VM
$nic = Get-AzureRmNetworkInterface -ResourceGroupName $ResourceGroupName -Name (Get-AzureRmResource -ResourceId $vm.NetworkInterfaceIDs[0]).ResourceName

# Get the network security group attached to the NIC
$nsg = Get-AzureRmNetworkSecurityGroup  -ResourceGroupName $ResourceGroupName  -Name (Get-AzureRmResource -ResourceId $nic.NetworkSecurityGroup.Id).Name 
# Add the new NSG rule, and update the NSG
$nsg | Add-AzureRmNetworkSecurityRuleConfig -Name "WinRM_HTTPS" -Priority 1100 -Protocol TCP -Access Allow -SourceAddressPrefix $SourceAddressPrefix -SourcePortRange * -DestinationAddressPrefix * -DestinationPortRange 5986 -Direction Inbound   | Set-AzureRmNetworkSecurityGroup

# get the NIC public IP
$ip = Get-AzureRmPublicIpAddress -ResourceGroupName $ResourceGroupName -Name (Get-AzureRmResource -ResourceId $nic.IpConfigurations[0].PublicIpAddress.Id).ResourceName 

Write-Host "To connect to the VM using the IP address while bypassing certificate checks use the following command:" -ForegroundColor Green
Write-Host "Enter-PSSession -ComputerName " $ip.IpAddress  " -Credential <admin_username> -UseSSL -SessionOption (New-PsSessionOption -SkipCACheck -SkipCNCheck)" -ForegroundColor Green


Once the function is loaded you must login to Azure. Then the function can be executed:

 Configure-AzureWinRMHTTPS -ResourceGroupName "TestGroup" -VMName "TestVM"

My next post will cover submitting the function to the PowerShell Gallery.

Comments (3)
  1. BZanten says:

    Very good instructions!
    I had to change the code to retrieve the key from:
    $key = (Get-AzureRmStorageAccountKey -Name $storageaccountname -ResourceGroupName $ResourceGroupName).Key1
    $key = (Get-AzureRmStorageAccountKey -Name $storageaccountname -ResourceGroupName $ResourceGroupName)[0].Value

  2. Martin says:

    After changing the variable to get the Storage key as BZanten suggested everything is working perfectly, but is this function still preffered solution to manage Azure RM VM’s With PowerShell, or is there any ‘easier’ solution?

  3. stephanus van staden says:

    You can also use the New-WSManInstance – save me a lot of time since winrm was disabled on the running instance of nano

    $cert=(get-childitem cert:\LocalMachine\My)[0]
    $thumbprint = $cert.Thumbprint
    $value=@{Hostname=”$DNSName”; CertificateThumbprint=”$thumbprint”}
    New-WSManInstance winrm/config/Listener -SelectorSet @{Address=”*”;Transport=”HTTPS”} -ValueSet $value


Comments are closed.

Skip to main content