gpt4 book ai didi

c# - 以空值将Powershell内容保存为JSON

转载 作者:行者123 更新时间:2023-12-03 00:06:55 25 4
gpt4 key购买 nike

我必须使用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/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com