From 725824e1dd3c2225a6274df074142621751bfb14 Mon Sep 17 00:00:00 2001 From: Matt Wrock Date: Sun, 11 Dec 2016 00:52:00 -0800 Subject: [PATCH] refactor winrm communicator to use latest winrm gems and v2 api Signed-off-by: Matt Wrock --- plugins/communicators/winrm/communicator.rb | 62 ++--------- plugins/communicators/winrm/config.rb | 3 + .../winrm/scripts/elevated_shell.ps1.erb | 101 ------------------ plugins/communicators/winrm/shell.rb | 70 ++++++------ plugins/hosts/windows/cap/ps.rb | 7 +- .../communicators/winrm/communicator_test.rb | 40 +++---- .../plugins/communicators/winrm/shell_test.rb | 69 +++++++++--- vagrant.gemspec | 5 +- .../docs/vagrantfile/winrm_settings.html.md | 20 +++- 9 files changed, 143 insertions(+), 234 deletions(-) delete mode 100644 plugins/communicators/winrm/scripts/elevated_shell.ps1.erb diff --git a/plugins/communicators/winrm/communicator.rb b/plugins/communicators/winrm/communicator.rb index 8c7a292cf..bfa5dc6b3 100644 --- a/plugins/communicators/winrm/communicator.rb +++ b/plugins/communicators/winrm/communicator.rb @@ -142,10 +142,10 @@ module VagrantPlugins interactive: false, }.merge(opts || {}) + opts[:shell] = :elevated if opts[:elevated] opts[:good_exit] = Array(opts[:good_exit]) - command = wrap_in_scheduled_task(command, opts[:interactive]) if opts[:elevated] @logger.debug("#{opts[:shell]} executing:\n#{command}") - output = shell.send(opts[:shell], command, &block) + output = shell.send(opts[:shell], command, opts, &block) execution_output(output, opts) end alias_method :sudo, :execute @@ -165,7 +165,7 @@ module VagrantPlugins # If we're passed a *nix command which PS can't parse we get exit code # 0, but output in stderr. We need to check both exit code and stderr. output = shell.send(:powershell, command) - return output[:exitcode] == 0 && flatten_stderr(output).length == 0 + return output.exitcode == 0 && output.stderr.length == 0 end def upload(from, to) @@ -180,7 +180,7 @@ module VagrantPlugins protected - # This creates anew WinRMShell based on the information we know + # This creates a new WinRMShell based on the information we know # about this machine. def create_shell winrm_info = Helper.winrm_info(@machine) @@ -192,55 +192,23 @@ module VagrantPlugins ) end - # Creates and uploads a PowerShell script which wraps a command in a - # scheduled task. The scheduled task allows commands to run on the guest - # as a true local admin without any of the restrictions that WinRM puts - # in place. - # - # @return The wrapper command to execute - def wrap_in_scheduled_task(command, interactive) - path = File.expand_path("../scripts/elevated_shell.ps1", __FILE__) - script = Vagrant::Util::TemplateRenderer.render(path, options: { - interactive: interactive, - }) - guest_script_path = "c:/tmp/vagrant-elevated-shell.ps1" - Tempfile.open(["vagrant-elevated-shell", "ps1"]) do |f| - f.binmode - f.write(script) - f.fsync - f.close - upload(f.path, guest_script_path) - end - - # Convert to double byte unicode string then base64 encode - # just like PowerShell -EncodedCommand expects. - # Suppress the progress stream from leaking to stderr. - wrapped_encoded_command = Base64.strict_encode64( - "$ProgressPreference='SilentlyContinue'; #{command}; exit $LASTEXITCODE".encode('UTF-16LE', 'UTF-8')) - - "powershell -executionpolicy bypass -file '#{guest_script_path}' " + - "-username '#{shell.username}' -password '#{shell.password}' " + - "-encoded_command '#{wrapped_encoded_command}' " + - "-execution_time_limit '#{shell.execution_time_limit}'" - end - # Handles the raw WinRM shell result and converts it to a # standard Vagrant communicator result def execution_output(output, opts) if opts[:shell] == :wql return output elsif opts[:error_check] && \ - !opts[:good_exit].include?(output[:exitcode]) + !opts[:good_exit].include?(output.exitcode) raise_execution_error(output, opts) end - output[:exitcode] + output.exitcode end def raise_execution_error(output, opts) # WinRM can return multiple stderr and stdout entries error_opts = opts.merge( - stdout: flatten_stdout(output), - stderr: flatten_stderr(output) + stdout: output.stdout, + stderr: output.stderr ) # Use a different error message key if the caller gave us one, @@ -250,20 +218,6 @@ module VagrantPlugins # Raise the error, use the type the caller gave us or the comm default raise opts[:error_class], error_opts end - - - # TODO: Replace with WinRM Output class when WinRM 1.3 is released - def flatten_stderr(output) - output[:data].map do | line | - line[:stderr] - end.compact.join - end - - def flatten_stdout(output) - output[:data].map do | line | - line[:flatten_stdout] - end.compact.join - end end #WinRM class end end diff --git a/plugins/communicators/winrm/config.rb b/plugins/communicators/winrm/config.rb index 9c2d7fe84..d8c6ffd6a 100644 --- a/plugins/communicators/winrm/config.rb +++ b/plugins/communicators/winrm/config.rb @@ -13,6 +13,7 @@ module VagrantPlugins attr_accessor :ssl_peer_verification attr_accessor :execution_time_limit attr_accessor :basic_auth_only + attr_accessor :codepage def initialize @username = UNSET_VALUE @@ -27,6 +28,7 @@ module VagrantPlugins @ssl_peer_verification = UNSET_VALUE @execution_time_limit = UNSET_VALUE @basic_auth_only = UNSET_VALUE + @codepage = UNSET_VALUE end def finalize! @@ -43,6 +45,7 @@ module VagrantPlugins @ssl_peer_verification = true if @ssl_peer_verification == UNSET_VALUE @execution_time_limit = "PT2H" if @execution_time_limit == UNSET_VALUE @basic_auth_only = false if @basic_auth_only == UNSET_VALUE + @codepage = nil if @codepage == UNSET_VALUE end def validate(machine) diff --git a/plugins/communicators/winrm/scripts/elevated_shell.ps1.erb b/plugins/communicators/winrm/scripts/elevated_shell.ps1.erb deleted file mode 100644 index 76b260b78..000000000 --- a/plugins/communicators/winrm/scripts/elevated_shell.ps1.erb +++ /dev/null @@ -1,101 +0,0 @@ -param([String]$username, [String]$password, [String]$encoded_command, [String]$execution_time_limit) - -# Try to get the Schedule.Service object. If it fails, we are probably -# on an older version of Windows. On old versions, we can just execute -# directly since priv. escalation isn't a thing. -$schedule = $null -Try { - $schedule = New-Object -ComObject "Schedule.Service" -} Catch [System.Management.Automation.PSArgumentException] { - powershell.exe -EncodedCommand $encoded_command - exit $LASTEXITCODE -} - -$ProgressPreference = "SilentlyContinue" -$task_name = "WinRM_Elevated_Shell" -$out_file = "$env:SystemRoot\Temp\WinRM_Elevated_Shell.log" - -if (Test-Path $out_file) { - del $out_file -} - -$task_xml = @' - - - - - {username} - <%= options[:interactive] ? 'InteractiveTokenOrPassword' : 'Password' %> - HighestAvailable - - - - IgnoreNew - false - false - true - false - false - - false - false - - true - true - false - false - false - {execution_time_limit} - 4 - - - - cmd - {arguments} - - - -'@ - -$arguments = "/c powershell.exe -EncodedCommand $encoded_command > $out_file 2>&1" - -$task_xml = $task_xml.Replace("{arguments}", $arguments) -$task_xml = $task_xml.Replace("{username}", $username) -$task_xml = $task_xml.Replace("{execution_time_limit}", $execution_time_limit) - -$schedule.Connect() -$task = $schedule.NewTask($null) -$task.XmlText = $task_xml -$folder = $schedule.GetFolder("\") -$folder.RegisterTaskDefinition($task_name, $task, 6, $username, $password, <%= options[:interactive] ? 3 : 1 %>, $null) | Out-Null - -$registered_task = $folder.GetTask("\$task_name") -$registered_task.Run($null) | Out-Null - -$timeout = 10 -$sec = 0 -while ( (!($registered_task.state -eq 4)) -and ($sec -lt $timeout) ) { - Start-Sleep -s 1 - $sec++ -} - -function SlurpOutput($out_file, $cur_line) { - if (Test-Path $out_file) { - get-content $out_file | select -skip $cur_line | ForEach { - $cur_line += 1 - Write-Host "$_" - } - } - return $cur_line -} - -$cur_line = 0 -do { - Start-Sleep -m 100 - $cur_line = SlurpOutput $out_file $cur_line -} while (!($registered_task.state -eq 3)) - -$exit_code = $registered_task.LastTaskResult -[System.Runtime.Interopservices.Marshal]::ReleaseComObject($schedule) | Out-Null - -exit $exit_code diff --git a/plugins/communicators/winrm/shell.rb b/plugins/communicators/winrm/shell.rb index 0ea9e3cbb..7a4444a8f 100644 --- a/plugins/communicators/winrm/shell.rb +++ b/plugins/communicators/winrm/shell.rb @@ -9,6 +9,7 @@ Vagrant::Util::SilenceWarnings.silence! do require "winrm" end +require "winrm-elevated" require "winrm-fs" module VagrantPlugins @@ -53,48 +54,55 @@ module VagrantPlugins @config = config end - def powershell(command, &block) - # Ensure an exit code - command += "\r\nif ($?) { exit 0 } else { if($LASTEXITCODE) { exit $LASTEXITCODE } else { exit 1 } }" - session.create_executor do |executor| - execute_with_rescue(executor.method("run_powershell_script"), command, &block) + def powershell(command, opts = {}, &block) + connection.shell(:powershell) do |shell| + execute_with_rescue(shell, command, &block) end end - def cmd(command, &block) - session.create_executor do |executor| - execute_with_rescue(executor.method("run_cmd"), command, &block) + def cmd(command, opts = {}, &block) + shell_opts = {} + shell_opts[:codepage] = @config.codepage if @config.codepage + connection.shell(:cmd, shell_opts) do |shell| + execute_with_rescue(shell, command, &block) end end - def wql(query, &block) + def elevated(command, opts = {}, &block) + connection.shell(:elevated) do |shell| + shell.interactive_logon = opts[:interactive] || false + execute_with_rescue(shell, command, &block) + end + end + + def wql(query, opts = {}, &block) retryable(tries: @config.max_tries, on: @@exceptions_to_retry_on, sleep: @config.retry_delay) do - handle_output(session.method("run_wql"), query, &block) + connection.run_wql(query) end rescue => e raise_winrm_exception(e, "run_wql", query) end def upload(from, to) - file_manager = WinRM::FS::FileManager.new(session) + file_manager = WinRM::FS::FileManager.new(connection) file_manager.upload(from, to) end def download(from, to) - file_manager = WinRM::FS::FileManager.new(session) + file_manager = WinRM::FS::FileManager.new(connection) file_manager.download(from, to) end protected - def execute_with_rescue(method, command, &block) - handle_output(method, command, &block) + def execute_with_rescue(shell, command, &block) + handle_output(shell, command, &block) rescue => e - raise_winrm_exception(e, method.name, command) + raise_winrm_exception(e, shell.class.name.split("::").last, command) end - def handle_output(execute_method, command, &block) - output = execute_method.call(command) do |out, err| + def handle_output(shell, command, &block) + output = shell.run(command) do |out, err| block.call(:stdout, out) if block_given? && out block.call(:stderr, err) if block_given? && err end @@ -104,14 +112,10 @@ module VagrantPlugins # Verify that we didn't get a parser error, and if so we should # set the exit code to 1. Parse errors return exit code 0 so we # need to do this. - if output[:exitcode] == 0 - (output[:data] || []).each do |data| - next if !data[:stderr] - if data[:stderr].include?("ParserError") - @logger.warn("Detected ParserError, setting exit code to 1") - output[:exitcode] = 1 - break - end + if output.exitcode == 0 + if output.stderr.include?("ParserError") + @logger.warn("Detected ParserError, setting exit code to 1") + output.exitcode = 1 end end @@ -159,21 +163,20 @@ module VagrantPlugins end end - def new_session + def new_connection @logger.info("Attempting to connect to WinRM...") @logger.info(" - Host: #{@host}") @logger.info(" - Port: #{@port}") @logger.info(" - Username: #{@config.username}") @logger.info(" - Transport: #{@config.transport}") - client = ::WinRM::WinRMWebService.new(endpoint, @config.transport.to_sym, endpoint_options) - client.set_timeout(@config.timeout) + client = ::WinRM::Connection.new(endpoint_options) client.logger = @logger client end - def session - @session ||= new_session + def connection + @connection ||= new_connection end def endpoint @@ -188,8 +191,11 @@ module VagrantPlugins end def endpoint_options - { user: @username, - pass: @password, + { endpoint: endpoint, + transport: @config.transport, + operation_timeout: @config.timeout, + user: @username, + password: @password, host: @host, port: @port, basic_auth_only: @config.basic_auth_only, diff --git a/plugins/hosts/windows/cap/ps.rb b/plugins/hosts/windows/cap/ps.rb index b02a31bd6..ec778359c 100644 --- a/plugins/hosts/windows/cap/ps.rb +++ b/plugins/hosts/windows/cap/ps.rb @@ -28,7 +28,7 @@ module VagrantPlugins args << "Bypass" args << "-NoExit" args << "-EncodedCommand" - args << ::WinRM::PowershellScript.new(command).encoded + args << encoded(command) if ps_info[:extra_args] args << ps_info[:extra_args] end @@ -36,6 +36,11 @@ module VagrantPlugins # Launch it Vagrant::Util::SafeExec.exec("powershell", *args) end + + def self.encoded(script) + encoded_script = script.encode('UTF-16LE', 'UTF-8') + Base64.strict_encode64(encoded_script) + end end end end diff --git a/test/unit/plugins/communicators/winrm/communicator_test.rb b/test/unit/plugins/communicators/winrm/communicator_test.rb index d69185d86..719167590 100644 --- a/test/unit/plugins/communicators/winrm/communicator_test.rb +++ b/test/unit/plugins/communicators/winrm/communicator_test.rb @@ -11,7 +11,9 @@ describe VagrantPlugins::CommunicatorWinRM::Communicator do let(:ui) { double("ui") } let(:machine) { double("machine", config: config, provider: provider, ui: ui) } let(:shell) { double("shell") } - + let(:good_output) { WinRM::Output.new.tap { |out| out.exitcode = 0 } } + let(:bad_output) { WinRM::Output.new.tap { |out| out.exitcode = 1 } } + subject do described_class.new(machine).tap do |comm| allow(comm).to receive(:create_shell).and_return(shell) @@ -81,61 +83,47 @@ describe VagrantPlugins::CommunicatorWinRM::Communicator do describe ".execute" do it "defaults to running in powershell" do - expect(shell).to receive(:powershell).with(kind_of(String)).and_return({ exitcode: 0 }) + expect(shell).to receive(:powershell).with(kind_of(String), kind_of(Hash)).and_return(good_output) expect(subject.execute("dir")).to eq(0) end - it "wraps command in elevated shell script when elevated is true" do - expect(shell).to receive(:upload).with(kind_of(String), "c:/tmp/vagrant-elevated-shell.ps1") - expect(shell).to receive(:powershell) do |cmd| - expect(cmd).to eq("powershell -executionpolicy bypass -file 'c:/tmp/vagrant-elevated-shell.ps1' " + - "-username 'vagrant' -password 'password' -encoded_command 'JABQAHIAbwBnAHIAZQBzAHMAUAByAGUAZgBlAHIAZQBuAGMAZQA9ACcAUwBpAGwAZQBuAHQAbAB5AEMAbwBuAHQAaQBuAHUAZQAnADsAIABkAGkAcgA7ACAAZQB4AGkAdAAgACQATABBAFMAVABFAFgASQBUAEMATwBEAEUA' -execution_time_limit 'PT2H'") - end.and_return({ exitcode: 0 }) + it "use elevated shell script when elevated is true" do + expect(shell).to receive(:elevated).and_return(good_output) expect(subject.execute("dir", { elevated: true })).to eq(0) end - it "wraps command in elevated and interactive shell script when elevated and interactive are true" do - expect(shell).to receive(:upload).with(kind_of(String), "c:/tmp/vagrant-elevated-shell.ps1") - expect(shell).to receive(:powershell) do |cmd| - expect(cmd).to eq("powershell -executionpolicy bypass -file 'c:/tmp/vagrant-elevated-shell.ps1' " + - "-username 'vagrant' -password 'password' -encoded_command 'JABQAHIAbwBnAHIAZQBzAHMAUAByAGUAZgBlAHIAZQBuAGMAZQA9ACcAUwBpAGwAZQBuAHQAbAB5AEMAbwBuAHQAaQBuAHUAZQAnADsAIABkAGkAcgA7ACAAZQB4AGkAdAAgACQATABBAFMAVABFAFgASQBUAEMATwBEAEUA' -execution_time_limit 'PT2H'") - end.and_return({ exitcode: 0 }) - expect(subject.execute("dir", { elevated: true, interactive: 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(shell).to receive(:cmd).with(kind_of(String), kind_of(Hash)).and_return(good_output) expect(subject.execute("dir", { shell: :cmd })).to eq(0) end it "raises error when error_check is true and exit code is non-zero" do - expect(shell).to receive(:powershell).with(kind_of(String)).and_return( - { exitcode: 1, data: [{ stdout: '', stderr: '' }] }) + expect(shell).to receive(:powershell).with(kind_of(String), kind_of(Hash)).and_return(bad_output) expect { subject.execute("dir") }.to raise_error( VagrantPlugins::CommunicatorWinRM::Errors::WinRMBadExitStatus) end it "does not raise error when error_check is false and exit code is non-zero" do - expect(shell).to receive(:powershell).with(kind_of(String)).and_return({ exitcode: 1 }) + expect(shell).to receive(:powershell).with(kind_of(String), kind_of(Hash)).and_return(bad_output) expect(subject.execute("dir", { error_check: false })).to eq(1) end end describe ".test" do it "returns true when exit code is zero" do - output = { exitcode: 0, data:[{ stderr: '' }] } - expect(shell).to receive(:powershell).with(kind_of(String)).and_return(output) + expect(shell).to receive(:powershell).with(kind_of(String)).and_return(good_output) expect(subject.test("test -d c:/windows")).to be_true end it "returns false when exit code is non-zero" do - output = { exitcode: 1, data:[{ stderr: '' }] } - expect(shell).to receive(:powershell).with(kind_of(String)).and_return(output) + expect(shell).to receive(:powershell).with(kind_of(String)).and_return(bad_output) expect(subject.test("test -d /tmp/foobar")).to be_false end it "returns false when stderr contains output" do - output = { exitcode: 0, data:[{ stderr: 'this is an error' }] } + output = WinRM::Output.new + output.exitcode = 1 + output << { stderr: 'this is an error' } expect(shell).to receive(:powershell).with(kind_of(String)).and_return(output) expect(subject.test("[-x stuff] && foo")).to be_false end diff --git a/test/unit/plugins/communicators/winrm/shell_test.rb b/test/unit/plugins/communicators/winrm/shell_test.rb index 0c77290c8..988c07a97 100644 --- a/test/unit/plugins/communicators/winrm/shell_test.rb +++ b/test/unit/plugins/communicators/winrm/shell_test.rb @@ -6,8 +6,8 @@ require Vagrant.source_root.join("plugins/communicators/winrm/config") describe VagrantPlugins::CommunicatorWinRM::WinRMShell do include_context "unit" - let(:session) { double("winrm_session") } - let(:executor) { double("command_executor") } + let(:connection) { double("winrm_connection") } + let(:shell) { double("winrm_shell") } let(:port) { config.transport == :ssl ? 5986 : 5985 } let(:config) { VagrantPlugins::CommunicatorWinRM::Config.new.tap do |c| @@ -21,44 +21,82 @@ describe VagrantPlugins::CommunicatorWinRM::WinRMShell do c.finalize! end } + let(:output) { WinRM::Output.new.tap { |out| out.exitcode = 0 } } - before { allow(session).to receive(:create_executor).and_yield(executor) } + before { allow(connection).to receive(:shell).and_yield(shell) } subject do described_class.new('localhost', port, config).tap do |comm| - allow(comm).to receive(:new_session).and_return(session) + allow(comm).to receive(:new_connection).and_return(connection) end end describe ".powershell" do it "should call winrm powershell" do - expect(executor).to receive(:run_powershell_script).with(/^dir.+/).and_return({ exitcode: 0 }) - expect(subject.powershell("dir")[:exitcode]).to eq(0) + expect(shell).to receive(:run).with("dir").and_return(output) + expect(subject.powershell("dir").exitcode).to eq(0) end it "should raise an execution error when an exception occurs" do - expect(executor).to receive(:run_powershell_script).with(/^dir.+/).and_raise( + expect(shell).to receive(:run).with("dir").and_raise( StandardError.new("Oh no! a 500 SOAP error!")) expect { subject.powershell("dir") }.to raise_error( VagrantPlugins::CommunicatorWinRM::Errors::ExecutionError) end end - describe ".cmd" do + describe ".elevated" do + it "should call winrm elevated" do + expect(shell).to receive(:run).with("dir").and_return(output) + expect(shell).to receive(:interactive_logon=).with(false) + expect(subject.elevated("dir").exitcode).to eq(0) + end + + it "should set interactive_logon when interactive is true" do + expect(shell).to receive(:run).with("dir").and_return(output) + expect(shell).to receive(:interactive_logon=).with(true) + expect(subject.elevated("dir", { interactive: true }).exitcode).to eq(0) + end + + it "should raise an execution error when an exception occurs" do + expect(shell).to receive(:run).with("dir").and_raise( + StandardError.new("Oh no! a 500 SOAP error!")) + expect { subject.powershell("dir") }.to raise_error( + VagrantPlugins::CommunicatorWinRM::Errors::ExecutionError) + end + end + + describe ".cmd" do it "should call winrm cmd" do - expect(executor).to receive(:run_cmd).with("dir").and_return({ exitcode: 0 }) - expect(subject.cmd("dir")[:exitcode]).to eq(0) + expect(connection).to receive(:shell).with(:cmd, { }) + expect(shell).to receive(:run).with("dir").and_return(output) + expect(subject.cmd("dir").exitcode).to eq(0) + end + + context "when codepage is given" do + let(:config) { + VagrantPlugins::CommunicatorWinRM::Config.new.tap do |c| + c.codepage = 800 + c.finalize! + end + } + + it "creates shell with the given codepage when set" do + expect(connection).to receive(:shell).with(:cmd, { codepage: 800 }) + expect(shell).to receive(:run).with("dir").and_return(output) + expect(subject.cmd("dir").exitcode).to eq(0) + end end end describe ".wql" do it "should call winrm wql" do - expect(session).to receive(:run_wql).with("select * from Win32_OperatingSystem").and_return({ exitcode: 0 }) - expect(subject.wql("select * from Win32_OperatingSystem")[:exitcode]).to eq(0) + expect(connection).to receive(:run_wql).with("select * from Win32_OperatingSystem") + subject.wql("select * from Win32_OperatingSystem") end it "should retry when a WinRMAuthorizationError is received" do - expect(session).to receive(:run_wql).with("select * from Win32_OperatingSystem").exactly(2).times.and_raise( + expect(connection).to receive(:run_wql).with("select * from Win32_OperatingSystem").exactly(2).times.and_raise( # Note: The initialize for WinRMAuthorizationError may require a status_code as # the second argument in a future WinRM release. Currently it doesn't track the # status code. @@ -104,9 +142,10 @@ describe VagrantPlugins::CommunicatorWinRM::WinRMShell do describe ".endpoint_options" do it "should create endpoint options" do expect(subject.send(:endpoint_options)).to eq( - { user: "username", pass: "password", host: "localhost", port: 5985, + { endpoint: "http://localhost:5985/wsman", operation_timeout: 1800, + user: "username", password: "password", host: "localhost", port: 5985, basic_auth_only: false, no_ssl_peer_verification: false, - retry_delay: 1, retry_limit: 2 }) + retry_delay: 1, retry_limit: 2, transport: :negotiate }) end end diff --git a/vagrant.gemspec b/vagrant.gemspec index 3c74eb161..f2c6fc736 100644 --- a/vagrant.gemspec +++ b/vagrant.gemspec @@ -28,8 +28,9 @@ Gem::Specification.new do |s| s.add_dependency "rb-kqueue", "~> 0.2.0" s.add_dependency "rest-client", ">= 1.6.0", "< 3.0" s.add_dependency "wdm", "~> 0.1.0" - s.add_dependency "winrm", "~> 1.6" - s.add_dependency "winrm-fs", "~> 0.3.0" + s.add_dependency "winrm", "~> 2.1" + s.add_dependency "winrm-fs", "~> 1.0" + s.add_dependency "winrm-elevated", "~> 1.1" # We lock this down to avoid compilation issues. s.add_dependency "nokogiri", "= 1.6.7.1" diff --git a/website/source/docs/vagrantfile/winrm_settings.html.md b/website/source/docs/vagrantfile/winrm_settings.html.md index 046d1854f..1fcf550fb 100644 --- a/website/source/docs/vagrantfile/winrm_settings.html.md +++ b/website/source/docs/vagrantfile/winrm_settings.html.md @@ -59,6 +59,20 @@ to use port 4567 to talk to the guest if there is no other option.
-`config.winrm.execution_time_limit` - The maximum duration that a WinRM -task can execute for. This defaults to two hours. The format of this value -must be in this [Microsoft-documented format](https://msdn.microsoft.com/en-us/library/aa382678.aspx). +`config.winrm.ssl_peer_verification` - When set to `false` ssl certificate validation is not performed. + +
+ +`config.winrm.timeout` - The maximum amount of time to wait for a response from the endpoint. This defaults to 60 seconds. Note that this will not "timeout" commands that exceed this amount of time to process, it just requires the endpoint to report the status of the command before the given amount of time passes. + +
+ +`config.winrm.retry_limit` - The maximum number of times to retry opening a shell after failure. This defaults to 3. + +
+ +`config.winrm.retry_delay` - The amount of time to wait between retries and defaults to 10 seconds. + +
+ +`config.winrm.codepage` - The WINRS_CODEPAGE which is the client's console output code page. The default is 65001 (UTF-8). Note: Versions of Windows older than Windows 7/Server 2008 R2 may exhibit undesirable behavior using the default UTF-8 codepage. When using these older versions of Windows, its best to use the native code page of the server's locale. For example, en-US servers will have a codepage of 437. The Windows `chcp` command can be used to determine the value of the native codepage.