Powershell软件审计输出-csv格式分隔列

时间:2013-10-11 23:56:24

标签: powershell csv

我当前的Powershell脚本会吐出计算机名称的.txt文档,以及我希望能够导入csv文件的软件,每个计算机名称都是新列。

目前输出如下:

PC1 =

productname

SoftwareA

SoftwareB

PC2 =

产品名

SoftwareA

SoftwareB

如何编写此脚本以对此数据进行适当排序?直接导入到csv将在单个列中包含所有这些信息。有什么我可以抛出foreach循环让它写入下一列?或者我可以让每个循环写入它自己的.txt,然后获取每个.csv并将它们导入到新的表单中

这是源代码:

 $ComputerNames = get-content ".\Computers.txt"


foreach ($Computer in $ComputerNames)
 {$arryStandardSoftware = get-content -path ".\StandardSoftware.txt"| Foreach-Object{$_.trim()}
 $AuditResult = (Get-WMIObject -namespace "root\cimv2\sms" -class sms_installedsoftware -computername "$computer"|
               Select-Object productname|Where-Object{$arryStandardSoftware -notcontains "$($_.productname)"})
 echo "$Computer ="$AuditResult | out-file ".\SoftwareAudit.txt" -append}

2 个答案:

答案 0 :(得分:1)

powershell的强大功能是对象(PsCustomObject)。为了将每台计算机作为列输出,您可以使用计算机名作为属性名来构造自定义对象并向其添加新属性(只要计算机名称不包含空格或特殊字符)。 以下脚本应输出如下内容:

ProductName,  PC1,  PC2
SoftwareA,    true, false
SoftwareB,    false, true

没有测试过,但你应该得到基本的想法。

$ComputerNames = get-content ".\Computers.txt"
$arryStandardSoftware = get-content -path ".\StandardSoftware.txt"| Foreach-Object{$_.trim()}
$reports = $arryStandardSoftware | select @{N="ProductName";E={$_}}

foreach ($Computer in $ComputerNames)
{
    $installed = Get-WMIObject -namespace "root\cimv2\sms" -class sms_installedsoftware -computername "$computer" | select ProductName

    foreach ($r in $reports)
    {
        Add-Member -InputObject $r -MemberType NoteProperty -Name $Computer -Value ($installed -contains $r.ProductName)
    }
}

$reports | export-csv .\SoftwareAudit.txt -NoTypeInformation

答案 1 :(得分:0)

你想要的是一个数组数组。

ComputerA      ComputerB      ComputerC
SoftwareX      SoftwareX      SoftwareY
SoftwareY      SoftwareZ      SoftwareZ
SoftwareZ                     SoftwareA
                              SoftwareB

要获得此结果,您需要在循环WMI结果时编译每个数组。找到最长数组的长度,然后写出每一行。

这是一种蛮力的做法:

$ComputerNames = get-content ".\Computers.txt"
$ComputerIndex = 0
$MasterArray = New-Object object[] $ComputerNames.Count

#collect the list in an array of arrays
foreach ($Computer in $ComputerNames) {
    $arryStandardSoftware = get-content -path ".\StandardSoftware.txt"| Foreach-Object{$_.trim()}
    $AuditResult = (Get-WMIObject -namespace "root\cimv2\sms" -class sms_installedsoftware -computername "$computer"|
               Select-Object productname|Where-Object{$arryStandardSoftware -notcontains "$($_.productname)"})  

    $SoftwareArray = @()
    $SoftwareArray += $Computer

    $AuditResult | % { $SoftwareArray += $_.productname }
    $MasterArray[$ComputerIndex] = $SoftwareArray
    $ComputerIndex += 1
 }

在上一个循环中,为每台计算机构建一个数组。第一个元素是计算机名称,数组的其余部分是软件列表。

现在找出哪个阵列最长。

$longest = 0
for ($i=0;$i -lt $MasterArray.Count; $i++) {
    if ($MasterArray[$i].Count -gt $longest){
        $longest = $MasterArray[$i].Count
    }
}

一旦我们知道最大列长度,我们就可以遍历所有数组,构建将输出到CSV文件的行。

$MyOutput = $null

for ($i=0;$i -lt $longest; $i++) {
    $row = ""
    for ($j=0;$j -lt $MasterArray.Count; $j++) {
        if ($i -lt $MasterArray[$j].Count){
            $row += $MasterArray[$j][$i]
        }         
        if ($j -lt ($MasterArray.Count - 1) ){
            $row += "`t"
        }
    }    
   $MyOutput += ($row + "`r`n")
} 

$MyOutput > 'My.csv'

就像我说的,这是一种蛮力方法,但要求将每台计算机的软件列表作为列限制了可用的输出选项。