require "json" require "vagrant/util/powershell" require_relative "plugin" module VagrantPlugins module HyperV class Driver ERROR_REGEXP = /===Begin-Error===(.+?)===End-Error===/m OUTPUT_REGEXP = /===Begin-Output===(.+?)===End-Output===/m def execute(path, options) r = execute_powershell(path, options) if r.exit_code != 0 raise Errors::PowerShellError, script: path, stderr: r.stderr end # We only want unix-style line endings within Vagrant r.stdout.gsub!("\r\n", "\n") r.stderr.gsub!("\r\n", "\n") error_match = ERROR_REGEXP.match(r.stdout) output_match = OUTPUT_REGEXP.match(r.stdout) if error_match data = JSON.parse(error_match[1]) # We have some error data. raise Errors::PowerShellError, script: path, stderr: data["error"] end # Nothing return nil if !output_match return JSON.parse(output_match[1]) end protected def execute_powershell(path, options, &block) lib_path = Pathname.new(File.expand_path("../scripts", __FILE__)) path = lib_path.join(path).to_s.gsub("/", "\\") options = options || {} ps_options = [] options.each do |key, value| ps_options << "-#{key}" ps_options << "'#{value}'" end # Always have a stop error action for failures ps_options << "-ErrorAction" << "Stop" opts = { notify: [:stdout, :stderr, :stdin] } Vagrant::Util::PowerShell.execute(path, *ps_options, **opts, &block) end end end end