実際のパスの代わりにSystem.Object

実際のパスの代わりにSystem.Object

以下のスクリプトは、CSV ファイル内の問題のファイルへのパスを生成しません。代わりに、System.Object[] が返されます。ここで何が間違っているのか教えてください。

私の目標は、冗長な GPO をクリーンアップすることです。GPO バックアップから xml ファイルを検索して分析する必要があります。2 つ以上の GPO で同じカスタム文字列が見つかった場合、パスによって冗長な文字列が含まれているフォルダーが表示されるので、GPO を結合するか、1 つをまとめて削除することができます。意味が通っていると思いますか?

$ht = @()
$files = Get-ChildItem -recurse -Filter *.xml
    foreach ($file in $files)
{
    $path = $file.FullName
    $lines = Get-Content $path
    foreach ($line in $lines)
    {
         if ($match = $ht | where { $_.line -EQ $line })
         {
            $match.count = $match.count + 1
            $match.Paths += $path
         }
        else
        {
            $ht += new-object PSObject -Property @{
                Count = 1
                Paths = @(, $path)
                Line = $line
            }
        }
    }
}

$ht
$ht.GetEnumerator() | select Count, Paths, Line | Export-Csv c:\temp    \NLG_GPO_Sort.csv

答え1

Export-Csv は CSV ファイルに文字列を出力する必要がありますが、 プロパティはPaths文字列ではないため、PowerShell は暗黙的に を呼び出しToString()、結果として文字列System.Object[]( の型Paths) が生成されます。

Select-Object次のように、セミコロンで区切られたパスの文字列を計算するために使用します。

$ht.GetEnumerator() | select Count, @{Name="Paths";e={$_.Paths -join ";"}}, Line|Export-Csv C:\temp\file.csv

そうは言っても、あなたがやろうとしていることは、以下を使用して単一のパイプラインで簡単に実現できますGroup-Object

Get-ChildItem -Recurse -Filter *.xml |Select-Object -First 10 |Select-String ".*" |Group-Object Line |Select-Object Count,@{Name="Paths";Expression={$_.Group.Filename -join ";"}},@{Name="Line",Expression={$_.Name}}

もう少し読みやすく:

$Lines = Get-ChildItem -Recurse -Filter *.xml |Select-Object -First 10 |Select-String ".*"
$Groups = $Lines |Group-Object Line 
$Output = $Groups |Select-Object Count,@{Name="Paths";Expression={$_.Group.Filename -join ";"}},@{Name="Line",Expression={$_.Name}}
$Output | Export-Csv C:\temp\file.csv

関連情報