inspec-core 4.21.3 → 4.23.4
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 +4 -4
- data/Gemfile +1 -1
- data/inspec-core.gemspec +3 -5
- data/lib/bundles/inspec-supermarket/cli.rb +1 -1
- data/lib/inspec/base_cli.rb +5 -1
- data/lib/inspec/config.rb +19 -1
- data/lib/inspec/exceptions.rb +1 -0
- data/lib/inspec/input.rb +4 -3
- data/lib/inspec/input_registry.rb +9 -2
- data/lib/inspec/metadata.rb +6 -1
- data/lib/inspec/plugin/v2/plugin_types/reporter.rb +4 -25
- data/lib/inspec/profile.rb +30 -9
- data/lib/inspec/reporters.rb +0 -3
- data/lib/inspec/reporters/automate.rb +3 -3
- data/lib/inspec/reporters/base.rb +7 -23
- data/lib/inspec/reporters/cli.rb +1 -0
- data/lib/inspec/reporters/json.rb +9 -4
- data/lib/inspec/resources/apt.rb +2 -0
- data/lib/inspec/resources/bridge.rb +1 -1
- data/lib/inspec/resources/host.rb +1 -1
- data/lib/inspec/resources/mount.rb +1 -1
- data/lib/inspec/resources/mysql_session.rb +31 -8
- data/lib/inspec/resources/postgres.rb +1 -1
- data/lib/inspec/resources/postgres_session.rb +6 -4
- data/lib/inspec/resources/processes.rb +1 -1
- data/lib/inspec/resources/service.rb +2 -2
- data/lib/inspec/resources/users.rb +1 -1
- data/lib/inspec/resources/windows_firewall.rb +110 -0
- data/lib/inspec/resources/windows_firewall_rule.rb +137 -0
- data/lib/inspec/run_data.rb +1 -1
- data/lib/inspec/run_data/profile.rb +7 -6
- data/lib/inspec/runner.rb +8 -2
- data/lib/inspec/runner_rspec.rb +4 -1
- data/lib/inspec/schema.rb +2 -0
- data/lib/inspec/schema/exec_json.rb +4 -3
- data/lib/inspec/schema/primitives.rb +1 -1
- data/lib/inspec/utils/parser.rb +1 -1
- data/lib/inspec/utils/run_data_filters.rb +104 -0
- data/lib/inspec/version.rb +1 -1
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/api.rb +4 -4
- data/lib/plugins/inspec-compliance/lib/inspec-compliance/cli.rb +1 -1
- data/lib/plugins/inspec-reporter-html2/templates/profile.html.erb +5 -2
- data/lib/plugins/inspec-reporter-junit/README.md +15 -0
- data/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit.rb +12 -0
- data/lib/{inspec/reporters/junit.rb → plugins/inspec-reporter-junit/lib/inspec-reporter-junit/reporter.rb} +22 -26
- data/lib/plugins/inspec-reporter-junit/lib/inspec-reporter-junit/version.rb +5 -0
- metadata +19 -36
- data/README.md +0 -474
data/lib/inspec/reporters/cli.rb
CHANGED
@@ -72,6 +72,7 @@ module Inspec::Reporters
|
|
72
72
|
"Profile" => format_profile_name(profile),
|
73
73
|
"Version" => profile[:version] || "(not specified)",
|
74
74
|
}
|
75
|
+
header["Failure Message"] = profile[:status_message] if profile[:status] == "failed"
|
75
76
|
header["Target"] = run_data[:platform][:target] unless run_data[:platform][:target].nil?
|
76
77
|
header["Target ID"] = @config["target_id"] unless @config["target_id"].nil?
|
77
78
|
|
@@ -45,8 +45,8 @@ module Inspec::Reporters
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def profiles
|
48
|
-
run_data[:profiles].map
|
49
|
-
{
|
48
|
+
run_data[:profiles].map do |p|
|
49
|
+
res = {
|
50
50
|
name: p[:name],
|
51
51
|
version: p[:version],
|
52
52
|
sha256: p[:sha256],
|
@@ -64,10 +64,15 @@ module Inspec::Reporters
|
|
64
64
|
groups: profile_groups(p),
|
65
65
|
controls: profile_controls(p),
|
66
66
|
status: p[:status],
|
67
|
-
|
67
|
+
status_message: p[:status_message],
|
68
68
|
waiver_data: p[:waiver_data],
|
69
69
|
}.reject { |_k, v| v.nil? }
|
70
|
-
|
70
|
+
|
71
|
+
# For backwards compatibility
|
72
|
+
res[:skip_message] = res[:status_message] if res[:status] == "skipped"
|
73
|
+
|
74
|
+
res
|
75
|
+
end
|
71
76
|
end
|
72
77
|
|
73
78
|
def profile_groups(profile)
|
data/lib/inspec/resources/apt.rb
CHANGED
@@ -90,12 +90,14 @@ module Inspec::Resources
|
|
90
90
|
# deb "http://archive.ubuntu.com/ubuntu/" wily main restricted ...
|
91
91
|
# deb http://archive.ubuntu.com/ubuntu/ wily main restricted ...
|
92
92
|
# deb [trusted=yes] http://archive.ubuntu.com/ubuntu/ wily main restricted ...
|
93
|
+
# deb cdrom:[Ubuntu 15.10 _Wily Werewolf_ - Release amd64 (20151021)]/ wily main restricted ...
|
93
94
|
|
94
95
|
words = line.split
|
95
96
|
words.delete_at 1 if words[1] && words[1].start_with?("[")
|
96
97
|
type, url, distro, *components = words
|
97
98
|
url = url.delete('"') if url
|
98
99
|
|
100
|
+
next if words[1] && words[1].start_with?("cdrom:") # skip unsupported apt-cdrom repos
|
99
101
|
next if components.empty?
|
100
102
|
next unless URI::HTTP === URI.parse(url)
|
101
103
|
next unless %w{deb deb-src}.include? type
|
@@ -27,7 +27,7 @@ module Inspec::Resources
|
|
27
27
|
elsif inspec.os.windows?
|
28
28
|
@bridge_provider = WindowsBridge.new(inspec)
|
29
29
|
else
|
30
|
-
|
30
|
+
skip_resource "The `bridge` resource is not supported on your OS yet."
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
@@ -71,7 +71,7 @@ module Inspec::Resources
|
|
71
71
|
|
72
72
|
missing_requirements = @host_provider.missing_requirements(protocol)
|
73
73
|
unless missing_requirements.empty?
|
74
|
-
|
74
|
+
skip_resource "The following requirements are not met for this resource: " \
|
75
75
|
"#{missing_requirements.join(", ")}"
|
76
76
|
end
|
77
77
|
end
|
@@ -4,6 +4,27 @@ require "inspec/resources/command"
|
|
4
4
|
require "shellwords"
|
5
5
|
|
6
6
|
module Inspec::Resources
|
7
|
+
class Lines
|
8
|
+
attr_reader :output, :stdout, :stderr, :exit_status
|
9
|
+
|
10
|
+
def initialize(raw, desc, exit_status)
|
11
|
+
@output = raw
|
12
|
+
@desc = desc
|
13
|
+
@exit_status = exit_status
|
14
|
+
# backwards compatibility
|
15
|
+
@stdout = raw
|
16
|
+
@stderr = raw
|
17
|
+
end
|
18
|
+
|
19
|
+
def lines
|
20
|
+
output.split("\n")
|
21
|
+
end
|
22
|
+
|
23
|
+
def to_s
|
24
|
+
@desc
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
7
28
|
class MysqlSession < Inspec.resource(1)
|
8
29
|
name "mysql_session"
|
9
30
|
supports platform: "unix"
|
@@ -12,7 +33,7 @@ module Inspec::Resources
|
|
12
33
|
example <<~EXAMPLE
|
13
34
|
sql = mysql_session('my_user','password','host')
|
14
35
|
describe sql.query('show databases like \'test\';') do
|
15
|
-
its('
|
36
|
+
its('output') { should_not match(/test/) }
|
16
37
|
end
|
17
38
|
EXAMPLE
|
18
39
|
|
@@ -28,15 +49,17 @@ module Inspec::Resources
|
|
28
49
|
|
29
50
|
def query(q, db = "")
|
30
51
|
mysql_cmd = create_mysql_cmd(q, db)
|
31
|
-
cmd =
|
52
|
+
cmd = if !@pass.nil?
|
53
|
+
inspec.command(mysql_cmd, redact_regex: /(mysql -u\w+ -p).+(\s-(h|S).*)/)
|
54
|
+
else
|
55
|
+
inspec.command(mysql_cmd)
|
56
|
+
end
|
32
57
|
out = cmd.stdout + "\n" + cmd.stderr
|
33
|
-
if out =~ /Can't connect to .* MySQL server/ || out.downcase =~ /^error
|
34
|
-
|
35
|
-
|
58
|
+
if cmd.exit_status != 0 || out =~ /Can't connect to .* MySQL server/ || out.downcase =~ /^error:.*/
|
59
|
+
Lines.new(out, "MySQL query with errors: #{q}", cmd.exit_status)
|
60
|
+
else
|
61
|
+
Lines.new(cmd.stdout.strip, "MySQL query: #{q}", cmd.exit_status)
|
36
62
|
end
|
37
|
-
|
38
|
-
# return the raw command output
|
39
|
-
cmd
|
40
63
|
end
|
41
64
|
|
42
65
|
def to_s
|
@@ -19,7 +19,7 @@ module Inspec::Resources
|
|
19
19
|
@conf_path = File.join @conf_dir, "postgresql.conf"
|
20
20
|
else
|
21
21
|
@conf_path = nil
|
22
|
-
|
22
|
+
skip_resource "Seems like PostgreSQL is not installed on your system"
|
23
23
|
end
|
24
24
|
end
|
25
25
|
|
@@ -26,12 +26,13 @@ module Inspec::Resources
|
|
26
26
|
supports platform: "windows"
|
27
27
|
desc "Use the postgres_session InSpec audit resource to test SQL commands run against a PostgreSQL database."
|
28
28
|
example <<~EXAMPLE
|
29
|
-
sql = postgres_session('username', 'password', 'host')
|
29
|
+
sql = postgres_session('username', 'password', 'host', 'port')
|
30
30
|
query('sql_query', ['database_name'])` contains the query and (optional) database to execute
|
31
31
|
|
32
32
|
# default values:
|
33
33
|
# username: 'postgres'
|
34
34
|
# host: 'localhost'
|
35
|
+
# port: 5432
|
35
36
|
# db: databse == db_user running the sql query
|
36
37
|
|
37
38
|
describe sql.query('SELECT * FROM pg_shadow WHERE passwd IS NULL;') do
|
@@ -39,15 +40,16 @@ module Inspec::Resources
|
|
39
40
|
end
|
40
41
|
EXAMPLE
|
41
42
|
|
42
|
-
def initialize(user, pass, host = nil)
|
43
|
+
def initialize(user, pass, host = nil, port = nil)
|
43
44
|
@user = user || "postgres"
|
44
45
|
@pass = pass
|
45
46
|
@host = host || "localhost"
|
47
|
+
@port = port || 5432
|
46
48
|
end
|
47
49
|
|
48
50
|
def query(query, db = [])
|
49
51
|
psql_cmd = create_psql_cmd(query, db)
|
50
|
-
cmd = inspec.command(psql_cmd)
|
52
|
+
cmd = inspec.command(psql_cmd, redact_regex: /(PGPASSWORD=').+(' psql .*)/)
|
51
53
|
out = cmd.stdout + "\n" + cmd.stderr
|
52
54
|
if cmd.exit_status != 0 || out =~ /could not connect to .*/ || out.downcase =~ /^error:.*/
|
53
55
|
Lines.new(out, "PostgreSQL query with errors: #{query}")
|
@@ -64,7 +66,7 @@ module Inspec::Resources
|
|
64
66
|
|
65
67
|
def create_psql_cmd(query, db = [])
|
66
68
|
dbs = db.map { |x| "-d #{x}" }.join(" ")
|
67
|
-
"PGPASSWORD='#{@pass}' psql -U #{@user} #{dbs} -h #{@host} -A -t -c #{escaped_query(query)}"
|
69
|
+
"PGPASSWORD='#{@pass}' psql -U #{@user} #{dbs} -h #{@host} -p #{@port} -A -t -c #{escaped_query(query)}"
|
68
70
|
end
|
69
71
|
end
|
70
72
|
end
|
@@ -138,7 +138,7 @@ module Inspec::Resources
|
|
138
138
|
command: 8,
|
139
139
|
}
|
140
140
|
else
|
141
|
-
command = "ps
|
141
|
+
command = "ps wwaxo label,pid,pcpu,pmem,vsz,rss,tty,stat,start,time,user:32,command"
|
142
142
|
regex = /^(.+?)\s+(\d+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+([^ ]+)\s+(\w{3} \d{2}|\d{2}:\d{2}:\d{2})\s+([^ ]+)\s+([^ ]+)\s+(.*)$/
|
143
143
|
field_map = {
|
144
144
|
label: 1,
|
@@ -141,7 +141,7 @@ module Inspec::Resources
|
|
141
141
|
elsif version > 0
|
142
142
|
SysV.new(inspec, service_ctl || "/usr/sbin/service")
|
143
143
|
end
|
144
|
-
when "redhat", "fedora", "centos", "oracle", "cloudlinux"
|
144
|
+
when "redhat", "fedora", "centos", "oracle", "cloudlinux", "scientific"
|
145
145
|
version = os[:release].to_i
|
146
146
|
|
147
147
|
systemd = ((platform != "fedora" && version >= 7) ||
|
@@ -154,7 +154,7 @@ module Inspec::Resources
|
|
154
154
|
end
|
155
155
|
when "wrlinux"
|
156
156
|
SysV.new(inspec, service_ctl)
|
157
|
-
when "mac_os_x"
|
157
|
+
when "mac_os_x", "darwin"
|
158
158
|
LaunchCtl.new(inspec, service_ctl)
|
159
159
|
when "freebsd"
|
160
160
|
BSDInit.new(inspec, service_ctl)
|
@@ -20,7 +20,7 @@ module Inspec::Resources
|
|
20
20
|
WindowsUser.new(inspec)
|
21
21
|
elsif ["darwin"].include?(os[:family])
|
22
22
|
DarwinUser.new(inspec)
|
23
|
-
elsif ["
|
23
|
+
elsif ["bsd"].include?(os[:family])
|
24
24
|
FreeBSDUser.new(inspec)
|
25
25
|
elsif ["aix"].include?(os[:family])
|
26
26
|
AixUser.new(inspec)
|
@@ -0,0 +1,110 @@
|
|
1
|
+
module Inspec::Resources
|
2
|
+
class WindowsFirewall < Inspec.resource(1)
|
3
|
+
name "windows_firewall"
|
4
|
+
supports platform: "windows"
|
5
|
+
desc "Check properties of the Windows Firewall for a specific profile."
|
6
|
+
example <<~EXAMPLE
|
7
|
+
describe windows_firewall("Public") do
|
8
|
+
it { should be_enabled }
|
9
|
+
its("default_inbound_action") { should_not cmp "NotConfigured" }
|
10
|
+
its("num_rules") { should be 19 }
|
11
|
+
end
|
12
|
+
EXAMPLE
|
13
|
+
|
14
|
+
def initialize(profile = "Public")
|
15
|
+
@profile = profile
|
16
|
+
@state = {}
|
17
|
+
|
18
|
+
load_profile_cmd = load_firewall_profile(profile)
|
19
|
+
cmd = inspec.powershell(load_profile_cmd)
|
20
|
+
|
21
|
+
@state = JSON.load(cmd.stdout) unless cmd.stdout.empty?
|
22
|
+
end
|
23
|
+
|
24
|
+
def to_s
|
25
|
+
"Windows Firewall (Profile #{@profile})"
|
26
|
+
end
|
27
|
+
|
28
|
+
def exist?
|
29
|
+
!@state.empty?
|
30
|
+
end
|
31
|
+
|
32
|
+
def enabled?
|
33
|
+
@state["enabled"]
|
34
|
+
end
|
35
|
+
|
36
|
+
def default_inbound_allowed?
|
37
|
+
@state["default_inbound_action"] == "Allow"
|
38
|
+
end
|
39
|
+
|
40
|
+
def default_outbound_allowed?
|
41
|
+
@state["default_outbound_action"] == "Allow"
|
42
|
+
end
|
43
|
+
|
44
|
+
# Access to return values from Powershell via `its("PROPERTY")` and `have_PROPERTY "VALUE"`
|
45
|
+
def method_missing(method_name, *arguments, &_block)
|
46
|
+
property = normalize_for_have_access(method_name)
|
47
|
+
|
48
|
+
if method_name.to_s.start_with? "has_"
|
49
|
+
expected_value = arguments.first
|
50
|
+
respond_to_have(property, expected_value)
|
51
|
+
else
|
52
|
+
access_property(property)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def respond_to_missing?(method_name, _include_private = false)
|
57
|
+
property = normalize_for_have_access(method_name)
|
58
|
+
|
59
|
+
@state.key? property
|
60
|
+
end
|
61
|
+
|
62
|
+
private
|
63
|
+
|
64
|
+
def normalize_for_have_access(property)
|
65
|
+
property.to_s
|
66
|
+
.delete_prefix("has_")
|
67
|
+
.delete_suffix("?")
|
68
|
+
end
|
69
|
+
|
70
|
+
def access_property(property)
|
71
|
+
@state[property]
|
72
|
+
end
|
73
|
+
|
74
|
+
def respond_to_have(property, value)
|
75
|
+
@state[property] == value
|
76
|
+
end
|
77
|
+
|
78
|
+
def load_firewall_profile(profile_name)
|
79
|
+
<<-EOH
|
80
|
+
Remove-TypeData System.Array # workaround for PS bug here: https://bit.ly/2SRMQ8M
|
81
|
+
$profile = Get-NetFirewallProfile -Name "#{profile_name}"
|
82
|
+
$count = @($profile | Get-NetFirewallRule).Count
|
83
|
+
([PSCustomObject]@{
|
84
|
+
profile_name = $profile.Name
|
85
|
+
profile = $profile.Profile.ToString()
|
86
|
+
description = $profile.Description
|
87
|
+
enabled = [bool]::Parse($profile.Enabled.ToString())
|
88
|
+
default_inbound_action = $profile.DefaultInboundAction.ToString()
|
89
|
+
default_outbound_action = $profile.DefaultOutboundAction.ToString()
|
90
|
+
|
91
|
+
allow_inbound_rules = $profile.AllowInboundRules.ToString()
|
92
|
+
allow_local_firewall_rules = $profile.AllowLocalFirewallRules.ToString()
|
93
|
+
allow_local_ipsec_rules = $profile.AllowLocalIPsecRules.ToString()
|
94
|
+
allow_user_apps = $profile.AllowUserApps.ToString()
|
95
|
+
allow_user_ports = $profile.AllowUserPorts.ToString()
|
96
|
+
allow_unicast_response_to_multicast = $profile.AllowUnicastResponseToMulticast.ToString()
|
97
|
+
|
98
|
+
notify_on_listen = $profile.NotifyOnListen.ToString()
|
99
|
+
enable_stealth_mode_for_ipsec = $profile.EnableStealthModeForIPsec.ToString()
|
100
|
+
log_max_size_kilobytes = $profile.LogMaxSizeKilobytes
|
101
|
+
log_allowed = $profile.LogAllowed.ToString()
|
102
|
+
log_blocked = $profile.LogBlocked.ToString()
|
103
|
+
log_ignored = $profile.LogIgnored.ToString()
|
104
|
+
|
105
|
+
num_rules = $count
|
106
|
+
}) | ConvertTo-Json
|
107
|
+
EOH
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,137 @@
|
|
1
|
+
module Inspec::Resources
|
2
|
+
class WindowsFirewallRule < Inspec.resource(1)
|
3
|
+
name "windows_firewall_rule"
|
4
|
+
supports platform: "windows"
|
5
|
+
desc "Check properties of a Windows Firewall rule."
|
6
|
+
example <<~EXAMPLE
|
7
|
+
describe windows_firewall_rule("Name") do
|
8
|
+
it { should exist }
|
9
|
+
it { should be_enabled }
|
10
|
+
|
11
|
+
it { should be_outbound}
|
12
|
+
it { should be_tcp }
|
13
|
+
it { should have_remote_port 80 }
|
14
|
+
end
|
15
|
+
EXAMPLE
|
16
|
+
|
17
|
+
def initialize(name)
|
18
|
+
@name = name
|
19
|
+
@state = {}
|
20
|
+
|
21
|
+
query = load_firewall_state(name)
|
22
|
+
cmd = inspec.powershell(query)
|
23
|
+
@state = JSON.load(cmd.stdout) unless cmd.stdout.empty?
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_s
|
27
|
+
"Windows Firewall Rule #{@name}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def exist?
|
31
|
+
!@state.empty?
|
32
|
+
end
|
33
|
+
|
34
|
+
def enabled?
|
35
|
+
@state["enabled"]
|
36
|
+
end
|
37
|
+
|
38
|
+
def allowed?
|
39
|
+
@state["action"] == "Allow"
|
40
|
+
end
|
41
|
+
|
42
|
+
def inbound?
|
43
|
+
@state["direction"] == "Inbound"
|
44
|
+
end
|
45
|
+
|
46
|
+
def outbound?
|
47
|
+
! inbound?
|
48
|
+
end
|
49
|
+
|
50
|
+
def tcp?
|
51
|
+
@state["protocol"] == "TCP"
|
52
|
+
end
|
53
|
+
|
54
|
+
def udp?
|
55
|
+
@state["protocol"] == "UDP"
|
56
|
+
end
|
57
|
+
|
58
|
+
def icmp?
|
59
|
+
@state["protocol"].start_with? "ICMP"
|
60
|
+
end
|
61
|
+
|
62
|
+
def icmpv4?
|
63
|
+
@state["protocol"] == "ICMPv4"
|
64
|
+
end
|
65
|
+
|
66
|
+
def icmpv6?
|
67
|
+
@state["protocol"] == "ICMPv6"
|
68
|
+
end
|
69
|
+
|
70
|
+
# Access to return values from Powershell via `its("PROPERTY")` and `have_PROPERTY? "VALUE"`
|
71
|
+
def method_missing(method_name, *arguments, &_block)
|
72
|
+
property = normalize_for_have_access(method_name)
|
73
|
+
|
74
|
+
if method_name.to_s.start_with? "has_"
|
75
|
+
expected_value = arguments.first
|
76
|
+
respond_to_have(property, expected_value)
|
77
|
+
else
|
78
|
+
access_property(property)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def respond_to_missing?(method_name, _include_private = false)
|
83
|
+
property = normalize_for_have_access(method_name)
|
84
|
+
|
85
|
+
@state.key? property
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def normalize_for_have_access(property)
|
91
|
+
property.to_s
|
92
|
+
.delete_prefix("has_")
|
93
|
+
.delete_suffix("?")
|
94
|
+
end
|
95
|
+
|
96
|
+
def access_property(property)
|
97
|
+
@state[property]
|
98
|
+
end
|
99
|
+
|
100
|
+
def respond_to_have(property, value)
|
101
|
+
@state[property] == value
|
102
|
+
end
|
103
|
+
|
104
|
+
# Taken from Chef, but changed `firewall_action` to `action` for consistency
|
105
|
+
# @see https://github.com/chef/chef/blob/master/lib/chef/resource/windows_firewall_rule.rb
|
106
|
+
def load_firewall_state(rule_name)
|
107
|
+
<<-EOH
|
108
|
+
Remove-TypeData System.Array # workaround for PS bug here: https://bit.ly/2SRMQ8M
|
109
|
+
$rule = Get-NetFirewallRule -Name "#{rule_name}"
|
110
|
+
$addressFilter = $rule | Get-NetFirewallAddressFilter
|
111
|
+
$portFilter = $rule | Get-NetFirewallPortFilter
|
112
|
+
$applicationFilter = $rule | Get-NetFirewallApplicationFilter
|
113
|
+
$serviceFilter = $rule | Get-NetFirewallServiceFilter
|
114
|
+
$interfaceTypeFilter = $rule | Get-NetFirewallInterfaceTypeFilter
|
115
|
+
([PSCustomObject]@{
|
116
|
+
rule_name = $rule.Name
|
117
|
+
description = $rule.Description
|
118
|
+
displayname = $rule.DisplayName
|
119
|
+
group = $rule.Group
|
120
|
+
local_address = $addressFilter.LocalAddress
|
121
|
+
local_port = $portFilter.LocalPort
|
122
|
+
remote_address = $addressFilter.RemoteAddress
|
123
|
+
remote_port = $portFilter.RemotePort
|
124
|
+
direction = $rule.Direction.ToString()
|
125
|
+
protocol = $portFilter.Protocol
|
126
|
+
icmp_type = $portFilter.IcmpType
|
127
|
+
action = $rule.Action.ToString()
|
128
|
+
profile = $rule.Profile.ToString()
|
129
|
+
program = $applicationFilter.Program
|
130
|
+
service = $serviceFilter.Service
|
131
|
+
interface_type = $interfaceTypeFilter.InterfaceType.ToString()
|
132
|
+
enabled = [bool]::Parse($rule.Enabled.ToString())
|
133
|
+
}) | ConvertTo-Json
|
134
|
+
EOH
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|