nexpose_sccm 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +14 -0
- data/MIT-LICENSE +21 -0
- data/README.md +212 -0
- data/bin/encrypt_settings.rb +135 -0
- data/bin/nexpose_sccm +69 -0
- data/bin/vuln_ids.csv +7 -0
- data/conf/logging.yml +8 -0
- data/conf/nexpose.yml +8 -0
- data/conf/postgres.yml +8 -0
- data/conf/queries.yml +87 -0
- data/conf/sccm.yml +30 -0
- data/conf/secret.yml +4 -0
- data/lib/nexpose_sccm.rb +294 -0
- data/lib/nexpose_sccm/collection.rb +42 -0
- data/lib/nexpose_sccm/connection.rb +165 -0
- data/lib/nexpose_sccm/data_source.rb +67 -0
- data/lib/nexpose_sccm/deployment_package.rb +37 -0
- data/lib/nexpose_sccm/device.rb +11 -0
- data/lib/nexpose_sccm/helpers/nexpose_helper.rb +65 -0
- data/lib/nexpose_sccm/helpers/pg_helper.rb +26 -0
- data/lib/nexpose_sccm/powershell.rb +111 -0
- data/lib/nexpose_sccm/remediation_item.rb +5 -0
- data/lib/nexpose_sccm/software_update_group.rb +54 -0
- data/lib/nexpose_sccm/utilities/nx_logger.rb +171 -0
- data/lib/nexpose_sccm/utilities/utility_config.rb +59 -0
- data/lib/nexpose_sccm/version.rb +5 -0
- data/lib/nexpose_sccm/wql.rb +35 -0
- data/nexpose_sccm.gemspec +35 -0
- metadata +128 -0
data/bin/vuln_ids.csv
ADDED
data/conf/logging.yml
ADDED
data/conf/nexpose.yml
ADDED
data/conf/postgres.yml
ADDED
data/conf/queries.yml
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
---
|
2
|
+
:queries:
|
3
|
+
:asset_best_solution:
|
4
|
+
#:nsc: Not implemented
|
5
|
+
:dwh: SELECT da.ip_address AS key, da.ip_address, da.host_name, ds.nexpose_id
|
6
|
+
FROM dim_asset_vulnerability_finding_rollup_solution davfrs
|
7
|
+
JOIN dim_asset da ON (da.asset_id = davfrs.asset_id)
|
8
|
+
JOIN dim_solution ds ON (ds.solution_id = davfrs.solution_id)
|
9
|
+
JOIN dim_vulnerability_category dvc ON (dvc.vulnerability_id = davfrs.vulnerability_id)
|
10
|
+
WHERE UPPER(dvc.category_name) = 'MICROSOFT'
|
11
|
+
GROUP BY da.ip_address, da.host_name, ds.nexpose_id
|
12
|
+
:asset_best_solution_by_site:
|
13
|
+
:nsc: SELECT da.ip_address AS key, da.ip_address, da.host_name, ds.nexpose_id, concat('site_id_', dsa.site_id) as site_id
|
14
|
+
FROM dim_asset_vulnerability_best_solution davbs
|
15
|
+
JOIN dim_asset da ON (da.asset_id = davbs.asset_id)
|
16
|
+
JOIN dim_site_asset dsa ON dsa.asset_id = davbs.asset_id AND dsa.site_id = '<site id>'
|
17
|
+
JOIN dim_vulnerability_category dvc ON (dvc.vulnerability_id = davbs.vulnerability_id)
|
18
|
+
AND UPPER(dvc.category_name) = 'MICROSOFT'
|
19
|
+
JOIN dim_solution ds ON (ds.solution_id = davbs.solution_id)
|
20
|
+
GROUP BY da.ip_address, da.host_name, ds.nexpose_id, dsa.site_id
|
21
|
+
:dwh: SELECT da.ip_address AS key, da.ip_address, da.host_name, ds.nexpose_id
|
22
|
+
FROM dim_asset_vulnerability_finding_rollup_solution davfrs
|
23
|
+
JOIN dim_asset da ON (da.asset_id = davfrs.asset_id)
|
24
|
+
JOIN dim_site_asset dsa ON dsa.asset_id = davfrs.asset_id AND dsa.site_id = '<site id>'
|
25
|
+
JOIN dim_vulnerability_category dvc ON (dvc.vulnerability_id = davfrs.vulnerability_id)
|
26
|
+
AND UPPER(dvc.category_name) = 'MICROSOFT'
|
27
|
+
JOIN dim_solution ds ON (ds.solution_id = davfrs.solution_id)
|
28
|
+
GROUP BY da.ip_address, da.host_name, ds.nexpose_id
|
29
|
+
:tag_best_solution:
|
30
|
+
:nsc: WITH tag_assets AS (
|
31
|
+
SELECT da.asset_id, da.ip_address, da.host_name
|
32
|
+
FROM dim_tag_asset dat
|
33
|
+
JOIN dim_tag dt ON (dt.tag_id = dat.tag_id)
|
34
|
+
JOIN dim_asset da ON (da.asset_id = dat.asset_id)
|
35
|
+
WHERE dt.tag_name = '<tag name>'
|
36
|
+
)
|
37
|
+
SELECT ta.ip_address as key, ta.ip_address, ta.host_name, ds.nexpose_id
|
38
|
+
FROM dim_asset_vulnerability_solution davfrs
|
39
|
+
JOIN tag_assets ta ON (ta.asset_id = davfrs.asset_id)
|
40
|
+
JOIN dim_solution ds ON (ds.solution_id = davfrs.solution_id)
|
41
|
+
JOIN dim_vulnerability_category dvc ON (dvc.vulnerability_id = davfrs.vulnerability_id)
|
42
|
+
WHERE UPPER(dvc.category_name) = 'MICROSOFT'
|
43
|
+
GROUP BY ta.ip_address, ta.host_name, ds.nexpose_id
|
44
|
+
:dwh: WITH tag_assets AS (
|
45
|
+
SELECT da.asset_id, da.ip_address, da.host_name
|
46
|
+
FROM dim_asset_tag dat
|
47
|
+
JOIN dim_tag dt ON (dt.tag_id = dat.tag_id)
|
48
|
+
JOIN dim_asset da ON (da.asset_id = dat.asset_id)
|
49
|
+
WHERE dt.name = '<tag name>'
|
50
|
+
)
|
51
|
+
SELECT ta.ip_address as key, ta.ip_address, ta.host_name, ds.nexpose_id
|
52
|
+
FROM dim_asset_vulnerability_finding_rollup_solution davfrs
|
53
|
+
JOIN tag_assets ta ON (ta.asset_id = davfrs.asset_id)
|
54
|
+
JOIN dim_solution ds ON (ds.solution_id = davfrs.solution_id)
|
55
|
+
JOIN dim_vulnerability_category dvc ON (dvc.vulnerability_id = davfrs.vulnerability_id)
|
56
|
+
WHERE UPPER(dvc.category_name) = 'MICROSOFT'
|
57
|
+
GROUP BY ta.ip_address, ta.host_name, ds.nexpose_id
|
58
|
+
:vuln_by_name: #Microsoft CVE-2017-0016: SMBv2/SMBv3 Null Dereference Denial of Service Vulnerability
|
59
|
+
:nsc: SELECT dv.nexpose_id AS key, da.ip_address, da.host_name, ds.nexpose_id
|
60
|
+
FROM dim_asset_vulnerability_best_solution davbs
|
61
|
+
JOIN dim_solution ds ON (ds.solution_id = davbs.solution_id)
|
62
|
+
JOIN dim_vulnerability dv ON (dv.vulnerability_id = davbs.vulnerability_id)
|
63
|
+
JOIN dim_asset da ON (da.asset_id = davbs.asset_id)
|
64
|
+
WHERE dv.title IN ('<vulnerability titles>') AND da.ip_address IN ('<asset_ips>')
|
65
|
+
GROUP BY da.ip_address, da.host_name, ds.nexpose_id, dv.nexpose_id
|
66
|
+
:dwh: SELECT dv.nexpose_id AS key, da.ip_address, da.host_name, ds.nexpose_id
|
67
|
+
FROM dim_asset_vulnerability_finding_solution davfs
|
68
|
+
JOIN dim_solution ds ON (ds.solution_id = davfs.solution_id)
|
69
|
+
JOIN dim_vulnerability dv ON (dv.vulnerability_id = davfs.vulnerability_id)
|
70
|
+
JOIN dim_asset da ON (da.asset_id = davfs.asset_id)
|
71
|
+
WHERE dv.title IN ('<vulnerability titles>') AND da.ip_address IN ('<asset ips>')
|
72
|
+
GROUP BY da.ip_address, da.host_name, ds.nexpose_id, dv.nexpose_id
|
73
|
+
:vuln_by_id: #msft-cve-2017-0016, msft-cve-2017-8527, msft-cve-2017-0280, msft-cve-2017-0267
|
74
|
+
:nsc: SELECT dv.nexpose_id AS key, da.ip_address, da.host_name, ds.nexpose_id
|
75
|
+
FROM dim_asset_vulnerability_best_solution davbs
|
76
|
+
JOIN dim_solution ds ON (ds.solution_id = davbs.solution_id)
|
77
|
+
JOIN dim_vulnerability dv ON (dv.vulnerability_id = davbs.vulnerability_id)
|
78
|
+
JOIN dim_asset da ON (da.asset_id = davbs.asset_id)
|
79
|
+
WHERE dv.nexpose_id IN ('<vulnerability ids>') AND da.ip_address IN ('<asset ips>')
|
80
|
+
GROUP BY dv.nexpose_id, da.ip_address, da.host_name, ds.nexpose_id
|
81
|
+
:dwh: SELECT dv.nexpose_id AS key, da.ip_address, da.host_name, ds.nexpose_id
|
82
|
+
FROM dim_asset_vulnerability_finding_solution davfs
|
83
|
+
JOIN dim_solution ds ON (ds.solution_id = davfs.solution_id)
|
84
|
+
JOIN dim_vulnerability dv ON (dv.vulnerability_id = davfs.vulnerability_id)
|
85
|
+
JOIN dim_asset da ON (da.asset_id = davfs.asset_id)
|
86
|
+
WHERE dv.nexpose_id IN ('<vulnerability ids>') AND da.ip_address IN ('<asset ips>')
|
87
|
+
GROUP BY dv.nexpose_id, da.ip_address, da.host_name, ds.nexpose_id
|
data/conf/sccm.yml
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
---
|
2
|
+
:sccm:
|
3
|
+
## Must be NetBIOS name
|
4
|
+
:host: 'SCCM_host_or_ip'
|
5
|
+
:port: 5986
|
6
|
+
:path: wsman
|
7
|
+
:protocol: https
|
8
|
+
:user: 'Administrator'
|
9
|
+
:pass: 'password'
|
10
|
+
:no_ssl_peer_verification: false
|
11
|
+
## openssl s_client -showcerts -servername 10.3.23.212 -connect 10.3.23.212:5986 < /dev/null 2>/dev/null | openssl x509 -fingerprint -noout -in /dev/stdin | sed -e "s/://g"
|
12
|
+
:ssl_peer_fingerprint: 'server_certificate_fingerprint'
|
13
|
+
:location: '<site_name>:\'
|
14
|
+
:namespace: 'root\sms\site_<site_name>'
|
15
|
+
:staging: '<software_download_location>'
|
16
|
+
:create_deployment_package: true
|
17
|
+
:download_updates: true
|
18
|
+
:integration_prefix: 'Rapid7'
|
19
|
+
:generate_unknown_device_report: true
|
20
|
+
:report_location: '../reports/'
|
21
|
+
:software_update_group:
|
22
|
+
## Available scopes are one of the following: [asset_best_solution, tag_best_solution]
|
23
|
+
:scope: asset_best_solution_by_site
|
24
|
+
## Create new software update group or update an existing
|
25
|
+
## Available actions include one of the following: [update, create]
|
26
|
+
:action: update
|
27
|
+
## data source can be 'nsc' or 'dwh' (Nexpose Security Console or Data Warehouse respectively)
|
28
|
+
:data_source: nsc
|
29
|
+
:software_update_group_key: key # How to group SUGs, base off of SQL query column name
|
30
|
+
:collection_key: site_id # How to group collections, base off of SQL query column name
|
data/conf/secret.yml
ADDED
data/lib/nexpose_sccm.rb
ADDED
@@ -0,0 +1,294 @@
|
|
1
|
+
require 'nexpose_sccm/collection'
|
2
|
+
require 'nexpose_sccm/connection'
|
3
|
+
require 'nexpose_sccm/deployment_package'
|
4
|
+
require 'nexpose_sccm/device'
|
5
|
+
require 'nexpose_sccm/software_update_group'
|
6
|
+
require 'nexpose_sccm/utilities/utility_config'
|
7
|
+
require 'nexpose_sccm/utilities/nx_logger'
|
8
|
+
require 'nexpose_sccm/data_source'
|
9
|
+
require 'nexpose_sccm/version'
|
10
|
+
|
11
|
+
module NexposeSCCM
|
12
|
+
class << self
|
13
|
+
|
14
|
+
def setup(settings)
|
15
|
+
@logger = NexposeSCCM::NxLogger.instance
|
16
|
+
@logger.setup_statistics_collection(NexposeSCCM::VENDOR,
|
17
|
+
NexposeSCCM::PRODUCT,
|
18
|
+
NexposeSCCM::VERSION)
|
19
|
+
@logger.setup_logging(true,
|
20
|
+
settings[:logging][:log_level],
|
21
|
+
settings[:logging][:log_stdout],
|
22
|
+
settings[:logging][:log_file_rotation],
|
23
|
+
settings[:logging][:log_file_size])
|
24
|
+
NexposeSCCM.logger = @logger
|
25
|
+
|
26
|
+
## Setting up SCCM connection
|
27
|
+
@logger.debug("Logging into SCCM")
|
28
|
+
sccm = settings[:sccm]
|
29
|
+
@sccm = NexposeSCCM::Connection.new(sccm[:protocol],
|
30
|
+
sccm[:host],
|
31
|
+
sccm[:port],
|
32
|
+
sccm[:path],
|
33
|
+
sccm[:location],
|
34
|
+
sccm[:user],
|
35
|
+
sccm[:pass],
|
36
|
+
sccm[:namespace],
|
37
|
+
sccm[:staging],
|
38
|
+
sccm[:no_ssl_peer_verification],
|
39
|
+
sccm[:ssl_peer_fingerprint])
|
40
|
+
## Logging into SCCM
|
41
|
+
@sccm.login
|
42
|
+
end
|
43
|
+
|
44
|
+
def generate_updates(settings, input_file=nil)
|
45
|
+
scope = settings[:sccm][:software_update_group][:scope]
|
46
|
+
data_source = settings[:sccm][:data_source]
|
47
|
+
|
48
|
+
if settings[:sccm][:generate_unknown_device_report]
|
49
|
+
date = Time.now.strftime('%Y%m%d_%H%M%S')
|
50
|
+
report = "devices-not-found-sccm-#{date}.csv"
|
51
|
+
report_location = settings[:sccm][:report_location]
|
52
|
+
unless File.exist?(File.expand_path(report_location))
|
53
|
+
Dir.mkdir(report_location)
|
54
|
+
end
|
55
|
+
|
56
|
+
csv_report_contents = Set.new()
|
57
|
+
end
|
58
|
+
|
59
|
+
# Get known SCCM devices with details
|
60
|
+
sccm_devices = @sccm.get_devices
|
61
|
+
## Get current list of collections
|
62
|
+
collections = @sccm.get_collections(sccm_devices)
|
63
|
+
|
64
|
+
## Initiate the data source connection
|
65
|
+
@logger.debug("Logging into Nexpose / DWH")
|
66
|
+
@nsc = NexposeSCCM::DataSource::Connection.new(data_source,
|
67
|
+
settings[:postgres],
|
68
|
+
settings[:nexpose])
|
69
|
+
|
70
|
+
@logger.info("Successfully connected to Data Source #{data_source}")
|
71
|
+
|
72
|
+
sup_data = []
|
73
|
+
begin
|
74
|
+
query = settings[:queries][scope.to_sym][data_source.to_sym]
|
75
|
+
match_for_prompt = query.scan(/'<.*?>'/)
|
76
|
+
|
77
|
+
unless match_for_prompt.nil? || match_for_prompt.empty?
|
78
|
+
if !input_file.nil? && File.exist?(input_file)
|
79
|
+
inputs = CSV.read(input_file, :headers=>true)
|
80
|
+
end
|
81
|
+
|
82
|
+
match_for_prompt.each do |match|
|
83
|
+
if !inputs.nil? && inputs.headers.include?(match.gsub("'<",'').gsub(">'",''))
|
84
|
+
input = inputs[match.gsub("'<",'').gsub(">'",'')]
|
85
|
+
else
|
86
|
+
input = prompt("Please provide #{match} to be processed " \
|
87
|
+
"(comma separated for any lists): ").strip.split(',')
|
88
|
+
end
|
89
|
+
input = input.map{|e| "'#{e}'"}
|
90
|
+
|
91
|
+
query.gsub!(/#{match}/, "#{input.join(',')}")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
@logger.debug("Retrieving Data")
|
96
|
+
sup_data = @nsc.fetch_data(query)
|
97
|
+
rescue => e
|
98
|
+
@logger.error("There was an error running the query. " \
|
99
|
+
"Check the scope and data source settings for validity: #{e}")
|
100
|
+
exit
|
101
|
+
end
|
102
|
+
|
103
|
+
unless sup_data.length > 0
|
104
|
+
@logger.debug("No updates returned using query: #{query}")
|
105
|
+
@logger.info('No updates to work on. Exiting...')
|
106
|
+
exit 0
|
107
|
+
end
|
108
|
+
|
109
|
+
## SUP scopes are defined by the query used to run them.
|
110
|
+
@logger.info("Software Update Group scope: #{scope}")
|
111
|
+
|
112
|
+
sugs = {}
|
113
|
+
|
114
|
+
@logger.debug("Getting CI_IDS using scope: #{scope}")
|
115
|
+
|
116
|
+
@logger.info("Looping through output of length #{sup_data.length}")
|
117
|
+
sup_data.each do |o|
|
118
|
+
unless o.key?(:key)
|
119
|
+
@logger.error("Query to pull data from #{data_source} " \
|
120
|
+
"does not have the 'key' field, exiting...")
|
121
|
+
exit 1
|
122
|
+
end
|
123
|
+
|
124
|
+
key = o[settings[:sccm][:software_update_group_key].to_sym]
|
125
|
+
collection_key = o[settings[:sccm][:collection_key].to_sym]
|
126
|
+
key_ip = o[:ip_address].split(':')[0].strip
|
127
|
+
key_hostname = o[:host_name]
|
128
|
+
|
129
|
+
device = sccm_devices.select do |dev|
|
130
|
+
(dev.host_name.to_s.casecmp(key_hostname) == 0 unless key_hostname.nil?) ||
|
131
|
+
(dev.ip_address.to_a.include?(key_ip) unless key_ip.nil?)
|
132
|
+
end.first
|
133
|
+
|
134
|
+
if device.nil?
|
135
|
+
if settings[:sccm][:generate_unknown_device_report]
|
136
|
+
csv_report_contents << [key_ip, key_hostname]
|
137
|
+
end
|
138
|
+
else
|
139
|
+
collection_name = "Rapid7_#{collection_key}"
|
140
|
+
collection_match = collections.select do |collection|
|
141
|
+
collection.name.eql?(collection_name)
|
142
|
+
end.first
|
143
|
+
|
144
|
+
if collection_match.nil?
|
145
|
+
collection_match = NexposeSCCM::Collection.new(collection_name)
|
146
|
+
collection_match.members.add(device)
|
147
|
+
collections << collection_match
|
148
|
+
else
|
149
|
+
collection_match.members.add(device)
|
150
|
+
end
|
151
|
+
end
|
152
|
+
|
153
|
+
unless sugs.key?(key)
|
154
|
+
sugs[key] = {
|
155
|
+
:ci_ids => [],
|
156
|
+
:description => "Scope: #{scope}",
|
157
|
+
:name => "Rapid7_#{key}"
|
158
|
+
}
|
159
|
+
end
|
160
|
+
|
161
|
+
## Pesky way of grabbing an UUID for the specific microsoft patch until
|
162
|
+
## Nexpose has a better way of making this data available
|
163
|
+
nexpose_id = o[:nexpose_id]
|
164
|
+
uuid = nil
|
165
|
+
begin
|
166
|
+
match = nexpose_id.match(/([0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12})/).captures
|
167
|
+
uuid = match[0]
|
168
|
+
rescue
|
169
|
+
@logger.debug('Must be no UUID available, going to next...')
|
170
|
+
end
|
171
|
+
next if uuid.nil?
|
172
|
+
ci_ids = @sccm.get_ci_id(uuid)
|
173
|
+
next unless ci_ids.length > 0
|
174
|
+
|
175
|
+
sugs[key][:ci_ids] += ci_ids
|
176
|
+
end
|
177
|
+
|
178
|
+
## Get current list of SUGs for update actions
|
179
|
+
@logger.debug("Retrieving current Software Update Groups from SCCM")
|
180
|
+
groups = @sccm.get_software_update_groups
|
181
|
+
|
182
|
+
sug_objects=[]
|
183
|
+
sug_action_type = settings[:sccm][:software_update_group][:action]
|
184
|
+
## At a minimum, we create Software Update Groups
|
185
|
+
sugs.each do |k,v|
|
186
|
+
@logger.info("Working on SUP: #{k}")
|
187
|
+
match = groups.select { |g| g.name.casecmp(v[:name]) == 0 }
|
188
|
+
## Update if we find matching names
|
189
|
+
if sug_action_type.casecmp('update') == 0
|
190
|
+
if match.length > 0
|
191
|
+
sug = match[0]
|
192
|
+
sug.ci_ids = v[:ci_ids]
|
193
|
+
sug.description = v[:description]
|
194
|
+
res = sug.save(@sccm)
|
195
|
+
sug_objects << sug
|
196
|
+
if res
|
197
|
+
msg = "Successfully updated Software Update Group: #{v[:name]}"
|
198
|
+
@logger.debug(msg)
|
199
|
+
else
|
200
|
+
@logger.error("Error updating Software Update Group: #{v[:name]}")
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
if sug_action_type.casecmp('create') == 0 || match.empty?
|
206
|
+
## Create sug if action is create or update didn't work.
|
207
|
+
sug = NexposeSCCM::SoftwareUpdateGroup.new(v[:name],
|
208
|
+
v[:description],
|
209
|
+
v[:ci_ids])
|
210
|
+
sug_objects << sug
|
211
|
+
res = sug.save(@sccm)
|
212
|
+
if res
|
213
|
+
msg = "Successfully created Software Update Group: #{v[:name]}"
|
214
|
+
@logger.debug(msg)
|
215
|
+
else
|
216
|
+
@logger.error("Error creating Software Update Group: #{v[:name]}")
|
217
|
+
end
|
218
|
+
end
|
219
|
+
end
|
220
|
+
|
221
|
+
# Save collections with devices
|
222
|
+
@logger.debug("Saving Collections")
|
223
|
+
collections.each do |collection|
|
224
|
+
collection.save(@sccm)
|
225
|
+
end
|
226
|
+
|
227
|
+
## Download/deployment package creation if set to true
|
228
|
+
if settings[:sccm].key?(:create_deployment_package) &&
|
229
|
+
settings[:sccm][:create_deployment_package]
|
230
|
+
@logger.debug("Creating the Deployment Packages")
|
231
|
+
sug_objects.each do |sug_object|
|
232
|
+
name = sug_object.name
|
233
|
+
package_name = "Rapid7-Deployment-Package-#{name}"
|
234
|
+
package_path = "#{@sccm.staging}\\#{name}"
|
235
|
+
|
236
|
+
deployment_package = @sccm.get_deployment_package(package_name)
|
237
|
+
package_id =
|
238
|
+
if deployment_package.empty?
|
239
|
+
nil
|
240
|
+
else
|
241
|
+
deployment_package.first[:package_id]
|
242
|
+
end
|
243
|
+
#deployment_package.empty? ? nil : deployment_package.first[:package_id]
|
244
|
+
package = NexposeSCCM::DeploymentPackage.new(package_name,
|
245
|
+
name,
|
246
|
+
package_path,
|
247
|
+
package_id)
|
248
|
+
|
249
|
+
# Don't process if no ci ids for SUG
|
250
|
+
unless sug_object.ci_ids.empty?
|
251
|
+
@logger.debug("Saving the Deployment Package: #{package_name}")
|
252
|
+
# Save deployment package if enabled and doesn't exist already
|
253
|
+
package.save(@sccm) if package.id.nil?
|
254
|
+
|
255
|
+
# Download updates if enabled
|
256
|
+
@logger.debug("Downloading the Deployment Package")
|
257
|
+
package.download_updates(@sccm) if settings[:sccm][:download_updates]
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
# Generate report if configured and content exists
|
263
|
+
if settings[:sccm][:generate_unknown_device_report]
|
264
|
+
report_length = csv_report_contents.length
|
265
|
+
if report_length > 0
|
266
|
+
@logger.debug("Creating Unknown Device report")
|
267
|
+
CSV.open(report_location + report, 'ab') do |csv|
|
268
|
+
csv << ['IP Address','Hostname']
|
269
|
+
csv_report_contents.each do |entry|
|
270
|
+
csv << entry
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
274
|
+
@logger.debug("Unknown Device report length: #{report_length}")
|
275
|
+
end
|
276
|
+
|
277
|
+
@logger.info("Nexpose SCCM integration has finished.")
|
278
|
+
end
|
279
|
+
|
280
|
+
def prompt(*args)
|
281
|
+
print(*args)
|
282
|
+
gets
|
283
|
+
end
|
284
|
+
|
285
|
+
attr_accessor :logger
|
286
|
+
def logger
|
287
|
+
if @logger.nil?
|
288
|
+
puts "Someone forgot to set their logger...exiting"
|
289
|
+
exit 1
|
290
|
+
end
|
291
|
+
@logger
|
292
|
+
end
|
293
|
+
end
|
294
|
+
end
|