From 3b519acebcad1e95a6a5ae32a4238d72f6c0cda8 Mon Sep 17 00:00:00 2001 From: Matt Dainty Date: Thu, 8 Nov 2018 11:48:27 +0000 Subject: [PATCH] Allow Powershell provisioner to use service accounts Fixes #6104 --- provisioner/powershell/elevated.go | 17 ++++++++++++++--- provisioner/powershell/provisioner.go | 5 ----- .../source/docs/provisioners/powershell.html.md | 8 ++++++++ 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/provisioner/powershell/elevated.go b/provisioner/powershell/elevated.go index 6e0faa3d6..be8dcdf62 100644 --- a/provisioner/powershell/elevated.go +++ b/provisioner/powershell/elevated.go @@ -19,11 +19,11 @@ $log = [System.Environment]::ExpandEnvironmentVariables("{{.LogFile}}") $s = New-Object -ComObject "Schedule.Service" $s.Connect() $t = $s.NewTask($null) -$t.XmlText = @' +$xml = [xml]@' - {{.TaskDescription}} + {{.TaskDescription}} @@ -59,9 +59,20 @@ $t.XmlText = @' '@ +$logon_type = 1 +$password = "{{.Password}}" +if ($password.Length -eq 0) { + $logon_type = 5 + $password = $null + $ns = New-Object System.Xml.XmlNamespaceManager($xml.NameTable) + $ns.AddNamespace("ns", $xml.DocumentElement.NamespaceURI) + $node = $xml.SelectSingleNode("/ns:Task/ns:Principals/ns:Principal/ns:LogonType", $ns) + $node.ParentNode.RemoveChild($node) | Out-Null +} +$t.XmlText = $xml.OuterXml if (Test-Path variable:global:ProgressPreference){$ProgressPreference="SilentlyContinue"} $f = $s.GetFolder("\") -$f.RegisterTaskDefinition($name, $t, 6, "{{.User}}", "{{.Password}}", 1, $null) | Out-Null +$f.RegisterTaskDefinition($name, $t, 6, "{{.User}}", $password, $logon_type, $null) | Out-Null $t = $f.GetTask("\$name") $t.Run($null) | Out-Null $timeout = 10 diff --git a/provisioner/powershell/provisioner.go b/provisioner/powershell/provisioner.go index c5724021b..ed35bdd01 100644 --- a/provisioner/powershell/provisioner.go +++ b/provisioner/powershell/provisioner.go @@ -190,11 +190,6 @@ func (p *Provisioner) Prepare(raws ...interface{}) error { errors.New("Only one of script or scripts can be specified.")) } - if p.config.ElevatedUser != "" && p.config.ElevatedPassword == "" { - errs = packer.MultiErrorAppend(errs, - errors.New("Must supply an 'elevated_password' if 'elevated_user' provided")) - } - if p.config.ElevatedUser == "" && p.config.ElevatedPassword != "" { errs = packer.MultiErrorAppend(errs, errors.New("Must supply an 'elevated_user' if 'elevated_password' provided")) diff --git a/website/source/docs/provisioners/powershell.html.md b/website/source/docs/provisioners/powershell.html.md index bc4129fa8..d12a39f14 100644 --- a/website/source/docs/provisioners/powershell.html.md +++ b/website/source/docs/provisioners/powershell.html.md @@ -120,6 +120,14 @@ Optional parameters: "elevated_password": "{{.WinRMPassword}}", ``` + If you specify an empty `elevated_password` value then the PowerShell + script is run as a service account. For example: + + ``` json + "elevated_user": "SYSTEM", + "elevated_password": "", + ``` + - `remote_path` (string) - The path where the PowerShell script will be uploaded to within the target build machine. This defaults to `C:/Windows/Temp/script-UUID.ps1` where UUID is replaced with a dynamically