如何从 PowerShell 中的 Get-ChildItem 中排除文件和文件夹?
How to exclude files and folders from Get-ChildItem in PowerShell?
我制作了一个 PowerShell 脚本,它运行带有 md5 检查的 robocopy。
它工作正常,但如果我尝试排除一些目录或文件,robocopy 会处理排除,而比较哈希的脚本的 MD5 部分不起作用,returns 一些错误,因为源files/hash 多于目的地...
我可能已经尝试了在这里和 Internet 上找到的所有方法!我无法从路径中排除 dirs and/or 个文件!
以下是我目前所做的。在这种模式下,md5-copy 有效(没有排除):
$Source = "F:\"
$IgnoreDir = @(
$Source + '$RECYCLE.BIN'
$Source + "System Volume Information"
$Source + "VMs"
)
$IgnoreFile = @(
$Source + "SHDrive.vmdk"
$Source + "SHDrive-flat.vmdk"
)
$Ignored = $IgnoreDir + $IgnoreFile
机械复制:
Robocopy.exe /R:1 /W:0 $Source $Dest /E /V /TEE /XD $IgnoreDir /XF $IgnoreFile /LOG:$LogDir\RBCY_MD5_F.txt
MD5:
$SourceHash = Get-ChildItem "$Source\*.*" -Recurse -Force -Exclude $Ignored | Where-Object {!$_.psiscontainer } | Get-FileHash
$SourceHash | Select-Object "Hash", "path" | ft -HideTableHeaders -AutoSize | Out-File -Width "300" $LogDir\SRC_MD5_REF.txt
$SourceHash.Hash | Out-File $LogDir\SRC_MD5.txt
比较:
$Diff = Compare-Object -ReferenceObject $(get-content "$LogDir\SRC_MD5.txt") -DifferenceObject $(get-content "$LogDir\DST_MD5.txt")
F:\盘的内容:
PS C:\Users\Robbi> Get-ChildItem F:\ -force
Directory: F:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d--hs- 19/03/2019 06:40 $RECYCLE.BIN
d----- 16/05/2020 04:41 DATA
d----- 19/01/2020 06:34 Drivers
d----- 16/05/2020 04:55 Gumball
d----- 16/05/2020 04:58 SW
d--hs- 19/03/2019 06:36 System Volume Information
d----- 13/03/2020 16:08 Tools
d----- 12/12/2019 00:02 VMs
d----- 16/05/2020 04:55 _Pre-Cestino
-a---- 08/02/2020 03:02 21474836480 SHDrive-flat.vmdk
-a---- 08/02/2020 03:02 466 SHDrive.vmdk
如何从 get-children 列表中排除我不想复制的数据?在这种特定情况下,如果可能,在 Get-ChildItem 必须排除整个文件系统中的显式内容列表(变量字符串 and/or 数组)的“所有情况”下。
从 PowerShell 7.1 开始,Get-ChildItem
等 cmdlet 的 -Exclude
和 -Include
提供程序参数仅对项目 names(文件/ 目录名称,在文件系统提供程序的情况下),而不是 完整路径 或目录 子树 .
- GitHub feature request #4126 要求将来也支持 path 模式。
- GitHub feature request #15159提出了一个新的subtree-exclusion参数,比如
-ExcludeRecursive
.
鉴于您要排除的所有路径都是目标目录的直接子目录,我建议采用两步法:
# Get all files and directories in $Source, except those to be excluded.
# Note the use of \* instead of \*.*, so as to also include the
# directories (whose names don't have an extension).
$items = Get-Item $Source\* -Force | Where-Object FullName -NotIn $Ignored
# Recursively process all resulting files and directories and
# calculate their hashes.
# Note the use of -File to limit output to files.
$SourceHash = $items | Get-ChildItem -Recurse -Force -File | Get-FileHash
当然,如果您只根据 file/directory names 定义 $Ignored
数组,您 可以 使用 -Exclude
:
# Convert the ignore list to file/directory names only.
$Ignored = $Ignored | Split-Path -Leaf
$SourceHash = Get-ChildItem -File $Source -Recurse -Force -Exclude $Ignored |
Get-FileHash
如果要排除的路径可以出现在子目录层次结构的任何级别,则需要做更多的工作:
$ignoredRegex = '(?<=^|\{0})({1})(?=\{0}|$)' -f
[IO.Path]::DirectorySeparatorChar,
($Ignored.ForEach({ [regex]::Escape($_) }) -join '|')
$SourceHash = Get-ChildItem $Source -Recurse -File -Force |
Where-Object FullName -notmatch $ignoredRegex
Get-FileHash
以上使用 regular expression with the (negated form of the) -match
运算符以递归方式 排除子目录树中任何位置的所有指定项 及其子项。
我制作了一个 PowerShell 脚本,它运行带有 md5 检查的 robocopy。
它工作正常,但如果我尝试排除一些目录或文件,robocopy 会处理排除,而比较哈希的脚本的 MD5 部分不起作用,returns 一些错误,因为源files/hash 多于目的地...
我可能已经尝试了在这里和 Internet 上找到的所有方法!我无法从路径中排除 dirs and/or 个文件!
以下是我目前所做的。在这种模式下,md5-copy 有效(没有排除):
$Source = "F:\"
$IgnoreDir = @(
$Source + '$RECYCLE.BIN'
$Source + "System Volume Information"
$Source + "VMs"
)
$IgnoreFile = @(
$Source + "SHDrive.vmdk"
$Source + "SHDrive-flat.vmdk"
)
$Ignored = $IgnoreDir + $IgnoreFile
机械复制:
Robocopy.exe /R:1 /W:0 $Source $Dest /E /V /TEE /XD $IgnoreDir /XF $IgnoreFile /LOG:$LogDir\RBCY_MD5_F.txt
MD5:
$SourceHash = Get-ChildItem "$Source\*.*" -Recurse -Force -Exclude $Ignored | Where-Object {!$_.psiscontainer } | Get-FileHash
$SourceHash | Select-Object "Hash", "path" | ft -HideTableHeaders -AutoSize | Out-File -Width "300" $LogDir\SRC_MD5_REF.txt
$SourceHash.Hash | Out-File $LogDir\SRC_MD5.txt
比较:
$Diff = Compare-Object -ReferenceObject $(get-content "$LogDir\SRC_MD5.txt") -DifferenceObject $(get-content "$LogDir\DST_MD5.txt")
F:\盘的内容:
PS C:\Users\Robbi> Get-ChildItem F:\ -force
Directory: F:\
Mode LastWriteTime Length Name
---- ------------- ------ ----
d--hs- 19/03/2019 06:40 $RECYCLE.BIN
d----- 16/05/2020 04:41 DATA
d----- 19/01/2020 06:34 Drivers
d----- 16/05/2020 04:55 Gumball
d----- 16/05/2020 04:58 SW
d--hs- 19/03/2019 06:36 System Volume Information
d----- 13/03/2020 16:08 Tools
d----- 12/12/2019 00:02 VMs
d----- 16/05/2020 04:55 _Pre-Cestino
-a---- 08/02/2020 03:02 21474836480 SHDrive-flat.vmdk
-a---- 08/02/2020 03:02 466 SHDrive.vmdk
如何从 get-children 列表中排除我不想复制的数据?在这种特定情况下,如果可能,在 Get-ChildItem 必须排除整个文件系统中的显式内容列表(变量字符串 and/or 数组)的“所有情况”下。
从 PowerShell 7.1 开始,Get-ChildItem
等 cmdlet 的 -Exclude
和 -Include
提供程序参数仅对项目 names(文件/ 目录名称,在文件系统提供程序的情况下),而不是 完整路径 或目录 子树 .
- GitHub feature request #4126 要求将来也支持 path 模式。
- GitHub feature request #15159提出了一个新的subtree-exclusion参数,比如
-ExcludeRecursive
.
鉴于您要排除的所有路径都是目标目录的直接子目录,我建议采用两步法:
# Get all files and directories in $Source, except those to be excluded.
# Note the use of \* instead of \*.*, so as to also include the
# directories (whose names don't have an extension).
$items = Get-Item $Source\* -Force | Where-Object FullName -NotIn $Ignored
# Recursively process all resulting files and directories and
# calculate their hashes.
# Note the use of -File to limit output to files.
$SourceHash = $items | Get-ChildItem -Recurse -Force -File | Get-FileHash
当然,如果您只根据 file/directory names 定义 $Ignored
数组,您 可以 使用 -Exclude
:
# Convert the ignore list to file/directory names only.
$Ignored = $Ignored | Split-Path -Leaf
$SourceHash = Get-ChildItem -File $Source -Recurse -Force -Exclude $Ignored |
Get-FileHash
如果要排除的路径可以出现在子目录层次结构的任何级别,则需要做更多的工作:
$ignoredRegex = '(?<=^|\{0})({1})(?=\{0}|$)' -f
[IO.Path]::DirectorySeparatorChar,
($Ignored.ForEach({ [regex]::Escape($_) }) -join '|')
$SourceHash = Get-ChildItem $Source -Recurse -File -Force |
Where-Object FullName -notmatch $ignoredRegex
Get-FileHash
以上使用 regular expression with the (negated form of the) -match
运算符以递归方式 排除子目录树中任何位置的所有指定项 及其子项。