如何在命令的输出中加入两个变量的值以使用 Powershell 在 json 模式下进行转换

How to join the value of two variables in the output of the command to convert in json mode with Powershell

使用 powershell,只需一行(先决条件)并使用 foreach,我可以获得文件夹的上次更新日期和天数差异,但是,我需要以一种格式获取此信息,以便通过json 并且我无法使用 $DiasV 的值显示 $pasta 的值 为什么在使用“| convertto-Json” 转换时结果格式不正确(我正在验证通过https://jsonformatter.org/json-parser).

foreach ($pasta in Get-ChildItem -Path C:\TEMP\ -Directory) 
{
$ErrorActionPreference = 'SilentlyContinue';
$path = 'C:\TEMP\' + $pasta + '\EXAMPLE';
$start = Get-ChildItem -Path $path -File | Sort-Object -Property CreationTime | Select-Object -ExpandProperty LastWriteTime -Last 1;
$end = Get-Date; $DiasV = (New-TimeSpan -Start $start -End $end);
write $pasta.Name $pasta.LastWriteTime $DiasV.Days | ConvertTo-Json 
}

输出:

[
    "A123_1A_CAB",
    {
        "value":  "\/Date(1649508388226)\/",
        "DateTime":  "sábado, 9 de abril de 2022 09:46:28"
    },
    0
]
[
    "C166_5AND_BBB",
    {
        "value":  "\/Date(1649610666329)\/",
        "DateTime":  "domingo, 10 de abril de 2022 14:11:06"
    },
    2
]

我的目的是得到这个输出:

[
    {
        "pasta":  "A123_1A_CAB"
        "value":  "\/Date(1649508388226)\/",
        "DateTime":  "sábado, 9 de abril de 2022 09:46:28"
        "Dias":  "0"
    },
    {
        "pasta":  "C166_5AND_BBB"
        "value":  "\/Date(1649610666329)\/",
        "DateTime":  "domingo, 10 de abril de 2022 14:11:06"
        "Dias":  "2"
    }
]

我需要帮助来解决这个问题,已经尝试了几种方法 success.I还在学习英语。

您的主要问题是您希望将输出转换为 单个 JSON 数组:

  • 通过将 ConvertTo-Json 调用 放在 foreach 循环中,您正在创建一个 单独的 JSON 每次迭代中的文档,当 合并 as-is 时会导致 格式错误 JSON .

  • 只需将ConvertTo-Json应用于所有你的输出对象,在所有循环迭代中;如果您切换到使用
    ForEach-Object cmdlet 的单个管道,这将更容易实现。

  • 此外,您需要将要为每个目录报告的信息片段封装在一个 object 中,其 properties包含信息:

将它们放在一起,并进行一些优化:

Get-ChildItem -Path C:\TEMP\ -Directory |
  ForEach-Object { 
    $ErrorActionPreference = 'SilentlyContinue';
    $path = $_.FullName + '\EXAMPLE';
    $start = Get-ChildItem -LiteralPath $path -File | 
               Sort-Object -Property CreationTime |
                 Select-Object -ExpandProperty LastWriteTime -Last 1;
    $end = Get-Date; $DiasV = ($end - $start).Days;
    # Create a helper object for the "value" and "DateTime" properties. 
    $dateTimeCustom = $_.LastWriteTime | ConvertTo-Json | ConvertFrom-Json
    # Output the pieces of information encapsulated in an object.
    [pscustomobject] @{ 
      pasta = $_.Name;
      value = $dateTimeCustom.value;
      DateTime = $dateTimeCustom.DateTime;
      Dias = $DiasV
    }
} | ConvertTo-Json 

注:

  • 我在语句末尾保留 ; 的唯一原因是便于将代码转换为 单行 。正如所写,; 不是 必需的。

  • 您的输出暗示您正在使用 Windows PowerShell,其中 ConvertTo-Json[datetime] 值序列化为 具有两个或三个属性的对象.value(基于 Unix 纪元时间表示的自定义字符串表示,例如 "\/Date(1649508388226)\/")、.DateTime、a友好的显示字符串,并且 - 如果 [datetime] 实例是通过 Get-Date 获得的 - 另外一个 .DisplayHint 属性.

    • 为了“扁平化”这些属性并使它们成为输出对象的直接属性,使用 round-trip JSON 转换来创建具有这些 属性 值 ($dateTimeCustom = $_.LastWriteTime | ConvertTo-Json | ConvertFrom-Json).

      • 严格来说,Windows PowerShell 中的 ConvertTo-Json 会为 [datetime] 实例生成具有属性 的 对象 -而不仅仅是 单个字符串 例如 "\/Date(1649508388226)\/" - 应该被认为是 bug,尤其是因为 round-tripping 这样的对象 不会 导致 [datetime] 实例,但会导致 [pscustomobject] 具有属性 .value.DateTime 的实例,并且在某些情况下也会 .DisplayHint(我们在这里利用它)。

      • 问题出现了,因为[datetime]实例被type-levelETSScriptProperty成员装饰,.DateTime,不幸的是,包含在序列化中,导致手头的 two-property 对象表示。如果您要删除与 [datetime] 关联的类型数据,问题就会消失(但 属性 也会消失),例如:

        # Windows PowerShell only.
        # Note that if you were to use Get-Date output, *another*,
        # instance-level ETS property would come into play, .DisplayHint
        PS> Remove-TypeData System.DateTime; [datetime]::now | ConvertTo-Json
        "\/Date(1649702531387)\/"  # e.g. - single string
        
  • 请注意,PowerShell (Core) 7+ 不再使用此 custom-object 表示,而是将 [datetime] 实例序列化为 [= ISO 8601 date-time 格式的 68=]strings(例如,"2021-10-11T13:27:12.3318432-04:00"