Merge pull request #5365 from DanHam/gh-4322-psleak

Fix Powershell Progress stream leak to stderr for normal and elevated commands
This commit is contained in:
SwampDragons 2017-09-26 15:53:54 -07:00 committed by GitHub
commit 0ef12c9810
5 changed files with 86 additions and 189 deletions

View File

@ -5,16 +5,17 @@ import (
)
type elevatedOptions struct {
User string
Password string
TaskName string
TaskDescription string
EncodedCommand string
User string
Password string
TaskName string
TaskDescription string
LogFile string
XMLEscapedCommand string
}
var elevatedTemplate = template.Must(template.New("ElevatedCommand").Parse(`
$name = "{{.TaskName}}"
$log = "$env:SystemRoot\Temp\$name.out"
$log = [System.Environment]::ExpandEnvironmentVariables("{{.LogFile}}")
$s = New-Object -ComObject "Schedule.Service"
$s.Connect()
$t = $s.NewTask($null)
@ -53,7 +54,7 @@ $t.XmlText = @'
<Actions Context="Author">
<Exec>
<Command>cmd</Command>
<Arguments>/c powershell.exe -EncodedCommand {{.EncodedCommand}} &gt; %SYSTEMROOT%\Temp\{{.TaskName}}.out 2&gt;&amp;1</Arguments>
<Arguments>/c {{.XMLEscapedCommand}}</Arguments>
</Exec>
</Actions>
</Task>

View File

@ -1,54 +0,0 @@
package powershell
import (
"encoding/base64"
"encoding/binary"
"unicode/utf16"
"unicode/utf8"
"golang.org/x/text/encoding/unicode"
)
func convertUtf8ToUtf16LE(message string) (string, error) {
utf16le := unicode.UTF16(unicode.LittleEndian, unicode.IgnoreBOM)
utfEncoder := utf16le.NewEncoder()
ut16LeEncodedMessage, err := utfEncoder.String(message)
return ut16LeEncodedMessage, err
}
// UTF16BytesToString converts UTF-16 encoded bytes, in big or little endian byte order,
// to a UTF-8 encoded string.
func UTF16BytesToString(b []byte, o binary.ByteOrder) string {
utf := make([]uint16, (len(b)+(2-1))/2)
for i := 0; i+(2-1) < len(b); i += 2 {
utf[i/2] = o.Uint16(b[i:])
}
if len(b)/2 < len(utf) {
utf[len(utf)-1] = utf8.RuneError
}
return string(utf16.Decode(utf))
}
func powershellEncode(message string) (string, error) {
utf16LEEncodedMessage, err := convertUtf8ToUtf16LE(message)
if err != nil {
return "", err
}
// Base64 encode the command
input := []uint8(utf16LEEncodedMessage)
return base64.StdEncoding.EncodeToString(input), nil
}
func powershellDecode(messageBase64 string) (retour string, err error) {
messageUtf16LeByteArray, err := base64.StdEncoding.DecodeString(messageBase64)
if err != nil {
return "", err
}
message := UTF16BytesToString(messageUtf16LeByteArray, binary.LittleEndian)
return message, nil
}

View File

@ -5,6 +5,7 @@ package powershell
import (
"bufio"
"bytes"
"encoding/xml"
"errors"
"fmt"
"io/ioutil"
@ -112,7 +113,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
}
if p.config.EnvVarFormat == "" {
p.config.EnvVarFormat = `$env:%s="%s"; `
p.config.EnvVarFormat = `$env:%s=\"%s\"; `
}
if p.config.ElevatedEnvVarFormat == "" {
@ -120,11 +121,11 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
}
if p.config.ExecuteCommand == "" {
p.config.ExecuteCommand = `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode`
p.config.ExecuteCommand = `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }"`
}
if p.config.ElevatedExecuteCommand == "" {
p.config.ElevatedExecuteCommand = `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'}; . {{.Vars}}; &'{{.Path}}'; exit $LastExitCode`
p.config.ElevatedExecuteCommand = `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"`
}
if p.config.Inline != nil && len(p.config.Inline) == 0 {
@ -389,25 +390,8 @@ func (p *Provisioner) createCommandTextNonPrivileged() (command string, err erro
return "", fmt.Errorf("Error processing command: %s", err)
}
commandText, err := p.generateCommandLineRunner(command)
if err != nil {
return "", fmt.Errorf("Error generating command line runner: %s", err)
}
return commandText, err
}
func (p *Provisioner) generateCommandLineRunner(command string) (commandText string, err error) {
log.Printf("Building command line for: %s", command)
base64EncodedCommand, err := powershellEncode(command)
if err != nil {
return "", fmt.Errorf("Error encoding command: %s", err)
}
commandText = "powershell -executionpolicy bypass -encodedCommand " + base64EncodedCommand
return commandText, nil
// Return the interpolated command
return command, nil
}
func (p *Provisioner) createCommandTextPrivileged() (command string, err error) {
@ -449,20 +433,42 @@ func (p *Provisioner) createCommandTextPrivileged() (command string, err error)
func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath string, err error) {
log.Printf("Building elevated command wrapper for: %s", command)
// generate command
var buffer bytes.Buffer
base64EncodedCommand, err := powershellEncode(command)
if err != nil {
return "", fmt.Errorf("Error encoding command: %s", err)
}
// Output from the elevated command cannot be returned directly to
// the Packer console. In order to be able to view output from elevated
// commands and scripts an indirect approach is used by which the
// commands output is first redirected to file. The output file is then
// 'watched' by Packer while the elevated command is running and any
// content appearing in the file is written out to the console.
// Below the portion of command required to redirect output from the
// command to file is built and appended to the existing command string
taskName := fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID())
// Only use %ENVVAR% format for environment variables when setting
// the log file path; Do NOT use $env:ENVVAR format as it won't be
// expanded correctly in the elevatedTemplate
logFile := `%SYSTEMROOT%\Temp\` + taskName + ".out"
command += fmt.Sprintf(" > %s 2>&1", logFile)
// elevatedTemplate wraps the command in a single quoted XML text
// string so we need to escape characters considered 'special' in XML.
err = xml.EscapeText(&buffer, []byte(command))
if err != nil {
return "", fmt.Errorf("Error escaping characters special to XML in command %s: %s", command, err)
}
escapedCommand := buffer.String()
log.Printf("Command [%s] converted to [%s] for use in XML string", command, escapedCommand)
buffer.Reset()
// Generate command
err = elevatedTemplate.Execute(&buffer, elevatedOptions{
User: p.config.ElevatedUser,
Password: p.config.ElevatedPassword,
TaskDescription: "Packer elevated task",
TaskName: fmt.Sprintf("packer-%s", uuid.TimeOrderedUUID()),
EncodedCommand: base64EncodedCommand,
User: p.config.ElevatedUser,
Password: p.config.ElevatedPassword,
TaskName: taskName,
TaskDescription: "Packer elevated task",
LogFile: logFile,
XMLEscapedCommand: escapedCommand,
})
if err != nil {

View File

@ -79,12 +79,12 @@ func TestProvisionerPrepare_Defaults(t *testing.T) {
t.Error("expected elevated_password to be empty")
}
if p.config.ExecuteCommand != `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode` {
t.Fatalf(`Default command should be "if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode", but got %s`, p.config.ExecuteCommand)
if p.config.ExecuteCommand != `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }"` {
t.Fatalf(`Default command should be 'powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }"', but got '%s'`, p.config.ExecuteCommand)
}
if p.config.ElevatedExecuteCommand != `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'}; . {{.Vars}}; &'{{.Path}}'; exit $LastExitCode` {
t.Fatalf(`Default command should be "if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'}; . {{.Vars}}; &'{{.Path}}'; exit $LastExitCode", but got %s`, p.config.ElevatedExecuteCommand)
if p.config.ElevatedExecuteCommand != `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"` {
t.Fatalf(`Default command should be 'powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"', but got '%s'`, p.config.ElevatedExecuteCommand)
}
if p.config.ValidExitCodes == nil {
@ -413,23 +413,9 @@ func TestProvisionerProvision_Inline(t *testing.T) {
t.Fatal("should not have error")
}
expectedCommand := `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode`
expectedCommandBase64Encoded := `aQBmACAAKABUAGUAcwB0AC0AUABhAHQAaAAgAHYAYQByAGkAYQBiAGwAZQA6AGcAbABvAGIAYQBsADoAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAKQB7ACQAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAPQAnAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAJwB9ADsAJABlAG4AdgA6AFAAQQBDAEsARQBSAF8AQgBVAEkATABEAEUAUgBfAFQAWQBQAEUAPQAiAGkAcwBvACIAOwAgACQAZQBuAHYAOgBQAEEAQwBLAEUAUgBfAEIAVQBJAEwARABfAE4AQQBNAEUAPQAiAHYAbQB3AGEAcgBlACIAOwAgACYAJwBjADoALwBXAGkAbgBkAG8AdwBzAC8AVABlAG0AcAAvAGkAbgBsAGkAbgBlAFMAYwByAGkAcAB0AC4AcABzADEAJwA7AGUAeABpAHQAIAAkAEwAYQBzAHQARQB4AGkAdABDAG8AZABlAA==`
expectedCommandPrefix := `powershell -executionpolicy bypass -encodedCommand `
expectedCommandEncoded := expectedCommandPrefix + expectedCommandBase64Encoded
actualCommandWithoutPrefix := strings.Replace(comm.StartCmd.Command, expectedCommandPrefix, "", -1)
actualCommandDecoded, err := powershellDecode(actualCommandWithoutPrefix)
if err != nil {
t.Fatal("should not have error when base64 decoding")
}
if actualCommandDecoded != expectedCommand {
t.Fatalf("Expected decoded: %s, got %s", expectedCommand, actualCommandDecoded)
}
if comm.StartCmd.Command != expectedCommandEncoded {
t.Fatalf("Expect command to be: %s, got %s", expectedCommandEncoded, comm.StartCmd.Command)
expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode }"`
if comm.StartCmd.Command != expectedCommand {
t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command)
}
envVars := make([]string, 2)
@ -444,23 +430,9 @@ func TestProvisionerProvision_Inline(t *testing.T) {
t.Fatal("should not have error")
}
expectedCommand = `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR="BAZ"; $env:FOO="BAR"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode`
expectedCommandBase64Encoded = `aQBmACAAKABUAGUAcwB0AC0AUABhAHQAaAAgAHYAYQByAGkAYQBiAGwAZQA6AGcAbABvAGIAYQBsADoAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAKQB7ACQAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAPQAnAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAJwB9ADsAJABlAG4AdgA6AEIAQQBSAD0AIgBCAEEAWgAiADsAIAAkAGUAbgB2ADoARgBPAE8APQAiAEIAQQBSACIAOwAgACQAZQBuAHYAOgBQAEEAQwBLAEUAUgBfAEIAVQBJAEwARABFAFIAXwBUAFkAUABFAD0AIgBpAHMAbwAiADsAIAAkAGUAbgB2ADoAUABBAEMASwBFAFIAXwBCAFUASQBMAEQAXwBOAEEATQBFAD0AIgB2AG0AdwBhAHIAZQAiADsAIAAmACcAYwA6AC8AVwBpAG4AZABvAHcAcwAvAFQAZQBtAHAALwBpAG4AbABpAG4AZQBTAGMAcgBpAHAAdAAuAHAAcwAxACcAOwBlAHgAaQB0ACAAJABMAGEAcwB0AEUAeABpAHQAQwBvAGQAZQA=`
expectedCommandPrefix = `powershell -executionpolicy bypass -encodedCommand `
expectedCommandEncoded = expectedCommandPrefix + expectedCommandBase64Encoded
actualCommandWithoutPrefix = strings.Replace(comm.StartCmd.Command, expectedCommandPrefix, "", -1)
actualCommandDecoded, err = powershellDecode(actualCommandWithoutPrefix)
if err != nil {
t.Fatal("should not have error when base64 decoding")
}
if actualCommandDecoded != expectedCommand {
t.Fatalf("Expected decoded: %s, got %s", expectedCommand, actualCommandDecoded)
}
if comm.StartCmd.Command != expectedCommandEncoded {
t.Fatalf("Expect command to be: %s, got %s", expectedCommandEncoded, comm.StartCmd.Command)
expectedCommand = `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR=\"BAZ\"; $env:FOO=\"BAR\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/inlineScript.ps1';exit $LastExitCode }"`
if comm.StartCmd.Command != expectedCommand {
t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command)
}
}
@ -483,24 +455,11 @@ func TestProvisionerProvision_Scripts(t *testing.T) {
t.Fatal("should not have error")
}
expectedCommand := `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE="footype"; $env:PACKER_BUILD_NAME="foobuild"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode`
expectedCommandBase64Encoded := `aQBmACAAKABUAGUAcwB0AC0AUABhAHQAaAAgAHYAYQByAGkAYQBiAGwAZQA6AGcAbABvAGIAYQBsADoAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAKQB7ACQAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAPQAnAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAJwB9ADsAJABlAG4AdgA6AFAAQQBDAEsARQBSAF8AQgBVAEkATABEAEUAUgBfAFQAWQBQAEUAPQAiAGYAbwBvAHQAeQBwAGUAIgA7ACAAJABlAG4AdgA6AFAAQQBDAEsARQBSAF8AQgBVAEkATABEAF8ATgBBAE0ARQA9ACIAZgBvAG8AYgB1AGkAbABkACIAOwAgACYAJwBjADoALwBXAGkAbgBkAG8AdwBzAC8AVABlAG0AcAAvAHMAYwByAGkAcAB0AC4AcABzADEAJwA7AGUAeABpAHQAIAAkAEwAYQBzAHQARQB4AGkAdABDAG8AZABlAA==`
expectedCommandPrefix := `powershell -executionpolicy bypass -encodedCommand `
expectedCommandEncoded := expectedCommandPrefix + expectedCommandBase64Encoded
actualCommandWithoutPrefix := strings.Replace(comm.StartCmd.Command, expectedCommandPrefix, "", -1)
actualCommandDecoded, err := powershellDecode(actualCommandWithoutPrefix)
if err != nil {
t.Fatal("should not have error when base64 decoding")
expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"footype\"; $env:PACKER_BUILD_NAME=\"foobuild\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"`
if comm.StartCmd.Command != expectedCommand {
t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command)
}
if actualCommandDecoded != expectedCommand {
t.Fatalf("Expected decoded: %s, got %s", expectedCommand, actualCommandDecoded)
}
if comm.StartCmd.Command != expectedCommandEncoded {
t.Fatalf("Expect command to be: %s, got %s", expectedCommandEncoded, comm.StartCmd.Command)
}
}
func TestProvisionerProvision_ScriptsWithEnvVars(t *testing.T) {
@ -529,23 +488,9 @@ func TestProvisionerProvision_ScriptsWithEnvVars(t *testing.T) {
t.Fatal("should not have error")
}
expectedCommand := `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR="BAZ"; $env:FOO="BAR"; $env:PACKER_BUILDER_TYPE="footype"; $env:PACKER_BUILD_NAME="foobuild"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode`
expectedCommandBase64Encoded := `aQBmACAAKABUAGUAcwB0AC0AUABhAHQAaAAgAHYAYQByAGkAYQBiAGwAZQA6AGcAbABvAGIAYQBsADoAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAKQB7ACQAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAPQAnAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAJwB9ADsAJABlAG4AdgA6AEIAQQBSAD0AIgBCAEEAWgAiADsAIAAkAGUAbgB2ADoARgBPAE8APQAiAEIAQQBSACIAOwAgACQAZQBuAHYAOgBQAEEAQwBLAEUAUgBfAEIAVQBJAEwARABFAFIAXwBUAFkAUABFAD0AIgBmAG8AbwB0AHkAcABlACIAOwAgACQAZQBuAHYAOgBQAEEAQwBLAEUAUgBfAEIAVQBJAEwARABfAE4AQQBNAEUAPQAiAGYAbwBvAGIAdQBpAGwAZAAiADsAIAAmACcAYwA6AC8AVwBpAG4AZABvAHcAcwAvAFQAZQBtAHAALwBzAGMAcgBpAHAAdAAuAHAAcwAxACcAOwBlAHgAaQB0ACAAJABMAGEAcwB0AEUAeABpAHQAQwBvAGQAZQA=`
expectedCommandPrefix := `powershell -executionpolicy bypass -encodedCommand `
expectedCommandEncoded := expectedCommandPrefix + expectedCommandBase64Encoded
actualCommandWithoutPrefix := strings.Replace(comm.StartCmd.Command, expectedCommandPrefix, "", -1)
actualCommandDecoded, err := powershellDecode(actualCommandWithoutPrefix)
if err != nil {
t.Fatal("should not have error when base64 decoding")
}
if actualCommandDecoded != expectedCommand {
t.Fatalf("Expected decoded: %s, got %s", expectedCommand, actualCommandDecoded)
}
if comm.StartCmd.Command != expectedCommandEncoded {
t.Fatalf("Expect command to be: %s, got %s", expectedCommandEncoded, comm.StartCmd.Command)
expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:BAR=\"BAZ\"; $env:FOO=\"BAR\"; $env:PACKER_BUILDER_TYPE=\"footype\"; $env:PACKER_BUILD_NAME=\"foobuild\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"`
if comm.StartCmd.Command != expectedCommand {
t.Fatalf("Expect command to be: %s, got %s", expectedCommand, comm.StartCmd.Command)
}
}
@ -588,7 +533,6 @@ func TestProvisioner_createFlattenedElevatedEnvVars_windows(t *testing.T) {
t.Fatalf("expected flattened env vars to be: %s, got %s.", expectedValue, flattenedEnvVars)
}
}
}
func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) {
@ -603,11 +547,11 @@ func TestProvisioner_createFlattenedEnvVars_windows(t *testing.T) {
{"FOO==bar"}, // User env var with value starting with equals
}
expected := []string{
`$env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
`$env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
`$env:BAZ="qux"; $env:FOO="bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
`$env:FOO="bar=baz"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
`$env:FOO="=bar"; $env:PACKER_BUILDER_TYPE="iso"; $env:PACKER_BUILD_NAME="vmware"; `,
`$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `,
`$env:FOO=\"bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `,
`$env:BAZ=\"qux\"; $env:FOO=\"bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `,
`$env:FOO=\"bar=baz\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `,
`$env:FOO=\"=bar\"; $env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; `,
}
p := new(Provisioner)
@ -635,27 +579,17 @@ func TestProvision_createCommandText(t *testing.T) {
p.communicator = comm
_ = p.Prepare(config)
// Defaults provided by Packer
p.config.PackerBuildName = "vmware"
p.config.PackerBuilderType = "iso"
// Non-elevated
cmd, _ := p.createCommandText()
expectedCommand := `if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=""; $env:PACKER_BUILD_NAME=""; &'c:/Windows/Temp/script.ps1';exit $LastExitCode`
expectedCommandBase64Encoded := `aQBmACAAKABUAGUAcwB0AC0AUABhAHQAaAAgAHYAYQByAGkAYQBiAGwAZQA6AGcAbABvAGIAYQBsADoAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAKQB7ACQAUAByAG8AZwByAGUAcwBzAFAAcgBlAGYAZQByAGUAbgBjAGUAPQAnAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAJwB9ADsAJABlAG4AdgA6AFAAQQBDAEsARQBSAF8AQgBVAEkATABEAEUAUgBfAFQAWQBQAEUAPQAiACIAOwAgACQAZQBuAHYAOgBQAEEAQwBLAEUAUgBfAEIAVQBJAEwARABfAE4AQQBNAEUAPQAiACIAOwAgACYAJwBjADoALwBXAGkAbgBkAG8AdwBzAC8AVABlAG0AcAAvAHMAYwByAGkAcAB0AC4AcABzADEAJwA7AGUAeABpAHQAIAAkAEwAYQBzAHQARQB4AGkAdABDAG8AZABlAA==`
expectedCommandPrefix := `powershell -executionpolicy bypass -encodedCommand `
expectedCommandEncoded := expectedCommandPrefix + expectedCommandBase64Encoded
expectedCommand := `powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};$env:PACKER_BUILDER_TYPE=\"iso\"; $env:PACKER_BUILD_NAME=\"vmware\"; &'c:/Windows/Temp/script.ps1';exit $LastExitCode }"`
actualCommandWithoutPrefix := strings.Replace(cmd, expectedCommandPrefix, "", -1)
actualCommandDecoded, err := powershellDecode(actualCommandWithoutPrefix)
if err != nil {
t.Fatal("should not have error when base64 decoding")
}
if actualCommandDecoded != expectedCommand {
t.Fatalf("Expected decoded: %s, got %s", expectedCommand, actualCommandDecoded)
}
if cmd != expectedCommandEncoded {
t.Fatalf("Expect command to be: %s, got %s", expectedCommandEncoded, cmd)
if cmd != expectedCommand {
t.Fatalf("Expected Non-elevated command: %s, got %s", expectedCommand, cmd)
}
// Elevated

View File

@ -56,7 +56,12 @@ Optional parameters:
endings (if there are any). By default this is false.
- `elevated_execute_command` (string) - The command to use to execute the elevated
script. By default this is `powershell if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'}; . {{.Vars}}; &'{{.Path}}'; exit $LastExitCode`.
script. By default this is as follows:
``` powershell
powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};. {{.Vars}}; &'{{.Path}}'; exit $LastExitCode }"
```
The value of this is treated as [configuration
template](/docs/templates/engine.html). There are two
available variables: `Path`, which is the path to the script to run, and
@ -68,7 +73,12 @@ Optional parameters:
as well, which are covered in the section below.
- `execute_command` (string) - The command to use to execute the script. By
default this is `powershell if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode`.
default this is as follows:
``` powershell
powershell -executionpolicy bypass "& { if (Test-Path variable:global:ProgressPreference){$ProgressPreference='SilentlyContinue'};{{.Vars}}&'{{.Path}}';exit $LastExitCode }"
```
The value of this is treated as [configuration
template](/docs/templates/engine.html). There are two
available variables: `Path`, which is the path to the script to run, and