我必须使用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值和Count;在我的代码(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
}[...]
最佳答案
您需要确保计算出的($PSItem | Get-NetFirewallPortFilter).LocalPort
属性中LocalPort
的输出是数组类型的,可以确保如下:
@{
Name='LocalPort'
Expression={ , [array] ($PSItem | Get-NetFirewallPortFilter).LocalPort }
}
[array]
可以确保将命令输出视为数组,即使仅输出单个值(例如Any
)也是如此。 ,
的一元形式将结果数组包装在aux中。临时数组,当将脚本块的({ ... }
)输出分配给Expression
哈希表条目时,可以防止单个元素数组解包。 顺便说一句:正如Theo指出的in his answer和优化一样,跨多个计算出的属性针对同一输入对象多次调用
Get-NetFireWallPortFilter
效率低下,并且降低了命令速度。上面的代码将始终为您提供所需的JSON表示形式,但是有一个警告:
ConvertTo-Json
通过对象为数组创建的JSON表示形式(包含数组元素的value
属性和元素计数的count
属性)应视为错误,因为数组应简单地表示为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讨论了详细信息,但是请注意,可以在给定的Windows PowerShell session 中运行以下命令一次来解决此问题:
# Run this once per session, before calling ConvertTo-Json, to
# fix the JSON array serialization problem:
Remove-TypeData System.Array -ErrorAction Ignore
关于c# - 以空值将Powershell内容保存为JSON,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59453502/