【PowerShell】zipファイルの圧縮・解凍を自動化するスクリプト作成術

【PowerShell】zipファイルの圧縮・解凍を自動化するスクリプト作成術

PR Amazonのアソシエイトとして、ITナレッジライフは適格販売により収入を得ています。

記事の文字数:5,832

PowerShellでzipファイルの圧縮・解凍を自動化する方法を徹底解説!Compress-ArchiveとExpand-Archiveなどのコマンドレットを使い、バックアップやデータ配布の効率を爆発的に上げる実用的なスクリプトの書き方をサンプルコード付きで分かりやすく紹介します。

ITエンジニアにお勧めの本 ↗

おすすめ

エンジニアが知っておきたい思考の整理術 複雑な情報を【理解する】【伝える】テクニック

難易度
実用性
図解

思考の整理というテーマを、実務ですぐに使える具体的な「技術」として落とし込んだ一冊です。

ベストセラー

世界一流エンジニアの思考法

難易度
実用性
思考法

技術スキル以上に大切な「考え方」をアップデートできる。世界基準の効率的な仕事術が学べます。

文系社会人のためのIT資格の歩き方: 文系のあなたに最適な道をご提案します (YKcreate kiki)

難易度
実用性
キャリア度

ロードマップが非常に明確。キャリアプランを見据えた、無駄のない学習順序を提案してくれます。

エンジニアを説明上手にする本 相手に応じた技術情報や知識の伝え方

難易度
実用性
コミュ力

「伝える技術」もエンジニアの重要なスキル。相手の視点に立った、具体的な説明のコツが満載です。

技術広報入門 ー テックブログから始めるエンジニアカルチャーのつくり方

難易度
実用性
独自性

テックブログを入口にエンジニア組織の文化をどう設計し、育てていくかという実践論が学べます。

日々の業務の中で、大量のレポートファイルやログをZIP形式に圧縮したり、配布されたアーカイブファイルを解凍して所定のフォルダに配置したりする作業を、手動で行うことに煩わしさを感じていないでしょうか。「定期的なバックアップ作業を自動化したいけれど、専用のツールを導入できない」「バッチ処理やPowerShellスクリプトでスマートに圧縮・解凍を組み込みたい」といった場面で、PowerShellの標準コマンドレットを活用すれば、外部ツールに依存せずとも堅牢な自動化処理を実現できます。

この記事を読むことで、PowerShellを用いたZIPファイルの圧縮・解凍の基本構文から、実務で使える日付付きバックアップの自動化スクリプトの書き方、そしてパス長制限や文字化けといったよくあるトラブルの回避策までを体系的に理解し、すぐに実務へ応用できるようになります。

確認した環境

本記事で紹介するスクリプトおよびコマンドレットは、以下の環境で動作確認を行っています。

PowerShellでのzip圧縮・解凍が業務自動化に不可欠な理由

Windows環境において、ファイルの圧縮や解凍はエクスプローラーの右クリックメニューから視覚的に行うのが一般的です。しかし、これが「毎日定時に行う」「数世代前の古いアーカイブを削除しつつ新しいバックアップを作成する」「複数のサブフォルダごとに個別のZIPファイルを作成する」といった要件に変わった途端、手作業では運用負荷が高くなり、ヒューマンエラーのリスクも増加します。

PowerShellを活用する最大のメリットは、OS標準の機能として組み込まれているため追加のソフトウェアインストールが不要であり、タスクスケジューラと組み合わせることで完全な無人運用が可能になる点です。次のセクションから、実際に使用する具体的なコマンドレットと構文を確認していきましょう。

Compress-ArchiveコマンドレットでフォルダやファイルをZIP圧縮する方法

PowerShellでファイルやフォルダをZIP形式に圧縮するには、Compress-Archiveコマンドレットを使用します。Compress-ArchiveはWindows PowerShell 5.0以降およびPowerShell 7で利用できる標準コマンドレットです。

単一のファイルやフォルダを圧縮する基本構文

単一のファイル、またはフォルダ配下の全ファイルを圧縮する際の基本構文は以下の通りです。

Terminal window
Compress-Archive -Path "C:\Data\Reports" -DestinationPath "C:\Backup\Reports.zip"

各パラメータの詳細は以下の通りです。

  • -Path: 圧縮対象となるファイルやフォルダのパスを指定します。ワイルドカード(*)を使用して、特定の拡張子を持つファイルだけを対象にすることも可能です。
    • 補足(階層構造の違い): "C:\Data\Reports" のようにフォルダパスを直接指定するとZIPのルートに Reports フォルダ自体が含まれますが、"C:\Data\Reports\*" のように末尾に \* を付けると Reports フォルダ自体は含まれず、その配下のファイルやサブフォルダがZIPのルート直下に格納されます。
  • -DestinationPath: 生成されるZIPファイルの保存先パスを指定します。拡張子の .zip は省略しても自動的に付与されます。

実行時の出力例や進捗状況を確認したい場合は、-Verboseスイッチを付与することで、どのファイルがアーカイブに追加されているかを詳細に出力させることができます。

Terminal window
Compress-Archive -Path "C:\Data\Reports\*" -DestinationPath "C:\Backup\Reports.zip" -Verbose

なお、Compress-Archiveにはいくつかの制約があります。隠し属性が設定されたファイルやフォルダは圧縮対象から除外されるため、システム全体のバックアップなど、すべてのファイルを確実に保存したい用途では注意が必要です。また、内部で使用する.NET APIAPI [エーピーアイ]Application Programming Interface。異なるソフトウェア間の接続口(System.IO.Compression.ZipArchive)の制約により、単一ファイルのサイズが2GBを超える場合は圧縮できません。このような場合は.NET APIの直接利用や専用のアーカイブツールの利用を検討してください。

既存のZIPファイルに追記・上書きする場合の注意点

すでに存在するZIPファイルに対して、新しくファイルを追加(追記)したい場合や、同名のZIPファイルが存在する状態で上書きしたい場合には注意が必要です。

デフォルトの状態(オプションなし)で既に存在する-DestinationPathを指定して実行すると、PowerShellはエラーを返します。既存のZIPファイルに新しいファイルを追加・更新したい場合は、-Updateパラメータを使用します。

Terminal window
Compress-Archive -Path "C:\Data\NewReport.xlsx" -DestinationPath "C:\Backup\Reports.zip" -Update

また、既存のZIPファイルを新しいもので完全に置き換えたい(上書きしたい)場合は、-Forceパラメータを指定します。

Terminal window
Compress-Archive -Path "C:\Data\Reports" -DestinationPath "C:\Backup\Reports.zip" -Force

-Updateは既存のZIP内にある同名ファイルを新しいファイルで更新し、新規ファイルも追加しますが、既存ZIP内のファイルを削除する機能ではありません。圧縮元から削除されたファイルが既存ZIP内に残る場合があるため、常に最新のフォルダ構成をバックアップしたい場合は、-Forceによるアーカイブの再作成を使用してください。

Expand-ArchiveコマンドレットでZIPファイルを解凍する方法

圧縮されたZIPファイルを展開(解凍)するには、Expand-Archiveコマンドレットを使用します。

指定したディレクトリへ展開する基本手順

ZIPファイルを指定した出力先ディレクトリに展開する基本構文は以下の通りです。

Terminal window
Expand-Archive -Path "C:\Backup\Reports.zip" -DestinationPath "C:\RestoredData"
  • -Path: 展開元のZIPファイルのパスを指定します。
  • -DestinationPath: 解凍したファイルの出力先ディレクトリを指定します。出力先ディレクトリが存在しない場合、PowerShellは自動的にディレクトリを作成してから展開を行います。

なお、信頼できない提供元から入手したZIPファイルを展開する場合は、ファイルの内容や展開後の容量を事前に確認してください。展開先の容量を圧迫する大量のファイルや想定以上の容量になるファイルが含まれる可能性があるため、重要なデータが保存されているディレクトリへの直接展開は避け、専用の一時フォルダなどを利用することをおすすめします。

また、Expand-Archiveも内部で使用する.NETのZipArchive APIの制約により、2GBを超える単一ファイルを含むZIPアーカイブの展開には対応できません。大容量ファイルを扱う場合は、別のアーカイブツールなどの利用を検討してください。

同名ファイルが存在する場合の上書き設定

出力先ディレクトリに同名のファイルがすでに存在する場合、Compress-Archiveと同様に、デフォルトではエラーが発生して上書きされません。すでに存在するファイルを強制的に上書きして展開したい場合は、-Forceパラメータを付与します。

Terminal window
Expand-Archive -Path "C:\Backup\Reports.zip" -DestinationPath "C:\RestoredData" -Force

【実践】日付付きファイル名を自動付与してバックアップをZIP圧縮するスクリプト

ここまでの基本を踏まえ、実務で頻繁に求められる「日々のログフォルダを対象に、実行日の日付(YYYYMMDD形式)をファイル名に自動付与してZIP圧縮する」実用的なスクリプトを作成します。

以下のスクリプトを Backup-Logs.ps1 などのファイル名で保存し、実行することで、指定したフォルダのバックアップを自動化できます。

Terminal window
# ==========================================
# ログフォルダの日付付きZIP圧縮スクリプト
# ==========================================
# 進捗バーの描画を無効化し、バックグラウンド実行時に不要な進捗表示が発生することを防止
# (大量のファイルを処理する場合には、進捗表示に伴うオーバーヘッドの軽減も期待できます)
$ProgressPreference = 'SilentlyContinue'
# 設定変数
$TargetFolder = "C:\App\Logs"
$BackupDir = "C:\Backup\Archives"
# 本日の日付を取得(例: 20261104)
# ※同日に複数回バックアップを取得する場合は "yyyyMMdd_HHmmss" に変更してください
$DateStamp = Get-Date -Format "yyyyMMdd"
$ZipFileName = "LogBackup_$DateStamp.zip"
$Destination = Join-Path $BackupDir $ZipFileName
# バックアップ保存先が存在しない場合は作成
if (-not (Test-Path $BackupDir)) {
New-Item -ItemType Directory -Path $BackupDir | Out-Null
}
# 対象フォルダの存在確認
if (-not (Test-Path $TargetFolder)) {
Write-Warning "圧縮対象のフォルダが見つかりません: $TargetFolder"
exit 1
}
Write-Host "圧縮処理を開始します: $TargetFolder" -ForegroundColor Cyan
try {
# 対象フォルダ内の圧縮対象ファイル有無を確認
# (※Compress-Archiveは隠しファイルを圧縮対象としないため、Get-ChildItemでも-Forceを指定せず条件を揃えています)
$Files = @(Get-ChildItem -Path $TargetFolder -ErrorAction Stop)
if ($Files.Count -eq 0) {
Write-Warning "圧縮対象のファイルが存在しません(空フォルダ、または隠しファイルのみ): $TargetFolder"
exit 1
}
# 既存の同名ファイルがある場合は上書きして圧縮
Compress-Archive -Path "$TargetFolder\*" -DestinationPath $Destination -Force -ErrorAction Stop
# バックアップファイルの存在とサイズを確認
if ((Test-Path $Destination) -and (Get-Item $Destination).Length -gt 0) {
Write-Host "バックアップファイルを確認しました: $Destination" -ForegroundColor Green
exit 0
} else {
throw "バックアップファイルが正常に作成されていません。"
}
}
catch {
Write-Error "圧縮処理中にエラーが発生しました: $_"
exit 1
}

スクリプト運用のポイント

  • 同日複数回実行への対応: 上記スクリプトでは日付(yyyyMMdd)でファイル名を生成し -Force を指定しているため、同じ日に複数回実行すると既存のバックアップが上書きされます。障害調査などで1日に複数回バックアップを残したい場合は、時刻まで含めたフォーマットに変更してください。
    Terminal window
    $DateStamp = Get-Date -Format "yyyyMMdd_HHmmss"
    $ZipFileName = "LogBackup_$DateStamp.zip" # 例: LogBackup_20261104_210000.zip
  • バックアップの検証: スクリプト内の確認処理は「ZIPファイルが存在し、サイズが0バイトでないこと」を確認するものです。ZIP内部のデータがすべて正常であることを保証するものではないため、重要なバックアップでは定期的な展開テストも組み合わせるとより信頼性が高まります。
  • タスクスケジューラへの登録設定: Windowsの「タスクスケジューラ」に登録して無人運用する際は、以下の設定と権限を確認してください。
    • プログラム/スクリプト: powershell.exe(Windows PowerShell 5.1)または pwsh.exe(PowerShell 7)
    • 引数の追加: -NoProfile -NonInteractive -ExecutionPolicy Bypass -File "C:\Scripts\Backup-Logs.ps1"(環境によってスクリプトの実行ポリシー Restricted 等でブロックされるのを防ぐため、-ExecutionPolicy Bypass の指定を推奨します)
    • 実行ユーザーの権限: タスクスケジューラではログオン中のユーザーと異なるアカウントで実行する場合があるため、実行ユーザーに対象フォルダの読み取り権限とバックアップ先の書き込み権限が付与されているか必ず確認してください。

よくあるエラーとトラブルシューティング

PowerShellでZIPファイルの圧縮・解凍を行う際、Windowsの制約や文字コードの仕様に起因するエラーに直面することがあります。ここでは代表的なトラブルとその回避策を解説します。

ファイルパスが長すぎるエラー(260文字制限)の回避策

Windows環境では、ファイルパスの文字数が長すぎる場合(従来のMAX_PATHである260文字を超える場合)、Compress-Archiveやその他のファイル操作コマンドレットがエラーを返すことがあります。

回避策:

  1. 一時的に浅い階層にコピーして圧縮する: 深い階層にあるファイル群を直接圧縮するのではなく、一時フォルダ(例: C:\Temp)に一旦コピーし、短いパスの状態で圧縮を実行します。
  2. OSの長パス設定とアプリケーションの対応状況を確認する: Windows 10 バージョン1607以降およびWindows Server 2016以降では、グループポリシーまたはレジストリの LongPathsEnabled を有効にすることで、長いパスを扱えるアプリケーションの制限を緩和できます。ただし、レジストリの設定だけでは不十分であり、OS側の設定有効化とアプリケーション側の長いパスへの対応の両方が必要です。Windows PowerShell 5.1とPowerShell 7では内部で使用する.NETの実行環境が異なるため、長いパスを扱う場合はPowerShellのバージョンだけで判断せず、実際の圧縮・解凍処理で動作確認することが重要です。

文字化けが発生する場合の対処法

古いシステムや異なる環境で作成されたZIPファイルをPowerShell標準のコマンドレットで解凍・圧縮すると、日本語のファイル名が文字化けすることがあります。Compress-ArchiveはUTF-8を使用するため、UTF-8以外の文字エンコーディング(Shift_JISなど)でファイル名が格納されたZIPファイルをExpand-Archiveで展開すると、元のファイル名と異なる名前になる場合があります。

対処法: PowerShell標準の Compress-Archive や Expand-Archive には文字コードを指定するパラメータがないため、文字化けが発生する場合は .NET の System.IO.Compression.ZipFile クラスを直接呼び出し、文字エンコーディング(Shift_JIS など)を明示的に指定します。なお、.NET Frameworkを使用するWindows PowerShell 5.1ではShift_JISなどの従来のコードページが標準でサポートされていますが、PowerShell 7が使用する.NETでは CodePagesEncodingProvider の登録が必要になるため、PowerShellのバージョンで処理を分岐しておくと両環境で確実に動作します。

Terminal window
# PowerShell 7以降の場合、従来の文字コードを利用できるようにする
if ($PSVersionTable.PSVersion.Major -ge 6) {
Add-Type -AssemblyName System.Text.Encoding.CodePages
[System.Text.Encoding]::RegisterProvider(
[System.Text.CodePagesEncodingProvider]::Instance
)
}
# ZIPファイルのファイル名をShift_JISとして解釈して解凍
Add-Type -AssemblyName System.IO.Compression.FileSystem
$Encoding = [System.Text.Encoding]::GetEncoding("Shift_JIS")
[System.IO.Compression.ZipFile]::ExtractToDirectory(
"C:\Backup\Reports.zip",
"C:\RestoredData",
$Encoding
)

※なお、CodePagesEncodingProviderを登録してもすべてのZIPファイルの文字化けが解消するわけではありません。ZIP内のファイル名が実際にどの文字コードで格納されているかを確認したうえで、適切なエンコーディングを指定してください。また、ZIPファイル内のファイル名にUTF-8を示すフラグが設定されている場合は、指定したエンコーディングではなくUTF-8として解釈されます。文字コードを指定しても文字化けが解消しない場合は、ZIPファイルの作成元やファイル名の格納方式も確認してください。あわせて、3引数の ExtractToDirectory メソッドは既存ファイルを上書きせず、同名ファイルがある場合はエラーになるため、空の展開先フォルダを指定してください。

まとめ:PowerShellスクリプトでファイル圧縮作業を効率化しよう

本記事では、PowerShellを用いたZIPファイルの圧縮・解凍の自動化について、以下のポイントを解説しました。

  • Compress-Archiveコマンドレットを使用することで、スクリプト内から簡単にフォルダやファイルをZIP圧縮できる(ただし隠しファイルの除外や単一ファイル2GB制限に注意)。
  • Expand-Archiveコマンドレットを使用し、ZIPファイルを指定ディレクトリへ展開できる(こちらも単一ファイル2GB制限あり)。
  • 日付情報を動的に付与したスクリプトを作成し、終了コードやファイル確認処理を組み込んでタスクスケジューラと連携することで、バックアップ業務を自動化できる。
  • パス長制限や文字化けといった実務でのつまずきポイントに対しても、OS・実行環境の仕様を踏まえた適切な回避策や代替手段を選択できる。

日常的なデータ整理やバックアップ作業をPowerShellで自動化し、ヒューマンエラーのない効率的なシステム運用を実現しましょう。


以上で本記事の解説を終わります。
よいITライフを!
ITナレッジライフ 運営者
この記事を書いた人

Z (ITナレッジライフ)

現役のITエンジニア。Linux、プログラミング、IT用語など、日々の業務で得た「痒いところに手が届く」技術情報を発信しています。

プロフィールと編集ポリシーを見る →

ITエンジニアにお勧めの本 ↗

おすすめ

エンジニアが知っておきたい思考の整理術 複雑な情報を【理解する】【伝える】テクニック

難易度
実用性
図解

思考の整理というテーマを、実務ですぐに使える具体的な「技術」として落とし込んだ一冊です。

人気記事


記事を評価

Thanks!
目次
Scroll to Top