Windows
Linux
PowerShell
syslog

Powershellで特定のファイルをLinuxのSyslogサーバに送信する

やりたいこと

WindowsサーバのEventLogに変化があった際に、Syslogサーバに送信したい。方法はいろいろあると思うが、「Windowsサーバにインストールされているアプリケーションに影響を与える可能性があるため、オープンソースのプログラムやフリーソフトはインストールしてはいけない」「Windowsサーバは2008からある」という制約の中で実施しようとすると、なかなか良い手がでてこない。

「今Winodowsサーバの中にインストールされているコマンドを使うのは可。バッチファイルやPowerShellを使っても良い。Windowsサーバが元々持っている機能を使用するのも可。」という範囲の中で、実現できないか考えてみた。

方針

  1. プログラムを1から書くのは無理
  2. 世の中にあるPowerShellのスクリプトを改変させてもらいなんとかする
  3. 1つのプログラムでなんとかしようとせず、やりたいことを分割して考える
  4. PowerShellはVer.2のものから動くようにする

「EventLogのデータを取得しSyslogサーバへ送信する」を分解して考えてみる。

  1. EventLogのデータに変化があった場合に、バッチファイルを動かすようにする
  2. 動かしたバッチファイルの中には、変化した内容をTextとして書き出す部分がある
  3. さらに、書き出したTextをSyslogサーバに送信する部分がある

1.の内容は、@ITの「イベント・ログをトリガーにしてメールを送信する(基本編)」という内容でバッチファイルが起動できそう。
2.については別の記事として投稿するよていだが、基本的には、PowerShellの「Get-EventLog」を使用し、取得したデータをUTF-8で保存するようにする。

今回の記事は、「書きだしたTextをSyslogサーバに送信する」というPowerShellができたので、それを備忘録として残しておく。

やったこと

以下の構成で、Windowsサーバ上でPowereShellを実行する。

構成

サーバ IP
Windowsサーバ 192.168.1.50
Syslogサーバ 192.168.1.100

送信するTEXTファイル:test.txt

WindowsサーバからSyslogにUDP514(Syslogプロトコル)でtext.txtを送信する。

実際の送信用のPowerShellは以下の通り。
この中の、\$IP,\$Port,\$Messageのところにあるtest.txtの3つを自分の環境に合わせて編集する。
test.txtとSend-UdpDatagram.ps1が同じディレクトリにおいてあるとして、

#powershell -ExecutionPolicy RemoteSigned -File .\Send-UdpDatagram.ps1

を実行すると、Syslogサーバにtest.txtが送信される。

Send-UdpDatagram.ps1
###   
#  Start of Script   
##   

# Define port and target IP address   
# Random here!   
$Port = 514  
$IP = "192.168.1.100"   
$Address = [system.net.IPAddress]::Parse( $IP )  

# Create IP Endpoint   
$End = New-Object System.Net.IPEndPoint $address , $port   

# Create Socket   
$Saddrf    = [System.Net.Sockets.AddressFamily]::InterNetwork  
$Stype    = [System.Net.Sockets.SocketType]::Dgram  
$Ptype     = [System.Net.Sockets.ProtocolType]::UDP  
$Sock      = New-Object System.Net.Sockets.Socket $saddrf , $stype , $ptype   
$Sock.TTL = 26  

# Connect to socket   
$sock.Connect( $end )  

# Create encoded buffer   
$Message = (Get-content .\test.txt) -as [string[]] 
$Buffer   = [System.Text.Encoding]::UTF8.GetBytes($Message) 

# Send the buffer   
$Sent   = $Sock.Send($Buffer)  

# End of Script

参考

PowerShell Scripts Blog
PowerShell で syslog を送信する
「Powershellで特定のファイルをLinuxのSyslogサーバに送信する」