【问题标题】:Powershell to zip folder & files, then delete old filesPowershell 压缩文件夹和文件,然后删除旧文件
【发布时间】:2016-09-23 14:00:07
【问题描述】:

我想使用 Powershell 来自动化: 1. 压缩超过 7 天的日志文件(.xml 和 .dat 扩展名), 2. 将这些压缩档案复制到别处并 3. 然后从源中删除原始日志文件。

我正在使用以下 Powershell 脚本,它是从各种资源中拼凑而成的。

function New-Zip
  {
   param([string]$zipfilename)
    set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
    (dir $zipfilename).IsReadOnly = $false
  }

function Add-Zip
  {
   param([string]$zipfilename)

   if(-not (test-path($zipfilename)))
    {
    set-content $zipfilename ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
    (dir $zipfilename).IsReadOnly = $false  
    }

  $shellApplication = new-object -com shell.application
  $zipPackage = $shellApplication.NameSpace($zipfilename)

   foreach($file in $input) 
     { 
        $zipPackage.CopyHere($file.FullName)
        Start-sleep -milliseconds 500
     }
   }

$targetFolder = 'C:\source'
$destinationFolder = 'D:\destination\'
$now = Get-Date
$days = 7
$lastWrite = $now.AddDays(-$days)

Get-ChildItem $targetFolder -Recurse | Where-Object { $_ -is [System.IO.FileInfo] } | ForEach-Object {
If ($_.LastWriteTime -lt $lastWrite)
{
    $_ | New-Zip $($destinationFolder + $_.BaseName + ".zip") 
    $_ | Add-Zip $($destinationFolder + $_.BaseName + ".zip")
}
}

Get-ChildItem $targetFolder -Recurse -Include "*.dat", "*.xml" | WHERE {($_.CreationTime -le $(Get-Date).AddDays(-$days))} | Remove-Item -Force

此脚本运行良好,因为它归档文件,并将它们复制到目标文件夹。

如果我的结构是 C:\source\bigfolder\logfile.dat,则生成的 zip 文件将无法获得我想要的文件夹结构:

logfile.zip>bigfolder>logfile.dat

相反,它只是得到:logfile.zip>logfile.dat

有人可以帮忙解决这个问题吗?

为了更好地对其进行微调,如果可能的话,我希望构建一些逻辑,以便仅在满足特定条件时才压缩文件。

我压缩的原始日志文件有一个如下命名例程:

Folders: 
  emstg#12_list\randomstring.xml

Individual log files:
  emstg#12_query_data.xml
  emstg#12_events_cache.dat etc... 

正如您所见,这些文件的开头与 emstg#number 相同。

如何在上面的脚本中实现“名称检测”机制?

谢谢

【问题讨论】:

    标签: powershell compression powershell-3.0


    【解决方案1】:

    您可以使用[System.IO.Compression] 压缩文件夹 我是根据你的脚本写的。 我的想法是将需要压缩的文件的整个文件夹结构复制到一个临时文件夹中,然后压缩该临时文件夹。 对于名称检测,您只需要另一个where-object(根据需要修改代码)

    function Zip
      {
        param(
            [string]$source,
            [string]$des
        )
        add-type -AssemblyName System.IO.Compression.FileSystem
        [System.IO.Compression.ZipFile]::CreateFromDirectory($source,$des,'Optimal',$true)
        Start-sleep -s 1
    }
    
    
    $targetFolder = "C:\source"
    $destinationFolder = "C:\destination"
    $temp = "C:\temp"
    $now = Get-Date
    $days = 7
    $lastWrite = $now.AddDays(-$days)
    $i = 1
    
    Get-ChildItem $targetFolder -Recurse | Where-Object { $_ -is [System.IO.FileInfo] } | Where-Object {$_ -like "*.*"} | ForEach-Object {
        If ($_.LastWriteTime -lt $lastWrite) {
            $halfDir = $_.DirectoryName.Trim($targetFolder)
            $s = $temp + "\" + $i + "\" + $halfDir
            $d = $destinationFolder + "\" + $_.BaseName + ".zip"
            Copy-Item $_.DirectoryName -Destination $s
            Copy-Item $_.FullName -Destination $s
            Zip -source $s -des $d
            $i++
        }
    }
    

    【讨论】:

    • Thx,一些错误如果我有一个文件夹和多个文件在文件名开头具有相同的命名约定,例如D:\source\emstg#12\string.xml(文件夹和文件),然后是单个文件:D:\source\emstg#12_data.xml D:\source\emstg#12_events.dat,由于名称相似而出现错误:使用“4”参数调用“CreateFromDirectory”异常:“文件'D:\destination\esmstg #12.zip' 已经存在。” 临时文件也不会被删除。修改后的代码为:..... | Where-Object {$_ -like "esmstg#12*"} | ForEach-Object { ZIP 应保持相同的文件夹/文件结构
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-03
    • 1970-01-01
    • 1970-01-01
    • 2010-09-05
    • 2010-12-14
    相关资源
    最近更新 更多