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を使って出力を行っている。