Skip to content

Commit

Permalink
Merge branch 'powershell-cb-updates'
Browse files Browse the repository at this point in the history
  • Loading branch information
schisamo committed Oct 28, 2011
2 parents 2cc692e + dfa7ba6 commit c3c81f6
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 115 deletions.
23 changes: 17 additions & 6 deletions powershell/README.md
Expand Up @@ -21,7 +21,7 @@ Platform
--------

* Windows XP
* Windows Server 2003
* Windows Server 2003 (R1, R2)
* Windows Vista
* Windows 7
* Windows Server 2008 (R1, R2)
Expand Down Expand Up @@ -53,6 +53,17 @@ Execute a script using the powershell interpreter (much like the script resource

### Examples

# change the computer's hostname
powershell "rename hostname" do
code <<-EOH
$computer_name = Get-Content env:computername
$new_name = 'test-hostname'
$sysInfo = Get-WmiObject -Class Win32_ComputerSystem
$sysInfo.Rename($new_name)
EOH
end


# write out to an interpolated path
powershell "write-to-interpolated-path" do
code <<-EOH
Expand All @@ -61,7 +72,7 @@ Execute a script using the powershell interpreter (much like the script resource
$stream.close()
EOH
end

# use the change working directory attribute
powershell "cwd-then-write" do
cwd Chef::Config[:file_cache_path]
Expand All @@ -76,7 +87,7 @@ Execute a script using the powershell interpreter (much like the script resource
$stream.close()
EOH
end

# cwd to a winodws env variable
powershell "cwd-to-win-env-var" do
cwd "%TEMP%"
Expand All @@ -86,7 +97,7 @@ Execute a script using the powershell interpreter (much like the script resource
$stream.close()
EOH
end

# pass an env var to script
powershell "read-env-var" do
cwd Chef::Config[:file_cache_path]
Expand All @@ -104,14 +115,14 @@ Usage
default
-------

Include the default recipe in a run list, to ensure PowerShell 2.0 is installed.
Include the default recipe in a run list, to ensure PowerShell 2.0 is installed.

On the following versions of Windows the PowerShell 2.0 package will be downloaded from Microsoft and installed:

* Windows XP
* Windows Server 2003
* Windows Server 2008 R1
* Windows Vista
* Windows Vista

On the following versions of Windows, PowerShell 2.0 is present and must just be enabled:

Expand Down
25 changes: 24 additions & 1 deletion powershell/attributes/default.rb
Expand Up @@ -18,4 +18,27 @@
# limitations under the License.
#

default['powershell']['version'] = 2.0
case platform_version.to_f
when 5.1 # Windows XP
default['powershell']['url'] = "http://download.microsoft.com/download/E/C/E/ECE99583-2003-455D-B681-68DB610B44A4/WindowsXP-KB968930-x86-ENG.exe"
default['powershell']['checksum'] = "0ef2a9b4f500b66f418660e54e18f5f525ed8d0a4d7c50ce01c5d1d39767c00c"

when 5.2 # Windows Server 2003
if kernel.machine =~ /x86_64/
default['powershell']['url'] = "http://download.microsoft.com/download/B/D/9/BD9BB1FF-6609-4B10-9334-6D0C58066AA7/WindowsServer2003-KB968930-x64-ENG.exe"
default['powershell']['checksum'] = "9f5d24517f860837daaac062e5bf7e6978ceb94e4e9e8567798df6777b56e4c8"
else
default['powershell']['url'] = "http://download.microsoft.com/download/1/1/7/117FB25C-BB2D-41E1-B01E-0FEB0BC72C30/WindowsServer2003-KB968930-x86-ENG.exe"
default['powershell']['checksum'] = "71b180e0affd9e005d7151a656414176e727b6dc80a9350e7b2b23bcac0cc98a"
end

when 6.0 # Windows Server 2008 & Windows Vista
if kernel.machine =~ /x86_64/
default['powershell']['url'] = "http://download.microsoft.com/download/2/8/6/28686477-3242-4E96-9009-30B16BED89AF/Windows6.0-KB968930-x64.msu"
default['powershell']['checksum'] = "19bd295d354538873afccc7c9a090ae6ba87beb968b20e8280bf5312826de9e3"
else
default['powershell']['url'] = "http://download.microsoft.com/download/F/9/E/F9EF6ACB-2BA8-4845-9C10-85FC4A69B207/Windows6.0-KB968930-x86.msu"
default['powershell']['checksum'] = "1c1fee616014da6e52aa7a117b9bcc3a79ac3d838d686b8afe4f723630225fa2"
end

end
41 changes: 19 additions & 22 deletions powershell/libraries/core.rb
Expand Up @@ -6,9 +6,9 @@
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#
# http://www.apache.org/licenses/LICENSE-2.0
#
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Expand All @@ -19,8 +19,8 @@
require 'chef/resource/execute'
require 'chef/resource/script'

# PLEASE NOTE - This is not a good example of shipping a Resource/Provider
# with a cookbook. Please check the Chef Wiki for more traditional DSL driven
# PLEASE NOTE - This is not a good example of shipping a Resource/Provider
# with a cookbook. Please check the Chef Wiki for more traditional DSL driven
# LWRPs. This 'heavyweight' resource will eventually be moved into Core Chef.

class Chef
Expand All @@ -31,22 +31,20 @@ def initialize(name, run_context=nil)
super
@resource_name = :powershell
@provider = Chef::Provider::PowershellScript
@interpreter = locate_powershell_interperter
@returns = [0,42] # successful commands return exit code 42
end

private
def locate_powershell_interperter
# force 64-bit powershell from 32-bit ruby process
if ::File.exist?("c:/windows/sysnative/WindowsPowershell/v1.0/powershell.exe")
"c:/windows/sysnative/WindowsPowershell/v1.0/powershell.exe"
elsif ::File.exist?("c:/windows/system32/WindowsPowershell/v1.0/powershell.exe")
"c:/windows/system32/WindowsPowershell/v1.0/powershell.exe"
else
"powershell.exe"
end
def interpreter
# force 64-bit powershell from 32-bit ruby process
if ::File.exist?("#{ENV['WINDIR']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe")
"#{ENV['WINDIR']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe"
elsif ::File.exist?("#{ENV['WINDIR']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe")
"#{ENV['WINDIR']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe"
else
"powershell.exe"
end
end
end
end
end

class Provider
Expand All @@ -56,11 +54,10 @@ def action_run
script_file.puts(@new_resource.code)
script_file.close
set_owner_and_group

# always set the ExecutionPolicy flag
# see http://technet.microsoft.com/en-us/library/ee176961.aspx
@new_resource.flags("#{@new_resource.flags} -ExecutionPolicy RemoteSigned -Command".strip)

# cwd hax...shell_out on windows needs to support proper 'cwd'
# follow CHEF-2357 for more
cwd = @new_resource.cwd ? "cd #{@new_resource.cwd} & " : ""
Expand All @@ -87,7 +84,7 @@ def unlink_script_file

private
# take advantage of PowerShell scriptblocks
# to pass scoped environment variables to the
# to pass scoped environment variables to the
# command
def build_powershell_scriptblock
# environment var hax...shell_out on windows needs to support proper 'environment'
Expand All @@ -99,9 +96,9 @@ def build_powershell_scriptblock
end
"& { #{env_string}#{ensure_windows_friendly_path(script_file.path)} }"
end
end
end
end

module Mixin
module Language
def ensure_windows_friendly_path(path)
Expand All @@ -114,4 +111,4 @@ def ensure_windows_friendly_path(path)
end
end
end
Chef::Platform.platforms[:default].merge! :powershell => Chef::Provider::PowershellScript
Chef::Platform.platforms[:default].merge! :powershell => Chef::Provider::PowershellScript
20 changes: 17 additions & 3 deletions powershell/libraries/helper.rb
Expand Up @@ -24,10 +24,24 @@ module Powershell
module Helper
include Chef::Mixin::ShellOut

def installed?
cmd = shell_out('powershell.exe -Command "& {Get-Host}"')
cmd.stderr.empty? && (cmd.stdout =~ /Version\s*:\s*2.0/i)
def powershell_installed?
begin
cmd = shell_out("#{interpreter} -Command \"& {Get-Host}\"")
cmd.stderr.empty? && (cmd.stdout =~ /Version\s*:\s*2.0/i)
rescue Errno::ENOENT
false
end
end

def interpreter
# force 64-bit powershell from 32-bit ruby process
if ::File.exist?("#{ENV['WINDIR']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe")
"#{ENV['WINDIR']}\\sysnative\\WindowsPowershell\\v1.0\\powershell.exe"
elsif ::File.exist?("#{ENV['WINDIR']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe")
"#{ENV['WINDIR']}\\system32\\WindowsPowershell\\v1.0\\powershell.exe"
else
"powershell.exe"
end
end
end
end
88 changes: 35 additions & 53 deletions powershell/recipes/default.rb
Expand Up @@ -25,69 +25,51 @@

case node['platform']
when "windows"
version = node.platform_version.to_f

case version
when 5.1..6.0

# TODO: move this to a library and create value_for_version_and_arch method
value_for_version_and_arch = {5.1 => { # Windows XP
'i386' => ["http://download.microsoft.com/download/E/C/E/ECE99583-2003-455D-B681-68DB610B44A4/WindowsXP-KB968930-x86-ENG.exe", "0ef2a9b4f500b66f418660e54e18f5f525ed8d0a4d7c50ce01c5d1d39767c00c"]
},
5.2 => { # Windows Server 2003
'i386' => ["http://download.microsoft.com/download/1/1/7/117FB25C-BB2D-41E1-B01E-0FEB0BC72C30/WindowsServer2003-KB968930-x86-ENG.exe", "71b180e0affd9e005d7151a656414176e727b6dc80a9350e7b2b23bcac0cc98a"],
'x86_64' => ["http://download.microsoft.com/download/B/D/9/BD9BB1FF-6609-4B10-9334-6D0C58066AA7/WindowsServer2003-KB968930-x64-ENG.exe", "9f5d24517f860837daaac062e5bf7e6978ceb94e4e9e8567798df6777b56e4c8"]
},
6.0 => { # Windows Server 2008 & Windows Vista
'i386' => ["http://download.microsoft.com/download/F/9/E/F9EF6ACB-2BA8-4845-9C10-85FC4A69B207/Windows6.0-KB968930-x86.msu", "1c1fee616014da6e52aa7a117b9bcc3a79ac3d838d686b8afe4f723630225fa2"],
'x86_64' => ["http://download.microsoft.com/download/2/8/6/28686477-3242-4E96-9009-30B16BED89AF/Windows6.0-KB968930-x64.msu", "19bd295d354538873afccc7c9a090ae6ba87beb968b20e8280bf5312826de9e3"]
}
}

download_url = value_for_version_and_arch[version][node['kernel']['machine']]
base_name = download_url[0].split(/\//)[-1]
unless powershell_installed?
# Windows Server 2008 R2 Core does not come
# with .NET or Powershell 2.0 enabled
if (win_version.windows_server_2008_r2? || win_version.windows_7?) && win_version.server_core?

unless installed?
# start ocsetup MicrosoftWindowsPowerShell
remote_file "#{Chef::Config[:file_cache_path]}/#{base_name}" do
source download_url[0]
checksum download_url[1]
mode "0644"
notifies :run, 'execute[install-powershell-2]', :immediately
windows_feature "NetFx2-ServerCore" do
action :install
end
execute "install-powershell-2" do
command "#{File.join(Chef::Config[:file_cache_path], base_name).gsub!(File::SEPARATOR, File::ALT_SEPARATOR)} /quiet /norestart"
returns [0,1,nil]
action :nothing
notifies :create, 'ruby_block[log-restart-message]', :immediately
windows_feature "MicrosoftWindowsPowerShell" do
action :install
end
ruby_block "log-restart-message" do
block do
Chef::Log.warn("Powershell 2.0 was successfully installed. The node may need to be restarted for changes to take effect.")
end
action :nothing

elsif (win_version.windows_server_2008? || win_version.windows_server_2003_r2? ||
win_version.windows_server_2003? || win_version.windows_xp?)

if node['kernel']['machine'] =~ /x86_64/
dot_net_2_url = "http://download.microsoft.com/download/9/8/6/98610406-c2b7-45a4-bdc3-9db1b1c5f7e2/NetFx20SP1_x64.exe"
dot_net_2_checksum = "1731e53de5f48baae0963677257660df1329549e81c48b4d7db7f7f3f2329aab"
else
dot_net_2_url = "http://download.microsoft.com/download/0/8/c/08c19fa4-4c4f-4ffb-9d6c-150906578c9e/NetFx20SP1_x86.exe"
dot_net_2_checksum = "c36c3a1d074de32d53f371c665243196a7608652a2fc6be9520312d5ce560871"
end
else
Chef::Log.info("PowerShell 2.0 is already installed and enabled on this node.")
end
when 6.1 # Windows Server 2008 R2 & Windows 7
# Windows Server 2008 R2 Core does not come
# with .NET or Powershell 2.0 enabled
unless installed?
# TODO create a .NET cookbook
execute "enable-dot-net" do
command "start /w ocsetup NetFx2-ServerCore"
action :run

windows_package "Microsoft .NET Framework 2.0 Service Pack 1" do
source dot_net_2_url
checksum dot_net_2_checksum
installer_type :custom
options "/quiet /norestart"
action :install
end
execute "enable-powershell-2" do
command "start /w ocsetup MicrosoftWindowsPowerShell"
action :run

windows_package "Windows Management Framework Core" do
source node['powershell']['url']
checksum node['powershell']['checksum']
installer_type :custom
options "/quiet /norestart"
action :install
end

else
Chef::Log.info("PowerShell 2.0 is already enabled on this version of Windows: #{node.platform_version}")
Chef::Log.warn("PowerShell 2.0 is not supported on this version of Windows: #{node.platform_version}")
end
else
Chef::Log.warn("PowerShell 2.0 is not supported on this version of Windows: #{node.platform_version}")
Chef::Log.info("PowerShell 2.0 is already installed/enabled.")
end
else
Chef::Log.warn('PowerShell 2.0 can only be installed on the Windows platform.')
Expand Down
24 changes: 17 additions & 7 deletions windows/libraries/version.rb
Expand Up @@ -65,10 +65,10 @@ class Version
VER_NT_SERVER = 0x0000003
# The operating system is Windows 7, Windows Vista, Windows XP Professional, Windows XP Home Edition, or Windows 2000 Professional.
VER_NT_WORKSTATION = 0x0000001

# GetSystemMetrics
# The build number if the system is Windows Server 2003 R2; otherwise, 0.
SM_SERVERR2 = 89
SM_SERVERR2 = 89

# http://msdn.microsoft.com/en-us/library/ms724358(v=vs.85).aspx
# this is what it sounds like...when kittens die
Expand Down Expand Up @@ -144,9 +144,9 @@ def initialize
"Windows Server 2008 R2" => {:major => 6, :minor => 1, :callable => lambda{ @product_type != VER_NT_WORKSTATION }},
"Windows Server 2008" => {:major => 6, :minor => 0, :callable => lambda{ @product_type != VER_NT_WORKSTATION }},
"Windows Vista" => {:major => 6, :minor => 0, :callable => lambda{ @product_type == VER_NT_WORKSTATION }},
"Windows Server 2003 R2" => {:major => 5, :minor => 2, :callable => lambda{ sm_serverr2 != 0 }},
"Windows Server 2003 R2" => {:major => 5, :minor => 2, :callable => lambda{ Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2) != 0 }},
"Windows Home Server" => {:major => 5, :minor => 2, :callable => lambda{ (@product_suite & VER_SUITE_WH_SERVER) == VER_SUITE_WH_SERVER }},
"Windows Server 2003" => {:major => 5, :minor => 2, :callable => lambda{ sm_serverr2 == 0 }},
"Windows Server 2003" => {:major => 5, :minor => 2, :callable => lambda{ Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2) == 0 }},
"Windows XP" => {:major => 5, :minor => 1},
"Windows 2000" => {:major => 5, :minor => 0}
}
Expand All @@ -173,7 +173,11 @@ def initialize
# Server Type checks
%w{ core full datacenter }.each do |m|
define_method("server_#{m}?") do
!(SKU[@sku][:name] =~ /#{m}/i).nil?
if @sku
!(SKU[@sku][:name] =~ /#{m}/i).nil?
else
false
end
end
end

Expand All @@ -183,12 +187,18 @@ def initialize
def sm_serverr2
@sm_serverr2 ||= Win32API.new('user32', 'GetSystemMetrics', 'I', 'I').call(SM_SERVERR2)
end

# query WMI Win32_OperatingSystem for required OS info
def get_os_info
cols = %w{ Version ProductType OSProductSuite OperatingSystemSKU ServicePackMajorVersion ServicePackMinorVersion }
os_info = WMI::Win32_OperatingSystem.find(:first)
cols.map{|c| os_info.send(c) }
cols.map do |c|
begin
os_info.send(c)
rescue NoMethodError # OperatingSystemSKU doesn't exist in all versions of Windows
nil
end
end
end
end
end

0 comments on commit c3c81f6

Please sign in to comment.