Packer
WinRM Communicator
Communicators are the mechanism Packer uses to upload files, execute scripts, etc. with the machine being created. The WinRM communicator uses the Windows Remote Management protocol to do this.
Getting Ready to Use the WinRM Communicator
The WinRM communicator is not the default communicator, so you will always have
to set the "communicator": "winrm",
template option explicitly. In addition,
you will almost always have to provide a pre-run script that enables and
configures WinRM on the guest machine. This will generally be in the form of a
PowerShell script or a batch file.
If you are building from a brand-new and unconfigured operating system image, you will need to provide this pre-run script as part of your Autounattend.xml file, required by Windows for automatic operating system installation. If you are building in a cloud or from a pre-installed image, your method for providing this pre-run script will vary based on the builder. Please refer to each builder's documentation for more information on how to supply the winrm configuration script.
If you are unfamiliar with how to use an autounattend file, take a look at our quick guides; knowing how to automatically initalize your operating system is critical for being able to successfully use Packer to build from an iso.
WinRM Communicator Options
winrm_username
(string) - The username to use to connect to WinRM.winrm_password
(string) - The password to use to connect to WinRM.winrm_host
(string) - The address for WinRM to connect to.NOTE: If using an Amazon EBS builder, you can specify the interface WinRM connects to via
ssh_interface
winrm_no_proxy
(bool) - Setting this totrue
adds the remotehost:port
to theNO_PROXY
environment variable. This has the effect of bypassing any configured proxies when connecting to the remote host. Default tofalse
.winrm_port
(int) - The WinRM port to connect to. This defaults to5985
for plain unencrypted connection and5986
for SSL whenwinrm_use_ssl
is set to true.winrm_timeout
(duration string | ex: "1h5m2s") - The amount of time to wait for WinRM to become available. This defaults to30m
since setting up a Windows machine generally takes a long time.winrm_use_ssl
(bool) - Iftrue
, use HTTPS for WinRM.winrm_insecure
(bool) - Iftrue
, do not check server certificate chain and host name.winrm_use_ntlm
(bool) - Iftrue
, NTLMv2 authentication (with session security) will be used for WinRM, rather than default (basic authentication), removing the requirement for basic authentication to be enabled within the target guest. Further reading for remote connection authentication can be found here.
Examples
Basics of WinRM Connection
Please note that WinRM is not a Packer-specific protocol. Microsoft has a great deal of documentation about WinRM. If you find after reading this guide that you are still not able to connect via WinRM, check the Microsoft documentation to make sure there isn't anything you're missing.
There are some steps that you will normally need to take in order for Packer to be able to connect via WinRM
- Set up a username and password that Packer to connect with.
- Make any necesary registry edits to enable remote execution (and remote execution with elevated privileges, if needed)
- Start WinRM, setting any config needed for allowing basic auth
- Open ports 5985 and/or 5986 depending on how you're connecting
- launch WinRM and set it to automatically launch when the computer restarts
- If necessary, generate a self-signed certificate or provide a real certificate to the WinRM listener.
Configuring WinRM in VMware
If you are configuring WinRM using an Autounattend.xml, the simplest way to set up WinRM is to put the configuration commands directly into the Autounattend file as shown here
Instead of entering each line individually, you can also add a batch file to your autounattend that contains the commands for configuring winrm. Depending on your winrm setup, this could be a complex batch file, or a very simple one.
Below is an example of how we would call a batch file from inside the Autounattend file.
<FirstLogonCommands>
...
<SynchronousCommand wcm:action="add">
<CommandLine>cmd.exe /c a:\winrmConfig.bat</CommandLine>
<Description>Configure WinRM</Description>
<Order>3</Order>
<RequiresUserInput>true</RequiresUserInput>
</SynchronousCommand>
...
</FirstLogonCommands>
It is also possible to call PowerShell scripts in a similar manner.
The winrmConfig.bat referenced above can be as simple as
rem basic config for winrm
cmd.exe /c winrm quickconfig -q
rem allow unencrypted traffic, and configure auth to use basic username/password auth
cmd.exe /c winrm set winrm/config/service @{AllowUnencrypted="true"}
cmd.exe /c winrm set winrm/config/service/auth @{Basic="true"}
rem update firewall rules to open the right port and to allow remote administration
cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes
rem restart winrm
cmd.exe /c net stop winrm
cmd.exe /c net start winrm
Please note that the above batch file is extremely simplistic, and not secure. It is intended to be an example of the bare minimum configuration. Below, you'll find a more complicated example of a more secure WinRM configuration process.
This batch file will only work for HTTP connections, not HTTPS, but will enable you to connect using only the username and password created earlier in the Autounattend file. The above batchfile will allow you to connect using a very simple Packer config:
"communicator": "winrm",
"winrm_username": "packeruser",
"winrm_password": "SecretPassword"
A more complex example of a PowerShell script used for configuration can be seen below.
# A Packer config that works with this example would be:
#
#
# "winrm_username": "Administrator",
# "winrm_password": "SuperS3cr3t!!!",
# "winrm_insecure": true,
# "winrm_use_ssl": true
#
#
# Create username and password
net user Administrator SuperS3cr3t!!!
wmic useraccount where "name='Administrator'" set PasswordExpires=FALSE
Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force -ErrorAction Ignore
# Don't set this before Set-ExecutionPolicy as it throws an error
$ErrorActionPreference = "stop"
# Remove HTTP listener
Remove-Item -Path WSMan:\Localhost\listener\listener* -Recurse
# Create a self-signed certificate to let ssl work
$Cert = New-SelfSignedCertificate -CertstoreLocation Cert:\LocalMachine\My -DnsName "packer"
New-Item -Path WSMan:\LocalHost\Listener -Transport HTTPS -Address * -CertificateThumbPrint $Cert.Thumbprint -Force
# WinRM
write-output "Setting up WinRM"
write-host "(host) setting up WinRM"
# Configure WinRM to allow unencrypted communication, and provide the
# self-signed cert to the WinRM listener.
cmd.exe /c winrm quickconfig -q
cmd.exe /c winrm set "winrm/config/service" '@{AllowUnencrypted="true"}'
cmd.exe /c winrm set "winrm/config/client" '@{AllowUnencrypted="true"}'
cmd.exe /c winrm set "winrm/config/service/auth" '@{Basic="true"}'
cmd.exe /c winrm set "winrm/config/client/auth" '@{Basic="true"}'
cmd.exe /c winrm set "winrm/config/service/auth" '@{CredSSP="true"}'
cmd.exe /c winrm set "winrm/config/listener?Address=*+Transport=HTTPS" "@{Port=`"5986`";Hostname=`"packer`";CertificateThumbprint=`"$($Cert.Thumbprint)`"}"
# Make sure appropriate firewall port openings exist
cmd.exe /c netsh advfirewall firewall set rule group="remote administration" new enable=yes
cmd.exe /c netsh firewall add portopening TCP 5986 "Port 5986"
# Restart WinRM, and set it so that it auto-launches on startup.
cmd.exe /c net stop winrm
cmd.exe /c sc config winrm start= auto
cmd.exe /c net start winrm
Please note that having WinRM auto-launch on all start ups may not be the right choice for you, if you don't need the server to recieve WinRM connections in the future. Clean up after yourself and close unnecesary firewall ports at a final provisioning step to make sure your image is secure.
Configuring WinRM in the Cloud
Most clouds allow you to provide a configuration script that runs when the
instance is launched. In AWS, this is the
user_data_file. In Google
Cloud, this is provided using the windows-startup-script-cmd
metadata tag.
Example
Essentially, these files are powershell or cmd scripts that configure winrm, without having to be wrapped in an Autounattend. Provide the script in the format requested by each cloud, and make sure you manually configure any firewall rules that the cloud doesn't allow you to manage internally. More specific details for each cloud can be found in the builder sections.
The above examples will work in cloud prep too, but may be overkill depending on how much preconfiguration the cloud has done for you.