Skip to content

Ansible Windows Management using HTTPS and SSL

Managing your Windows machines and servers using Ansible is pretty easy as there are more than hundred modules available to handle your Windows operations. This is a series of articles and in this article you will learn how to connect Windows from Ansible using HTTPS and SSL certificate.

See other articles to learn how to manage windows using Ansible

Note: Most of the steps and commands are copied from the Ansible documentation but added a lot of explanations and additional details to support the process.

Ansible to Windows Authentication

You have multiple authentication options to connect and authenticate to your Windows machine from Ansible.

You can see the basic authentication method here in this article – How to configure Windows for Ansible. In this article you will learn how to connect Windows from Ansible using HTTPS and SSL certificate.

Step 1. Generate SSL Certificate

You can create SSL Certificate from Linux or Windows (PowerShell) and in this guide we will explain how to generate SSL certificate from Linux (you can do this from your Ansible controlnode itself).

Set the username which we are going to use to access Windows machine (eg: ansible)

$ set WINUSERNAME="ansible"

Now we need to set some arguments for the openssl and we will create a openssl.conf file for the same. Create openssl.conf file as below.

$ cat > openssl.conf << EOL
distinguished_name = req_distinguished_name
extendedKeyUsage = clientAuth
subjectAltName = otherName:;UTF8:[email protected]

To pass this openssl.conf we can set the OPENSSL_CONF environment variable so that openssl command will take this configuration file and use it during execution.

$ export OPENSSL_CONF=openssl.conf

Create SSL Certificate

$ openssl req -x509 -nodes \
  -days 3650 -newkey rsa:2048 \
  -out cert.pem \
  -outform PEM \
  -keyout cert_key.pem \
  -subj "/CN=$WINUSERNAME" \
  -extensions \

Generating a 2048 bit RSA private key
writing new private key to 'cert_key.pem'

Delete openssl.conf

$ rm openssl.conf

Step 2. Import a Certificate to the Certificate Store in Windows

Now you need to import the Certificate to the Windows machine which you want to connect from Ansible. Please note, below steps have to be executed on Windows machine.

First you need to copy cert.pem using any of the method (eg: WinSCP) to the Windows machine.

Import Issuing Certificate

Now you need to import the Certificate on Windows machine using PowerShell commands.

$cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2

$store_name = [System.Security.Cryptography.X509Certificates.StoreName]::Root
$store_location = [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine
$store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList $store_name, $store_location

Import the client certificate public key

Since this is self-signed certificate both the issuing certificate and public key are the same.

$cert = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Certificate2

$store_name = [System.Security.Cryptography.X509Certificates.StoreName]::TrustedPeople
$store_location = [System.Security.Cryptography.X509Certificates.StoreLocation]::LocalMachine
$store = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList $store_name, $store_location

Step 3. Mapping a Certificate to an Account in Windows

Now you need to map the Certificate with a use account. It can be the Administrator account or any dedicated account like ansible which we have created for this specific purpose.

$username = "ansible"
$password = ConvertTo-SecureString -String "Welcome123" -AsPlainText -Force
$credential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, $password

# This is the issuer thumbprint which in the case of a self generated cert
# is the public key thumbprint, additional logic may be required for other
# scenarios
$thumbprint = (Get-ChildItem -Path cert:\LocalMachine\root | Where-Object { $_.Subject -eq "CN=$username" }).Thumbprint

New-Item -Path WSMan:\localhost\ClientCertificate `
    -Subject "[email protected]" `
    -URI * `
    -Issuer $thumbprint `
    -Credential $credential `

You will get some response as below.

   WSManConfig: Microsoft.WSMan.Management\WSMan::localhost\ClientCertificate

Type            Keys                                Name
----            ----                                ----
Container       {URI=*, Issuer=0E2C17459D7C82630... ClientCertificate_2070301166

Step 4. Enabling Certificate Authentication Option in Windows

PS > winrm set winrm/config/service/Auth '@{Certificate="true"}'
    Basic = true
    Kerberos = true
    Negotiate = true
    Certificate = true
    CredSSP = false
    CbtHardeningLevel = Relaxed

Step 5. Configure Variables in Ansible

I have configured my host variables as below in my inventory. You are free to configure these variable as per your configuration practices. Please note, I have disabled ansible_user and ansible_password to ensure that ansible is using SSL/HTTPS communication.

win2019 ansible_host=



# enable HTTPS

Step 6. Connect from Ansible to Windows using HTTPS

Now we have configured SSL certificates and Ansible variables. Let’s test Ansible connection to Windows machine using a simple win_ping module. I am adding -vvv to enable high verbose mode to see and verify HTTP connection details as below.

$ ansible win2019 -m win_ping -vvv

ansible 2.9.0
  config file = /Users/gini/workarea/windows-ssl-demo/ansible.cfg
  configured module search path = ['/Users/gini/.ansible/plugins/modules', '/usr/share/ansible/plugins/modules']
  ansible python module location = /Users/gini/python-venv/ansible-29/lib/python3.7/site-packages/ansible
  executable location = /Users/gini/python-venv/ansible-29/bin/ansible
  python version = 3.7.3 (default, Nov 15 2019, 04:04:52) [Clang 11.0.0 (clang-1100.0.33.16)]
Using /Users/gini/workarea/windows-ssl-demo/ansible.cfg as config file
host_list declined parsing /Users/gini/workarea/windows-ssl-demo/hosts as it did not pass its verify_file() method
script declined parsing /Users/gini/workarea/windows-ssl-demo/hosts as it did not pass its verify_file() method
auto declined parsing /Users/gini/workarea/windows-ssl-demo/hosts as it did not pass its verify_file() method
Parsed /Users/gini/workarea/windows-ssl-demo/hosts inventory source with ini plugin
META: ran handlers
Using module file /Users/gini/python-venv/ansible-29/lib/python3.7/site-packages/ansible/modules/windows/win_ping.ps1
Pipelining is enabled.
EXEC (via pipeline wrapper)
win2019 | SUCCESS => {
    "changed": false,
    "invocation": {
        "module_args": {
            "data": "pong"
    "ping": "pong"
META: ran handlers
META: ran handlers

Great ! All good and we have connected to Windows machine using Ansible over HTTPS. I want to try one more task using win_whoami module and see the result. There are so much details but let’s focus few items as highlighted below.

$ ansible win2019 -m win_whoami

win2019 | SUCCESS => {
    "account": {
        "account_name": "ansible",
        "domain_name": "WIN-OCEE554K769",
        "sid": "S-1-5-21-2652326372-650916474-2589809930-1000",
        "type": "User"
    "authentication_package": "NTLM",
    "changed": false,
    "dns_domain_name": "",
    "groups": [
            "account_name": "Local account and member of Administrators group",
            "attributes": [
                "Enabled by default",
            "domain_name": "NT AUTHORITY",
            "sid": "S-1-5-114",
            "type": "WellKnownGroup"
    "impersonation_level": "SecurityAnonymous",
    "label": {
        "account_name": "High Mandatory Level",
        "domain_name": "Mandatory Label",
        "sid": "S-1-16-12288",
        "type": "Label"
    "login_domain": "WIN-OCEE554K769",
    "login_time": "2021-09-29T21:54:55.8543746-07:00",
    "logon_id": 3606545,
    "logon_server": "WIN-OCEE554K769",
    "logon_type": "Network",
    "privileges": {
        "SeBackupPrivilege": "enabled-by-default",
        "SeChangeNotifyPrivilege": "enabled-by-default",
        "SeCreateGlobalPrivilege": "enabled-by-default",
        "SeCreatePagefilePrivilege": "enabled-by-default",
        "SeCreateSymbolicLinkPrivilege": "enabled-by-default",
        "SeDebugPrivilege": "enabled-by-default",
        "SeDelegateSessionUserImpersonatePrivilege": "enabled-by-default",
        "SeImpersonatePrivilege": "enabled-by-default",
        "SeIncreaseBasePriorityPrivilege": "enabled-by-default",
        "SeIncreaseQuotaPrivilege": "enabled-by-default",
        "SeIncreaseWorkingSetPrivilege": "enabled-by-default",
        "SeLoadDriverPrivilege": "enabled-by-default",
        "SeManageVolumePrivilege": "enabled-by-default",
        "SeProfileSingleProcessPrivilege": "enabled-by-default",
        "SeRemoteShutdownPrivilege": "enabled-by-default",
        "SeRestorePrivilege": "enabled-by-default",
        "SeSecurityPrivilege": "enabled-by-default",
        "SeShutdownPrivilege": "enabled-by-default",
        "SeSystemEnvironmentPrivilege": "enabled-by-default",
        "SeSystemProfilePrivilege": "enabled-by-default",
        "SeSystemtimePrivilege": "enabled-by-default",
        "SeTakeOwnershipPrivilege": "enabled-by-default",
        "SeTimeZonePrivilege": "enabled-by-default",
        "SeUndockPrivilege": "enabled-by-default"
    "rights": [
    "token_type": "TokenPrimary",
    "upn": "",
    "user_flags": []

Additional Steps

Once the HTTPS communication has been enabled and verified with WinRM, you may proceed with additional steps listed below to ensure you are using only secure communication between Ansible and your Windows machine. These are not mandatory but recommended as part of best practices.

Disable Username and Password if any

If you have configured any username or password for Windows machine, disable the same in your Ansible variable configurations; we do not need this anymore.


Disable unencrypted PowerShell Remoting

PS > winrm set winrm/config/service '@{AllowUnencrypted="false"}'

    MaxConcurrentOperations = 4294967295
    MaxConcurrentOperationsPerUser = 1500
    EnumerationTimeoutms = 240000
    MaxConnections = 300
    MaxPacketRetrievalTimeSeconds = 120
    AllowUnencrypted = false
        Basic = true
        Kerberos = true
        Negotiate = true
        Certificate = false
        CredSSP = false
        CbtHardeningLevel = Relaxed
        HTTP = 5985
        HTTPS = 5986
    IPv4Filter = *
    IPv6Filter = *
    EnableCompatibilityHttpListener = false
    EnableCompatibilityHttpsListener = false
    AllowRemoteAccess = true

Disable WinRM Basic Authentication

If you want to disable the WinRM Basic authentication (username & password), then disable the same.

PS > winrm set winrm/config/service/Auth '@{Basic="false"}'
    Basic = false
    Kerberos = true
    Negotiate = true
    Certificate = true
    CredSSP = false
    CbtHardeningLevel = Relaxed

Disclaimer: The views expressed and the content shared are those of the author and do not reflect the views of the author’s employer or techbeatly platform.

Gineesh Madapparambath is the author of the book - 𝗔𝗻𝘀𝗶𝗯𝗹𝗲 𝗳𝗼𝗿 𝗥𝗲𝗮𝗹-𝗟𝗶𝗳𝗲 𝗔𝘂𝘁𝗼𝗺𝗮𝘁𝗶𝗼𝗻. He has worked as a Systems Engineer, Automation Specialist, and content author. His primary focus is on Ansible Automation, Containerisation (OpenShift & Kubernetes), and Infrastructure as Code (Terraform). (aka Gini Gangadharan -


6 Responses

  1. […] Ansible Windows Management using HTTPS and SSL […]

  2. […] Ansible Windows Management using HTTPS and SSL […]

  3. […] Ansible Windows Management using HTTPS and SSL […]

  4. Ahmad Faeez says:

    I’m getting this issue

    New-Item : Cannot validate argument on parameter ‘Issuer’. The argument is
    null or empty. Provide an argument that is not null or empty, and then try
    the command again.
    At line:4 char:13
    + -Issuer $thumbprint `
    + ~~~~~~~~~~~
    + CategoryInfo : InvalidData: (:) [New-Item], ParameterBindingV
    + FullyQualifiedErrorId : ParameterArgumentValidationError,Microsoft.Pow

    How can i solve this?
    Thank You

  5. Ahmad Faeez says:

    Windows 11 Pro

Leave a Reply

Your email address will not be published.

This site uses Akismet to reduce spam. Learn how your comment data is processed.

%d bloggers like this: