![実際のパスの代わりにSystem.Object](https://rvso.com/image/658366/%E5%AE%9F%E9%9A%9B%E3%81%AE%E3%83%91%E3%82%B9%E3%81%AE%E4%BB%A3%E3%82%8F%E3%82%8A%E3%81%ABSystem.Object.png)
以下のスクリプトは、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