Running PowerShell Scripts In Puppet

There are times when you have a complex script that you just need to get into configuration management. Re-writing scripts into manifests is time-consuming, no doubt about it. In this article, I will show how to run PowerShell scripts from Puppet.

Puppet support for Windows is constantly growing. Puppet itself creates a lot of native Windows modules, in addition to providing the ability to actually use Desired State Configuration resources inside your Puppet manifests. With that said, you can actually use Puppet to run PowerShell scripts as well. I will mention this is a less-than-ideal way to manage Windows servers as it has drawbacks, but it is very much supported in Puppet.

Puppet Exec Resource

The Puppet “exec” resource allows users to run commands and scripts on nodes. This can be used with bash on Linux, but with the PowerShell provider, it can run PowerShell on Windows and Linux nodes as well.

There are a few important parameters to use when writing an exec resource with PowerShell. These are command, onlyif, returns and unless. The command parameter specifies either the exact command or script to run on the node. Onlyif and unless are somewhat similar as they serve as conditional operators in Puppet which means the command runs based on the output of what is in these parameters. I will show how these work in the example below.

Running a Sample Puppet Manifest on a Node

In this example, I want to run a PowerShell script on a Windows host that will set the hostname only if the hostname is different than the name specified in the script. Here is my sample Puppet module that is named “rename_hostname”:

class rename_hostname {

exec { 'win-hostname':

  command   => file('rename_hostname/rename-hostname.ps1'),

  onlyif    => file('rename_hostname/hostname-exists.ps1'),

  provider  => powershell,

  logoutput => true,



These two PowerShell scripts are kept in my Puppet module “rename_hostname” under a subdirectory “files”. This is by default where Puppet will look for scripts when they are stated in a manifest using file().

So when I apply this configuration to a node, it will run “hostname-exists.ps1” first, and if this script does stop with an exit code of 0, it will then run “rename-hostname.ps1”. If the script does not exit with a 0 exit code, the PowerShell script rename-hostname.ps1 does not run. This is the design of the onlyif Puppet parameter.

Related: Setting Up Your First Puppet Master Server

Here are my two PowerShell scripts:

1. hostname-exists.ps1 script

if ($env:computername -ne ‘test-1’) {

   write-output 'Change hostname'

   exit 0


else {

   write-output 'hostname is correct'

   exit 1



Comments are closed.