21

複数のディレクトリからファイルのリストを作成する PowerShell スクリプトを作成しようとしています。すべてのディレクトリがメイン リストに追加された後、すべてのファイルに対して同じ処理を実行したいと考えています。

これは私が持っているものです:

$items = New-Object Collections.Generic.List[IO.FileInfo]

$loc1 = @(Get-ChildItem -Path "\\server\C$\Program Files (x86)\Data1\" -Recurse)
$loc2 = @(Get-ChildItem -Path "\\server\C$\Web\DataStorage\" -Recurse)

$items.Add($loc1) # This line fails (the next also fails)
$items.Add($loc2)

# Processing code is here

このエラーで失敗します:

引数 "0"、値: "System.Object[]"、"Add" を "System.IO.FileInfo" 型に変換できません: "型 "System.Object[]" の値を変換できません。 Object[]" を "System.IO.FileInfo" と入力します。"

私は主に、この種の状況に対する正しいアプローチに興味があります。私のコードは非常にC的な方法であることに気付きました。同じタスクを達成するためのより多くの PowerShell の方法があれば、私はそれを支持します。重要なのは、の数が$loc#'s時間の経過とともに変化する可能性があるため、結果のコードで 1 つまたは 2 つを追加および削除するのは簡単なはずです。

4

5 に答える 5

34

ここで一般的なリストが必要かどうかはわかりません。たとえば、PowerShell 配列を使用できます。

$items  = @(Get-ChildItem '\\server\C$\Program Files (x86)\Data1\' -r)
$items += @(Get-ChildItem '\\server\C$\Web\DataStorage\' -r)

PowerShell 配列は、 を使用して連結できます+=

于 2011-01-20T16:56:41.593 に答える
29

get-help get-childitem より: -Path 1 つまたは複数の場所へのパスを指定します。ワイルドカードを使用できます。デフォルトの場所は現在のディレクトリ (.) です。

$items = get-childitem '\\server\C$\Program Files (x86)\Data1\','\\server\C$\Web\DataStorage\' -Recurse
于 2011-01-20T19:16:18.503 に答える
6

これは、一部の連結や結果への明示的な項目の追加をまったく必要としない、おそらくさらに PowerShell っぽい方法です。

# Collect the results by two or more calls of Get-ChildItem
# and perhaps do some other job (but avoid unwanted output!)
$result = .{

    # Output items
    Get-ChildItem C:\TEMP\_100715_103408 -Recurse

    # Some other job
    $x = 1 + 1

    # Output some more items
    Get-ChildItem C:\TEMP\_100715_110341 -Recurse

    #...
}

# Process the result items
$result

ただし、スクリプト ブロック内のコードは、不要な出力がファイル システム項目と混ざらないように、もう少し慎重に記述する必要があります。

編集: あるいは、おそらくより効果的に、or.{ ... }を使用する代わりに、 whereは の複数の呼び出しを含むコードを表します。@( ... )$( ... )...Get-ChildItem

于 2011-01-20T18:11:45.530 に答える
5

Keith の答えは PowerShell の方法です。@(...)+@(...) を使用するだけです。

タイプセーフな List[IO.FileInfo] が実際に必要な場合は、AddRange を使用し、オブジェクト配列を FileInfo 配列にキャストする必要があります。また、DirectoryInfo オブジェクトを取得しないようにする必要があります。リストタイプとして IO.FileSystemInfo を使用する必要があります。

したがって、ディレクトリは避けてください。

$items = New-Object Collections.Generic.List[IO.FileInfo]
$items.AddRange( ([IO.FileSystemInfo[]](ls '\\server\C$\Program Files (x86)\Data1\' -r | Where { -not $_.PSIsContainer } )) )
$items.AddRange( ([IO.FileSystemInfo[]](ls '\\server\C$\Web\DataStorage\' -r | Where { -not $_.PSIsContainer } )) )

または、FileSystemInfo (FileInfo と DirectoryInfo の共通基本クラス) を使用します。

$items = New-Object Collections.Generic.List[IO.FileSystemInfo]
$items.AddRange( ([IO.FileSystemInfo[]](ls '\\server\C$\Program Files (x86)\Data1\' -r)) )
$items.AddRange( ([IO.FileSystemInfo[]](ls '\\server\C$\Web\DataStorage\' -r)) )
于 2011-01-20T17:41:32.560 に答える