2014年8月5日火曜日

SystemCenter勉強会

先月、会社の有志?を集め、「SystemCenter勉強会」を実施しようというお話があった。
最近、管理仕事ばかりで全く技術者っぽくなくなってしまった自分を戒める為にも「参加しよう!」と意気込んでみたものの、仕事が忙しくてなかなか手を付けられず…。



はい。そうです。言い訳です。



 という事で、頑張ってブログ更新しながらSystemCenter備忘録まとめていきたいと思います。


 何やらカテゴリが一杯あってとても覚えられそうにないので…。

2014年7月21日月曜日

フォルダにファイルが作成されたこと をイベントトリガーにする

お久しぶりです。

転職&引っ越しをしてからやたら忙しい毎日を送っております。
今回は、別の勉強していたら面白い機能をネットで見かけたので備忘録がてら記事にしてみたり。
(決して本来の勉強の脱線じゃない!)


昔の現場で、以下の要件のPowerShellスクリプトを作成しました。
  • 特定のフォルダのファイル(XML)を読み込んで、とある処理をする。
  • そのファイル自体は、有ったり無かったりする。
    • つまり、ファイルが有れば処理実行。無ければ何もしない。


こんな感じ(↑)の実装をどうやったか。
  • タスクスケジューラでスクリプトを5分おきに実行し、フォルダ内をチェックする。
  • 特定のファイルが有れば処理実行。無ければ何もしない。


・・・はい。誰でも思いつく事ですね。無駄なリソース使ってますね。。。ゴメンナサイ。


そこで今回見つけた便利機能。
FileSystemWatcher クラス
ファイル システムの変更通知を待機し、ディレクトリまたはディレクトリ内のファイルが変更されたときにイベントを発生させます。

なんだよ。こんな便利機能あるんじゃないかよ。
一年前の自分に教えてあげたい・・・。


という訳で、拝借してきたスクリプトは以下。
$watcher = New-Object System.IO.FileSystemWatcher
$watcher.Path = "C:\temp"
$watcher.Filter = "*.xml"
Register-ObjectEvent -InputObject $watcher -SourceIdentifier mywatch -EventName Created -Action {
 Write-Host "hoge"
}


実行結果。
Id     Name            PSJobTypeName   State         HasMoreData     Location 
--     ----            -------------   -----         -----------     -------- 
3      mywatch                         NotStarted    False                    


「C:\temp」内に.xmlファイルを置いてあげると、「hoge」ってコンソールに出てきます。


実際に使う時にはコンソールに文字出しても意味が無いので、-ActionのWrite-Host部分でイベントログにでもログを出して、そのログをトリガーにスクリプトを動かせば良い様な気がする。


確認するには
Get-EventSubscriber

SubscriptionId   : 3
SourceObject     : System.IO.FileSystemWatcher
EventName        : Created
SourceIdentifier : mywatch
Action           : System.Management.Automation.PSEventJob
HandlerDelegate  :
SupportEvent     : False
ForwardEvent     : False


削除するには
Unregister-Event -SourceIdentifier mywatch

2013年5月11日土曜日

プレゼンテーションテクニック

Community Open Day 2013 の東京会場(Microsoft品川本社)に参加してきました。

色々なセッションを見て、それぞれがとても面白く参考になる話でしたが、特にMicrosoftエバンジェリスト西脇氏の「プレゼンテーションテクニック講座」が面白かった!

ということで、忘れないうちに印象に残った内容をメモメモ。


プレゼンの種類


  • オーソドックス型
    • 一つのスライドの中に必要な情報を記載し、プレゼンしていくタイプ
  • 詳細型
    • 一つのスライドの中に大量の情報を記載し、プレゼンしていくタイプ
  • フラッシュプレゼンテーション
    • 一つ一つのスライドには短いメッセージのみを記載して、プレゼンしていくタイプ


今まで色々な人のプレゼンを見てきたが、技術系のセッションではフラッシュプレゼンテーションが多かった。というかほとんどこのパターンな気がする。(見なくてもいいですよw という名目で詳細を織り交ぜるパターンもあったが)

ただ、技術系のライトニングセッションでは、相手に技術の詳細まで説明するような場では無いから、何がどうなって、どういう結果になるから、こうすると良いよ、みたいな内容をフラッシュプレゼンテーションで伝えたほうが、聞いてる人にとっても解りやすくて良いのだと思う。
対企業のプレゼンとかだと違うのかもね。やったこと無いからワカラナイですが。



デマンド(必要性)を植え付ける

相手にとって、「この商品が無いとこんな困ることがありますよー」という「ホラーストーリー」を語れるか。
「サクセスストーリー」は、成功事例を引っ張ってくるだけなので誰でも語れる。
だからサクセスストーリーだけじゃなくて、相手の立場に立った時のホラーストーリーを語れた方が良いらしい。
後は、その商品の希少性、魅力を植え付ける様にすると良いとのこと。

まぁジャパネットたかた社長に学ぶ感じです。




ちょっとした仕草などのテクニック


  • 自己紹介は、名前を一番最初に
    • 社名とか部署名とかではなく
  • 相手との距離感を縮める
    • 「今日は歩いてここまで来ました」とか
  • 動く
    • 自分の想像以上に動く
    • 「接続詞」で振り向く
  • 言葉に修飾する
    • 名詞には副詞・修飾子を付けて修飾する
  • 変化のある語尾を活用する
    • 体言止めとか、質問と回答を巧みに入れる


今回、自分的には目からウロコだったのが、こういう細かいテクニック。
特に「接続詞で振り向く」とか、言われてみればプレゼン上手い人って、ゆっくりと左右に動きながら喋って、「しかし!」とかで方向転換するわw

「我々はこうやって○○を実施してきました。」という言い方一つとっても、
「我々は○○をしてきたのです。そう、○○。」とか、
「我々が行なってきたのは何だと思いますか?そう、○○です。」とか。



あー。こういう細かい所が明暗を分けるんだなーと思いました。
と同時に、プレゼン上手い人っていうのは、喋り、立ち振る舞いの全てが計算されているんだと実感しました。
無意識レベルで実施できているプロもいると思いますが。

他にも色々教えて頂けましたが、とりあえず自分の印象が強かった部分のみメモしておきます。


まぁとりあえず、練習しなきゃ上手くはなれないって事でした!

2013年4月10日水曜日

Invoke-CommandでリモートPCに引数を渡す

PowershellでリモートPCを操作する方法は以下の3つらしい。


  1. <コマンドレット> -ComputerName <リモートPC>
  2. Invoke-Command -ComputerName <リモートPC> -scriptblock{Get-Service}
  3. Enter-PSSession -ComputerName <リモートPC>


1は、コマンドレットに「-ComputerName」があればそのまま使用できるタイプ。
PowerShellでイベントログを取得する」で使用した「Get-Eventlog」とかとか。
当然だが、全てのコマンドレットにあるわけではない。スコープはサーバ側。

2は、「-scriptblock{}」をリモートPCで実行できるコマンドレット。
スコープはクライアント側。

3は、対話モードでリモートPCに接続するコマンドレット。
リモートPCにログインするような形で接続してゴニョゴニョできる。当然スコープはクライアント側。


で、やっぱり1だけではリモートPCの管理を全てスクリプト化することは難しいので、2を使用することになるんだけど、ここで問題になったのがよくあるスコープの話。

例を書くと、

$hostname = "192.168.1.2"
Invoke-Command -Computername $hostname -Scriptblock{Test-Path C:\Windows}
True

リモートPC側に「C:\Windows」ってフォルダはあるんだけど

$hostname = "192.168.1.2"
$a = "C:\Windows"
Invoke-Command -Computername $hostname -Scriptblock{Test-Path $a}
引数が null であるため、パラメーター 'Path' にバインドできません。
    + CategoryInfo          : InvalidData: (:) [Test-Path]、ParameterBindingVal 
   idationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,M 
   icrosoft.PowerShell.Commands.TestPathCommand
    + PSComputerName        : 192.168.1.2

引数として書いてしまうとそんな変数なんも値ないよと。。

ということで、Invoke-Commandのヘルプとにらめっこ。

すること数分。
あやしいのを発見|д゚)チラッ



 -ArgumentList <Object[]>
        コマンドのローカル変数の値を指定します。コマンドの変数は、リモート コン
        ピューターでのコマンドの実行前にこれらの値で置換されます。値をコンマ区切
        り一覧で入力します。値は、一覧されている順に変数に関連付けられます。Argu
        mentList のエイリアスは "Args" です。
     
        ArgumentList の値は、"1024" などの実際の値にすることも、"$max" などのロ
        ーカル変数の参照にすることもできます。
     
        コマンドでローカル変数を使用するには、次のコマンド形式を使用します。
        {param($<名前 1>[, $<名前 2>]...)<ローカル変数を持つコマンド>} -Argument
        List <値 | $ローカル変数>
     
        "param" キーワードには、コマンドで使用するローカル変数を列挙します。Argu
        mentList パラメーターには、変数を列挙した順にその値を指定します。


さっそく実行。配列で渡るということなので

$hostname = "192.168.1.2"
$a = "C:\Windows"
$b = "C:\Program Files"
Invoke-Command -Computername $hostname -Scriptblock{Test-Path $args[0];Test-Path $args[1]} -ArgumentList $a,$b

True
True


とりあえず上記を使用すれば目的は達成できそうです。


PowerShellでイベントログを取得する

「なにを今更。Get-Eventlog使うだけじゃん!」
なんてツッコミが飛んできそうですけど。。

いや、確かに使いますよ。げっといべんとろぐ。

とりあえず、こんな感じで欲しい情報は取得できます。

Get-EventLog -ComputerName 192.168.0.1 -LogName "Application"  | Select-Object EntryType,EventID,Source,TimeGenerated,Message


そして今回のお客様のご要望は以下。
  • 何日前までとか指定したい
  • さっと見れるようにテキストに結果吐いて

ということで、こんな感じで実装しました。
$IpAddress = "192.168.0.1"
$EventLogName = "Application"
$StartDate = Get-Date
$EndDate = $StartDate - (New-TimeSpan -day 6)
$file = "C:\" + $EventLogName + ".txt"

#イベントログ取得
function getEventLog ($IpAddress,$EventLogName,$StartDate,$EndDate,$file)
{
    #イベントログ取得
    $logArray = Get-EventLog -Computername $IpAddress -logname $EventLogName -after $EndDate -before $StartDate | Select-Object EntryType,EventID,Source,TimeGenerated,Message
    #期間内のイベントログが無い場合は、ファイルにログ無しと書き込む
    if ($null -eq $logArray)
    {
        $message = "イベントログがありません。 期間:" + $startdate + " ~ " + $enddate
        $message | Out-File -Filepath $file
    }
    else
    {
        #取得したイベントログをファイルに書き込む
        foreach ($row in $logArray)
        {
            #Messageに入っている改行コードを変換
            $workMessage = [string]$row.Message.Replace("`n"," ")
            #日付の書式を整形
            $workTimeGenerated = [string]$row.TimeGenerated.ToString("yyyy/MM/dd HH:mm:ss")
            
            #一行としてまとめる
            $line = $workTimeGenerated + "`t" + [string]$row.EntryType + "`t" + [string]$row.EventID + "`t" + [string]$row.Source + "`t" + $workMessage
            
            #ファイルに書き込む
            $line | Out-File -Filepath $file  -Append
        }
    }
    #ファイルの存在チェックをして終了
    if (Test-Path $file)
    {
        #ログを出力
        Write-Host $file "を作成しました。"
    }
}

#実行
getEventLog $IpAddress $EventLogName $StartDate $EndDate $file


ガッと取ってきて一行づつ取り出して、日付を整形して、本文の改行コードを変換してテキストに追記していってます。

2013年4月9日火曜日

Write-Host で表示されるメッセージに色をつける


なんとなく検索していたら面白いもの見つけたのでメモメモ。

Write-Host コマンドレットの使用

Write-Hostで表示されるメッセージに色つけれるみたい!

Write-Host "コメント" -foregroundcolor red -backgroundcolor yellow 

ということで、各サーバのCドライブの利用状況を色別けして表示させてみるスクリプトとか作ってみた。


function MyFunction
{

    $serverlist = @("192.168.1.1"; "192.168.1.2"; "192.168.1.3")

    #サーバリストの分だけループ
    foreach ($ipaddress in $serverlist)
    {
        Write-Host "`n"
        Write-Host "★☆★-----------------【" $ipaddress "】-----------------★☆★" -foregroundcolor red -backgroundcolor yellow 

        #実行
        #Cドライブの使用状況を表示する
        CheckDiskSize

        Read-Host "実行結果を確認して、エンターを押してください!"
    }
}

function CheckDiskSize
{
    Write-Host "■□■ Cドライブの使用状況を表示します。 ■□■"
    #Session作成
    $Session = New-PSSession -ComputerName $ipaddress
    
    #コマンド実行
    Invoke-Command -Session $Session -Scriptblock{
        $drive = $args[0]
        #ドライブの容量チエック
        $used = (Get-PSDrive $drive).Used / 1GB
        $free = (Get-PSDrive $drive).Free / 1GB
        #使用率(四捨五入)
        $rate = [math]::Truncate((($used / ($free + $used)) * 100)+.5)

        #メッセージ作成
        $Message = $scriptName + "`n" + "`n" + 
            $drive + "ドライブの使用量:" + ([math]::Truncate($used)+.5) + "GB" + "`n" + 
            $drive + "ドライブの空き容量:" + ([math]::Truncate($free)+.5) + "GB" + "`n" + 
            $drive + "ドライブの使用率:" + $rate + "%"

        #使用率が70%以上で80%未満だったら黄色で表示
        if ($rate -gt "70" -and $rate -le "80")
        {
            Write-Host $Message -foregroundcolor Yellow
        }
        #使用率が80%以上だったら赤字で表示
        elseif ($rate -gt "80")
        {
            Write-Host $Message -foregroundcolor Red
        }
        #それ以外はセーフ
        else
        {
            Write-Host $Message -foregroundcolor Green
        }
    } -ArgumentList "C"
    
    #Session削除
    Remove-PSSession $Session

    }
}

#実行
MyFunction

WinRMで$serverlistの端末に対してドライブの容量チェックを実行していきます。
使用率に応じてコンソールに表示される色を変えています。



手動でサッと確認したいときに便利かと。

BloggerでPowerShellコードをシンタックスハイライトする

とりあえずGoogle先生にお尋ねしてたどり着いた先が↓のサイト様でした。

How to Add Syntax Highlighter(v3) to Blogger Blogs

上記サイトの「Syntax Highlighter Scripts Generator」で「PowerShell」にチェックを入れてJSを生成して頂き、Bloggerのテンプレートの</head>の上に書き込むと。
(まぁ使い方に書いてありますね…)

で、実際にPSのコードを記載する際には、


<pre class='brush:powershell;'>
 $OutputParh = "C:\hogehoge"
 New-Item $OutputParh -ItemType Directory
</pre>

みたいに<pre>タグで囲って、classに「brush:powershell」と書いてあげると、

 $OutputParh = "C:\hogehoge"
 New-Item $OutputParh -ItemType Directory



ふぅ。めでたしめでたし。