今日を基準にしたファイル一覧コマンド

PowerShellではGet-ChildItemコマンドレット(省略形gci)で、ファイルの一覧を表示することができます。また、表示するファイルを日付で絞り込みたい場合、パイプラインでWhere-Object(省略形where)コマンドレットに送って抽出します。

例えば、本日が2011年2月8日である場合、本日のファイルをカレントディレクトリ以下のディレクトリから表示するには、以下のように実行します。

gci  -Recurse  | where { $_.LastWriteTime -ge "2011/2/8" }

Get-ChildItemの-Recurseオプションでサブディレクトリごと検索し、Where-Objectで、LastWriteTimeプロパティ(最終更新日時)が2011年2月8日以降のものを抽出します。

しかし、毎回これをコマンドラインに入力するのは面倒です。

そこで、今号より、Get-FileInfomation todayと入力すれば今日のファイル、Get-FileInfomation yesterdayと入力すれば昨日のファイル、Get-FileInfomation thisweekと入力すれば今週のファイル...と、実行する当日を基準として、わかりやすくタイムスタンプの範囲を指定できるスクリプトを作成します。

PowerShell ISE

今回から、PowerShell ISE(Windows PowerShell Integrated Scripting Environment)を使ってスクリプトを作成します。PowerShell ISEはWindows Server 2008、Windows Vista以降のWindowsに装備されているPowerShellスクリプト開発環境で、PowerShell単語を色分けして表示するエディタ、バックスクロールできる実行画面、PowerShellプロンプトを備えています。

※ PowerShell ISEがない環境では、メモ帳などのエディタでPowerShellスクリプトを作成してください。スクリプトの拡張子はps1です。

PowerShell ISEの画面は、3つのペイン(枠)に分かれています。初期設定では上下に3段になっていますので、上から順に次のようになります。

スクリプトペイン

複数のスクリプトを開いて、タブによってスクリプトペインを切り替えられます。

出力ペイン

コマンドレットやスクリプトの出力結果を表示します。

コマンドペイン

プロンプトにコマンドレットやスクリプトを入力して、実行します。

Windows PowerShell ISEは、スタートメニューの[すべてのプログラム]→[アクセサリ]→[Windows PowerShell]→[Windows PowerShell ISE]をクリックして起動します。

なお、x64版(64ビット版)Windowsでは、Windows PowerShell、Windows PowerShell ISEとも、x64版とx86版(32ビット版)の両方を装備しています。

Windows PowerShell ISEの画面。

なお、当連載ではこれまで原則としてWindows Server 2008初期版の画面でPowerShellを紹介してきました。PowerShell ISEを使うため、今号よりWindows 7の画面で紹介します。

スクリプト実行環境の準備

Windows PowerShellの初期状態ではスクリプトを実行できません。まず、スクリプトを実行できるように実行ポリシーにRemoteSignedを設定してください。実行ポリシーを変更するときは、[管理者として実行]でPowerShellを起動します。また、実行ポリシーの設定値はレジストリに保存するため、毎回実行ポリシーを変更する必要はありません。

 (1)Windows PowerShell ISEを[管理者として実行]で実行します。

スタートメニューの[Windows PowerShell ISE]を右クリックし、ショートカットメニューの[管理者として実行]をクリックします。

 (2)Get-ExecutionPolicyで現在の設定を確認します。

Get-ExecutionPolicyコマンドレットを実行し、現在の状態を確認します。

コマンドペインにコマンドラインを入力してEnterキーを押すと、実行結果を出力ペインに表示します。実行ポリシーの既定値はRestrictedで、スクリプトの実行を拒否します。

 (3)Set-ExecutionPolicyで、RemoteSignedを設定します。

RemoteSignedは、自作スクリプトの実行を許可し、ダウンロードしたスクリプトに関しては電子署名がされているスクリプトだけ実行を許可します。

 (4)実行ポリシーを変更するとき、警告メッセージを表示します。

[はい]をクリックして、実行ポリシーを変更します。

※ スクリプト実行ポリシーに関しては当連載第7回の記事を参照してください。

プログラムの概要

これから作成するプログラムは、today、yesterdayなどのキーワードで、そのタイムスタンプのファイルを検索して表示します。仕様を考えてみましょう。

 (1)オプションパラメータとして、today、yesterdayなどのキーワードを指定します。

 (2)オプションパラメータを指定しないで実行したときは、ヘルプを表示します。

 (3)基本動作は、Get-ChildItemとWhere-Objectをパイプラインで接続します。

以上を踏まえると、プログラムを作成する上で一番ポイントとなりそうなのは、todayなどのキーワードから、どうWhere-Objectのスクリプトブロックを構成するか、となります。Where-Objectのスクリプトブロックでは、{($_.LastWriteTime -ge $date1) -and ($_.LastWriteTime -lt $date2))} のように条件を設定しなければなりません。このスクリプトブロックが意味するのは、「ファイル情報の最終更新日時がdate1以降、date2以前」です。そこで、todayやthisweekといったキーワードと現在の年月日から、状況に応じたdate1とdate2を算出しなければなりません。

プログラム全体を一度に作成するのは、大変な作業になりますし、それだけにプログラミングミスも起こしやすくなります。関数(function)を作成しながら、少しずつプログラムを構築していきましょう。

最初の関数...TodayPeriod

まず最初に、Get-FileInfomationにtodayと指定した時を想定した、「今日」の範囲を算出するプログラムを作成します。今日の範囲は、当日の0:00:00から、翌日の0:00:00の直前までと考えます。

基本となるのはGet-Dateコマンドレットです。Get-Dateコマンドレットは、単純に実行すると現在のシステム日時のオブジェクトを返します。

スクリプトペインに「Get-Date」と入力し、ツールバーの[スクリプトを実行]ボタンをクリックするか、F5キーを押してください。出力ペインに実行結果を表示します。

現在の日時。スクリプトペインに実行行を入力して、実行ボタンをクリックすると、出力ペインに結果を表示します。

※ コマンドペイント異なり、スクリプトペインに入力した内容は、編集して何度でも実行できます。実行を繰り返し、試行錯誤しながらスクリプトを作成するのに最適です。

Get-Dateは現在日時時刻を取得できますが、実際に必要なのはtodayの絞り込み範囲となる、本日の0:00:00です。このように一部の値を0に指定するには、-Hour(時)、-Minute(分)、-Second(秒)を使います。

「Get-Date -Hour 0 -Minute 0 -Second 0」と実行すれば、本日の0:00:00を得られます。

今度は、Get-Dateの出力を変数date1に代入し、パイプラインでGet-Memberに流してみます。Get-Memberはオブジェクトのメンバ関数やプロパティを確認するコマンドレットです。メンバ関数にどのような関数があるかを確認したいだけなので、あとで編集することはありません。そこで、コマンドペインに入力して実行します。

Get-Dateが出力するオブジェクトのメンバ関数に、日付を加える(減じる)AddDays()という関数があることがわかります。

Get-Dateの働きがわかったところで、「today(本日)」の範囲を出力する関数、TodayPeriodを作成しましょう。

スクリプトペインで、以下のように編集します。行頭の行番号は、プログラムを解説上で便宜上につけたものですので、PowerShell ISEには入力しないでください。

1:function TodayPeriod
2:{
3:  $date1 = Get-Date -Hour 0 -Minute 0 -Second 0
4:  $date1
5:  $date1.AddDays(1)
6:}
7:
8:TodayPeriod

まず、function TodayPeriod {}で、新しくTodayPeriodという関数(PowerShellでは実質コマンド)を宣言します。

3行目では、本日の日付の0時0分0秒の日付時刻型オブジェクトを取得し、変数date1に保存します。4行目ではdate1の値をパイプラインに出力します(PowerShellでは、代入先がない式の記述は、パイプラインにオブジェクトを出力します)。

5行目では、日付時刻型オブジェクトのメンバ関数AddDaysを使って、date1の値に1日加えた値を算出し、パイプラインに出力します。

1~6行目で関数TodayPeriodを定義しますが、これだけだと定義しただけで実行されないので、8行目でTodayPeriodを実行し、結果を確認します。

関数TodayPeriodを定義し、実行した結果。

予想通りに実行できました。この2つの値...本日0時0分0秒以降、翌日の0時0分0秒未満が、「本日」の範囲と言えます。

最後に、ここまでの結果を保存ボタンをクリックしてスクリプトファイル「Get-FileInformation.ps1」として保存してください。