Powershell – Puppet not running PowerShell script on Windows 2008 server

powershellpuppetwindows-server-2008

The Puppet agent on my Windows VMs is not executing PowerShell scripts. I have tested it with a very simple script as well. The script is stored on the C drive as test.ps1. Its contents are as follows:

"$(Get-Date -format F)" | Out-File C:\z.txt -Encoding ASCII

When I run this as ./test.ps1 from the PowerShell console manually, it works fine and the file z.txt is created. But for some reason the Puppet agent doesn't run this. The contents of my site.pp are:

exec { "Run Script":
        command => 'C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -Executionpolicy Unrestricted -File c:/test.ps1',
        logoutput => true,
        refreshonly => true,
}

And the output of "puppet agent -t" from the VM itself is:

C:\Users\Administrator>puppet agent -t
Info: Retrieving pluginfacts
Warning: Copying owner/mode/group from the source file on Windows is deprecated;
 use source_permissions => ignore.
   (at C:/Program Files (x86)/Puppet Labs/Puppet/puppet/lib/puppet/type/file/sou
rce.rb:120:in `each')
Info: Retrieving plugin
Info: Caching catalog for f9881998-7fdf-4e96-a784-d9690fcd5495
Info: Applying configuration version '1410182959'
Notice: Finished catalog run in 0.42 seconds

So it seems to me that there is no error anywhere, but still the PowerShell script doesn't run. What am I doing wrong?

Best Answer

A Puppet resource of the exec type does not synchronize of its own accord. It only "refreshes" itself, meaning that the command is run only if the resource receives a signal from another resource that successfully changes from an unsynchronized state.

file { 'C:\not-yet-existent':
    ensure => 'file',
    notify => Exec['Run Script'],
}

This is not a very good mode of operation, because if your script fails for any reason, the Puppet will likely not know to create a new event, because the file resource now is in sync.

It is better to not use refreshonly => true, and instead give Puppet a hint to find out wether to run the command or not. The exec type can do this via its onlyif and unless parameters, and the often useful (as in your case) creates parameter.

exec { "Run Script":
    command   => 'C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -Executionpolicy Unrestricted -File c:/test.ps1',
    logoutput => true,
    creates   => 'C:\z.txt',
}
Related Topic