1

私の現在の Powershell スクリプトは、コンピューター名の .txt ドキュメントと、csv ファイルにインポートできるようにしたいソフトウェアを吐き出します。各コンピューター名は新しい列です。

現在、出力は次のようになります。

PC1=

商品名

ソフトウェアA

ソフトウェアB

PC2=

商品名

ソフトウェアA

ソフトウェアB

このデータを適切にソートするためにこれをスクリプト化するにはどうすればよいですか? csv に直接インポートすると、この情報がすべて 1 つの列に表示されます。次の列に書き込むために 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}
4

2 に答える 2

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'

前述したように、これは強引なアプローチですが、各コンピューターのソフトウェア リストを列として持つ必要があるため、使用できる出力オプションが制限されます。

于 2013-10-12T02:45:49.973 に答える