369 lines
11 KiB
Plaintext
369 lines
11 KiB
Plaintext
---
|
|
description: |
|
|
The PowerShell Packer provisioner runs PowerShell scripts on Windows machines.
|
|
It assumes that the communicator in use is WinRM.
|
|
layout: docs
|
|
page_title: PowerShell - Provisioners
|
|
sidebar_title: PowerShell
|
|
---
|
|
|
|
# PowerShell Provisioner
|
|
|
|
Type: `powershell`
|
|
|
|
The PowerShell Packer provisioner runs PowerShell scripts on Windows machines.
|
|
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
|
|
below](/docs/provisioners/powershell#combining-the-powershell-provisioner-with-the-ssh-communicator)
|
|
for details.
|
|
|
|
## Basic Example
|
|
|
|
The example below is fully functional.
|
|
|
|
<Tabs>
|
|
<Tab heading="JSON">
|
|
|
|
```json
|
|
{
|
|
"type": "powershell",
|
|
"inline": ["dir c:\\"]
|
|
}
|
|
```
|
|
|
|
</Tab>
|
|
<Tab heading="HCL2">
|
|
|
|
```hcl
|
|
provisioner "powershell" {
|
|
inline = ["dir c:\\"]
|
|
}
|
|
```
|
|
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
## Configuration Reference
|
|
|
|
### Required
|
|
|
|
@include 'provisioners/shell-config.mdx'
|
|
|
|
### Optional
|
|
@include 'provisioner/powershell/Config-not-required.mdx'
|
|
|
|
@include 'provisioners/common-config.mdx'
|
|
|
|
## Default Environmental Variables
|
|
|
|
<Tabs>
|
|
<Tab heading="JSON">
|
|
|
|
```json
|
|
{
|
|
"type": "powershell",
|
|
"environment_vars": ["WINRMPASS={{ build `Password`}}"],
|
|
"inline": ["Write-Host \"Automatically generated aws password is: $Env:WINRMPASS\""]
|
|
},
|
|
```
|
|
|
|
</Tab>
|
|
<Tab heading="HCL2">
|
|
|
|
```hcl
|
|
provisioner "powershell" {
|
|
environment_vars = ["WINRMPASS=${build.Password}"]
|
|
inline = ["Write-Host \"Automatically generated aws password is: $Env:WINRMPASS\""]
|
|
}
|
|
```
|
|
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
In addition to being able to specify custom environmental variables using the
|
|
`environment_vars` configuration, the provisioner automatically defines certain
|
|
commonly useful environmental variables:
|
|
|
|
- `PACKER_BUILD_NAME` is set to the [name of the
|
|
build](/docs/templates/builders#named-builds) that Packer is running.
|
|
This is most useful when Packer is making multiple builds and you want to
|
|
distinguish them slightly from a common provisioning script.
|
|
|
|
- `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.
|
|
|
|
- `PACKER_HTTP_ADDR` If using a builder that provides an http server for file
|
|
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.
|
|
|
|
|
|
## Setting Elevated User and Password
|
|
|
|
<Tabs>
|
|
<Tab heading="JSON">
|
|
|
|
```json
|
|
{
|
|
"type": "powershell",
|
|
"elevated_user": "Administrator",
|
|
"elevated_password": "{{ build `Password`}}",
|
|
...
|
|
},
|
|
```
|
|
|
|
</Tab>
|
|
<Tab heading="HCL2">
|
|
|
|
```hcl
|
|
provisioner "powershell" {
|
|
elevated_user = "Administrator"
|
|
elevated_password = build.Password
|
|
}
|
|
```
|
|
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
If you specify an empty `elevated_password` value then the PowerShell
|
|
script is run as a service account. For example:
|
|
|
|
<Tabs>
|
|
<Tab heading="JSON">
|
|
|
|
```json
|
|
{
|
|
"type": "powershell",
|
|
"elevated_user": "SYSTEM",
|
|
"elevated_password": "",
|
|
...
|
|
},
|
|
```
|
|
|
|
</Tab>
|
|
<Tab heading="HCL2">
|
|
|
|
```hcl
|
|
provisioner "powershell" {
|
|
elevated_user = "SYSTEM"
|
|
elevated_password = ""
|
|
}
|
|
```
|
|
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
|
|
## Combining the PowerShell Provisioner with the SSH Communicator
|
|
|
|
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.
|
|
|
|
Now the caveats. If you are using an alternative configuration, and your SSH
|
|
connection lands you in a \*nix shell on the remote host, then you will most
|
|
likely need to manually set the `execute_command`; The default
|
|
`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.
|
|
|
|
The following example shows how the standard `execute_command` can be
|
|
reconfigured to work on a remote system with
|
|
[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.
|
|
|
|
<Tabs>
|
|
<Tab heading="JSON">
|
|
|
|
```json
|
|
"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\""]
|
|
}
|
|
]
|
|
```
|
|
|
|
</Tab>
|
|
<Tab heading="HCL2">
|
|
|
|
```hcl
|
|
provisioner "powershell" {
|
|
execute_command = "powershell -executionpolicy bypass \"& { if (Test-Path variable:global:ProgressPreference){\\$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit \\$LastExitCode }\""
|
|
inline = [ "Write-Host \"Hello from PowerShell\""]
|
|
}
|
|
```
|
|
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
## Packer's Handling of Characters Special to PowerShell
|
|
|
|
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.
|
|
|
|
### 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
|
|
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.
|
|
|
|
<Tabs>
|
|
<Tab heading="JSON">
|
|
|
|
```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.\""
|
|
]
|
|
}
|
|
]
|
|
```
|
|
|
|
</Tab>
|
|
<Tab heading="HCL2">
|
|
|
|
```hcl
|
|
provisioner "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.\"",
|
|
]
|
|
}
|
|
```
|
|
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
The above snippet should result in the following output on the Packer console:
|
|
|
|
```shell-session
|
|
==> 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.
|
|
```
|
|
|
|
### When Not To Escape...
|
|
|
|
Special characters appearing in user environment variable values and in the
|
|
`elevated_user` and `elevated_password` fields will be automatically dealt with
|
|
for the user. There is no need to use escapes in these instances.
|
|
|
|
<Tabs>
|
|
<Tab heading="JSON">
|
|
|
|
```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\""
|
|
]
|
|
}
|
|
]
|
|
...
|
|
}
|
|
```
|
|
|
|
</Tab>
|
|
<Tab heading="HCL2">
|
|
|
|
```hcl
|
|
variable "psvar" {
|
|
type = string
|
|
default = "My$tring"
|
|
}
|
|
|
|
build {
|
|
sources = ["source.amazon-ebs.example"]
|
|
|
|
provisioner "powershell" {
|
|
elevated_user = "Administrator"
|
|
elevated_password = "Super$3cr3t!"
|
|
inline = ["Write-Output \"The dollar in the elevated_password is interpreted correctly\""]
|
|
}
|
|
provisioner "powershell" {
|
|
environment_vars = [
|
|
"VAR1=A$Dollar",
|
|
"VAR2=A`Backtick",
|
|
"VAR3=A'SingleQuote",
|
|
"VAR4=A\"DoubleQuote",
|
|
"VAR5=${var.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\"",
|
|
]
|
|
}
|
|
}
|
|
```
|
|
|
|
</Tab>
|
|
</Tabs>
|
|
|
|
The above snippet should result in the following output on the Packer console:
|
|
|
|
```shell-session
|
|
==> 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
|
|
```
|