将两个不同的Get-ChildItem调用的结果合并为单个变量,以对它们执行相同的处理

Nat*_*ate 19 arrays powershell get-childitem

我正在尝试编写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
Run Code Online (Sandbox Code Playgroud)

失败并出现此错误:

无法转换参数"0",值为:"System.Object []","Add"键入"System.IO.FileInfo":"无法转换"System.Object []"va lue类型"系统. Object []"键入"System.IO.FileInfo"."

我最感兴趣的是这种情况的正确方法是什么.我意识到我的代码是一种非常简单的C方式 - 如果有更多的PowerShell方法来完成相同的任务,我就是全力以赴.关键是,数量$loc#'s可能会随着时间的推移而变化,因此在生成的代码中添加和删除一两个应该很容易.

mjo*_*nor 29

来自get-help get-childitem:-Path 指定一个或多个位置的路径.允许使用通配符.默认位置是当前目录(.).

$items = get-childitem '\\server\C$\Program Files (x86)\Data1\','\\server\C$\Web\DataStorage\' -Recurse
Run Code Online (Sandbox Code Playgroud)


Kei*_*ill 25

不确定你需要一个通用列表.您可以使用PowerShell数组,例如:

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

PowerShell数组可以使用连接+=.

  • 也许应该解释对`@()`的需求(?). (4认同)

Jay*_*kul 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 } )) )
Run Code Online (Sandbox Code Playgroud)

或者使用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)) )
Run Code Online (Sandbox Code Playgroud)


Rom*_*min 5

这是一些甚至更像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
Run Code Online (Sandbox Code Playgroud)

但是应该更加仔细地编写脚本块中的代码,以避免不必要的输出与文件系统项混合在一起。

编辑:或者,也许更有效,而不是.{ ... }我们可以使用@( ... )$( ... )其中...代表包含几个调用的代码Get-ChildItem