Running PowerShell Scripts in Puppet

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


2. rename-hostname.ps1 script:

Rename-Computer -NewName puppetagent-win -Force -Confirm:$false

On my node “test-1” I have changed the hostname to something other than “test-1” so that when I apply the Puppet configuration, it will change the hostname:

C:\Users\Administrator>puppet agent --test --certname test-1

Info: Retrieving pluginfacts                                                                        

Info: Retrieving plugin                                                                             

Info: Loading facts                                                                                  

Info: Caching catalog for test-1

Info: Applying configuration version '1530211488'                                                   

Notice: /Stage[main]/Rename_hostname/Exec[win-hostname]/returns: WARNING: The ch                     

anges will take effect after you restart the computer what.                                         

Notice: /Stage[main]/Rename_hostname/Exec[win-hostname]/returns: executed succes                    


Notice: Finished catalog run in 2.87 seconds  

 If I apply this configuration again, it will not attempt to make any changes since the hostname is now set to ”test-1”:

C:\Users\Administrator>puppet agent --test –certname=test-1

Info: Retrieving pluginfacts                                                                        

Info: Retrieving plugin                                                                              

Info: Loading facts                                                                                 

Info: Caching catalog for test-1

Info: Applying configuration version '1530213484'                                                   

Notice: Finished catalog run in 2.62 seconds


One of the beautiful aspects of using Puppet is the simplicity in writing configurations instead of scripts, but there are use cases where it is easier or faster to use PowerShell still, especially for users new to Puppet but experienced in PowerShell. Puppet has made a great push to add Windows functionality. Providing a way for Windows users to write PowerShell scripts in their Puppet manifests is a great addition to its tool.


Related Posts

Comments are disabled in preview mode.
Loading animation