Using Powershell in facters yields no data

180 views
Skip to first unread message

Brian Morris

unread,
Sep 18, 2014, 3:11:31 PM9/18/14
to puppet...@googlegroups.com
Hello all,

I have been banging my head against this one for a couple of days. I am trying to use Powershell to comb the Windows registry for installed applications, such as VMware Tools, to create a custom facter. If I run this code from a PS prompt it works, and returns the expected data:

PS C:\> Get-ChildItem hklm:\software\microsoft\windows\currentversion\uninstall | ForEach-Object {Get-ItemProperty $_.ps
path} | Where-Object {$_.DisplayName -eq "VMware Tools"} | ForEach-Object -process {$_.DisplayVersion }
9.4.6.1770165

However, running the same thing through Puppet as a facter yields zero data:

----------
Facter.add("vmtools_version") do
confine :osfamily => "Windows"
  setcode do
    Facter::Util::Resolution.exec('C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command "& {Get-ChildItem hklm:\software\microsoft\windows\currentversion\uninstall | ForEach-Object {Get-ItemProperty $_.pspath} | Where-Object {$_.DisplayName -eq \"VMware Tools\"} | ForEach-Object -process {$_.DisplayVersion } } "')
end
end
----------

The left side shows up in the facters as "vmtools_version", but the right side is always empty. I have tried using the  GetItem module instead, and tried various combinations of the "-Command" switch, removed the "For-Each" handler to see if would spit out a huge block of text, and even tried wrapping the whole thing in a "try & catch" to see if any error states are generated, but have never gotten any right side output at all.

Does anyone have an idea that might make this work?

Brian Morris

unread,
Sep 18, 2014, 3:24:28 PM9/18/14
to puppet...@googlegroups.com
I almost forgot. I have also tried setting the exec line up as a variable, and returning that variable, to no effect.

Rob Reynolds

unread,
Sep 18, 2014, 4:55:26 PM9/18/14
to puppet...@googlegroups.com
On Thu, Sep 18, 2014 at 2:11 PM, Brian Morris <nomadic...@gmail.com> wrote:
Hello all,

I have been banging my head against this one for a couple of days. I am trying to use Powershell to comb the Windows registry for installed applications, such as VMware Tools, to create a custom facter. If I run this code from a PS prompt it works, and returns the expected data:

PS C:\> Get-ChildItem hklm:\software\microsoft\windows\currentversion\uninstall | ForEach-Object {Get-ItemProperty $_.ps
path} | Where-Object {$_.DisplayName -eq "VMware Tools"} | ForEach-Object -process {$_.DisplayVersion }
9.4.6.1770165


This is running in a 64bit process.

 
However, running the same thing through Puppet as a facter yields zero data:

----------
Facter.add("vmtools_version") do
confine :osfamily => "Windows"
  setcode do
    Facter::Util::Resolution.exec('C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command "& {Get-ChildItem hklm:\software\microsoft\windows\currentversion\uninstall | ForEach-Object {Get-ItemProperty $_.pspath} | Where-Object {$_.DisplayName -eq \"VMware Tools\"} | ForEach-Object -process {$_.DisplayVersion } } "')
end
end
----------

This is in a 32bit process unless you are on the newest 3.7.0 or 3.7.1 x64 builds of Puppet. You are hitting registry redirection.  Be sure to checkout Common Gotchas[1] especially for how to turn off registry redirection in a 32 bit process.




More detail:

When a 32 bit process calls the registry and is subject to redirection, it only sees the Wow6432Node under software. Check out that link above, it explains quite a bit in more detail.

 

The left side shows up in the facters as "vmtools_version", but the right side is always empty. I have tried using the  GetItem module instead, and tried various combinations of the "-Command" switch, removed the "For-Each" handler to see if would spit out a huge block of text, and even tried wrapping the whole thing in a "try & catch" to see if any error states are generated, but have never gotten any right side output at all.

Does anyone have an idea that might make this work?

--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/a76b897f-9f1f-4e82-ab18-344ae9a6e2c7%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Rob Reynolds
Developer, Puppet Labs

Join us at PuppetConf 2014September 20-24 in San Francisco

Rob Reynolds

unread,
Sep 18, 2014, 4:59:59 PM9/18/14
to puppet...@googlegroups.com
On Thu, Sep 18, 2014 at 3:54 PM, Rob Reynolds <r...@puppetlabs.com> wrote:


On Thu, Sep 18, 2014 at 2:11 PM, Brian Morris <nomadic...@gmail.com> wrote:
Hello all,

I have been banging my head against this one for a couple of days. I am trying to use Powershell to comb the Windows registry for installed applications, such as VMware Tools, to create a custom facter. If I run this code from a PS prompt it works, and returns the expected data:

PS C:\> Get-ChildItem hklm:\software\microsoft\windows\currentversion\uninstall | ForEach-Object {Get-ItemProperty $_.ps
path} | Where-Object {$_.DisplayName -eq "VMware Tools"} | ForEach-Object -process {$_.DisplayVersion }
9.4.6.1770165


This is running in a 64bit process.

 
However, running the same thing through Puppet as a facter yields zero data:

----------
Facter.add("vmtools_version") do
confine :osfamily => "Windows"
  setcode do
    Facter::Util::Resolution.exec('C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -Command

C:\Windows\System32 is also subject to File system redirection, which is also talked about in that post. Likely fixing only this as sysnative will return the right data because PowerShell will run in 64bit mode. But I would explore the ruby only way to speed up the fact.
 
"& {Get-ChildItem hklm:\software\microsoft\windows\currentversion\uninstall | ForEach-Object {Get-ItemProperty $_.pspath} | Where-Object {$_.DisplayName -eq \"VMware Tools\"} | ForEach-Object -process {$_.DisplayVersion } } "')
end
end
----------

This is in a 32bit process unless you are on the newest 3.7.0 or 3.7.1 x64 builds of Puppet. You are hitting registry redirection.  Be sure to checkout Common Gotchas[1] especially for how to turn off registry redirection in a 32 bit process.




More detail:

When a 32 bit process calls the registry and is subject to redirection, it only sees the Wow6432Node under software. Check out that link above, it explains quite a bit in more detail.

 

The left side shows up in the facters as "vmtools_version", but the right side is always empty. I have tried using the  GetItem module instead, and tried various combinations of the "-Command" switch, removed the "For-Each" handler to see if would spit out a huge block of text, and even tried wrapping the whole thing in a "try & catch" to see if any error states are generated, but have never gotten any right side output at all.

Does anyone have an idea that might make this work?

--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/a76b897f-9f1f-4e82-ab18-344ae9a6e2c7%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--
Rob Reynolds
Developer, Puppet Labs

Join us at PuppetConf 2014September 20-24 in San Francisco

Brian Morris

unread,
Sep 18, 2014, 5:17:58 PM9/18/14
to puppet...@googlegroups.com
Holy cow, Rob... that was great info! All I did was change "System32" to "sysnative", and it worked on the first try. All of that frustration boiled down to one part of one path...

Thank you for the link, too. It helps to understand why this happens. Cheers to you!

--
You received this message because you are subscribed to a topic in the Google Groups "Puppet Users" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/puppet-users/8m8mt4G_OKU/unsubscribe.
To unsubscribe from this group and all its topics, send an email to puppet-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/CAMJiBK7GNgWponY1y74bpQ5x_YPbRcPeK3%3DmsyBc-W2txDfQaQ%40mail.gmail.com.

Josh Cooper

unread,
Sep 18, 2014, 7:24:35 PM9/18/14
to puppet...@googlegroups.com
On Thu, Sep 18, 2014 at 2:17 PM, Brian Morris <nomadic...@gmail.com> wrote:
Holy cow, Rob... that was great info! All I did was change "System32" to "sysnative", and it worked on the first try. All of that frustration boiled down to one part of one path...

Thank you for the link, too. It helps to understand why this happens. Cheers to you!

I filed https://tickets.puppetlabs.com/browse/FACT-710. as facter should use 64-bit powershell when available.


For more options, visit https://groups.google.com/d/optout.



--
Josh Cooper

Brian Morris

unread,
Sep 18, 2014, 8:25:56 PM9/18/14
to puppet...@googlegroups.com
Thank you for that, Josh, as well as for creating the Powershell module for Puppet. I hope to meet both you and Rob at PuppetConf next week.

Reply all
Reply to author
Forward
0 new messages