【Compress-Archive】PowerShellでファイルやフォルダをZIP圧縮する方法

こんにちは。チェシャ男です。(-皿-)

今回は、

【PowerShell でファイルやフォルダをZIP圧縮する方法】

についてご紹介します。

今回紹介する ”Compress-Archive” コマンドレットは PowerShell 5.0 で新たに追加されたものです。

Windows で圧縮といえばお馴染みの「ZIPファイル」を作成することができます。圧縮だけでなく書庫化して複数のファイルをひとまとめにできるのも魅力的ですね。

PowerShell 5.0 以降ではフリーソフトを使用しなくても圧縮することができるので”Lhaplus” などをインストールする必要もありませんね。

圧縮ファイルの解凍方法についてはこちら↓をご覧ください。

[blogcard url=”https://cheshire-wara.com/powershell/ps-cmdlets/item-file/expand-archive/”]

Compress-Archive でファイルを圧縮する

ファイル圧縮を行うコマンドレットに

Compress-Archive(→ コマンドレットの詳細はこちら

というものがあります。

【コマンドレット】

Compress-Archive

【オプション】

パターン1
-Path                      <圧縮元ファイルパス>
-DestinationPath      <圧縮ファイル出力先>
-CompressionLevel   <圧縮レベル>
-Update
-Confirm
-WhatIf

パターン2
-DestinationPath      <圧縮ファイル出力先>
-LiteralPath              <圧縮元ファイル(リテラル)パス>
-CompressionLevel   <圧縮レベル>
-Update
-Confirm
-WhatIf

【入力】

System.String[]

【出力】

 System.IO.FileInfo

【エイリアス】

なし

ファイルを圧縮する

さっそく圧縮してみましょう。まずは単純に1つのファイルを圧縮してみます。

Compress-Archive -Path <ファイルパス> -DestinationPath <出力先.zip>

というように ”-Path” オプションで圧縮元のファイル名を指定し ”-DestinationPath” オプションで圧縮先のファイル名を指定しましょう。

PS C:\work> #圧縮元のファイル
PS C:\work> Get-ChildItem


    ディレクトリ: C:\work


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2016/11/13     2:15              0 File1.txt


PS C:\work> #圧縮する
PS C:\work> Compress-Archive -Path .\File1.txt -DestinationPath .\Test.zip

PS C:\work> #圧縮の確認
PS C:\work> Get-ChildItem


    ディレクトリ: C:\work


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2016/11/13      2:15              0 File1.txt
-a----       2016/11/13      2:54            116 Test.zip

圧縮元と圧縮先を指定するだけなので分かりやすい使い方ですね。

”-Path” で圧縮元を指定するだけではなくパイプラインで渡すこともできます。

PS C:\work> #圧縮元のファイル
PS C:\work> Get-ChildItem


    ディレクトリ: C:\work


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2016/11/13      2:15              0 File1.txt


PS C:\work> #ファイルをパイプで指定
PS C:\work> .\File1.txt | Compress-Archive -DestinationPath .\Test.zip
パイプラインの中央にあるドキュメント C:\work\File1.txt を実行できません。
発生場所 行:1 文字:1
+ .\File1.txt | Compress-Archive -DestinationPath .\Test.zip
+ ~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (C:\work\File1.txt:String) []、RuntimeException
    + FullyQualifiedErrorId : CantActivateDocumentInPipeline


PS C:\work> #""でファイル名を囲む
PS C:\work>  ".\File1.txt" | Compress-Archive -DestinationPath .\Test.zip

PS C:\work> #圧縮の確認
PS C:\work> Get-ChildItem


    ディレクトリ: C:\work


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2016/11/13      2:15              0 File1.txt
-a----       2016/11/13      2:58            116 Test.zip

実行結果を見ていただけるとわかると思いますが、パイプするファイル名を””(ダブルクォーテーション)等で囲んでいなければ失敗するようなので注意が必要ですね。

複数のファイルを圧縮する

先ほどは1つのファイルを圧縮したので今度は複数のファイルをまとめて圧縮してみましょう。

方法はいくつかありますが今回はわかりやすいように連番になっているファイルを”*(ワイルドカード)”で指定します。

PS C:\work> #圧縮元のファイル
PS C:\work> Get-ChildItem


    ディレクトリ: C:\work


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2016/11/13     20:52              0 File1.txt
-a----       2016/11/13     20:52              0 File2.txt
-a----       2016/11/13     20:52              0 File3.txt
-a----       2016/11/13     20:52              0 File4.txt
-a----       2016/11/13     20:52              0 File5.txt


PS C:\work> #複数ファイルを圧縮
PS C:\work> Compress-Archive -Path .\File*.txt -DestinationPath Test.zip
PS C:\work>
PS C:\work> #圧縮の確認
PS C:\work> Get-ChildItem


    ディレクトリ: C:\work


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2016/10/05     21:15              0 File1.txt
-a----       2016/11/13     20:52              0 File2.txt
-a----       2016/11/13     20:52              0 File3.txt
-a----       2016/11/13     20:52              0 File4.txt
-a----       2016/11/13     20:52              0 File5.txt
-a----       2016/11/17      3:05            492 Test.zip

ZIPファイルの中身も確認してみると、

zipの中身-チェシャわら

となっているので問題なさそうですね。

“-Update” オプションで ZIP にファイルを追加する

すでに圧縮してまとめてしまった ZIP ファイルに対しては ”-Update” オプションを使ってファイルを追加することができます。

もしあなたがバックアップとしてZIP圧縮を使用しているとしたら、かなり便利ではありませんか!

Compress-Archive -Path <ファイルパス> -DestinationPath <出力先.zip> -Update

以下は実行例です。

PS C:\work> #追加するファイルを作成
PS C:\work> New-Item -Name .\File6.txt


    ディレクトリ: C:\work\.


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2016/11/13      3:17              0 File6.txt


PS C:\work> #圧縮ファイルにファイル追加
PS C:\work> Compress-Archive -Path .\File6.txt -DestinationPath .\Test.zip -Update

エクスプローラから実際にZIPファイルの中身を覗いてみましょう。

zipにファイル追加-チェシャわら

ご覧のようにファイルが追加されていますね。

フォルダを圧縮する

ファイル圧縮と同様にフォルダの圧縮も可能です。

圧縮方法もファイル圧縮時と同様に ”-Path” オプションで圧縮元を指定し ”-DestinationPath” オプションで圧縮先を指定します。

PS C:\work> #圧縮元を確認
PS C:\work> Get-ChildItem


    ディレクトリ: C:\work


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2016/11/13      3:25                Folder1


PS C:\work> #フォルダ内に移動
PS C:\work> Set-Location .\Folder1\
PS C:\work\Folder1>
PS C:\work\Folder1> #フォルダの中身
PS C:\work\Folder1> Get-ChildItem


    ディレクトリ: C:\work\Folder1


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2016/11/13      2:52              0 File1.txt
-a----       2016/11/13      2:52              0 File2.txt
-a----       2016/11/13      2:52              0 File3.txt
-a----       2016/11/13      2:52              0 File4.txt
-a----       2016/11/13      2:52              0 File5.txt


PS C:\work\Folder1> #元の位置に戻る
PS C:\work\Folder1> Set-Location ..
PS C:\work>
PS C:\work> #フォルダ圧縮
PS C:\work> Compress-Archive -Path .\Folder1\ -DestinationPath Test.zip
PS C:\work>
PS C:\work> #圧縮の確認
PS C:\work> Get-ChildItem


    ディレクトリ: C:\work


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2016/11/13      3:25                Folder1
-a----       2016/11/13      3:32            572 Test.zip

ZIP ファイルの中身も確認してみましょう。下図のように ZIP ファイルの中にファイルが圧縮格納されていることがわかります。

フォルダを圧縮-チェシャわら

ちなみに図を見ていただくとわかるように、フォルダを圧縮した場合は

.. \ 圧縮先フォルダ(DestinationPath) \ 圧縮したフォルダ名(Path) \ フォルダの中身

という構造になることに注意してください。

“-CompressionLevel” で指定する圧縮レベル

-CompressionLevel” オプションでは、圧縮ファイルを作成する時どのくらいの圧縮力・圧縮スピードで圧縮するか決めることができます。

高速圧縮を使用すると圧縮ファイルを作成するための時間が短く済みますがファイルサイズが大きくなってしまうという欠点もあります

逆に最適な圧縮率で圧縮させる場合は圧縮元のファイルサイズによっては長く時間がかかる場合があります。

このオプションで設定できる値は次の通りです。

  • Fastest:
    ->処理時間を短縮するために利用可能な最速となる圧縮率を使用します。
  • NoCompression:
    ->圧縮しないで書庫化だけ行う。
  • Optimal:
    ->最適な圧縮率を適用する。処理時間はファイルサイズに依存する。(デフォルト)

効率をも考えながら状況によって使い分ける方がよさそうですね。

単にファイルのアーカイブや整理として圧縮なしで使うという方法もありだと思います。

Compress-Archive 使用時の注意点

ここまで、”Compress-Archive” コマンドレットの使用方法を紹介しましたが Microsoft には以下のように説明があります。

DESCRIPTION

The Compress-Archive cmdlet creates a zipped (or compressed) archive file from one or more specified files or folders. An archive file allows multiple files to be packaged, and optionally compressed, into a single zipped file for easier distribution and storage. An archive file can be compressed by using the compression algorithm specified by the CompressionLevel parameter.

Because Compress-Archive relies upon the Microsoft .NET Framework API System.IO.Compression.ZipArchive to compress files, the maximum file size that you can compress by using Compress-Archive is currently 2 GB. This is a limitation of the underlying API.

Compress Archive-Microsoft Developer Network/© 2017 Microsoft

大事なところをザックリ訳すと、現在コマンドレットで圧縮可能な最大サイズは2GBまでとなっているようです。

また、環境によっては日本語のファイル名を圧縮しようとすると文字化けする場合もあります。

[blogcard url=”https://cheshire-wara.com/powershell/ps-column/compress-archive-incident/”]

( .Net Framework 4.5 以降を導入している場合は直接フレームワークの機能から圧縮することもできるみたいですね)

 まとめ

ファイルやフォルダを圧縮したい場合は

Compress-Archive -Path <圧縮元> -Destination <圧縮先>

を使用する。

圧縮済みのZIPファイルにファイルを追加する場合は、

-Update

圧縮率を変更したい場合は、

-CompressLevel

を使用する。

6 COMMENTS

y.k

チェシャ 男 さん
以下のようなディレクトリ構成で、
b.txtだけNoCompressionを指定する方法、もしご存知でしたら
ご教示頂けないでしょうか。

dir1配下にa.txtとdir2が存在し、dir2配下にはb.txtが存在する。

返信する
チェシャ 男

y.kさん

コメントありがとうございます。
特定のファイルだけ圧縮レベルを変更することは仕様的にできなそうです。

が、無理やりやるのであれば、

①直下ファイルを圧縮したZIPを作る(下記だとa.txtを指定
②無圧縮で追加したいファイルを-Updateで追加する。その際CompressionLevel を指定する

Compress-Archive .\dir1\a.txt -DestinationPath dir1.zip
Compress-Archive .\dir1\dir2\ -DestinationPath dir1.zip -Update -CompressionLevel NoCompression

で、可能だと思います。

2.67KBのb.txtを用意して実際に試したところ、

・dir丸ごとZIPにした場合には、245B
・後からNoCompressで追加した場合には2.87KB

となりました。

返信する
y.k

チェシャ 男 さん
ご回答ありがとうございました。

仕様的にできなさそうということで承知致しました。
ご提示頂いた手法も、試してみました。

返信する
hoge

複数のサブフォルダをサブフォルダ名.ZIPのファイル名で各々に作成することはできませんか

返信する
チェシャ 男

Hogeさん

コメントありがとうございます。

サブフォルダはサブフォルダ単位で、親フォルダは配下とサブフォルダでZIPファイルを作るとすると
以下のコードなどはいかがでしょうか!

Get-ChildItem -Recurse -Force -Directory | %{Compress-Archive -Path $_.FullName -DestinationPath "$($_.Name).zip"}

返信する

コメントを残す

メールアドレスが公開されることはありません。