简体   繁体   English

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

[英]Powershell Software Audit Output -csv format separated columns

My current Powershell script spits out a .txt doc of the computer name, and software that I would like to be able to import into a csv file, with each computer name being a new column. 我当前的Powershell脚本吐出了一个.txt文档,其中包含计算机名称以及我希望能够导入到csv文件中的软件,每台计算机名称都是一个新列。

currently the output looks like this: 当前输出看起来像这样:

PC1= PC1 =

productname 产品名称

SoftwareA SoftwareA

SoftwareB SoftwareB

PC2= PC2 =

productname 产品名称

SoftwareA SoftwareA

SoftwareB SoftwareB

how can I script this to appropriately sort this data? 如何编写脚本以对数据进行适当排序? a straight import to csv will have all of this info in a single column. 直接导入到csv将在单列中包含所有这些信息。 Is there something I can throw on the foreach loop to have it write to the next column? 我可以在foreach循环上添加一些内容以使其写入下一列吗? Or could I have each loop write to it's own .txt, and then grab each .csv and have them import into a new sheet 或者我可以让每个循环将其写入自己的.txt,然后抓取每个.csv并将其导入到新工作表中

here's the source code: 这是源代码:

 $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}

The power of powershell is objects (PsCustomObject). powershell的功能是对象(PsCustomObject)。 In order to output each computer as a column, you can construct custom object and add new property to it, using computer name as property name (so long the computer name does not contain spaces or special characters). 为了将每台计算机输出为一列,可以使用计算机名作为属性名(只要计算机名不包含空格或特殊字符),就可以构造自定义对象并向其添加新属性。 The following script should output something like this: 以下脚本应输出如下内容:

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

Haven't tested it, but you should get the basic idea. 还没有测试过,但是您应该了解基本概念。

$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

What you want is an array of arrays. 您想要的是一个数组数组。

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

To get this result, you need to compile each array as you loop through the WMI results. 为了获得此结果,您需要在遍历WMI结果时编译每个数组。 Find the length of the longest array and then write out each row. 找到最长的数组的长度,然后写出每一行。

Here is a brute force approach to doing that: 这是一种蛮力的方法:

$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
 }

In the previous loop, an array is built for each computer. 在上一个循环中,为每台计算机构建一个阵列。 The first element is the computer name and the rest of the array is the list of software. 第一个元素是计算机名称,而数组的其余部分是软件列表。

Now find out which of the arrays is the longest. 现在找出哪个数组最长。

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

Once we know the maximum column length, we can iterate through all the arrays, building the rows which will be output to the CSV file. 一旦知道最大列长度,就可以遍历所有数组,构建将输出到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'

Like I said, this is a brute force approach, but the requirement to have each computer's software list as a column restricts the output options available. 就像我说的那样,这是一种蛮力方法,但是要求将每台计算机的软件列表作为一列,这限制了可用的输出选项。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM