How to run Powershell command in provisioner remote-exec

Hi,
I have a Terraform template that create a basic Windows Azure VM (attached with an existing vnet - we dont create a public ip for that). After the creation of VM, I want to run the remote-exec in the provisioner to run some arbitrary powershell commands to install chocolatey and a few choco packages. However, it keeps failing because of the connection which requires me to fill in the public ip which I dont have.
Or is that because of winrm itself?

resource "azurerm_virtual_machine" "vm" {
    ##...vm creation..
os_profile_windows_config {
    provision_vm_agent        = true
    enable_automatic_upgrades = true

    # Auto-Login's required to configure WinRM
    additional_unattend_config {
      pass         = "oobeSystem"
      component    = "Microsoft-Windows-Shell-Setup"
      setting_name = "AutoLogon"
      content      = "<AutoLogon><Password><Value>__admin_username__</Value></Password><Enabled>true</Enabled><LogonCount>1</LogonCount><Username>AdminPassword</Username></AutoLogon>"
    }

    # Unattend config is to enable basic auth in WinRM, required for the provisioner stage.
    additional_unattend_config {
      pass         = "oobeSystem"
      component    = "Microsoft-Windows-Shell-Setup"
      setting_name = "FirstLogonCommands"
      content      = "${file("./files/FirstLogonCommands.xml")}"
    }
  }
  
    provisioner "remote-exec" {
        connection {
            # it threw an error for the host
           #Error:  Error: timeout - last error: unknown error Post https://*.*.*.*:5985/wsman: dial tcp **.**.**.**:5985: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.
            host        = "${element(azurerm_network_interface.nic.*.private_ip_address, count.index)}"
            type        = "winrm"
            user        = "${var.admin_user}"
            password    = "__AdminPassword__"
            port        = 5985
            https       = true
            timeout     = "5m"
        }

#I have tried different ways to run PS commands but none of them worked for me
        inline = [
            "powershell.exe \"Set-ExecutionPolicy Bypass -Scope Process -Force; iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))"",
            "powershell.exe \"choco install chefdk""
        ]
   }
}

#winrm.ps1
$profiles = Get-NetConnectionProfile
Foreach ($i in $profiles) {
    Write-Host ("Updating Interface ID {0} to be Private.." -f $profiles.InterfaceIndex)
    Set-NetConnectionProfile -InterfaceIndex $profiles.InterfaceIndex -NetworkCategory Private
}

Write-Host "Obtaining the Thumbprint of the Certificate from KeyVault"
$Thumbprint = (Get-ChildItem -Path Cert:\LocalMachine\My | Where-Object {$_.Subject -match "$ComputerName"}).Thumbprint

Write-Host "Enable HTTPS in WinRM.."
winrm create winrm/config/Listener?Address=*+Transport=HTTPS "@{Hostname=`"$ComputerName`"; CertificateThumbprint=`"$Thumbprint`"}"

Write-Host "Enabling Basic Authentication.."
winrm set winrm/config/service/Auth "@{Basic=`"true`"}"

Write-Host "Re-starting the WinRM Service"
net stop winrm
net start winrm

Write-Host "Open Firewall Ports"
netsh advfirewall firewall add rule name="Windows Remote Management (HTTPS-In)" dir=in action=allow protocol=TCP localport=5986

firstLogonCommands.xml

<FirstLogonCommands>
    <SynchronousCommand>
        <CommandLine>cmd /c "mkdir C:\terraform"</CommandLine>
        <Description>Create the Terraform working directory</Description>
        <Order>11</Order>
    </SynchronousCommand>
    <SynchronousCommand>
        <CommandLine>cmd /c "copy C:\AzureData\CustomData.bin C:\terraform\winrm.ps1"</CommandLine>
        <Description>Move the CustomData file to the working directory</Description>
        <Order>12</Order>
    </SynchronousCommand>
    <SynchronousCommand>
        <CommandLine>powershell.exe -sta -ExecutionPolicy Unrestricted -file C:\terraform\winrm.ps1</CommandLine>
        <Description>Execute the WinRM enabling script</Description>
        <Order>13</Order>
    </SynchronousCommand>
</FirstLogonCommands>

I run the Terraform template via a Azure DevOps release pipeline not in my local machine, so I dont think i can run the local-exec.

Could anyone please help me point out what have I missed out or any other better solutions are more than welcome?
Thanks so much

You connection block seems to be enabled to use HTTPS however the port is mentioned as 5985 instead of 5986. You may want to check the connection block again and correct/add additional parameter to check if connection is even getting established.

You can add NTLM = true / false and Insecure = true / false parameter as well to ensure connection is specified correctly.

Thanks for your reply, I have tried all the approaches you suggested but none of them works :frowning: Not sure how i can get over this issue now. Is there any other ways you could recommend again ? ssh over windows? could it be a solution to replace winrm at this point?

Hi,

I am also facing the same issue with remote provisioner, Error : timeout - last error: http response error: 401 - invalid content type

Kindly assist me to fix this issue,

my code
provider “aws” {
region = var.aws_region
access_key = var.aws-access-key
secret_key = var.aws-secret-key
}
resource “aws_instance” “instance1” {
ami = var.ami
instance_type = var.instance_type
subnet_id = var.subnet_id
vpc_security_group_ids = [var.sg_id]
key_name = var.key_name
user_data = file(“Start_up_scripts”)
tags = {
Name = var.ec2_name
}
}
resource “null_resource” remoteExecProvisionerWFolder {
provisioner “remote-exec” {
inline = [“echo ${aws_instance.instance1.id} > id.txt”]
}
connection {
type = “winrm”
host = aws_instance.instance1.public_ip
port = 5985
user = “Administrator”
password = aws_instance.instance1.get_password_data

}
}

I tried remote-exec to run powershell script for aws ec2.But execution of ps1 script didn’t took place.I checked all logs.

I ended up using local-exec specifying the powershell script and making use of Azure CLI and
“az vm run-command invoke”
Works pretty solid, haven’t had any failures.
No need for remote connections.