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
|
#
# Copyright:: 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.
#
require_relative "../resource"
class Chef
class Resource
class WindowsDefenderExclusion < Chef::Resource
provides :windows_defender_exclusion
description "Use the **windows_defender_exclusion** resource to exclude paths, processes, or file types from Windows Defender realtime protection scanning."
introduced "17.3"
examples <<~DOC
**Add excluded items to Windows Defender scans**:
```ruby
windows_defender_exclusion 'Add to things to be excluded from scanning' do
paths 'c:\\foo\\bar, d:\\bar\\baz'
extensions 'png, foo, ppt, doc'
process_paths 'c:\\windows\\system32'
action :add
end
```
**Remove excluded items from Windows Defender scans**:
```ruby
windows_defender_exclusion 'Remove things from the list to be excluded' do
process_paths 'c:\\windows\\system32'
action :remove
end
```
DOC
unified_mode true
property :paths, [String, Array], default: [],
coerce: proc { |x| to_consistent_path_array(x) },
description: "File or directory paths to exclude from scanning."
property :extensions, [String, Array], default: [],
coerce: proc { |x| to_consistent_path_array(x) },
description: "File extensions to exclude from scanning."
property :process_paths, [String, Array], default: [],
coerce: proc { |x| to_consistent_path_array(x) },
description: "Paths to executables to exclude from scanning."
def to_consistent_path_array(x)
fixed = x.dup || []
fixed = fixed.split(/\s*,\s*/) if fixed.is_a?(String)
fixed.map!(&:downcase)
fixed.map! { |v| v.gsub(%r{/}, "\\") }
fixed
end
load_current_value do |new_resource|
Chef::Log.debug("Running 'Get-MpPreference | Select-Object ExclusionExtension,ExclusionPath,ExclusionProcess' to get Windows Defender State")
values = powershell_exec!("Get-MPpreference | Select-Object ExclusionExtension,ExclusionPath,ExclusionProcess").result
values.transform_values! { |x| Array(x) }
paths new_resource.paths & values["ExclusionPath"]
extensions new_resource.extensions & values["ExclusionExtension"]
process_paths new_resource.process_paths & values["ExclusionProcess"]
end
action :add do
converge_if_changed do
powershell_exec!(add_cmd)
end
end
action :remove do
converge_if_changed do
powershell_exec!(remove_cmd)
end
end
action_class do
MAPPING = {
paths: "ExclusionPath",
extensions: "ExclusionExtension",
process_paths: "ExclusionProcess",
}.freeze
def add_cmd
cmd = "Add-MpPreference -Force"
MAPPING.each do |prop, flag|
to_add = new_resource.send(prop) - current_resource.send(prop)
cmd << " -#{flag} #{to_add.join(",")}" unless to_add.empty?
end
cmd
end
def remove_cmd
cmd = "Remove-MpPreference -Force"
MAPPING.each do |prop, flag|
to_add = new_resource.send(prop) & current_resource.send(prop)
cmd << " -#{flag} #{to_add.join(",")}" unless to_add.empty?
end
cmd
end
end
end
end
end
|