若干Windows Serverからは離れますが、自宅用にPowerShellスクリプトを書いたので紹介してみます。デジカメ、スマートフォンなどで撮影した画像、動画ファイルをリネーム後月ごとのフォルダに移動するスクリプトを書きました。ソースコードはgistにアップしたので参考になる部分があれば…。
[gist id=4175880]
以下、ちょっと苦労した点等です。
Exif情報の取得
Exif情報から撮影日時を取得しています。Exif情報の取得には.NET FrameworkのSystem.Drawing.Bitmapクラスを使っています。以下の部分です。
[Reflection.Assembly]::LoadWithPartialName(“System.Drawing”) | Out-Null $img = $null $img = New-Object Drawing.Bitmap($file_path) $date = ($img.PropertyItems | Where-Object{$_.Id -eq 306}).value $date = [Text.Encoding]::ASCII.GetString($date).Replace(":",".").Replace(" “, “-”) $date = $date.Substring(0, $date.Length -1) $img.Dispose() $img = $null [Reflection.Assembly]::LoadWithPartialName(“System.Drawing”) の部分はOut-Nullにパイプしておいてあげないと関数の戻り値として戻ってきてしまいました。PowerShellってそういうものなのですね。今まで知りませんでした・・・。
BitmapクラスのPropertyItemsプロパティでIdが306のものが撮影日時みたいです。Exifの企画やBitmapクラスの仕様はよくわかっていませんが、これで問題なかったのでよしとしてます・・・。
バイナリで入っているのでText.Encoding.ASCIIのGetString関数で文字列にしています。この時に文字列の最後にヌル文字(\0)が入っているのですが、これがどうやっても取れず、しかたがないので$date = $date.Substring(0, $date.Length -1)としてしまいました。妥協です。「`0」が該当するのかと思ったのですが、違うみたいです・・・。
$img.Dispose()しておいてあげないと、連続してリネームしたり移動する時に「他のプロセスが使用しています。」と怒られてしまったので処理を入れています。
その他は考えてみたらあまり苦労していないのですが、本筋とは違うテストの部分でPesterが端末毎に挙動がちがったり、最新版を使おうとするとそもそもPesterがうまく動かなかったり、しかたがないのでPSUnitを使ってみたらテストに失敗しても実際のオブジェクトの内容を表示してくれなかったりなど、テスト周りで苦労してしまいました。結局ちゃんとテストが書けていません。PowerShellのテストはPesterでOKだと思っていたのですが、もうちょっと研究が必要なようです…。