特定のフォルダーのPowerShellスクリプトを自動署名する

以前、こんなのを書いた。
Powershellスクリプトの署名と証明書の操作 - じゅんじゅんのきまぐれ
一応、分けて運用してたのだけど、モジュールの展開とかいろいろ面倒になって、ま、署名されたスクリプトを直接更新してやれ、という気になったので変更を検知すると署名するように変更してみました。



スクリプト

Start-Watcherにもちろん依存しています。
Powershellで非同期にファイル変更を監視する - じゅんじゅんのきまぐれ

	$sign = {
		Param($sender, $ev)
		$p = $ev.FullPath
		if($p -match '\.psm?1$' -and (Test-Path $p)) {
			$f = Get-Item $p
		} else {
			return
		}
		$d = $Event.MessageData
		if(!$d.ContainsKey($p) -or ($f.LastWriteTime -gt $d[$p])) {
			$d[$p] = [DateTime]::MaxValue
			$Certificate = (Get-ChildItem Cert:\CurrentUser\My -CodeSigningCert | Select-Object -First 1)
			Set-AuthenticodeSignature -Certificate $Certificate $p
			$d[$p] = [DateTime]::Now	# LastWriteTimeよりちょっと後にする必要がある
		}
	}
	Start-Watcher $sign (Split-Path $PROFILE) '*.*' -IncludeSubdirectories -MessageData (New-Object 'System.Collections.Generic.Dictionary[string,DateTime]')

とりあえず、Start-Watcherで監視しているのは、$PROFILEのあるフォルダー以下です。
全ファイル監視して、正規表現'\.psm?1$'とマッチしたもののみ署名対象としています。
$Event.MessageDataを使って、更新毎にスクリプト変更での更新か署名での更新かを判定してます。
LastWriteTimeを入れてたら、更新が更新を呼ぶパターンがあったため、少し大きいNowにしました。


これで、$PROFILEやモジュールが署名対象になります。
他のフォルダーも監視させたいなら、Start-Watcherを増やしてください。