diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index 3d2f16f85..41b38ed6d 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -24,6 +24,13 @@ import ( var retryableSleep = 2 * time.Second +var psEscape = strings.NewReplacer( + "$", "`$", + "\"", "`\"", + "`", "``", + "'", "`'", +) + type Config struct { common.PackerConfig `mapstructure:",squash"` @@ -359,7 +366,13 @@ func (p *Provisioner) createFlattenedEnvVars(elevated bool) (flattened string) { // Split vars into key/value components for _, envVar := range p.config.Vars { keyValue := strings.SplitN(envVar, "=", 2) - envVars[keyValue[0]] = keyValue[1] + // Escape chars special to PS in each env var value + escapedEnvVarValue := psEscape.Replace(keyValue[1]) + if escapedEnvVarValue != keyValue[1] { + log.Printf("Env var %s converted to %s after escaping chars special to PS", keyValue[1], + escapedEnvVarValue) + } + envVars[keyValue[0]] = escapedEnvVarValue } // Create a list of env var keys in sorted order @@ -480,13 +493,26 @@ func (p *Provisioner) generateElevatedRunner(command string) (uploadedPath strin } escapedCommand := buffer.String() log.Printf("Command [%s] converted to [%s] for use in XML string", command, escapedCommand) - buffer.Reset() + // Escape chars special to PowerShell in the ElevatedUser string + escapedElevatedUser := psEscape.Replace(p.config.ElevatedUser) + if escapedElevatedUser != p.config.ElevatedUser { + log.Printf("Elevated user %s converted to %s after escaping chars special to PowerShell", + p.config.ElevatedUser, escapedElevatedUser) + } + + // Escape chars special to PowerShell in the ElevatedPassword string + escapedElevatedPassword := psEscape.Replace(p.config.ElevatedPassword) + if escapedElevatedPassword != p.config.ElevatedPassword { + log.Printf("Elevated password %s converted to %s after escaping chars special to PowerShell", + p.config.ElevatedPassword, escapedElevatedPassword) + } + // Generate command err = elevatedTemplate.Execute(&buffer, elevatedOptions{ - User: p.config.ElevatedUser, - Password: p.config.ElevatedPassword, + User: escapedElevatedUser, + Password: escapedElevatedPassword, TaskName: taskName, TaskDescription: "Packer elevated task", LogFile: logFile,