以特定方式从Powershell序列化JSON

时间:2017-10-04 22:00:27

标签: json powershell

所以我有这个脚本,它可以找到机器上安装的所有软件版本,让人们知道什么软件以及何时安装在多个虚拟机上。

我想将它放在我们使用的仪表板提供程序上,但它们具有使用它的特定格式。

它确实产生了有效的JSON,但我发现它不符合公司希望的格式。

将是:

{"table": [["header1", "header2"], ["row1column1", "row1column2"], ["row2column1", "row2column2"]]}

我的第一个想法是将标题行作为开始变量,然后为每个组件生成单个变量,但为每个单独的数据行创建变量(日期,软件名称等)会非常繁琐和费力。然后在最后将它们组合成1并转换为json

我的脚本是这样的:

[CmdletBinding()]
Param (
    [Parameter(ValueFromPipeline = $true,
        ValueFromPipelinebyPropertyName = $true)]
    [Alias("Servers")]
    [string[]]$Name = (Get-Content "c:\utils\servers.txt")
)
Begin {

}
Process {
    $AllComputers = @()
    #Gather all computer names before processing
    ForEach ($Computer in $Name) {
        $AllComputers += $Computer
    }
}

End {
    ForEach ($Computer in $AllComputers) {

        write-output "Checking $computer"
        if ($computer -like "*x86*") {
            $data = Invoke-Command -cn $computer -ScriptBlock {Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object @{Label = "ServerName"; Expression = {$env:computername}}, DisplayName, Publisher, DisplayVersion, InstallDate | Where-object { $_.Publisher -match "Foobar"  }}
            $jsondata += $data
        }
        else {
            $data = Invoke-Command -cn $computer -ScriptBlock { Get-ItemProperty HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object @{Label = "ServerName"; Expression = {$env:computername}}, DisplayName, Publisher, DisplayVersion, InstallDate | Where-object { $_.Publisher -match "foobar" } }
            $jsondata += $data
        }
    } 
    $jsondata | ConvertTo-Json -depth 100 | Out-File "\\servername\C$\Utils\InstalledApps.json"
}

1 个答案:

答案 0 :(得分:0)

从提供的示例输出格式中我得出结论,您正在寻找一个数组数组。有一个"bug" using ConvertTo-Json when trying to do this但是因为我们无论如何都需要它在一个表对象中。我将使用您的代码展示一个示例,但仅在我的本地计算机上。将其集成到您的代码中应该不是问题。

# gather the results
$results = Get-ItemProperty HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\* | Where-object { $_.Publisher -match "The"  } | Select-Object @{Label = "ServerName"; Expression = {$env:computername}}, DisplayName, Publisher, DisplayVersion, InstallDate

# Prepare an array of arrays for the output. 
$outputToBeConverted = @()

# build the header
$header = ($results | Get-Member -MemberType NoteProperty).Name
$outputToBeConverted += ,$header

# Add the rows 
Foreach($item in $results){
    # Create a string array by calling each property individually
    $outputToBeConverted += ,[string[]]($header | ForEach-Object{$item."$_"})
}

[pscustomobject]@{table=$outputToBeConverted} | ConvertTo-Json -Depth 5 

基本上它是制作一个参差不齐的数组,其中第一个成员是你的"标题"并且每行都是从$results集合中的项目手动构建的。

您将看到上面使用的一元运算符,。这样做是为了防止PowerShell展开数组。如果没有它,你可能会在输出中得到一个长数组。