2021年11月29日(月) [長年日記]
■ [windows] Zipファイルを作るPowerShellスクリプト
初めてPowerShellスクリプトを書いた。フォルダパスとZipファイルパスを指定すると、フォルダ内の.exeと.dllをアーカイブしたZipファイルを作成するスクリプト。
param(
[Parameter(Mandatory=$true)][String]$srcDir,
[Parameter(Mandatory=$true)][String]$zipFile
)
try {
# エラーが発生したら処理を止める
$ErrorActionPreference = "Stop"
Write-Host "$srcDir --> $zipFile"
# 一時フォルダを作成
$tmpDir = New-TemporaryFile |
% { Remove-Item $_; New-Item -ItemType Directory $_-d }
# 一時フォルダへ必要なファイルだけをコピー
Copy-Item -Include *.exe,*.dll $srcDir\* $tmpDir
# zipファイルが存在している場合はそれを削除
if (Test-Path $zipFile) { Remove-Item $zipFile }
# zipファイルを作成
Compress-Archive $tmpDir/* $zipFile
# zipファイルの内容を出力
Add-Type -AssemblyName System.IO.Compression.FileSystem
[System.IO.Compression.ZipFile]::OpenRead($zipFile).Entries |
Format-Table -Property FullName,LastWriteTime
} finally {
# 一時フォルダを削除
if ($tmpDir) { Remove-Item -Recurse $tmpDir }
}
PowerShellスクリプトの実行方法
PowerShellスクリプトはデフォルトの設定だとセキュリティエラーになり実行できない。
PowerShellコマンドにExecutionPolicyオプションと共にスクリプトを指定すれば実行できる。
> powershell -ExecutionPolicy unrestricted ./make-zip.ps1 test test.zip test --> test.zip FullName LastWriteTime -------- ------------- a.exe 2021/11/29 16:26:54 +09:00 b.dll 2021/11/29 16:20:18 +09:00
スクリプトのパラメータ
スクリプトのパラメータはparamで指定できる。ちゃんとした説明を見つけられないがParameters in scriptsで少し説明されている。
上のスクリプトではParameter属性を使って2つのパラメータ(srcDirとzipFile)を必須に設定している。
エラー時にスクリプトを終了する
処理中にエラーが発生したらそこでスクリプトは止まってほしい。それを実現するには、$ErrorActionPreferenceにStopを設定すればいいようだ。
メッセージの出力
メッセージを出力するにはWrite-HostまたはWrite-Outputが使える。
一時フォルダの作成と削除
PowerShellには一時フォルダを作成する機能はなさそう。上のスクリプトではStack Overflowにあった例を真似して、一時ファイルを生成 → その一時ファイルのパスを利用して一時フォルダを作成、という手順で作っている。
なお、一時フォルダ作成処理内にある「%」はForEach-Objectのエイリアス。
作成した一時フォルダの削除はtry/finallyステートメントのfinally内で行うようにしている。
Zipファイルの作成
Zipファイルの作成にはCompress-Archiveが使える。
Zipファイル内のファイル一覧を出力
Zipファイルの作成は上述のCompress-Archiveでできるが、Zipファイル内のファイル一覧を得るコマンドレットは無いみたい。Zipファイルを展開するのならExpand-Archiveを使えるのだけれど。
ファイル一覧を得るには、.NETのライブラリを使う必要がありそう。System.IO.Compression.ZipFileというクラスが使える。
PowerShellでは、Add-Typeを使うとDLLを読み込んで.NETのクラスを使えるようになる。上のスクリプトではSystem.IO.Compression.FileSystem.dllを読み込んで ZipFile#OpenRead() を呼び出し、更にFormat-Tableを使って出力を行っている。