LoginSignup
6
4

More than 5 years have passed since last update.

代替データストリームを利用した1日1回起動スクリプト

Last updated at Posted at 2015-11-08

minrさんの代替データストリーム(ADS)について色々調べてみたを読んで実際に代替データストリームを使ってみた。

※最初の投稿に不備があったので一部訂正します。

代替データストリームの読み書き

代替データストリームはNTFS上のファイルやディレクトリに付与できる情報とのこと。PowerShellでこれにアクセスするコマンドは次の6つ。

コマンドレット 機能
Add-Content -Path ファイル名 -Value 値 -Stream ストリーム名 指定された既存のストリームに値を追記
Clear-Content -Path ファイル名 -Stream ストリーム名 指定された既存のストリームから値のみを削除
Get-Content -Path ファイル名 -Stream ストリーム名 指定された既存のストリームの値を得る
Set-Content -Path ファイル名 -Value 値 -Stream ストリーム名 指定されたストリームに値を設定(存在しない場合はストリームを作成)
Get-Item -Path ファイル名 -Stream ストリーム名 指定された既存のストリームの値とサイズを得る
Remove-Item -Path ファイル名 -Stream ストリーム名 指定された既存のストリームそのものを削除

似たようなコマンドレットがありますが、それぞれ微妙に違いがあります。

  • Add-Contentは値を追記するが、Set-Contentは値を上書きしてしまう

  • *-Content系コマンドレットはストリーム名の指定にワイルドカードが使えないが、*-Item系はストリーム名の指定にワイルドカードが使える

  • Clear-Contentはストリーム名を残したまま値を削除するが、Remove-Itemはストリームそのものを削除する

自分自身が起動された日付を覚えよう

毎日決められた時刻までに残業申請をしなくてはいけません。(´Д` )

なので朝イチPC起動時にスタートアップから立ち上がるPowerShellコンソールの$profileに、その日最初の1回だけ残業申請ファイルを立ち上げるスクリプトを書くのです。

OneTimeExecute.ps1
if ($PSVersionTable.PSVersion.Major -ne 5) {
  "このPowerShellでは動作しません。"
} else {
  $today = Get-Date
  $myname = $MyInvocation.MyCommand.Path
  $Keyword = Get-Item -Path $myname -Stream * | Where-Object {$_.Stream -match 'LastBoot'}
  if ((Get-Content -Path $myname -Stream $Keyword.Stream) -ne $today.Date.toString()) {
    "本日最初の起動です。"
  }
  Set-Content -Path $myname -Value $today.Date.toString() -Stream 'LastBoot'
}

6行目でスクリプトファイル自身に付与されているであろう代替データストリームの内容を抽出し、7行目でこれを照合しています。処理が終わったら10行目で今日の日付を代替データストリームに書き込んで終了します。

実際には8行目のメッセージのところを残業申請ファイルの立ち上げプロセスに書き換えて使用します。

必ず存在する:$DATA

Get-Itemでストリーム名を*にして検索すると、必ず表示されるストリーム名があります。ファイルサイズを表す:$DATAストリームです。

代替データストリームを扱うコマンドレットはいずれも存在しないストリーム名を指定するとエラーを吐きます。なので、このスクリプトの初回起動時にLastBootというデータストリームが存在しない場合を想定して、3行目ではあえてすべてのデータストリームの中からLastBootを抽出するというまどろっこしいことをしました。

これができるのも、:$DATAという必ず存在する代替データストリームのおかげです。

追記:Windows7では動かなかった

代替データストリーム自体はNTFSの機能なのでWindows7にもあるはずですが、Get-ItemGet-ContentSet-ContentStreamパラメータを扱えませんでした。

Windows7のPowerShellはVersion2です。当初このスクリプトを動かして確認したWindows10のPowerShellはVersion5。

3や4で動くのかどうかわかりませんが、とりあえず動作確認の取れているVersion5のみ動作するように書き換えました。

1行目で自動変数の値をみてPowerShellのVersion5かどうかをチェックしています。

6
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
4