1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
|
#
# Author:: Greg Zapp (<greg.zapp@gmail.com>)
#
# Copyright:: 2015-2018, Chef Software, Inc
#
# 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.
# See the License for the specific language governing permissions and
# limitations under the License.
#
class Chef
class Resource
class WindowsFeaturePowershell < Chef::Resource
resource_name :windows_feature_powershell
provides :windows_feature_powershell
description "Use the windows_feature_powershell resource to add, remove or"\
" delete Windows features and roles using PowerShell. This resource"\
" offers significant speed benefits over the windows_feature_dism resource,"\
" but requires installing the Remote Server Administration Tools on"\
" non-server releases of Windows"
introduced "14.0"
property :feature_name, [Array, String],
description: "The name of the feature/role(s) to install if it differs from the resource name.",
coerce: proc { |x| Array(x) },
name_property: true
property :source, String,
description: "Use a local repository for the feature install."
property :all, [true, false],
description: "Install all sub features. This is equivalent to using the"\
" -InstallAllSubFeatures switch with Add-WindowsFeature.",
default: false
property :timeout, Integer,
description: "Specifies a timeout (in seconds) for feature install.",
default: 600
property :management_tools, [true, false],
description: "",
default: false
include Chef::Mixin::PowershellOut
action :install do
description "Install a Windows role/feature using PowerShell"
Chef::Log.warn("Requested feature #{new_resource.feature_name.join(',')} is not available on this system.") unless available?
unless !available? || installed?
converge_by("install Windows feature#{'s' if new_resource.feature_name.count > 1} #{new_resource.feature_name.join(',')}") do
addsource = new_resource.source ? "-Source \"#{new_resource.source}\"" : ""
addall = new_resource.all ? "-IncludeAllSubFeature" : ""
addmanagementtools = new_resource.management_tools ? "-IncludeManagementTools" : ""
cmd = if node["os_version"].to_f < 6.2
powershell_out!("#{install_feature_cmdlet} #{new_resource.feature_name.join(',')} #{addall}", timeout: new_resource.timeout)
else
powershell_out!("#{install_feature_cmdlet} #{new_resource.feature_name.join(',')} #{addsource} #{addall} #{addmanagementtools}", timeout: new_resource.timeout)
end
Chef::Log.info(cmd.stdout)
end
end
end
action :remove do
description "Remove a Windows role/feature using PowerShell"
if installed?
converge_by("remove Windows feature#{'s' if new_resource.feature_name.count > 1} #{new_resource.feature_name.join(',')}") do
cmd = powershell_out!("#{remove_feature_cmdlet} #{new_resource.feature_name.join(',')}", timeout: new_resource.timeout)
Chef::Log.info(cmd.stdout)
end
end
end
action :delete do
description "Remove a Windows role/feature from the image using Powershell"
if available?
converge_by("delete Windows feature#{'s' if new_resource.feature_name.count > 1} #{new_resource.feature_name.join(',')} from the image") do
cmd = powershell_out!("Uninstall-WindowsFeature #{new_resource.feature_name.join(',')} -Remove", timeout: new_resource.timeout)
Chef::Log.info(cmd.stdout)
end
end
end
action_class do
# @todo remove this when we're ready to drop windows 8/2012
def install_feature_cmdlet
node["os_version"].to_f < 6.2 ? "Import-Module ServerManager; Add-WindowsFeature" : "Install-WindowsFeature"
end
# @todo remove this when we're ready to drop windows 8/2012
def remove_feature_cmdlet
node["os_version"].to_f < 6.2 ? "Import-Module ServerManager; Remove-WindowsFeature" : "Uninstall-WindowsFeature"
end
def installed?
@installed ||= begin
# @todo remove this when we're ready to drop windows 8/2012
cmd = if node["os_version"].to_f < 6.2
powershell_out("Import-Module ServerManager; @(Get-WindowsFeature #{new_resource.feature_name.join(',')} | ?{$_.Installed -ne $TRUE}).count", timeout: new_resource.timeout)
else
powershell_out("@(Get-WindowsFeature #{new_resource.feature_name.join(',')} | ?{$_.InstallState -ne \'Installed\'}).count", timeout: new_resource.timeout)
end
cmd.stderr.empty? && cmd.stdout.chomp.to_i == 0
end
end
def available?
@available ||= begin
# @todo remove this when we're ready to drop windows 8/2012
cmd = if node["os_version"].to_f < 6.2
powershell_out("Import-Module ServerManager; @(Get-WindowsFeature #{new_resource.feature_name.join(',')}).count", timeout: new_resource.timeout)
else
powershell_out("@(Get-WindowsFeature #{new_resource.feature_name.join(',')} | ?{$_.InstallState -ne \'Removed\'}).count", timeout: new_resource.timeout)
end
cmd.stderr.empty? && cmd.stdout.chomp.to_i > 0
end
end
end
end
end
end
|