github.com/StackPointCloud/packer@v0.10.2-0.20180716202532-b28098e0f79b/website/source/docs/provisioners/powershell.html.md (about)

     1  ---
     2  description: |
     3      The PowerShell Packer provisioner runs PowerShell scripts on Windows
     4      machines.
     5      It assumes that the communicator in use is WinRM.
     6  layout: docs
     7  page_title: 'PowerShell - Provisioners'
     8  sidebar_current: 'docs-provisioners-powershell'
     9  ---
    10  
    11  # PowerShell Provisioner
    12  
    13  Type: `powershell`
    14  
    15  The PowerShell Packer provisioner runs PowerShell scripts on Windows machines.
    16  It assumes that the communicator in use is WinRM. However, the provisioner
    17  can work equally well (with a few caveats) when combined with the SSH
    18  communicator. See the [section
    19  below](/docs/provisioners/powershell.html#combining-the-powershell-provisioner-with-the-ssh-communicator)
    20  for details.
    21  
    22  ## Basic Example
    23  
    24  The example below is fully functional.
    25  
    26  ``` json
    27  {
    28    "type": "powershell",
    29    "inline": ["dir c:\\"]
    30  }
    31  ```
    32  
    33  ## Configuration Reference
    34  
    35  The reference of available configuration options is listed below. The only
    36  required element is either "inline" or "script". Every other option is
    37  optional.
    38  
    39  Exactly *one* of the following is required:
    40  
    41  -   `inline` (array of strings) - This is an array of commands to execute. The
    42      commands are concatenated by newlines and turned into a single file, so
    43      they are all executed within the same context. This allows you to change
    44      directories in one command and use something in the directory in the next
    45      and so on. Inline scripts are the easiest way to pull off simple tasks
    46      within the machine.
    47  
    48  -   `script` (string) - The path to a script to upload and execute in
    49      the machine. This path can be absolute or relative. If it is relative, it
    50      is relative to the working directory when Packer is executed.
    51  
    52  -   `scripts` (array of strings) - An array of scripts to execute. The scripts
    53      will be uploaded and executed in the order specified. Each script is
    54      executed in isolation, so state such as variables from one script won't
    55      carry on to the next.
    56  
    57  Optional parameters:
    58  
    59  -   `binary` (boolean) - If true, specifies that the script(s) are binary
    60      files, and Packer should therefore not convert Windows line endings to Unix
    61      line endings (if there are any). By default this is false.
    62  
    63  -   `elevated_execute_command` (string) - The command to use to execute the
    64      elevated script. By default this is as follows:
    65  
    66      ``` powershell
    67      powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"
    68      ```
    69  
    70      The value of this is treated as [configuration
    71      template](/docs/templates/engine.html). There are two
    72      available variables: `Path`, which is the path to the script to run, and
    73      `Vars`, which is the location of a temp file containing the list of
    74      `environment_vars`, if configured.
    75  
    76  -   `environment_vars` (array of strings) - An array of key/value pairs to
    77      inject prior to the execute\_command. The format should be `key=value`.
    78      Packer injects some environmental variables by default into the
    79      environment, as well, which are covered in the section below.
    80      If you are running on AWS, Azure or Google Compute and would like to access the generated
    81      password that Packer uses to connect to the instance via
    82      WinRM, you can use the template variable `{{.WinRMPassword}}` to set this
    83      as an environment variable. For example:
    84  
    85      ```json
    86        {
    87          "type": "powershell",
    88          "environment_vars": "WINRMPASS={{.WinRMPassword}}",
    89          "inline": ["Write-Host \"Automatically generated aws password is: $Env:WINRMPASS\""]
    90        },
    91      ```
    92  
    93  -   `execute_command` (string) - The command to use to execute the script. By
    94      default this is as follows:
    95  
    96      ``` powershell
    97      powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"
    98      ```
    99  
   100      The value of this is treated as [configuration
   101      template](/docs/templates/engine.html). There are two
   102      available variables: `Path`, which is the path to the script to run, and
   103      `Vars`, which is the location of a temp file containing the list of
   104      `environment_vars`. The value of both `Path` and `Vars` can be
   105      manually configured by setting the values for `remote_path` and
   106      `remote_env_var_path` respectively.
   107  
   108  -   `elevated_user` and `elevated_password` (string) - If specified, the
   109      PowerShell script will be run with elevated privileges using the given
   110      Windows user. If you are running a build on AWS, Azure or Google Compute and would like to run using
   111      the generated password that Packer uses to connect to the instance via 
   112      WinRM, you may do so by using the template variable {{.WinRMPassword}}.
   113      For example:
   114  
   115      ``` json
   116      "elevated_user": "Administrator",
   117      "elevated_password": "{{.WinRMPassword}}",
   118      ```
   119  
   120  -   `remote_path` (string) - The path where the PowerShell script will be
   121      uploaded to within the target build machine. This defaults to
   122      `C:/Windows/Temp/script-UUID.ps1` where UUID is replaced with a
   123      dynamically generated string that uniquely identifies the script.
   124  
   125      This setting allows users to override the default upload location. The
   126      value must be a writable location and any parent directories must
   127      already exist.
   128  
   129  -   `remote_env_var_path` (string) - Environment variables required within
   130      the remote environment are uploaded within a PowerShell script and then
   131      enabled by 'dot sourcing' the script immediately prior to execution of
   132      the main command or script.
   133  
   134      The path the environment variables script will be uploaded to defaults to
   135      `C:/Windows/Temp/packer-ps-env-vars-UUID.ps1` where UUID is replaced
   136      with a dynamically generated string that uniquely identifies the
   137      script.
   138  
   139      This setting allows users to override the location the environment
   140      variable script is uploaded to. The value must be a writable location
   141      and any parent directories must already exist.
   142  
   143  -   `start_retry_timeout` (string) - The amount of time to attempt to *start*
   144      the remote process. By default this is "5m" or 5 minutes. This setting
   145      exists in order to deal with times when SSH may restart, such as a
   146      system reboot. Set this to a higher value if reboots take a longer amount
   147      of time.
   148  
   149  -   `valid_exit_codes` (list of ints) - Valid exit codes for the script. By
   150      default this is just 0.
   151  
   152  ## Default Environmental Variables
   153  
   154  In addition to being able to specify custom environmental variables using the
   155  `environment_vars` configuration, the provisioner automatically defines certain
   156  commonly useful environmental variables:
   157  
   158  -   `PACKER_BUILD_NAME` is set to the
   159      [name of the build](/docs/templates/builders.html#named-builds) that Packer is running.
   160      This is most useful when Packer is making multiple builds and you want to
   161      distinguish them slightly from a common provisioning script.
   162  
   163  -   `PACKER_BUILDER_TYPE` is the type of the builder that was used to create
   164      the machine that the script is running on. This is useful if you want to
   165      run only certain parts of the script on systems built with certain
   166      builders.
   167  
   168  -   `PACKER_HTTP_ADDR` If using a builder that provides an http server for file
   169      transfer (such as hyperv, parallels, qemu, virtualbox, and vmware), this
   170      will be set to the address. You can use this address in your provisioner to
   171      download large files over http. This may be useful if you're experiencing
   172      slower speeds using the default file provisioner. A file provisioner using
   173      the `winrm` communicator may experience these types of difficulties.
   174  
   175  ## Combining the PowerShell Provisioner with the SSH Communicator
   176  
   177  The good news first. If you are using the
   178  [Microsoft port of OpenSSH](https://github.com/PowerShell/Win32-OpenSSH/wiki)
   179  then the provisioner should just work as expected - no extra configuration
   180  effort is required.
   181  
   182  Now the caveats. If you are using an alternative configuration, and your SSH
   183  connection lands you in a *nix shell on the remote host, then you will most
   184  likely need to manually set the `execute_command`; The default
   185  `execute_command` used by Packer will not work for you.
   186  When configuring the command you will need to ensure that any dollar signs
   187  or other characters that may be incorrectly interpreted by the remote shell
   188  are escaped accordingly.
   189  
   190  The following example shows how the standard `execute_command` can be
   191  reconfigured to work on a remote system with
   192  [Cygwin/OpenSSH](https://cygwin.com/) installed.
   193  The `execute_command` has each dollar sign backslash escaped so that it is
   194  not interpreted by the remote Bash shell - Bash being the default shell for
   195  Cygwin environments.
   196  
   197  ```json
   198    "provisioners": [
   199      {
   200        "type": "powershell",
   201        "execute_command": "powershell -executionpolicy bypass \"& { if (Test-Path variable:global:ProgressPreference){\\$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit \\$LastExitCode }\"",
   202        "inline": [
   203          "Write-Host \"Hello from PowerShell\"",
   204        ]
   205      }
   206    ]
   207  ```
   208  
   209  
   210  ## Packer's Handling of Characters Special to PowerShell
   211  
   212  The escape character in PowerShell is the `backtick`, also sometimes
   213  referred to as the `grave accent`. When, and when not, to escape characters
   214  special to PowerShell is probably best demonstrated with a series of examples.
   215  
   216  ### When To Escape...
   217  
   218  Users need to deal with escaping characters special to PowerShell when they
   219  appear *directly* in commands used in the `inline` PowerShell provisioner and
   220  when they appear *directly* in the users own scripts.
   221  Note that where double quotes appear within double quotes, the addition of
   222  a backslash escape is required for the JSON template to be parsed correctly.
   223  
   224  ``` json
   225    "provisioners": [
   226      {
   227        "type": "powershell",
   228        "inline": [
   229            "Write-Host \"A literal dollar `$ must be escaped\"",
   230            "Write-Host \"A literal backtick `` must be escaped\"",
   231            "Write-Host \"Here `\"double quotes`\" must be escaped\"",
   232            "Write-Host \"Here `'single quotes`' don`'t really need to be\"",
   233            "Write-Host \"escaped... but it doesn`'t hurt to do so.\"",
   234        ]
   235      },
   236  ```
   237  
   238  The above snippet should result in the following output on the Packer console:
   239  
   240  ```
   241  ==> amazon-ebs: Provisioning with Powershell...
   242  ==> amazon-ebs: Provisioning with powershell script: /var/folders/15/d0f7gdg13rnd1cxp7tgmr55c0000gn/T/packer-powershell-provisioner508190439
   243      amazon-ebs: A literal dollar $ must be escaped
   244      amazon-ebs: A literal backtick ` must be escaped
   245      amazon-ebs: Here "double quotes" must be escaped
   246      amazon-ebs: Here 'single quotes' don't really need to be
   247      amazon-ebs: escaped... but it doesn't hurt to do so.
   248  ```
   249  
   250  ### When Not To Escape...
   251  
   252  Special characters appearing in user environment variable values and in the
   253  `elevated_user` and `elevated_password` fields will be automatically
   254  dealt with for the user. There is no need to use escapes in these instances.
   255  
   256  ``` json
   257  {
   258    "variables": {
   259      "psvar": "My$tring"
   260    },
   261    ...
   262    "provisioners": [
   263      {
   264        "type": "powershell",
   265        "elevated_user": "Administrator",
   266        "elevated_password": "Super$3cr3t!",
   267        "inline": "Write-Output \"The dollar in the elevated_password is interpreted correctly\""
   268      },
   269      {
   270        "type": "powershell",
   271        "environment_vars": [
   272          "VAR1=A$Dollar",
   273          "VAR2=A`Backtick",
   274          "VAR3=A'SingleQuote",
   275          "VAR4=A\"DoubleQuote",
   276          "VAR5={{user `psvar`}}"
   277        ],
   278        "inline": [
   279          "Write-Output \"In the following examples the special character is interpreted correctly:\"",
   280          "Write-Output \"The dollar in VAR1:                            $Env:VAR1\"",
   281          "Write-Output \"The backtick in VAR2:                          $Env:VAR2\"",
   282          "Write-Output \"The single quote in VAR3:                      $Env:VAR3\"",
   283          "Write-Output \"The double quote in VAR4:                      $Env:VAR4\"",
   284          "Write-Output \"The dollar in VAR5 (expanded from a user var): $Env:VAR5\""
   285        ]
   286      }
   287    ]
   288    ...
   289  }
   290  ```
   291  
   292  The above snippet should result in the following output on the Packer console:
   293  
   294  ```
   295  ==> amazon-ebs: Provisioning with Powershell...
   296  ==> amazon-ebs: Provisioning with powershell script: /var/folders/15/d0f7gdg13rnd1cxp7tgmr55c0000gn/T/packer-powershell-provisioner961728919
   297      amazon-ebs: The dollar in the elevated_password is interpreted correctly
   298  ==> amazon-ebs: Provisioning with Powershell...
   299  ==> amazon-ebs: Provisioning with powershell script: /var/folders/15/d0f7gdg13rnd1cxp7tgmr55c0000gn/T/packer-powershell-provisioner142826554
   300      amazon-ebs: In the following examples the special character is interpreted correctly:
   301      amazon-ebs: The dollar in VAR1:                            A$Dollar
   302      amazon-ebs: The backtick in VAR2:                          A`Backtick
   303      amazon-ebs: The single quote in VAR3:                      A'SingleQuote
   304      amazon-ebs: The double quote in VAR4:                      A"DoubleQuote
   305      amazon-ebs: The dollar in VAR5 (expanded from a user var): My$tring
   306  ```