Ink

Contents related to tech, hobby, etc

PowerShellでファイルの変更監視

|

PowerShellでファイルの変更監視

注: 正直、今回の記事は参考サイトの晴耕雨読さんの内容ほぼ同じです。主に は自分用のメモとなります。

Linuxでは確立したAPIがなく面倒ですが、Windowsでは System.IO.FileSystemWatcher を用いることで様々なファイルの変更を検知 出来ます。全体的に1つの企業が作っているメリットみたいな所ありますね。 (それが嫌な所でもありますが)

.NETのクラスは New-Object で作成出来ます。その後、各プロパティを設定します。

$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\Users/me\AppData\Local\Temp"
$watcher.Filter = "execute.bat"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true
FileSystemWatcher.Path監視対象のディレクトリ
FileSystemWatcher.FilterPath以下のファイルのうち、一致した名前を持つファイルのみを監視する
FileSystemWatcher.IncludeSubdirectoriesサブディレクトリも監視対象にするか否か

そして、 FileSystemWatcher クラスの各イベントにアクションを登録します。

イベントへの登録は Register-ObjectEvent で可能です。イベントに関連す る情報は、 $Event, $EventSubscriber, $Sender, $EventArgs, $Args 変数に格納されるので、それを適宜参照することで様々なことが行えます。

Register-ObjectEvent $watcher "Created" -action {
  Write-Host "Created Event is called."
  # 関連処理
}

用例: 自動的に消滅するファイルのバックアップをとる

実際に自分が使用した例です。

Unity HubでUnity Editorをインストールする際、管理者権限で AppData/Local/Temp/UNKNOWN_HASH/execute.bat を実行する許可を求められ ました。中身を確認してから実行したいのでそれを読もうとした所、許可プロ ンプトの後にはもう削除されていました。

そこで、該当のファイルが生成された時にコピーするようなスクリプトを書きました。

$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\Users/me\AppData\Local\Temp"
$watcher.Filter = "execute.bat"
$watcher.IncludeSubdirectories = $true
$watcher.EnableRaisingEvents = $true

Register-ObjectEvent $watcher "Created" -action {
  Write-Host "Created Event is called."
  $targetDir = Split-Path -Parent $Event.SourceEventArgs.FullPath
  Write-Host "target directory: $targetDir"
  $saveTo = Join-Path -Path (Split-Path -Parent $targetDir) -ChildPath "saved-by-watchandcopy"
  Write-Host "Save to: $saveTo"
  Copy-Item $targetDir $saveTo -Recurse
}

参考サイト