diff --git a/lib/vagrant/util/powershell.rb b/lib/vagrant/util/powershell.rb index 9afb4da65..8e48aad1d 100644 --- a/lib/vagrant/util/powershell.rb +++ b/lib/vagrant/util/powershell.rb @@ -20,12 +20,16 @@ module Vagrant if !defined?(@_powershell_executable) @_powershell_executable = "powershell" - # Try to use WSL interoperability if PowerShell is not symlinked to - # the container. - if Which.which(@_powershell_executable).nil? && Platform.wsl? - @_powershell_executable += ".exe" + if Which.which(@_powershell_executable).nil? + # Try to use WSL interoperability if PowerShell is not symlinked to + # the container. + if Platform.wsl? + @_powershell_executable += ".exe" - if Which.which(@_powershell_executable).nil? + if Which.which(@_powershell_executable).nil? + @_powershell_executable = nil + end + else @_powershell_executable = nil end end @@ -41,6 +45,9 @@ module Vagrant # Execute a powershell script. # # @param [String] path Path to the PowerShell script to execute. + # @param [Array] args Command arguments + # @param [Hash] opts Options passed to execute + # @option opts [Hash] :env Custom environment variables # @return [Subprocess::Result] def self.execute(path, *args, **opts, &block) validate_install! @@ -57,7 +64,7 @@ module Vagrant "-NoProfile", "-NonInteractive", "-ExecutionPolicy", "Bypass", - "#{env}&('#{path}')", + "#{resize_console}#{env}&('#{path}')", args ].flatten @@ -72,10 +79,16 @@ module Vagrant # Execute a powershell command. # # @param [String] command PowerShell command to execute. + # @param [Hash] opts Extra options + # @option opts [Hash] :env Custom environment variables # @return [nil, String] Returns nil if exit code is non-zero. # Returns stdout string if exit code is zero. - def self.execute_cmd(command) + def self.execute_cmd(command, **opts) validate_install! + env = opts.delete(:env) + if env + env = env.map{|k,v| "$env:#{k}=#{v}"}.join(";") + "; " + end c = [ executable, "-NoLogo", @@ -83,7 +96,7 @@ module Vagrant "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", - command + "#{resize_console}#{env}#{command}" ].flatten.compact r = Subprocess.execute(*c) @@ -95,9 +108,14 @@ module Vagrant # # @param [String] command PowerShell command to execute. # @param [Hash] opts A collection of options for subprocess::execute + # @option opts [Hash] :env Custom environment variables # @param [Block] block Ruby block def self.execute_inline(*command, **opts, &block) validate_install! + env = opts.delete(:env) + if env + env = env.map{|k,v| "$env:#{k}=#{v}"}.join(";") + "; " + end c = [ executable, "-NoLogo", @@ -105,7 +123,7 @@ module Vagrant "-NonInteractive", "-ExecutionPolicy", "Bypass", "-Command", - command + "#{resize_console}#{env}#{command}" ].flatten.compact c << opts @@ -224,6 +242,19 @@ module Vagrant def self.reset! instance_variables.each(&method(:remove_instance_variable)) end + + # @private + # This is a helper method that provides the PowerShell command to resize + # the "console" to prevent output wrapping or truncating. An environment + # variable guard is provided to disable the behavior in cases where it + # may cause unexpected results (VAGRANT_POWERSHELL_RESIZE_DISABLE) + def self.resize_console + if ENV["VAGRANT_POWERSHELL_RESIZE_DISABLE"] + "" + else + "$host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.Size(512,50); " + end + end end end end