You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

提取文件元数据时如何跳过指定子文件夹?

修改PowerShell脚本实现跳过指定子文件夹

你的脚本依赖robocopy扫描文件,而robocopy本身支持/XD参数排除目录,不需要用continue语句,直接扩展参数并修改命令即可解决问题。

具体修改步骤

1. 添加排除文件夹的参数

在函数的Param块中,新增ExcludeFolder参数,放在ExcludeFile参数下方:

[parameter(ParameterSetName='Exclude')]
[string[]]$ExcludeFolder,

2. 修改robocopy命令构建逻辑

替换原脚本中构建robocopy命令的代码,同时处理文件排除和文件夹排除:

# 初始化基础robocopy命令
$Script = "robocopy \`"$item\`" NULL $Filter $params"
# 添加文件排除参数
If ($PSBoundParameters['ExcludeFile']) {
    $Script += " /XF $($ExcludeFile  -join ',')"
}
# 添加文件夹排除参数
If ($PSBoundParameters['ExcludeFolder']) {
    $Script += " /XD $($ExcludeFolder  -join ',')"
}

3. 修改后的完整脚本

Function Get-FolderItem {
    
    [cmdletbinding(DefaultParameterSetName='Filter')]
    Param (
        [parameter(Position=0,ValueFromPipeline=$True,ValueFromPipelineByPropertyName=$True)]
        [Alias('FullName')]
        [string[]]$Path = $PWD,
        [parameter(ParameterSetName='Filter')]
        [string[]]$Filter = '*.*',    
        [parameter(ParameterSetName='Exclude')]
        [string[]]$ExcludeFile,
        [parameter(ParameterSetName='Exclude')]
        [string[]]$ExcludeFolder,             
        [parameter()]
        [int]$MaxAge,
        [parameter()]
        [int]$MinAge
    )
    Begin {
        $params = New-Object System.Collections.Arraylist
        $params.AddRange(@("/L","/E","/NJH","/BYTES","/FP","/NC","/XJ","/R:0","/W:0","T:W","/UNILOG:c:\temp\test.txt"))
        If ($PSBoundParameters['MaxAge']) {
            $params.Add("/MaxAge:$MaxAge") | Out-Null
        }
        If ($PSBoundParameters['MinAge']) {
            $params.Add("/MinAge:$MinAge") | Out-Null
        }
    }
    Process {
        ForEach ($item in $Path) {
            Try {
                $item = (Resolve-Path -LiteralPath $item -ErrorAction Stop).ProviderPath
                If (-Not (Test-Path -LiteralPath $item -Type Container -ErrorAction Stop)) {
                    Write-Warning ("{0} is not a directory and will be skipped" -f $item)
                    Return
                }
                # 构建robocopy命令,同时处理文件和文件夹排除
                $Script = "robocopy \`"$item\`" NULL $Filter $params"
                If ($PSBoundParameters['ExcludeFile']) {
                    $Script += " /XF $($ExcludeFile  -join ',')"
                }
                If ($PSBoundParameters['ExcludeFolder']) {
                    $Script += " /XD $($ExcludeFolder  -join ',')"
                }
                Write-Verbose ("Scanning {0}" -f $item)
                Invoke-Expression $Script | Out-Null
                get-content "c:\temp\test.txt" | ForEach {
                    Try {
                        If ($_.Trim() -match "^(?<Children>\d+)\s(?<FullName>.*)") {
                           $object = New-Object PSObject -Property @{
                                FullName = $matches.FullName
                                #Extension = $matches.fullname -replace '.*\.(.*)','$1'
                                #FullPathLength = [int] $matches.FullName.Length
                                #FileHash = Get-FileHash -LiteralPath "\\?\$($matches.FullName)" |Select -Expand Hash
                                #Created = ([System.IO.FileInfo] $matches.FullName).creationtime
                                #Created = ([System.IO.FileInfo] "\\?\$($matches.FullName)").creationtime
                                #LastWriteTime = ([System.IO.FileInfo] "\\?\$($matches.FullName)").LastWriteTime
                                #Characters = (Get-Content -LiteralPath "\\?\$($matches.FullName)" | Measure-Object -ignorewhitespace -Character).Characters
                                #Size = ([System.IO.FileInfo] "\\?\$($matches.FullName)").length
                                #Access = ((Get-Acl -LiteralPath "\\?\$($matches.FullName)") |Select -Expand AccessToString)-replace '[\r\n]',' '
                                #$permission = (Get-Acl $Folder).Access | ?{$_.IdentityReference -match $User} | Select IdentityReference,FileSystemRights
                                #Owner = (Get-ACL $matches.Fullname).Owner
                            } 
                            $object.pstypenames.insert(0,'System.IO.RobocopyDirectoryInfo')
                            Write-Output $object
                        } Else {
                            Write-Verbose ("Not matched: {0}" -f $_)
                        }
                    } Catch {
                        Write-Warning ("{0}" -f $_.Exception.Message)
                        Return
                    }
                }
            } Catch {
                Write-Warning ("{0}" -f $_.Exception.Message)
                Return
            }
        }
    }
}

# 调用示例:跳过指定子文件夹
$a = Get-FolderItem "C:\Temp\ExtractMetadata" -ExcludeFolder "C:\Temp\ExtractMetadata\Folder_to_Skip" | Export-Csv -Path C:\Temp\2023-12-12Testing.csv -Encoding Unicode

调用说明

现在可以直接使用-ExcludeFolder参数指定要跳过的子文件夹路径,支持多个路径(用逗号分隔):

# 跳过单个文件夹
Get-FolderItem "C:\Temp\ExtractMetadata" -ExcludeFolder "C:\Temp\ExtractMetadata\Folder_to_Skip"

# 跳过多个文件夹
Get-FolderItem "C:\Temp\ExtractMetadata" -ExcludeFolder "C:\Temp\ExtractMetadata\Folder1","C:\Temp\ExtractMetadata\Folder2"

原方法失效原因

  • 用-ExcludeFile指定文件夹:/XF参数仅对文件生效,无法排除目录,所以该方法无效。
  • 用-Filter指定文件夹下的文件:robocopy的Filter参数是匹配文件名,而非完整路径,所以路径格式的过滤条件无法匹配任何文件,导致输出为空。

内容的提问来源于stack exchange,提问作者oymonk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 09:54:53