2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ matrix:
env: PUPPET_GEM_VERSION="~> 3.0"
- rvm: 2.1.5
env: PUPPET_GEM_VERSION="~> 4.0"
- rvm: 2.3.1
env: PUPPET_GEM_VERSION="~> 4.0"
- rvm: 2.0.0
env: PUPPET_GEM_VERSION="~> 3.0" FUTURE_PARSER="yes"
- rvm: 1.9.3
Expand Down
19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,22 @@
##2016-10-05 - Supported Release 2.0.3
###Summary

Small release with bugs fixes and another speed improvement.

###Bug Fixes
- Miscellaneous fixes which improve reliability
- Capture exit codes when executing external scripts ([MODULES-3399](https://tickets.puppetlabs.com/browse/MODULES-3399))
- Add ability to set current working directory ([MODULES-3565](https://tickets.puppetlabs.com/browse/MODULES-3565))
- Respect user specified timeout ([MODULES-3709](https://tickets.puppetlabs.com/browse/MODULES-3709))
- Improve handling of user code exceptions ([MODULES-3443](https://tickets.puppetlabs.com/browse/MODULES-3443))
- Output line and stacktrace of user code exception ([MODULES-3839](https://tickets.puppetlabs.com/browse/MODULES-3839))
- Improve resilience to failure of PowerShell host ([MODULES-3875](https://tickets.puppetlabs.com/browse/MODULES-3875))
- Fix race condition in threading with PowerShell host ([MODULES-3144](https://tickets.puppetlabs.com/browse/MODULES-3144))
- Modify tests to detect differences in PowerShell error text ([MODULES-3442](https://tickets.puppetlabs.com/browse/MODULES-3442))

###Documentation updates
- Document how to handle exit codes ([MODULES-3588](https://tickets.puppetlabs.com/browse/MODULES-3588))

##2016-07-12 - Supported Release 2.0.2
###Summary

Expand Down
10 changes: 7 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@ end
puppetversion = ENV['PUPPET_GEM_VERSION'] || ENV['GEM_PUPPET_VERSION'] || ENV['PUPPET_LOCATION'] || '>= 0'
gem 'puppet', *location_for(puppetversion)

# json_pure 2.0.2 added a requirement on ruby >= 2. We pin to json_pure 2.0.1
# if using ruby 1.x
gem 'json_pure', '<=2.0.1', :require => false if RUBY_VERSION =~ /^1\./

# Only explicitly specify Facter/Hiera if a version has been specified.
# Otherwise it can lead to strange bundler behavior. If you are seeing weird
# gem resolution behavior, try setting `DEBUG_RESOLVER` environment variable
Expand Down Expand Up @@ -98,14 +102,14 @@ if explicitly_require_windows_gems
gem "win32-eventlog", "0.5.3","<= 0.6.5", :require => false
gem "win32-process", "0.6.5","<= 0.7.5", :require => false
gem "win32-security", "~> 0.1.2","<= 0.2.5", :require => false
gem "win32-service", "0.7.2","<= 0.8.7", :require => false
gem "win32-service", "0.7.2","<= 0.8.8", :require => false
gem "minitar", "0.5.4", :require => false
else
gem "ffi", "~> 1.9.0", :require => false
gem "win32-eventlog", "~> 0.5","<= 0.6.5", :require => false
gem "win32-process", "~> 0.6","<= 0.7.5", :require => false
gem "win32-security", "~> 0.1","<= 0.2.5", :require => false
gem "win32-service", "~> 0.7","<= 0.8.7", :require => false
gem "win32-service", "~> 0.7","<= 0.8.8", :require => false
gem "minitar", "~> 0.5.4", :require => false
end

Expand All @@ -132,7 +136,7 @@ else
gem "win32-eventlog", "<= 0.6.5", :require => false
gem "win32-process", "<= 0.7.5", :require => false
gem "win32-security", "<= 0.2.5", :require => false
gem "win32-service", "<= 0.8.7", :require => false
gem "win32-service", "<= 0.8.8", :require => false
end
end

Expand Down
46 changes: 46 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
* [Setup requirements](#setup-requirements)
* [Beginning with powershell](#beginning-with-powershell)
4. [Usage - Configuration options and additional functionality](#usage)
* [External files and exit codes](#external-files-and-exit-codes)
* [Console Error Output](#console-error-output)
5. [Reference - An under-the-hood peek at what the module is doing and how](#reference)
5. [Limitations - OS compatibility, etc.](#limitations)
6. [Development - Guide for contributing to the module](#development)
Expand Down Expand Up @@ -76,6 +78,50 @@ $obj.Rename("OtherGuest")

This has the added benefit of not requiring escaping '$' in the PowerShell code. Note that the files need to have DOS linefeeds or they will not work as expected. One tool for converting UNIX linefeeds to DOS linefeeds is [unix2dos](http://freecode.com/projects/dos2unix).

### External files and exit codes
If you are calling external files, such as other PowerShell scripts or executables, be aware that the last executed script's exitcode will be used by Puppet to determine whether the command was successful. For example:

Suppose the file `C:\fail.ps1` contains the following PowerShell script

~~~ powershell
& cmd /c EXIT 5
& cmd /c EXIT 1
~~~

and we use the following Puppet manifest

~~~ puppet
exec { 'test':
command => '& C:\fail.ps1',
provider => powershell,
}
~~~

The `exec['test']` resource will always fail because the last exit code from the the external file `C:\fail.ps1` is `1`. This behavior may have unintended consequences if you are combining multiple external files.

To stop this behavior ensure that you use explicit `Exit` statements in your PowerShell scripts. For example we changed the Puppet manifest from above to:

~~~ puppet
exec { 'test':
command => '& C:\fail.ps1; Exit 0',
provider => powershell,
}
~~~

It will always succeed because the `Exit 0` statement overrides the exit code from the `C:\fail.ps1` script.

### Console Error Output
The PowerShell module will internally capture output sent to the .NET `[System.Console]::Error` stream like:

~~~ puppet
exec { 'test':
command => '[System.Console]::Error.WriteLine("foo")',
provider => powershell,
}
~~~

However, to produce output from a script, prefer to use the `Write-` prefixed cmdlets like `Write-Output`, `Write-Debug` and `Write-Error`


## Reference

Expand Down
4 changes: 4 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ environment:
RUBY_VER: 21
- PUPPET_GEM_VERSION: ~> 4.0
RUBY_VER: 21-x64
- PUPPET_GEM_VERSION: ~> 4.0
RUBY_VER: 23
- PUPPET_GEM_VERSION: ~> 4.0
RUBY_VER: 23-x64
- PUPPET_GEM_VERSION: 3.0.0
RUBY_VER: 193
matrix:
Expand Down
12 changes: 8 additions & 4 deletions lib/puppet/provider/exec/powershell.rb
Original file line number Diff line number Diff line change
Expand Up @@ -68,16 +68,20 @@ def run(command, check = false)
return super("cmd.exe /c \"\"#{native_path(command(:powershell))}\" #{legacy_args} -Command - < \"#{native_path}\"\"", check)
end
else
result = ps_manager.execute(command)
working_dir = resource[:cwd]
if (!working_dir.nil?)
self.fail "Working directory '#{working_dir}' does not exist" unless File.directory?(working_dir)
end
timeout_ms = resource[:timeout].nil? ? nil : resource[:timeout] * 1000

result = ps_manager.execute(command,timeout_ms,working_dir)

stdout = result[:stdout]
stderr = result[:stderr]
exit_code = result[:exitcode]

unless stderr.nil?
stderr.each do |er|
er.each { |e| Puppet.debug "STDERR: #{e.chop}" } unless er.empty?
end
stderr.each { |e| Puppet.debug "STDERR: #{e.chop}" unless e.empty? }
end

Puppet.debug "STDERR: #{result[:errormessage]}" unless result[:errormessage].nil?
Expand Down
Loading