Skip to content

Enable HTTPS WinRM – Systems Not Connected to a Domain

When used between two systems within a domain, WinRM uses Kerberos to authenticate that the target server is trusted. Agentless scanning of non-domain-joined systems requires additional setup. WinRM on the Connection Manager host must be able to authenticate the target system. This is achieved with certificates. The following topic describes how to create a self-signed certificate on a target host and configure a HTTPS WinRM listener service. Cloudhouse provides a PowerShell script that automates the process and exports the self-signed certificate to a predictable location, for importing into the trusted certificate store on the Connection Manager host. You are then required to import the certificate on the Connection Manager host and modify the WinRM TrustedHosts list. Once complete, you need to edit your WinRM nodes in Guardian to use HTTPS port 5986. For more information on how to troubleshoot common problems related to HTTPS WinRM, see Troubleshoot WinRM – HTTP, HTTPS.

System Requirements

To perform Agentless scanning on non-domain systems, the following system requirements must be met:

  • HTTPS WinRM listener – Configured on the scan target, with a certificate that is considered valid on the Connection Manager operating system (OS) host.
  • Basic authentication – Configured on the scan target WinRM listener, to allow local account user authentication.
  • Firewall rules – Configured on the scan target, to permit traffic to the HTTPS WinRM listener port (default 5986).
  • A TrustedHosts entry – For the scan target in the WinRM configuration, on the Connection Manager host.

Remote Endpoint Configuration

First, you need to configure a Windows host for remote management with WinRM/HTTPS. Cloudhouse provide a PowerShell script that checks the current WinRM/PSRemoting configuration and makes the necessary changes to allow Ansible or Guardian to connect, authenticate and execute PowerShell commands. It also exports keys so that they can be loaded on to Windows Connection Managers and (optionally) remove access for HTTP.

Note: For this use case, the certificate validity is set to 10 years.

Configuration

To enable scripts to run on your system, use the command Set-ExecutionPolicy RemoteSigned.

To view the status of the script during runtime, you can set the following command $VerbosePreference = "Continue".

To skip the network profile check, you can set the following command $SkipNetworkProfileCheck.

Note: If you don't specify to skip the network profile check, the script will only run if the device's interfaces are in DOMAIN or PRIVATE zones. Provide this switch if you want to enable WinRM on a device with an interface in PUBLIC zone.

PowerShell Script

To configure a Windows host for remote management with WinRM/HTTPS, run the following PowerShell script on the client node that you wish to connect to.

Param (
    [string]$SubjectName = $env:COMPUTERNAME,
        [string]$IpAddress = (get-netadapter | ? status -eq 'up' | get-netipaddress -AddressFamily ipv4).ipaddress,
        [string]$FilePath = $env:USERPROFILE + "\winrm.crt",
    [int]$CertValidityDays = 3650,
    [switch]$SkipNetworkProfileCheck,
    $CreateSelfSignedCert = $true
)

# Setup error handling.
Trap
{
    $_
    Exit 1
}
$ErrorActionPreference = "Stop"

# Detect PowerShell version.
If ($PSVersionTable.PSVersion.Major -lt 3)
{
    Throw "PowerShell version 3 or higher is required."
}

# Find and start the WinRM service.
Write-Verbose "Verifying WinRM service."
If (!(Get-Service "WinRM"))
{
    Throw "Unable to find the WinRM service."
}
ElseIf ((Get-Service "WinRM").Status -ne "Running")
{
    Write-Verbose "Starting WinRM service."
    Start-Service -Name "WinRM" -ErrorAction Stop
}

# WinRM should be running; check that we have a PS session config.
If (!(Get-PSSessionConfiguration -Verbose:$false) -or (!(Get-ChildItem WSMan:\localhost\Listener)))
{
  if ($SkipNetworkProfileCheck) {
    Write-Verbose "Enabling PS Remoting without checking Network profile."
    Enable-PSRemoting -SkipNetworkProfileCheck -Force -ErrorAction Stop
  }
  else {
    Write-Verbose "Enabling PS Remoting"
    Enable-PSRemoting -Force -ErrorAction Stop
  }
}
Else
{
    Write-Verbose "PS Remoting is already enabled."
}

# Make sure there is a SSL listener.
$listeners = Get-ChildItem WSMan:\localhost\Listener
If (!($listeners | Where {$_.Keys -like "TRANSPORT=HTTPS"}))
{
    # HTTPS-based endpoint does not exist.
    $cert = New-SelfSignedCertificate -DnsName $IpAddress,$SubjectName -CertStoreLocation "Cert:\LocalMachine\My"
    $thumbprint = $cert.Thumbprint
    Write-Host "Self-signed SSL certificate generated; thumbprint: $thumbprint"

        Export-Certificate -Cert $cert -FilePath $FilePath
        Write-Host "Self-signed SSL certificate exported to $FilePath"

    # Create the hashtables of settings to be used.
    $valueset = @{}
    $valueset.Add('Hostname', $IpAddress)
    $valueset.Add('CertificateThumbprint', $thumbprint)

    $selectorset = @{}
    $selectorset.Add('Transport', 'HTTPS')
    $selectorset.Add('Address', '*')

    Write-Verbose "Enabling SSL listener."
    New-WSManInstance -ResourceURI 'winrm/config/Listener' -SelectorSet $selectorset -ValueSet $valueset
}
Else
{
    Write-Verbose "SSL listener is already active."
}

# Check for basic authentication.
$basicAuthSetting = Get-ChildItem WSMan:\localhost\Service\Auth | Where {$_.Name -eq "Basic"}
If (($basicAuthSetting.Value) -eq $false)
{
    Write-Verbose "Enabling basic auth support."
    Set-Item -Path "WSMan:\localhost\Service\Auth\Basic" -Value $true
}
Else
{
    Write-Verbose "Basic auth is already enabled."
}

# Configure firewall to allow WinRM HTTPS connections.
$fwtest1 = netsh advfirewall firewall show rule name="Allow WinRM HTTPS"
$fwtest2 = netsh advfirewall firewall show rule name="Allow WinRM HTTPS" profile=any
If ($fwtest1.count -lt 5)
{
    Write-Verbose "Adding firewall rule to allow WinRM HTTPS."
    netsh advfirewall firewall add rule profile=any name="Allow WinRM HTTPS" dir=in localport=5986 protocol=TCP action=allow
}
ElseIf (($fwtest1.count -ge 5) -and ($fwtest2.count -lt 5))
{
    Write-Verbose "Updating firewall rule to allow WinRM HTTPS for any profile."
    netsh advfirewall firewall set rule name="Allow WinRM HTTPS" new profile=any
}
Else
{
    Write-Verbose "Firewall rule already exists to allow WinRM HTTPS."
}

# Test a remoting connection to localhost, which should work.
$httpResult = Invoke-Command -ComputerName "localhost" -ScriptBlock {$env:COMPUTERNAME} -ErrorVariable httpError -ErrorAction SilentlyContinue
$httpsOptions = New-PSSessionOption -SkipCACheck -SkipCNCheck -SkipRevocationCheck

$httpsResult = New-PSSession -UseSSL -ComputerName "localhost" -SessionOption $httpsOptions -ErrorVariable httpsError -ErrorAction SilentlyContinue

If ($httpResult -and $httpsResult)
{
    Write-Verbose "HTTP: Enabled | HTTPS: Enabled"
}
ElseIf ($httpsResult -and !$httpResult)
{
    Write-Verbose "HTTP: Disabled | HTTPS: Enabled"
}
ElseIf ($httpResult -and !$httpsResult)
{
    Write-Verbose "HTTP: Enabled | HTTPS: Disabled"
}
Else
{
    Throw "Unable to establish an HTTP or HTTPS remoting session."
}
Write-Verbose "PS Remoting has been successfully configured."

Connection Manager Endpoint Configuration

Next, you need to transfer the winrm.crt file to the machine that will initiate HTTPS WinRM connections to remote endpoints. To do this, you need to copy the winrm.crt file from the current user’s home directory to the Windows Connection Manager host server.

Then, to install the self-signed certificate that was created on the host, use the following PowerShell command.

Import-Certificate -Filepath "C:\Path\To\Certificate" -CertStoreLocation "Cert:\LocalMachine\Root"

Verification of Certificate Installation

To verify that the certificate has been stored correctly on both the Windows Connection Manager host server and the remote endpoint servers, you can use the certificate add-in of the Microsoft Management Console (MMC) by following the process described below.

  1. In the Windows Search box, type 'mmc'. Then, click to Open. The Console dialog is displayed.

  2. Click the File drop-down list, then select Add/Remove Snap-ins. The Add/Remove Snap-ins dialog is displayed.

  3. Double click on the 'Certificates' Snap-in. The Certificates snap-in dialog is displayed.

  4. Select the 'Computer account' radio button, then click Next. The Select Computer dialog is displayed.

  5. Select the 'Local computer' radio button, then click Finish. The Add/Remove Snap-ins dialog is displayed.

  6. Click OK to return to the Console.

  7. In the Console Root, navigate to the Certificates folder (Personal > Certificates). Here, the certificate corresponding to the hostname or IP address is displayed.

If the certificate is displayed in the Certificates folder, the certificate has been stored correctly on both the Windows Connection Manager host server and the remote endpoint servers. If the certificate is not displayed, the self-signed certificate that was created on the host was not installed correctly.

Add Remote Endpoints to List of Trusted Hosts

To add the remote endpoint server node to the list of trusted hosts on your Windows Connection Manager machine, run the following command, replacing machineA with the hostname or IP Address of your machine.

winrm set winrm/config/client ‘@{TrustedHosts="machineA"}’

You can add more trusted hosts to the list, by using a comma separated list of values in the string.

Note: A quicker way to add remote endpoints, if you choose to write a script for it, is by working with the PSDrive (WSMan:\):. This allows you to use Get-Item to retrieve the current value of the TrustedHosts, save it to a variable (e.g. $OldVal), and Set-Item for the new ones with $OldVal,NewHost.

To retrieve the list of your trusted hosts currently on your Windows Connection Manager machine, run the following command.

Get-Item WSMan:\localhost\Client\TrustedHosts

To set trusted hosts on your Windows Connection Manager machine, run the following command:

Set-Item WSMan:\localhost\Client\TrustedHosts -Value "machineA,machineB,machineC"

Wildcards are also accepted in the format below.

Set-Item WSMan:\localhost\Client\TrustedHosts -Value "192.168.140.*,machine*,*"

Verification of WinRM HTTPS Connectivity

To verify that HTTPS WinRM has been set up correctly, run the following command.

Note: WinRM on a target node can be configured to listen for SSL connections, non-SSL connections, or both. If you want to be sure non-SSL is not enabled on the target (for security reasons) add the option -UseSSL on the following command.

Enter-PSSession -ComputerName COMPUTERNAME.DOMAIN.COM -UseSSL -Credential (Get-Credential)

Once complete, you will be prompted to enter the credentials of the user you would like to use connect to the remote endpoint. This should be the Windows service user account. If the correct details are provided, the remote endpoint server is successfully connected to via the PowerShell console.

Tip: The Windows Connection Manager emulates the parameters defined in the Enter-PSSession cmdlet. Using this cmdlet, you can troubleshoot your Connection Manager, separate from the Guardian software itself.

HTTPS Port Configuration

Once you have confirmed that HTTPS WinRM has been set up correctly, you need to edit your WinRM nodes in Guardian to use HTTPS port 5986. By default, WinRM is configured to communicate through HTTP port 5985. However, since WinRM has now been configured to use HTTPS, you need to manually set the port to 5986 for each node that has been configured as part of this process.

  1. In the Guardian web application, navigate to the Monitored tab (Inventory > Monitored).

    Here, a list of all monitored nodes are displayed and categorised by Node Groups.

  2. Select the node that needs the WinRM port changed. Then, click to Edit. The Edit [Node-Name] page is displayed.

  3. Navigate to the WinRM Port field and enter '5986', then click to Update Node.

Once updated, a confirmation message is displayed. You are required to complete this process for each node that has been configured to use HTTPS.