2010/11/10

USBメモリ抜き忘れ防止スクリプトをPowerShellでやってみる

久々にPowerShellを使う機会にめぐまれたので、投稿します。

USBメモリ、今では安価となりかなり利用率は増えましたが
それと同時にメモリの抜き忘れも増えているみたいです。
なんとかならんのかー、という要望があったので
折角なのでPowerShellでログオフ時にUSBメモリがささっているとダイアログを出すスクリプトを作ってみました。
ちなみに、色々ネット上にある参考スクリプトをツギハギしたりしています。
使用時は自己責任でお願いします ><


とりあえず、1つ目のポイントとして、USBメモリの有無確認ですが、
win32_usbhub クラスを利用することでみつけることができます。

Win32_USBHub クラス - WMI Fun !!
http://www.wmifun.net/library/win32_usbhub.html

USBメモリの場合、Nameが "USB 大容量記憶装置"であり、
Statusが"OK"であれば、ほぼちゃんと認識された状態のUSBメモリがささっているといえます。
Get-WmiObject -Class win32_usbhub | ? { $_.name -eq "USB 大容量記憶装置" } | ? { $_.status -eq  "OK" }
USBメモリをさしていた場合

あとは、ダイアログとして出すようにスクリプトを組めば完成です。
詳細は以下。
#USBログオフ時メッセージプロンプト処理
#メッセージ文
$messagePath="C:\temp\usbmessage.txt"
#ログ出力パス
$usbLOG="\\buso-pcv\test\usblog.txt"

#--------------------------------------
#メッセージボックス
#--------------------------------------
function MessageBox([string]$p_value = "")
{
    [Void][Windows.Forms.MessageBox]::Show($p_value,"お知らせ","OK", "Warning")
}


$crUSB = Get-WmiObject -Class win32_usbhub | ? { $_.name -eq "USB 大容量記憶装置" } | ? { $_.status -eq  "OK" }


if ($crUSB) {
    write-output "$env:computername,$env:username,$(get-date)" >> $usbLOG

    #Windowsフォームのロード
    [Void][Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms");

    MessageBox $([String]::Join("`r`n", (Get-Content $messagePath)))
   
}
 メッセージ文は、いろんな人が編集する場所でもあることから、
別テキストからの呼び出しに 。(ここでは "C:\temp\usbmessage.txt")
以下のようにusbmessage.txtに書いてみました。
USBがさしっぱなしだぞー( ゚Д゚)
誰かに盗まれても知らないぞ( ´∀`)
って、席にもういないッッΣΣ(゚Д゚;)
また、ダイヤログが出たときに、使用者のホスト名、ユーザー名、時刻を吐き出すようにしてみました。
このスクリプトをログオフスクリプトとして設置しておけば完了です。
実際に使用するとこんな感じ。
USB差しっぱなしでログオフした場合

usblogに記録されたログ

ちなみにGPOでPowershellのログオフスクリプトを管理する場合には、
スクリプト実行ポリシーを有効にすることと、PowerShell用のタブが別途あるので注意しましょう。
(あと、もちろん適用環境ではPowerShellがインストールされていることが前提です(笑))


GPOによるスクリプト実行ポリシーの許可

ログオフスクリプトのPowerShellタブ

また、「ハードウェアの安全な取り外し」を行わなくても大丈夫か?という点については
書き込み中でなければ、ほぼ問題ないとのこと。
ログオフ後なら なおのこと その後ぬいても問題ないでしょう。
どうしても怖いというのであれば、もう一度ログインして手順を踏んで抜いてもらうということで。

USBメモリやUSB HDDを安心して取り外す - ITmedia
http://bizmakoto.jp/bizid/articles/0710/03/news062.html


さて、これで使用者には注意を促しましたが、上記のメッセージにある通り
そもそも、使用者はログオフボタンを押した時点で皆 律儀に席に座っているとはかぎりません。

なので、USBメモリをさしてログオフした人を管理者へ知らせるスクリプトも作ってみました。

今回は長くなったので、スクリプトについてはまた次回。
ちなみに動作としてはこんな感じに出力させました。
USBメモリさし忘れ監視
ログを監視し続けて、書き込みがあったら出力、ついでにポップアップ表示もさせています。
では、また次回。(といって、またえらく時間あいたら嫌だな・・)

2010/08/18

ActiveDirectoryでの監査ポリシーを考えてみる

ADを運用していると、
オブジェクトの変更をしたりログイン・ログオフしたときの様々なログを取得したいーという要望があります。
そんな時は、ADによる 監査ポリシーを使用するという手段がありました。
しかし、監査ポリシーの使用は精度があまり高くない、使いにくいという話もちらほら聞こえたりしていて
結局積極的に使用を控えていました。
しかし、2008R2Serverも浸透している現在、少し立ち戻って本当に使えないのか少し検証してみたいと思います。

・監査ポリシーとは
Technet 監査ポリシー
http://technet.microsoft.com/ja-jp/library/cc730601%28WS.10%29.aspx
上記にあるように、GPOによる設定で様々な「監査」を実施することで、セキュリティログへ情報を書き出します。
設定できる監査項目は以下のとおり。
http://technet.microsoft.com/ja-jp/library/cc787176%28WS.10%29.aspx
---
http://technet.microsoft.com/ja-jp/library/cc787567%28WS.10%29.aspx

---
http://technet.microsoft.com/ja-jp/library/cc737542%28WS.10%29.aspx

---
http://technet.microsoft.com/ja-jp/library/cc776774%28WS.10%29.aspx
---
http://technet.microsoft.com/ja-jp/library/cc728087%28WS.10%29.aspx
---

残り4つの監査項目はまた次回。
監査ポリシーの問題点や、チューニングについてもおいおい調べていきたいと思ってます。

2010/08/09

DISMコマンド

DISMコマンドは7には標準搭載されているコマンドですが、色々できるようです。


WindowsTips
新しい DISM ツールを使用して Windows イメージを準備およびサービスする
http://technet.microsoft.com/ja-jp/windows/ee183884.aspx



COMPUTERWORLD BLOG
VHD のオフラインパッチ by DISM
http://blog.computerworld.jp/2010/08/09/offlinepatch-by-dism/

@IT
Windows 7/Windows Server 2008 R2のコンポーネントをdismコマンドで管理する
http://www.atmarkit.co.jp/fwin2k/win2ktips/1296dism/dism.html

な○の 屋
WinPE 3.0 ( Windows AIK for Windows 7 )
http://yuichi.tea-nifty.com/blog/2009/08/winpe-30-window.html

Windows 7 エンタープライズ ショート ビデオ
How Do I: Deployment Image Servicing and Management (DISM)?
http://technet.microsoft.com/ja-jp/windows/dd320284.aspx

---
Dism /? でヘルプが出ます。
上記記事にあるように、適用したパッチをオフラインからアンインストールしたり、
イメージを展開することなく、更新プログラムの確認などができるようです。

まだ、イメージ展開サービスやVHDファイルを運用レベルで使ってはいないのですが、
今後使用する機会もあるかもしれないですねー

2010/06/04

PowerShellにしゃべらせる

Windowsでしゃべらせるには色々な方法があるみたいですが、
.NET Framework 3.0 を入れているのであれば、Speech.Synthesis.SpeechSynthesizerクラスを使うのが楽っぽいです。
$null = [Reflection.Assembly]::LoadWithPartialName("System.Speech")
$SMSpeaker = new-object System.Speech.Synthesis.SpeechSynthesizer

あとは Speakメソッドでしゃべらせるだけ。
 $SMSpeaker.Speak("hello buso")
日本語はデフォでは対応していないらしく、Office2003についてくるLH Kenj なんかの音声合成エンジンを使わなければならないっぽい。
2010も出る今となってOffice2003といわれてもなぁ。
ちなみに、ツイッターと連動させて読み上げさせるスクリプトを作っている人もいました。
うーん、僕も日本語でも読み上げさせたいぞ。


まぁ、監視として、何かあったら読み上げるというのもこれで簡単にできそうですね。

2010/06/01

サーバのグループポリシーのリンク監視の方法を模索してみる その3

さらにグループポリシーリンク監視の模索の続き。
サーバのグループポリシーのリンク監視の方法を模索してみる その1
サーバのグループポリシーのリンク監視の方法を模索してみる その2

前回、前々回とポリシー編集とリンクの付与の比較を出力する方法を模索し、
スクリプトを作ってみました。処理内容はこんな感じ。


エラー時の動作などはまったく組み込んでないので参考程度でどぞ。
#CheckGPO

Import-Module activedirectory
Import-Module grouppolicy

#origpoファイルの場所
$workpath="C:\hogehoge\"

#メール配信先設定
$smtpHost = "SMTPサーバアドレス"
$mailfrom = "FROMのアドレス"
$mailto = "メール配信先"
$mailsubject = "GPOCheckログ"
$mailer = New-Object System.net.mail.smtpclient($smtpHost)

function comparegpo ($crlink, $orilink, $crgpo, $origpo) {
    
#gpo設定 変更された場合は新しいGPOのバックアップを行い oriファイルを更新
    compare-object $crgpo $origpo -property modificationtime,gpostatus,displayname | Set-Variable diffgpo
    if ($diffgpo) { 
        "$(get-date) :--GPO変更が発生しました"
        $diffgpo | sort displayname | ft -AutoSize
    $timename=$(Get-ItemProperty $workpath\origpo.xml).LastWriteTime -replace "[/,:, ]",""

    $diffgpo | ? { $_.sideindicator -eq "<=" } | % { "backup実施"; backup-gpo $_.displayname -path $workpath\gpbackup | fl }
    move-item $workpath\origpo.xml $workpath\log\$timename"gpo.xml" | Out-null
        $crgpo | Export-Clixml $workpath\origpo.xml
     }

#link設定  変更された場合は oriファイルを更新
    compare-object $crlink $orilink -Property target,displayname,enabled | Set-Variable diffgpl
    if ($diffgpl) { 
        "$(get-date) :--GPO Linkに増減が発生しました"
        $diffgpl | sort displayname | ft -AutoSize
    $timename=$(Get-ItemProperty $workpath\orilink.xml).LastWriteTime -replace "[/,:, ]",""
    move-item $workpath\orilink.xml $workpath\log\$timename"orilink.xml"
        $crlink | Export-Clixml $workpath\orilink.xml 
    }

}

#origpo存在チェック
if (test-path "$workpath\origpo.xml"){
    $origpo=Import-Clixml "$workpath\origpo.xml"
} else {
    "origpo.xml NotFound"
    get-gpo -all | Export-Clixml $workpath\origpo.xml
    return
}

if (test-path "$workpath\orilink.xml"){
    $orilink=Import-Clixml "$workpath\orilink.xml"
} else {
    "orilink.xml NotFound"
    Get-ADOrganizationalUnit -Filter 'Name -like "*"' | % { Get-GPInheritance -Target $_ } | ? { $_.gpolinks -ne "" } | % { $_.path; $_.gpolinks } | Export-Clixml $workpath\orilink.xml
    return
}


#現在のOU状態の取得
$crlink = Get-ADOrganizationalUnit -Filter 'Name -like "*"' | % { Get-GPInheritance -Target $_ } | ? { $_.gpolinks -ne "" } | % { $_.path; $_.gpolinks }
$crgpo = get-gpo -all


#比較対象を関数で渡し、戻り値が存在した場合にはメールを出す
$result=comparegpo $crlink $orilink $crgpo $origpo

if ($result) { 
    $mailbody=[string]::join("`r`n", ($result | out-string -width 200 ))
    $mailer.send($mailfrom, $mailto, $mailsubject, $mailbody )
    $result | out-string -width 200 > $workpath\recent.log
    $result
    "変更が発生し、メールを出しました"
}
$work フォルダの配下にlog フォルダと、 gpbackupフォルダを用意してください。
適当にGPOを変更かけて、リンクをつけたあとにスクリプトを実行してみました。


あとはこのスクリプトを一定時間のタスクで回しておけば、
多少の監視にはなるかなぁと。

結局、サイトのGPOは対応できなかったけどなッッ