diff --git a/plugins/communicators/winrm/communicator.rb b/plugins/communicators/winrm/communicator.rb index c9cfa8327..670748536 100644 --- a/plugins/communicators/winrm/communicator.rb +++ b/plugins/communicators/winrm/communicator.rb @@ -61,9 +61,19 @@ module VagrantPlugins :error_class => Errors::ExecutionError, :error_key => :execution_error, :command => command, - :shell => :powershell + :shell => :powershell, + :elevated => false }.merge(opts || {}) + if opts[:elevated] + path = File.expand_path("../scripts/elevated_shell.ps1", __FILE__) + command = Vagrant::Util::TemplateRenderer.render(path, options: { + username: shell.username, + password: shell.password, + command: command, + }) + end + output = shell.send(opts[:shell], command, &block) execution_output(output, opts) end diff --git a/test/unit/plugins/communicators/winrm/communicator_test.rb b/test/unit/plugins/communicators/winrm/communicator_test.rb index 84a4e8bd2..d6013be7c 100644 --- a/test/unit/plugins/communicators/winrm/communicator_test.rb +++ b/test/unit/plugins/communicators/winrm/communicator_test.rb @@ -17,6 +17,11 @@ describe VagrantPlugins::CommunicatorWinRM::Communicator do end end + before do + allow(shell).to receive(:username).and_return('vagrant') + allow(shell).to receive(:password).and_return('password') + end + describe ".ready?" do it "returns true if hostname command executes without error" do expect(shell).to receive(:powershell).with("hostname").and_return({ exitcode: 0 }) @@ -42,6 +47,16 @@ describe VagrantPlugins::CommunicatorWinRM::Communicator do expect(subject.execute("dir")).to eq(0) end + it "wraps command in elevated shell script when elevated is true" do + expect(shell).to receive(:powershell) do |cmd| + expect(cmd).to include("$command = \"dir\"") + expect(cmd).to include("$user = 'vagrant'") + expect(cmd).to include("$password = 'password'") + expect(cmd).to include("New-Object -ComObject \"Schedule.Service\"") + end.and_return({ exitcode: 0 }) + expect(subject.execute("dir", { elevated: true })).to eq(0) + end + it "can use cmd shell" do expect(shell).to receive(:cmd).with(kind_of(String)).and_return({ exitcode: 0 }) expect(subject.execute("dir", { :shell => :cmd })).to eq(0)