2012-06-13 141 views
23

我正在創建夜間數據庫模式文件,並且希望將每晚創建的所有文件(每個數據庫一個)放入一個文件夾並壓縮該文件夾。 我有一個PowerShell腳本來創建schema.Only數據庫的創建腳本,然後將所有文件添加到一個新的文件夾。問題在於這個過程的壓縮部分。使用Powershell或命令行在Windows中創建壓縮/壓縮文件夾

有沒有人有任何想法,如果這可以通過預先安裝的Windows實用工具來處理文件夾壓縮?

如果可能,最好使用該工具而不是像7zip(我不想在每個客戶的服務器上安裝7zip,如果我問他們可能需要IT年)。

+0

我認爲這解釋了您的選擇:http://richardspowershellblog.wordpress.com/2007/06/02/powershell-and-compressed-files/ – David

+1

非常感謝!這是一個乾淨而簡單的解決方案。任何其他人可能會遇到此線索的指示。從下列網站下載PowerShell社區擴展: http://pscx.codeplex.com/downloads 提取文件,然後將目錄移至: C:\ Windows \ System32 \ WindowsPowerShell \ v1.0 \ Modules。然後通過運行以下命令導入模塊: Import-Module Pscx – TechDawg270

回答

19

下面是幾個與zip相關的函數,它們不依賴擴展:Compress Files with Windows PowerShell

那你可能感興趣的主要功能是:

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 
    } 
} 

用法:

dir c:\demo\files\*.* -Recurse | Add-Zip c:\demo\myzip.zip 

有一點需要注意:在shell.application對象的NameSpace()功能無法打開zip文件如果路徑不是絕對的,則用於書寫。所以,如果你傳遞了一個相對路徑爲Add-Zip,它會失敗並出現空錯誤,所以zip文件的路徑必須是絕對路徑。

或者你可以在函數的開頭添加一個$zipfilename = resolve-path $zipfilename

+0

這確實奏效,我很欣賞及時的響應,但我認爲下載和安裝PowerShell社區擴展並具有Write-Zip commandlet的可用性是更簡單/更簡單實現功能的方法。 – TechDawg270

+0

@ TechDawg270:同意 - 我主要是爲了完整性而發佈的。 – voithos

3

這將壓縮。\在內容上。\ out.zip與System.IO.Packaging.ZipPackage下面的例子here

$zipArchive = $pwd.path + "\out.zip" 
[System.Reflection.Assembly]::Load("WindowsBase,Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35") 
$ZipPackage=[System.IO.Packaging.ZipPackage]::Open($zipArchive, [System.IO.FileMode]"OpenOrCreate", [System.IO.FileAccess]"ReadWrite") 
$in = gci .\in | select -expand fullName 
[array]$files = $in -replace "C:","" -replace "\\","/" 
ForEach ($file In $files) { 
    $partName=New-Object System.Uri($file, [System.UriKind]"Relative") 
    $part=$ZipPackage.CreatePart($partName, "application/zip", [System.IO.Packaging.CompressionOption]"Maximum") 
    $bytes=[System.IO.File]::ReadAllBytes($file) 
    $stream=$part.GetStream() 
    $stream.Write($bytes, 0, $bytes.Length) 
    $stream.Close() 
                } 
$ZipPackage.Close() 
1

使用voithos'答案zip文件了在PowerShell中,只是有一個問題使用Add-Zip函數,Start-sleep-milliseconds 500會導致問題,如果文件無法在此時完全壓縮 - >下一個在完成之前開始導致錯誤並且一些文件不會被壓縮。

所以在玩了一下之後,首先試着讓計數器檢查$ zipPackage.Items()的計數,並且只在計數增加後繼續計數(這不起作用,因爲它會返回0有些情況下它不應該)我發現它將返回0,如果包仍在壓縮/複製文件(我想,哈哈)。添加了一個簡單的while循環,其中包含start-sleep,等待zipPackage.Items()。計數爲非零值,然後繼續,這似乎解決了問題。

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) 
     do 
     { 
      Start-sleep -milliseconds 250 
     } 
     while ($zipPackage.Items().count -eq 0) 
} 
} 
-3

使用PowerShell 3.0版:

Copy-ToZip -File ".\blah" -ZipFile ".\blah.zip" -Force 

希望這有助於。

+4

這不是PowerShell 3 cmdlet。 –

21

最新的.NET 4的本地方式。5框架,但完全功能少:

創作:

Add-Type -Assembly "System.IO.Compression.FileSystem" ; 
[System.IO.Compression.ZipFile]::CreateFromDirectory("c:\your\directory\to\compress", "yourfile.zip") ; 

提取:

Add-Type -Assembly "System.IO.Compression.FileSystem" ; 
[System.IO.Compression.ZipFile]::ExtractToDirectory("yourfile.zip", "c:\your\destination") ; 

如前所述,完全功能少,所以不要指望一個覆蓋標誌。

+1

這是優雅的。有一個upvote .. – deepelement

+0

我得到了訪問路徑否認這個解決方案:(你有想法強制? – Jerome2606

+0

@ Jerome2606 ...然後讓你的路徑訪問。也如上所述,「不要指望覆蓋國旗」 – sonjz

4

從PowersShell 5開始,有一個Compress-Archive cmdlet可以完成開箱即用的任務。