我必须使用命令Get-NetFirewallRule保存一些信息,并将它们保存在一个.JSON文件中。我就是这样做的
Get-NetFirewallRule |
select-object -Property Name,
DisplayName,
DisplayGroup,
@{Name='Protocol';Expression={($PSItem | Get-NetFirewallPortFilter).Protocol}},
@{Name='LocalPort';Expression={($PSItem | Get-NetFirewallPortFilter).LocalPort}},
@{Name='RemotePort';Expression={($PSItem | Get-NetFirewallPortFilter).RemotePort}},
@{Name='RemoteAddress';Expression={($PSItem | Get-NetFirewallAddressFilter).RemoteAddress}},
Enabled,
Profile,
Direction,
Action |
ConvertTo-Json | Out-File "C:\Users\Administrator\Desktop\firewall.txt"输出文件如下(这是文件的一小部分)
"Name": "Microsoft-Windows-PeerDist-WSD-Out",
"DisplayName": "BranchCache Peer Discovery (WSD-Out)",
"DisplayGroup": "BranchCache - Peer Discovery (Uses WSD)",
"Protocol": "UDP",
"LocalPort": "Any",
"RemotePort": "3702",
"RemoteAddress": "LocalSubnet",
"Enabled": 2,
"Profile": 0,
"Direction": 2,
"Action": 2
},
{
"Name": "Microsoft-Windows-PeerDist-HostedServer-In",
"DisplayName": "BranchCache Hosted Cache Server (HTTP-In)",
"DisplayGroup": "BranchCache - Hosted Cache Server (Uses HTTPS)",
"Protocol": "TCP",
"LocalPort": {
"value": [
"80",
"443"
],
"Count": 2
},
"RemotePort": "Any",
"RemoteAddress": "Any",
"Enabled": 2,
"Profile": 0,
"Direction": 1,
"Action": 2
}如您所见,powershell以两种不同的方式保存LocalPort :第一种使用1值,第二种使用2值和计数;在我的代码(C#)中,我编写了以下代码来读取JSON文件
string file = File.ReadAllText(MainWindow.path + @"\..\..\misc\json\FirewallRules.json");
List<GetSetFRules> rulesList = JsonConvert.DeserializeObject<List<GetSetFRules>>(file);但是有一个问题:类GetSetFRules无法保存JSON的内容,因为JSON中的格式对于每个规则都不一样
class GetSetFRules
{
public string Name { get; set; }
public string DisplayName { get; set; }
public string DisplayGroup { get; set; }
public string Protocol { get; set; }
public Localport LocalPort { get; set; }
public string RemotePort { get; set; }
public string RemoteAddress { get; set; }
public int Enabled { get; set; }
public int Profile { get; set; }
public int Direction { get; set; }
public int Action { get; set; }
}
public class Localport
{
public string[] value { get; set; }
public int Count { get; set; }
}那么,问题是,是否有一种方法可以像这样保存每个空值的规则?
[...]"LocalPort": "Any",[...]⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇⬇
[...]"LocalPort": {
"value": [
"Any",
],
"Count": 1
}[...]或者这个
[...]"LocalPort": {
"value": [
"",
],
"Count": 0
}[...]发布于 2019-12-23 18:38:53
您需要确保计算出的($PSItem | Get-NetFirewallPortFilter).LocalPort属性中的LocalPort输出是数组类型的,可以确保如下所示:
@{
Name='LocalPort'
Expression={ , [array] ($PSItem | Get-NetFirewallPortFilter).LocalPort }
}[array]确保将命令输出作为数组处理,即使只有一个值(如Any )被输出。数组构造操作符,的一元形式{ ... })的输出分配给Expression哈希表条目时,防止单个元素数组被打开的临时数组.顺便说一句:正如Theo指出的那样,in his answer和一个优化一样,对同一个输入对象多次调用Get-NetFireWallPortFilter,跨越多个计算的属性,效率很低,并且降低了命令的速度。
上面的内容将始终如一地为您提供所需的JSON表示,但是有一个警告
ConvertTo-Json通过一个对象为数组创建的JSON表示形式(包含带有数组元素的value属性和带有元素计数的count属性)应该被视为一个bug,因为数组应该简单地表示为JSON数组
也就是说,就像:
, (80, 443) | ConvertTo-Json应该屈服:
# OK: This is how it works in PowerShell v6+
[
80,
443
]而不是
# BUG in Windows PowerShell v5.1
{
"value": [
80,
443
],
"Count": 2
}This answer讨论了详细信息,但请注意,在给定的PowerShell会话中运行以下一次可用于修复问题:
# Run this once per session, before calling ConvertTo-Json, to
# fix the JSON array serialization problem:
Remove-TypeData System.Array -ErrorAction Ignore发布于 2019-12-23 13:42:48
我想我找到了解决办法
将类GetSetFRules替换为类dynamic
List<dynamic> rulesList = JsonConvert.DeserializeObject<List<dynamic>>(file);发布于 2019-12-23 14:48:09
在我的Win10机器上,使用Powershell代码还显示了RemotePort和Protocol的数组输出。我认为最好不要尝试调整所有的项,使其具有这样的输出,而是将所有的规则对象按原样列出,这样它们都有这些属性的一个值。
另外,您可以通过不多次执行Get-NetFirewallPortFilter来加快速度:
# Retrieve every firewall rule object as single object.
# All of these objects will have properties 'LocalPort', RemotePort, 'Protocol'
# listed as single string values; not as array values in the output
Get-NetFirewallRule | ForEach-Object {
$portFilter = $_ | Get-NetFirewallPortFilter
$_ | Select-Object -Property Name,
DisplayName,
DisplayGroup,
@{Name='Protocol';Expression={$portFilter.Protocol}},
@{Name='LocalPort';Expression={$portFilter.LocalPort}},
@{Name='RemotePort';Expression={$portFilter.RemotePort}},
@{Name='RemoteAddress';Expression={($_ | Get-NetFirewallAddressFilter).RemoteAddress}},
Enabled,
Profile,
Direction,
Action
} | Sort-Object DisplayName | ConvertTo-Json | Out-File "C:\Users\Administrator\Desktop\firewall.txt"部分产出:
{“名称”:“{56BC733-582E-45e8-9249-F88002B598E9}”、"DisplayName":"Microsoft管理控制台“、"DisplayGroup":null、”协议“:"TCP”、"LocalPort":“任意”、"RemotePort":“任意”、"RemoteAddress":“任意”、“启用”:1。“配置文件”:4,“指示”:1,“操作”:4 },{“名称”:"{C3F4E91A-65F5-4805-8F6B-86C6ECA5F4EE}","DisplayName":“”,"DisplayGroup":null,"Protocol":"UDP","LocalPort":"Any","RemotePort":"Any","RemoteAddress":"Any","Enabled":1,"Profile":4,“RemotePort”:1,"Action":4 },{ "Name":"UDP Query RemotePort“"DisplayName":"DisplayGroup":null,“协议”:"UDP","LocalPort":“任意”,"RemotePort":“任何”,"RemoteAddress":“任意”,“启用”:1,“配置文件”:2,“方向”:1,“操作”:2 },{“名称”:"TCP查询User{C99F0EF2-8891-4B2D-B389-4A3F8B66638A}C:\windows\system32\mmc.exe",“DisplayName:"Microsoft管理控制台”、"DisplayGroup":null、“DisplayGroup”:"TCP“、"LocalPort":”Any“、"RemotePort":"Any","RemoteAddress":“任意”,“启用”:1,“配置文件”:2,“方向”:1,“操作”:2}
https://stackoverflow.com/questions/59453502
复制相似问题