问题描述
我正在尝试编写一个 PS 脚本,该脚本将搜索所有标记为受限数据的目录,并在受限数据文件夹或其子文件夹中有任何文件时返回结果。我遇到的问题是,即使受限数据中有空子文件夹,它也会返回结果。我认为这可能是因为我的脚本包含 $_.GetDirectories().Count -gt 0
,但是当我删除该部分时没有得到任何有效或无效的结果。
Get-ChildItem -Path "C:\Temp" -Recurse | Where-Object {$_.name -like "Restricted Data" -and ($_.GetFiles().Count -gt 0 -or $_.GetDirectories().Count -gt 0)}
有什么想法吗?
我正在更新这篇文章,以包含一些被询问的细节。
文件结构如下例所示。每个 RootFolder 将包含一个或多个 PName 文件夹。每个 PName 文件夹可能包含一个名为 Restricted Data 的文件夹。每个受限数据文件夹将包含子文件夹。这些子文件夹可能包含也可能不包含文件,并且可能存在直接位于受限数据文件夹内的文件。如果脚本直接在受限数据文件夹或任何子文件夹中找到任何文件,我需要它返回指示这些目录的 RootFolder\PName 路径的结果。
RootFolder1\PName\Restricted Data\Subfolder\Subfolder\file.docx
RootFolder1\PName2\Restricted Data\Subfolder\Subfolder\file.docx
RootFolder2\PName\Restricted Data\Subfolder\Subfolder
RootFolder3\PName\Restricted Data\Subfolder\file.xlsx
RootFolder4\PName\Restricted Data\Subfolder\
解决方法
如果我正确解释了您的问题,这里是包含一些示例文件的目录结构。除了以下结构中的两个 test.txt
文件外,所有都是目录:
C:\TEMP\test
C:\TEMP\test2
C:\TEMP\test3
C:\TEMP\test2\Restricted Data
C:\TEMP\test2\test.txt
C:\TEMP\test2\Restricted Data\test.txt
C:\TEMP\test3\Restricted Data
C:\TEMP\test3\Restricted Data\empty
此命令将仅查找具有确切名称 Restricted Data
的目录,然后仅列出具有多个文件的 Restricted Data
目录:
dir -Recurse -Directory -Path 'Restricted Data' | ?{ (Get-ChildItem $_ -File).Count } | %{ "$($_.FullName): $((Get-ChildItem $_ -File).Count)" }
或删除别名:
Get-ChildItem -Recurse -Directory -Path 'Restricted Data' | `
Where-Object { (Get-ChildItem $_ -File).Count } | `
Foreach-Object { "$($_.FullName): $((Get-ChildItem $_ -File).Count)" }
您可以更改输出,但我的示例仅显示 Restricted Data
不为空时的文件数:
C:\TEMP\test2\Restricted Data: 1
,
您可以尝试以下脚本。
它只列出与搜索词匹配且至少包含一个文件的目录。
它不计算文件。
此外,它节省了处理时间,因为当在该特定文件夹中已经找到一个文件时,它不会枚举所有文件(通过使用 System.Linq 完成)
$rootDirectoryPath = 'C:\Temp'
$searchTerm = 'Restricted Data'
Get-ChildItem -LiteralPath $rootDirectoryPath -Directory -Filter $searchTerm -Recurse |
Where-Object {
($null -ne [System.Linq.Enumerable]::FirstOrDefault(
[System.IO.Directory]::EnumerateFiles($_.FullName,'*',[System.IO.SearchOption]::AllDirectories)
)
)
}
更新
这是一个更简单的解决方案,在访问异常方面可能更好。
当使用 Direcotry.EnumerateFiles(来自之前的解决方案)并且遇到“拒绝访问”异常时,它将停止并且不会查看其他目录。
新的解决方案不会停止。它只是抛出一个异常并使用下一个目录。
$rootDirectoryPath = 'C:\Temp'
$searchTerm = 'Restricted Data'
Get-ChildItem -LiteralPath $rootDirectoryPath -Directory -Filter $searchTerm -Recurse |
Where-Object {
$null -ne (Get-ChildItem -LiteralPath $_.FullName -File -Recurse | Select-Object -First 1)
}