diff --git a/lib/bolt/shell/powershell/snippets.rb b/lib/bolt/shell/powershell/snippets.rb index 7fd5486520..c1412c014b 100644 --- a/lib/bolt/shell/powershell/snippets.rb +++ b/lib/bolt/shell/powershell/snippets.rb @@ -20,6 +20,14 @@ def execute_process(command) PS end + def exit_with_code(command) + <<~PS + #{command} + if (-not $? -and ($LASTEXITCODE -eq $null)) { exit 1 } + exit $LASTEXITCODE + PS + end + def make_tmpdir(parent) <<~PS $parent = #{parent} diff --git a/lib/bolt/transport/local/connection.rb b/lib/bolt/transport/local/connection.rb index 76f4951daf..f5e71d55ef 100644 --- a/lib/bolt/transport/local/connection.rb +++ b/lib/bolt/transport/local/connection.rb @@ -50,7 +50,8 @@ def execute(command) # If it's already a powershell command then invoke it normally. # Otherwise, wrap it in powershell.exe. unless command.start_with?('powershell.exe') - command = ['powershell.exe', *Bolt::Shell::Powershell::PS_ARGS, '-Command', command] + cmd = Bolt::Shell::Powershell::Snippets.exit_with_code(command) + command = ['powershell.exe', *Bolt::Shell::Powershell::PS_ARGS, '-Command', cmd] end end diff --git a/spec/integration/local_spec.rb b/spec/integration/local_spec.rb index a4509eed25..8e5ec1cb9d 100644 --- a/spec/integration/local_spec.rb +++ b/spec/integration/local_spec.rb @@ -33,6 +33,13 @@ expect(result[0]['_error']).to be end + it 'returns correct exit code', winrm: true do + cmd = 'puppet apply --trace --detailed-exitcodes -e "notify {foo:}"' + result = run_failed_nodes(%W[command run #{cmd} -t #{uri}]).first + expect(result['_error']['msg']).to eq('The command failed with exit code 2') + expect(result['_error']['details']['exit_code']).to eq(2) + end + it 'runs a ruby task using bolt ruby', :reset_puppet_settings do result = run_one_node(%w[task run sample::bolt_ruby message=somemessage] + config_flags) expect(result['env']).to match(/somemessage/)