ファイルの更新日時を一括で変更するコマンド(PowerShell)

今回はWindowsにおいてファイルの更新日時を一括で変更するコマンド(PowerShell)について調べてみました。

環境

  • Windows 10 Pro バージョン 1511
  • PowerShell バージョン 5.0

PowerShell?

What is PowerShell?

PowerShell is an automation platform and scripting language for Windows and Windows Server that allows you to simplify the management of your systems. Unlike other text-based shells, PowerShell harnesses the power of the .NET Framework, providing rich objects and a massive set of built-in functionality for taking control of your Windows environments.

Microsoft PowerShell

ファイルの確認

確認のために幾つかファイルを作成しておきます。 フォルダー構造は次の通りです。

PS C:\> tree /f
C:.
│  file01.txt
│  file02.txt
│  file03.txt
│  file04.xlsx
│
└─fol1der11
        file11.txt
        file12.txt

これらのファイルの更新日時(LastWriteTime)は次の通りです。 全部2016/02/08になっています。

PS C:\> Get-ChildItem -Recurse


    ディレクトリ: C:\


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2016/02/08     19:25                fol1der11
-a----       2016/02/08     19:21              0 file01.txt
-a----       2016/02/08     19:21              0 file02.txt
-a----       2016/02/08     19:21              0 file03.txt
-a----       2016/02/08     19:22          10350 file04.xlsx


    ディレクトリ: C:\fol1der11


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2016/02/08     19:21              0 file11.txt
-a----       2016/02/08     19:21              0 file12.txt

ファイルの更新日時を変更する

PowerShellのコマンドを実行するためにWindows PowerShellを開きます。 エクスプローラーのメニューからファイル-Windows PowerShell を開く(R)を選択します。 表示されるコマンドプロンプトからコマンドを入力します。

Get-ChildItemで対象のファイルを取得します。 -Recurseを指定することでフォルダーを再帰的に対象とします。 Where-Objectでファイルのみを対象(フォルダーは対象外)とします。 ForEach-Objectで対象となったファイルを繰り返し処理します。 Set-ItemPropertyで更新日時を変更します。 ここでは日付だけ変更するようにしています。 時刻まで同じにしたくないこともありますよね。 なので時刻はもともとあったそれぞれのファイルの時刻になります。

PS C:\> Get-ChildItem -Recurse | Where-Object { $_ -is [System.IO.FileInfo] } | ForEach-Object { Set-ItemProperty $_.FullName -Name LastWriteTime -Value ("2016/02/07" + " " + $_.LastWriteTime.ToString("HH:mm:ss")) }

更新日時を確認します。 2016/02/07に変更されました。 フォルダーはそのままの日付です。

PS C:\> Get-ChildItem -Recurse


    ディレクトリ: C:\


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d-----       2016/02/08     19:25                fol1der11
-a----       2016/02/07     19:21              0 file01.txt
-a----       2016/02/07     19:21              0 file02.txt
-a----       2016/02/07     19:21              0 file03.txt
-a----       2016/02/07     19:22          10350 file04.xlsx


    ディレクトリ: C:\fol1der11


Mode                LastWriteTime         Length Name
----                -------------         ------ ----
-a----       2016/02/07     19:21              0 file11.txt
-a----       2016/02/07     19:21              0 file12.txt

ファイルの作成日時を変更する

Set-ItemPropertyLastWriteTimeのところをCreationTimeにするとファイルの作成日時を変更できます。

PS C:\> Get-ChildItem -Recurse | Where-Object { $_ -is [System.IO.FileInfo] } | ForEach-Object { Set-ItemProperty $_.FullName -Name CreationTime -Value ("2016/02/07" + " " + $_.CreationTime.ToString("HH:mm:ss")) }

ファイルのアクセス日時を変更する

あまり需要はないと思いますが、LastWriteTimeのところをLastAccessTimeにするとファイルのアクセス日時を変更できます。

PS C:\> Get-ChildItem -Recurse | Where-Object { $_ -is [System.IO.FileInfo] } | ForEach-Object { Set-ItemProperty $_.FullName -Name LastAccessTime -Value ("2016/02/07" + " " + $_.LastAccessTime.ToString("HH:mm:ss")) }

対象とするファイルの指定

Get-ChildItemのところで対象とするファイル変えることができます。 次のようにするとカレントフォルダーの拡張子が.txt.xlsxのファイルが対象になります。

Get-ChildItem -Path *.txt,*.xlsx

次のようにするとfolder11フォルダーの中の拡張子が.txtのファイルが対象になります。 001.txtは除外されます。

Get-ChildItem -Path folder11\* -Exclude 001.txt -Include *.txt

大量のファイルを作成する

PowerShellはあまり使わないので覚えたことの一つ目です。 空のファイルを大量に作成したくなったら。

1..100のところを1..1000にすると1000のファイルが作成できます。 後ろの方の("000")はファイル名を001002のように0埋めしています。 ".txt"は拡張子で、空のファイルなのでテキストエディタで開くことを想定して".txt"にしています。

(1..100) | ForEach-Object { New-Item -ItemType file ($_.ToString("000") + ".txt") }

PowerShellのバージョンを調べる

PowerShellはあまり使わないので覚えたことの二つ目です。 PSVersionがPowerShellのバージョンです。

PS C:\> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.0.10586.63
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.10586.63
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

終わり

今回はPowerShellを使っていますので、これが標準でWindowsに入ってきたのはいつかと調べてみましたが、Windows 7からのようです。 最近のような気もしますけど、Windows 7ってもうメインストリームのサポートも終わっているんですね。

Windows ライフサイクルのファクト シート - Windows ヘルプ

ECMAScriptみたいに先行して不確実なものを取り入れるのはあまり賛成ではないですけど、こういう終わるものは早く入れ替える方がいいと思っています。

参考