Oddity with not_ifs on Windows


#1

I’m noticing a really odd behavior with not_if statements on Windows and I was curious if anyone else had run into a similar situation. I’m trying to set powershell execution policy to unrestricted with Chef using the following resources:

execute ‘set 64bit powershell execution to unrestricted’ do
command '%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force’
action :run
not_if { %SystemRoot%\\system32\\WindowsPowerShell\\v1.0\\powershell.exe Get-ExecutionPolicy.include?(‘Unrestricted’) }
end

execute ‘set 32bit powershell execution to unrestricted’ do
command '%SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force’
action :run
not_if { %SystemRoot%\\syswow64\\WindowsPowerShell\\v1.0\\powershell.exe Get-ExecutionPolicy.include?(‘Unrestricted’) }
end

The trouble is the resources are always skipped. If I run the following from cmd as the Administrator I get back ‘restricted’ as expected:
%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe Get-ExecutionPolicy
Restricted

If I fire up IRB I get a completely different answer:

irb(main):019:0> %SystemRoot%\\system32\\WindowsPowerShell\\v1.0\\powershell.exe Get-ExecutionPolicy
=> "Unrestricted\n”

I noticed that if I echo the architecture in IRB I get 32bit, while I get 64bit back from the command prompt. It seems like I should still back the correct answer since I’m trying to execute against 32bit powershell, but clearly something is wrong here. Any advice?

-Tim


The information in this message may be confidential. It is intended solely
for
the addressee(s). If you are not the intended recipient, any disclosure,
copying or distribution of the message, or any action or omission taken by
you
in reliance on it, is prohibited and may be unlawful. Please immediately
contact the sender if you have received this message in error.


#2

I see two issues below:

  1.   You might try including –scope in your get-executionpolicy – I
    

remember hitting issues without that, and all my cookbooks include this for
a very similar scenario

  1.   I believe the not_if for your 64-bit expression will always run a
    

32-bit cmd.exe (and powershell.exe) and thus give you a 32-bit answer. You
can try using “sysnative” instead of ‘system32’ to get around this
(sysnative is doc’d on msdn).

However, I can also think of some other ways to do this – if you’re using
Chef 11.12 or later, you can use the guard_interpreter attribute (
http://docs.opscode.com/resource_common.html) to write a simpler
expression – this one sets 64-bit execution policy to remotesigned:

powershell_script “set execution policy” do

guard_interpreter :powershell_script

code “set-executionpolicy -scope localmachine remotesigned”

not_if “(get-executionpolicy -scope localmachine) -eq ‘remotesigned’”

end

The above would handle it for x64, just add architecture to do it for x86
(aka i386) – the guard inherits the i386-ness:

powershell_script “set execution policy” do

guard_interpreter :powershell_script

architecture :i386

code “set-executionpolicy -scope localmachine remotesigned”

not_if “(get-executionpolicy -scope localmachine) -eq ‘remotesigned’”

end

You can do similar things prior to 11.12 and use the architecture
attribute, but without guard_interpreter, you have to write more
complicated expressions for the guard since the guard will always execute a
64-bit process. Guard_interpreter also does some magic to make boolean
expressions in PowerShell into process exit codes that work as guards,
similar to what you can do with the test ( aka [] ) in Unix shells with
guards (described in convert_boolean_return attribute in
http://docs.opscode.com/release_notes.html).

-Adam

From: Tim Smith [mailto:tsmith@llnw.com]
Sent: Friday, May 30, 2014 5:21 PM
To: chef@lists.opscode.com
Subject: [chef] Oddity with not_ifs on Windows

I’m noticing a really odd behavior with not_if statements on Windows and I
was curious if anyone else had run into a similar situation. I’m trying to
set powershell execution policy to unrestricted with Chef using the
following resources:

execute ‘set 64bit powershell execution to unrestricted’ do

command ‘%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe
Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force’

action :run

not_if { %SystemRoot%\\system32\\WindowsPowerShell\\v1.0\\powershell.exe Get-ExecutionPolicy.include?(‘Unrestricted’) }

end

execute ‘set 32bit powershell execution to unrestricted’ do

command ‘%SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe
Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force’

action :run

not_if { %SystemRoot%\\syswow64\\WindowsPowerShell\\v1.0\\powershell.exe Get-ExecutionPolicy.include?(‘Unrestricted’) }

end

The trouble is the resources are always skipped. If I run the following
from cmd as the Administrator I get back ‘restricted’ as expected:

%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe
Get-ExecutionPolicy

Restricted

If I fire up IRB I get a completely different answer:

irb(main):019:0>
%SystemRoot%\\system32\\WindowsPowerShell\\v1.0\\powershell.exe Get-ExecutionPolicy

=> "Unrestricted\n”

I noticed that if I echo the architecture in IRB I get 32bit, while I get
64bit back from the command prompt. It seems like I should still back the
correct answer since I’m trying to execute against 32bit powershell, but
clearly something is wrong here. Any advice?

-Tim

The information in this message may be confidential. It is intended solely
for

the addressee(s). If you are not the intended recipient, any disclosure,

copying or distribution of the message, or any action or omission taken by
you

in reliance on it, is prohibited and may be unlawful. Please immediately

contact the sender if you have received this message in error.


#3

Thanks for the info Adam. In this case I ended up just making the change via the registry vs. shelling out, but I’m sure I’ll hit a similar issue soon. I think guard_interpreter is the key. I had forgotten that had been added. Very handy feature.

-Tim

On May 31, 2014, at 7:47 AM, Adam Edwards adamed@getchef.com wrote:

I see two issues below:

  1.   You might try including –scope in your get-executionpolicy – I remember hitting issues without that, and all my cookbooks include this for a very similar scenario
    
  2.   I believe the not_if for your 64-bit expression will always run a 32-bit cmd.exe (and powershell.exe) and thus give you a 32-bit answer. You can try using “sysnative” instead of ‘system32’ to get around this (sysnative is doc’d on msdn).
    

However, I can also think of some other ways to do this – if you’re using Chef 11.12 or later, you can use the guard_interpreter attribute (http://docs.opscode.com/resource_common.html) to write a simpler expression – this one sets 64-bit execution policy to remotesigned:

powershell_script “set execution policy” do
guard_interpreter :powershell_script
code "set-executionpolicy -scope localmachine remotesigned"
not_if "(get-executionpolicy -scope localmachine) -eq ‘remotesigned’"
end

The above would handle it for x64, just add architecture to do it for x86 (aka i386) – the guard inherits the i386-ness:

powershell_script “set execution policy” do
guard_interpreter :powershell_script
architecture :i386
code "set-executionpolicy -scope localmachine remotesigned"
not_if "(get-executionpolicy -scope localmachine) -eq ‘remotesigned’"
end

You can do similar things prior to 11.12 and use the architecture attribute, but without guard_interpreter, you have to write more complicated expressions for the guard since the guard will always execute a 64-bit process. Guard_interpreter also does some magic to make boolean expressions in PowerShell into process exit codes that work as guards, similar to what you can do with the test ( aka [] ) in Unix shells with guards (described in convert_boolean_return attribute inhttp://docs.opscode.com/release_notes.html).

-Adam

From: Tim Smith [mailto:tsmith@llnw.com]
Sent: Friday, May 30, 2014 5:21 PM
To: chef@lists.opscode.com
Subject: [chef] Oddity with not_ifs on Windows

I’m noticing a really odd behavior with not_if statements on Windows and I was curious if anyone else had run into a similar situation. I’m trying to set powershell execution policy to unrestricted with Chef using the following resources:

execute ‘set 64bit powershell execution to unrestricted’ do
command '%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force’
action :run
not_if { %SystemRoot%\\system32\\WindowsPowerShell\\v1.0\\powershell.exe Get-ExecutionPolicy.include?(‘Unrestricted’) }
end

execute ‘set 32bit powershell execution to unrestricted’ do
command '%SystemRoot%\syswow64\WindowsPowerShell\v1.0\powershell.exe Set-ExecutionPolicy Unrestricted -Scope LocalMachine -Force’
action :run
not_if { %SystemRoot%\\syswow64\\WindowsPowerShell\\v1.0\\powershell.exe Get-ExecutionPolicy.include?(‘Unrestricted’) }
end

The trouble is the resources are always skipped. If I run the following from cmd as the Administrator I get back ‘restricted’ as expected:
%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe Get-ExecutionPolicy
Restricted

If I fire up IRB I get a completely different answer:

irb(main):019:0> %SystemRoot%\\system32\\WindowsPowerShell\\v1.0\\powershell.exe Get-ExecutionPolicy
=> "Unrestricted\n”

I noticed that if I echo the architecture in IRB I get 32bit, while I get 64bit back from the command prompt. It seems like I should still back the correct answer since I’m trying to execute against 32bit powershell, but clearly something is wrong here. Any advice?

-Tim

The information in this message may be confidential. It is intended solely for
the addressee(s). If you are not the intended recipient, any disclosure,
copying or distribution of the message, or any action or omission taken by you
in reliance on it, is prohibited and may be unlawful. Please immediately
contact the sender if you have received this message in error.


The information in this message may be confidential. It is intended solely
for
the addressee(s). If you are not the intended recipient, any disclosure,
copying or distribution of the message, or any action or omission taken by
you
in reliance on it, is prohibited and may be unlawful. Please immediately
contact the sender if you have received this message in error.