2015-06-14 14:08:32 -04:00
|
|
|
---
|
2017-06-14 21:04:16 -04:00
|
|
|
description: |
|
2018-10-26 20:02:51 -04:00
|
|
|
The PowerShell Packer provisioner runs PowerShell scripts on Windows machines.
|
2018-02-07 10:51:58 -05:00
|
|
|
It assumes that the communicator in use is WinRM.
|
2015-07-22 22:31:00 -04:00
|
|
|
layout: docs
|
2017-06-14 21:04:16 -04:00
|
|
|
page_title: 'PowerShell - Provisioners'
|
|
|
|
sidebar_current: 'docs-provisioners-powershell'
|
2017-03-25 18:13:52 -04:00
|
|
|
---
|
2015-06-14 14:08:32 -04:00
|
|
|
|
|
|
|
# PowerShell Provisioner
|
|
|
|
|
|
|
|
Type: `powershell`
|
|
|
|
|
|
|
|
The PowerShell Packer provisioner runs PowerShell scripts on Windows machines.
|
2018-10-26 20:02:51 -04:00
|
|
|
It assumes that the communicator in use is WinRM. However, the provisioner can
|
|
|
|
work equally well (with a few caveats) when combined with the SSH communicator.
|
|
|
|
See the [section
|
2018-04-19 10:50:12 -04:00
|
|
|
below](/docs/provisioners/powershell.html#combining-the-powershell-provisioner-with-the-ssh-communicator)
|
|
|
|
for details.
|
2015-06-14 14:08:32 -04:00
|
|
|
|
|
|
|
## Basic Example
|
|
|
|
|
|
|
|
The example below is fully functional.
|
|
|
|
|
2017-06-14 21:04:16 -04:00
|
|
|
``` json
|
2015-06-14 14:08:32 -04:00
|
|
|
{
|
|
|
|
"type": "powershell",
|
|
|
|
"inline": ["dir c:\\"]
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
## Configuration Reference
|
|
|
|
|
|
|
|
The reference of available configuration options is listed below. The only
|
2018-02-07 10:47:21 -05:00
|
|
|
required element is either "inline" or "script". Every other option is
|
|
|
|
optional.
|
2015-06-14 14:08:32 -04:00
|
|
|
|
2015-07-22 22:31:00 -04:00
|
|
|
Exactly *one* of the following is required:
|
2015-06-14 14:08:32 -04:00
|
|
|
|
2017-06-14 21:04:16 -04:00
|
|
|
- `inline` (array of strings) - This is an array of commands to execute. The
|
2018-02-07 10:47:21 -05:00
|
|
|
commands are concatenated by newlines and turned into a single file, so
|
|
|
|
they are all executed within the same context. This allows you to change
|
2015-07-22 23:25:58 -04:00
|
|
|
directories in one command and use something in the directory in the next
|
|
|
|
and so on. Inline scripts are the easiest way to pull off simple tasks
|
|
|
|
within the machine.
|
|
|
|
|
2018-10-26 20:02:51 -04:00
|
|
|
- `script` (string) - The path to a script to upload and execute in the
|
|
|
|
machine. This path can be absolute or relative. If it is relative, it is
|
|
|
|
relative to the working directory when Packer is executed.
|
2015-07-22 23:25:58 -04:00
|
|
|
|
2017-06-14 21:04:16 -04:00
|
|
|
- `scripts` (array of strings) - An array of scripts to execute. The scripts
|
2015-07-22 23:25:58 -04:00
|
|
|
will be uploaded and executed in the order specified. Each script is
|
|
|
|
executed in isolation, so state such as variables from one script won't
|
|
|
|
carry on to the next.
|
2015-06-14 14:08:32 -04:00
|
|
|
|
|
|
|
Optional parameters:
|
|
|
|
|
2018-02-07 10:47:21 -05:00
|
|
|
- `binary` (boolean) - If true, specifies that the script(s) are binary
|
|
|
|
files, and Packer should therefore not convert Windows line endings to Unix
|
|
|
|
line endings (if there are any). By default this is false.
|
2015-07-22 23:25:58 -04:00
|
|
|
|
2018-02-08 18:15:15 -05:00
|
|
|
- `elevated_execute_command` (string) - The command to use to execute the
|
2018-02-07 10:47:21 -05:00
|
|
|
elevated script. By default this is as follows:
|
2017-09-20 11:13:27 -04:00
|
|
|
|
|
|
|
``` powershell
|
|
|
|
powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"
|
|
|
|
```
|
|
|
|
|
2017-09-14 13:48:56 -04:00
|
|
|
The value of this is treated as [configuration
|
2018-10-26 20:02:51 -04:00
|
|
|
template](/docs/templates/engine.html). There are two available variables:
|
|
|
|
`Path`, which is the path to the script to run, and `Vars`, which is the
|
|
|
|
location of a temp file containing the list of `environment_vars`, if
|
|
|
|
configured.
|
2017-09-14 13:48:56 -04:00
|
|
|
|
2017-06-14 21:04:16 -04:00
|
|
|
- `environment_vars` (array of strings) - An array of key/value pairs to
|
2015-07-22 23:25:58 -04:00
|
|
|
inject prior to the execute\_command. The format should be `key=value`.
|
2018-02-07 10:47:21 -05:00
|
|
|
Packer injects some environmental variables by default into the
|
2018-10-26 20:02:51 -04:00
|
|
|
environment, as well, which are covered in the section below. If you are
|
|
|
|
running on AWS, Azure or Google Compute and would like to access the
|
|
|
|
generated password that Packer uses to connect to the instance via WinRM,
|
|
|
|
you can use the template variable `{{.WinRMPassword}}` to set this as an
|
|
|
|
environment variable. For example:
|
2018-03-16 17:25:09 -04:00
|
|
|
|
2018-10-26 20:02:51 -04:00
|
|
|
``` json
|
2018-03-16 17:28:20 -04:00
|
|
|
{
|
|
|
|
"type": "powershell",
|
|
|
|
"environment_vars": "WINRMPASS={{.WinRMPassword}}",
|
|
|
|
"inline": ["Write-Host \"Automatically generated aws password is: $Env:WINRMPASS\""]
|
|
|
|
},
|
2018-03-16 17:25:09 -04:00
|
|
|
```
|
2015-07-22 23:25:58 -04:00
|
|
|
|
2017-06-14 21:04:16 -04:00
|
|
|
- `execute_command` (string) - The command to use to execute the script. By
|
2017-09-20 11:13:27 -04:00
|
|
|
default this is as follows:
|
|
|
|
|
|
|
|
``` powershell
|
2018-02-07 10:47:21 -05:00
|
|
|
powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"
|
2017-09-20 11:13:27 -04:00
|
|
|
```
|
|
|
|
|
2015-07-22 23:25:58 -04:00
|
|
|
The value of this is treated as [configuration
|
2018-10-26 20:02:51 -04:00
|
|
|
template](/docs/templates/engine.html). There are two available variables:
|
|
|
|
`Path`, which is the path to the script to run, and `Vars`, which is the
|
|
|
|
location of a temp file containing the list of `environment_vars`. The
|
|
|
|
value of both `Path` and `Vars` can be manually configured by setting the
|
|
|
|
values for `remote_path` and `remote_env_var_path` respectively.
|
2015-07-22 23:25:58 -04:00
|
|
|
|
2018-10-09 16:34:26 -04:00
|
|
|
If you use the SSH communicator and have changed your default shell, you
|
|
|
|
may need to modify your `execute_command` to make sure that the command is
|
|
|
|
valid and properly escaped; the default assumes that you have not changed
|
|
|
|
the default shell away from cmd.
|
|
|
|
|
2017-06-14 21:04:16 -04:00
|
|
|
- `elevated_user` and `elevated_password` (string) - If specified, the
|
2015-07-22 23:25:58 -04:00
|
|
|
PowerShell script will be run with elevated privileges using the given
|
2018-10-26 20:02:51 -04:00
|
|
|
Windows user. If you are running a build on AWS, Azure or Google Compute
|
|
|
|
and would like to run using the generated password that Packer uses to
|
|
|
|
connect to the instance via WinRM, you may do so by using the template
|
|
|
|
variable {{.WinRMPassword}}. For example:
|
2018-03-16 17:25:09 -04:00
|
|
|
|
|
|
|
``` json
|
|
|
|
"elevated_user": "Administrator",
|
|
|
|
"elevated_password": "{{.WinRMPassword}}",
|
|
|
|
```
|
2015-07-22 23:25:58 -04:00
|
|
|
|
2018-04-18 07:20:52 -04:00
|
|
|
- `remote_path` (string) - The path where the PowerShell script will be
|
|
|
|
uploaded to within the target build machine. This defaults to
|
2018-10-26 20:02:51 -04:00
|
|
|
`C:/Windows/Temp/script-UUID.ps1` where UUID is replaced with a dynamically
|
|
|
|
generated string that uniquely identifies the script.
|
2018-04-18 07:20:52 -04:00
|
|
|
|
|
|
|
This setting allows users to override the default upload location. The
|
2018-10-26 20:02:51 -04:00
|
|
|
value must be a writable location and any parent directories must already
|
|
|
|
exist.
|
2015-07-22 23:25:58 -04:00
|
|
|
|
2018-10-26 20:02:51 -04:00
|
|
|
- `remote_env_var_path` (string) - Environment variables required within the
|
|
|
|
remote environment are uploaded within a PowerShell script and then enabled
|
|
|
|
by 'dot sourcing' the script immediately prior to execution of the main
|
|
|
|
command or script.
|
2018-04-18 06:18:47 -04:00
|
|
|
|
|
|
|
The path the environment variables script will be uploaded to defaults to
|
2018-10-26 20:02:51 -04:00
|
|
|
`C:/Windows/Temp/packer-ps-env-vars-UUID.ps1` where UUID is replaced with a
|
|
|
|
dynamically generated string that uniquely identifies the script.
|
2018-04-18 06:18:47 -04:00
|
|
|
|
2018-10-26 20:02:51 -04:00
|
|
|
This setting allows users to override the location the environment variable
|
|
|
|
script is uploaded to. The value must be a writable location and any parent
|
|
|
|
directories must already exist.
|
2015-07-22 23:25:58 -04:00
|
|
|
|
2017-06-14 21:04:16 -04:00
|
|
|
- `start_retry_timeout` (string) - The amount of time to attempt to *start*
|
2015-07-22 23:25:58 -04:00
|
|
|
the remote process. By default this is "5m" or 5 minutes. This setting
|
2018-10-26 20:02:51 -04:00
|
|
|
exists in order to deal with times when SSH may restart, such as a system
|
|
|
|
reboot. Set this to a higher value if reboots take a longer amount of time.
|
2015-07-22 23:25:58 -04:00
|
|
|
|
2017-06-14 21:04:16 -04:00
|
|
|
- `valid_exit_codes` (list of ints) - Valid exit codes for the script. By
|
2015-07-22 23:25:58 -04:00
|
|
|
default this is just 0.
|
2017-01-17 20:07:36 -05:00
|
|
|
|
|
|
|
## Default Environmental Variables
|
|
|
|
|
|
|
|
In addition to being able to specify custom environmental variables using the
|
|
|
|
`environment_vars` configuration, the provisioner automatically defines certain
|
|
|
|
commonly useful environmental variables:
|
|
|
|
|
2018-10-26 20:02:51 -04:00
|
|
|
- `PACKER_BUILD_NAME` is set to the [name of the
|
|
|
|
build](/docs/templates/builders.html#named-builds) that Packer is running.
|
2017-01-17 20:07:36 -05:00
|
|
|
This is most useful when Packer is making multiple builds and you want to
|
|
|
|
distinguish them slightly from a common provisioning script.
|
|
|
|
|
2018-02-07 10:47:21 -05:00
|
|
|
- `PACKER_BUILDER_TYPE` is the type of the builder that was used to create
|
|
|
|
the machine that the script is running on. This is useful if you want to
|
|
|
|
run only certain parts of the script on systems built with certain
|
|
|
|
builders.
|
2017-01-17 20:07:36 -05:00
|
|
|
|
2017-06-14 21:04:16 -04:00
|
|
|
- `PACKER_HTTP_ADDR` If using a builder that provides an http server for file
|
2017-01-17 20:07:36 -05:00
|
|
|
transfer (such as hyperv, parallels, qemu, virtualbox, and vmware), this
|
|
|
|
will be set to the address. You can use this address in your provisioner to
|
|
|
|
download large files over http. This may be useful if you're experiencing
|
|
|
|
slower speeds using the default file provisioner. A file provisioner using
|
|
|
|
the `winrm` communicator may experience these types of difficulties.
|
2018-02-08 18:15:15 -05:00
|
|
|
|
2018-04-19 10:50:12 -04:00
|
|
|
## Combining the PowerShell Provisioner with the SSH Communicator
|
|
|
|
|
2018-10-26 20:02:51 -04:00
|
|
|
The good news first. If you are using the [Microsoft port of
|
|
|
|
OpenSSH](https://github.com/PowerShell/Win32-OpenSSH/wiki) then the provisioner
|
|
|
|
should just work as expected - no extra configuration effort is required.
|
2018-04-19 10:50:12 -04:00
|
|
|
|
|
|
|
Now the caveats. If you are using an alternative configuration, and your SSH
|
2018-10-26 20:02:51 -04:00
|
|
|
connection lands you in a \*nix shell on the remote host, then you will most
|
2018-04-19 10:50:12 -04:00
|
|
|
likely need to manually set the `execute_command`; The default
|
2018-10-26 20:02:51 -04:00
|
|
|
`execute_command` used by Packer will not work for you. When configuring the
|
|
|
|
command you will need to ensure that any dollar signs or other characters that
|
|
|
|
may be incorrectly interpreted by the remote shell are escaped accordingly.
|
2018-04-19 10:50:12 -04:00
|
|
|
|
|
|
|
The following example shows how the standard `execute_command` can be
|
|
|
|
reconfigured to work on a remote system with
|
2018-10-26 20:02:51 -04:00
|
|
|
[Cygwin/OpenSSH](https://cygwin.com/) installed. The `execute_command` has each
|
|
|
|
dollar sign backslash escaped so that it is not interpreted by the remote Bash
|
|
|
|
shell - Bash being the default shell for Cygwin environments.
|
2018-04-19 10:50:12 -04:00
|
|
|
|
2018-10-26 20:02:51 -04:00
|
|
|
``` json
|
2018-04-19 10:50:12 -04:00
|
|
|
"provisioners": [
|
|
|
|
{
|
|
|
|
"type": "powershell",
|
|
|
|
"execute_command": "powershell -executionpolicy bypass \"& { if (Test-Path variable:global:ProgressPreference){\\$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit \\$LastExitCode }\"",
|
|
|
|
"inline": [
|
|
|
|
"Write-Host \"Hello from PowerShell\"",
|
|
|
|
]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
```
|
|
|
|
|
2018-02-08 18:15:15 -05:00
|
|
|
## Packer's Handling of Characters Special to PowerShell
|
|
|
|
|
2018-10-26 20:02:51 -04:00
|
|
|
The escape character in PowerShell is the `backtick`, also sometimes referred
|
|
|
|
to as the `grave accent`. When, and when not, to escape characters special to
|
|
|
|
PowerShell is probably best demonstrated with a series of examples.
|
2018-02-08 18:15:15 -05:00
|
|
|
|
|
|
|
### When To Escape...
|
|
|
|
|
|
|
|
Users need to deal with escaping characters special to PowerShell when they
|
|
|
|
appear *directly* in commands used in the `inline` PowerShell provisioner and
|
2018-10-26 20:02:51 -04:00
|
|
|
when they appear *directly* in the users own scripts. Note that where double
|
|
|
|
quotes appear within double quotes, the addition of a backslash escape is
|
|
|
|
required for the JSON template to be parsed correctly.
|
2018-02-08 18:15:15 -05:00
|
|
|
|
|
|
|
``` json
|
|
|
|
"provisioners": [
|
|
|
|
{
|
|
|
|
"type": "powershell",
|
|
|
|
"inline": [
|
|
|
|
"Write-Host \"A literal dollar `$ must be escaped\"",
|
|
|
|
"Write-Host \"A literal backtick `` must be escaped\"",
|
|
|
|
"Write-Host \"Here `\"double quotes`\" must be escaped\"",
|
|
|
|
"Write-Host \"Here `'single quotes`' don`'t really need to be\"",
|
|
|
|
"Write-Host \"escaped... but it doesn`'t hurt to do so.\"",
|
|
|
|
]
|
|
|
|
},
|
|
|
|
```
|
|
|
|
|
|
|
|
The above snippet should result in the following output on the Packer console:
|
|
|
|
|
2018-10-26 20:02:51 -04:00
|
|
|
==> amazon-ebs: Provisioning with Powershell...
|
|
|
|
==> amazon-ebs: Provisioning with powershell script: /var/folders/15/d0f7gdg13rnd1cxp7tgmr55c0000gn/T/packer-powershell-provisioner508190439
|
|
|
|
amazon-ebs: A literal dollar $ must be escaped
|
|
|
|
amazon-ebs: A literal backtick ` must be escaped
|
|
|
|
amazon-ebs: Here "double quotes" must be escaped
|
|
|
|
amazon-ebs: Here 'single quotes' don't really need to be
|
|
|
|
amazon-ebs: escaped... but it doesn't hurt to do so.
|
2018-02-08 18:15:15 -05:00
|
|
|
|
|
|
|
### When Not To Escape...
|
|
|
|
|
|
|
|
Special characters appearing in user environment variable values and in the
|
2018-10-26 20:02:51 -04:00
|
|
|
`elevated_user` and `elevated_password` fields will be automatically dealt with
|
|
|
|
for the user. There is no need to use escapes in these instances.
|
2018-02-08 18:15:15 -05:00
|
|
|
|
|
|
|
``` json
|
|
|
|
{
|
|
|
|
"variables": {
|
|
|
|
"psvar": "My$tring"
|
|
|
|
},
|
|
|
|
...
|
|
|
|
"provisioners": [
|
|
|
|
{
|
|
|
|
"type": "powershell",
|
|
|
|
"elevated_user": "Administrator",
|
|
|
|
"elevated_password": "Super$3cr3t!",
|
|
|
|
"inline": "Write-Output \"The dollar in the elevated_password is interpreted correctly\""
|
|
|
|
},
|
|
|
|
{
|
|
|
|
"type": "powershell",
|
|
|
|
"environment_vars": [
|
|
|
|
"VAR1=A$Dollar",
|
|
|
|
"VAR2=A`Backtick",
|
|
|
|
"VAR3=A'SingleQuote",
|
|
|
|
"VAR4=A\"DoubleQuote",
|
|
|
|
"VAR5={{user `psvar`}}"
|
|
|
|
],
|
|
|
|
"inline": [
|
|
|
|
"Write-Output \"In the following examples the special character is interpreted correctly:\"",
|
|
|
|
"Write-Output \"The dollar in VAR1: $Env:VAR1\"",
|
|
|
|
"Write-Output \"The backtick in VAR2: $Env:VAR2\"",
|
|
|
|
"Write-Output \"The single quote in VAR3: $Env:VAR3\"",
|
|
|
|
"Write-Output \"The double quote in VAR4: $Env:VAR4\"",
|
|
|
|
"Write-Output \"The dollar in VAR5 (expanded from a user var): $Env:VAR5\""
|
|
|
|
]
|
|
|
|
}
|
|
|
|
]
|
|
|
|
...
|
|
|
|
}
|
|
|
|
```
|
|
|
|
|
|
|
|
The above snippet should result in the following output on the Packer console:
|
|
|
|
|
2018-10-26 20:02:51 -04:00
|
|
|
==> amazon-ebs: Provisioning with Powershell...
|
|
|
|
==> amazon-ebs: Provisioning with powershell script: /var/folders/15/d0f7gdg13rnd1cxp7tgmr55c0000gn/T/packer-powershell-provisioner961728919
|
|
|
|
amazon-ebs: The dollar in the elevated_password is interpreted correctly
|
|
|
|
==> amazon-ebs: Provisioning with Powershell...
|
|
|
|
==> amazon-ebs: Provisioning with powershell script: /var/folders/15/d0f7gdg13rnd1cxp7tgmr55c0000gn/T/packer-powershell-provisioner142826554
|
|
|
|
amazon-ebs: In the following examples the special character is interpreted correctly:
|
|
|
|
amazon-ebs: The dollar in VAR1: A$Dollar
|
|
|
|
amazon-ebs: The backtick in VAR2: A`Backtick
|
|
|
|
amazon-ebs: The single quote in VAR3: A'SingleQuote
|
|
|
|
amazon-ebs: The double quote in VAR4: A"DoubleQuote
|
|
|
|
amazon-ebs: The dollar in VAR5 (expanded from a user var): My$tring
|