Windows 从powershell递归归档特定类型的所有文件

Windows 从powershell递归归档特定类型的所有文件,windows,powershell,archive,compress-archive,Windows,Powershell,Archive,Compress Archive,有没有一种方法可以使用压缩存档脚本,当从路径运行时: 存档与通配符筛选器(*.doc)匹配的所有文件 将这些文件归档到当前文件夹和所有子文件夹中 保存相对文件夹结构(不过,使用相对或绝对选项会更好) 我很难让它同时完成这三项任务 编辑: 以下过滤器和递归,但不维护文件夹结构 Get-ChildItem -Path ".\" -Filter "*.docx" -Recurse | Compress-Archive -CompressionLevel Optimal -DestinationPath

有没有一种方法可以使用压缩存档脚本,当从路径运行时:

  • 存档与通配符筛选器(*.doc)匹配的所有文件
  • 将这些文件归档到当前文件夹和所有子文件夹中
  • 保存相对文件夹结构(不过,使用相对或绝对选项会更好)
  • 我很难让它同时完成这三项任务

    编辑:

    以下过滤器和递归,但不维护文件夹结构

    Get-ChildItem -Path ".\" -Filter "*.docx" -Recurse |
    Compress-Archive -CompressionLevel Optimal -DestinationPath "$pwd\doc.archive-$(Get-Date -f yyyyMMdd.hhmmss).zip"
    
    此项不会重复出现:

    Compress-Archive -Path "$pwd\*.docx" -CompressionLevel Optimal -DestinationPath "$pwd\doc.archive-$(Get-Date -f yyyyMMdd.hhmmss).zip"
    

    在某个时候,我有一个命令会递归,但不会过滤,但现在无法返回到该命令。

    不幸的是,从Windows PowerShell v5.1/PowerShell Core 6.1.0开始,
    压缩归档文件
    非常有限:

    • 保存子目录树的唯一方法是将目录路径传递给
      压缩归档文件

      • 不幸的是,这样做并没有提供包含/排除机制来仅选择文件的子集

      • 此外,生成的归档文件将在内部包含一个以输入目录命名的根目录(例如,如果将
        C:\temp\foo
        传递给
        Compress Archive
        ,则生成的归档将包含一个包含输入目录子树的
        foo
        目录,而不是在顶层包含
        C:\temp\foo
        的内容)

      • 没有保留绝对路径的选项

    • 一个麻烦的解决方法是创建目录树的临时副本,其中只包含感兴趣的文件(
      copy Item-Recurse-Filter*.docx.$env:TEMP\tmpDir;Compress Archive$env:TEMP\tmpDir out.zip
      -注意,将包括空目录)

      • 考虑到归档文件中的输入目录总是以一个根目录命名,即使这样也可能不适合您,请参见底部的备选方案

    使用备选方案可能会更好:

    • 直接使用.NET v4.5+和类型。
      在Windows PowerShell中,与PowerShell Core不同的是,大多数情况下都是使用
      添加类型-AssemblyName System.IO.Compression手动加载相关程序集的

    • 使用外部程序,例如


    直接使用.NET v4.5+类解决此问题: 注:

    • 在Windows PowerShell中,与PowerShell Core不同的是,大多数情况下都是使用
      Add Type-AssemblyName System.IO.Compression
      手动加载相关程序集

    • 由于自Windows PowerShell v5.1/PowerShell Core 6.1.0起,PowerShell不支持隐式使用扩展方法,因此您还必须显式使用该类

    # Windows PowerShell: must load assembly System.IO.Compression manually.
    Add-Type -AssemblyName System.IO.Compression
    
    # Create the target archive via .NET to provide more control over how files
    # are added.
    # Make sure that the target file doesn't already exist.
    $archive = [System.IO.Compression.ZipFile]::Open(
      "$pwd\doc.archive-$(Get-Date -f yyyyMMdd.hhmmss).zip",
      'Create'
    )
    
    # Get the list of files to archive with their relative paths and
    # add them to the target archive one by one.
    $useAbsolutePaths = $False # Set this to true to use absolute paths instead.
    Get-ChildItem -Recurse -Filter *.docx | ForEach-Object {
        # Determine the entry path, i.e., the archive-internal path.
        $entryPath = (
              ($_.FullName -replace ([regex]::Escape($PWD.ProviderPath) + '[/\\]'), ''), 
              $_.FullName
            )[$useAbsolutePaths]
        $null = [System.IO.Compression.ZipFileExtensions]::CreateEntryFromFile(
          $archive, 
          $_.FullName, 
          $entryPath
        )
      }
    
    # Close the archive.
    $archive.Dispose()