1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

■ PowerShellでSyslogメッセージ送信 ~RFC 3164形式対応させたよ~

Last updated at Posted at 2025-05-24

PowerShell_banner.png

こんにちは!
技術は実際に触って学ぶタイプです。零壱(ゼロイチ)テクトです。

先日、OpenWrtでSyslogサーバを立てたのですが
僕が使うWindowsではLinuxのようなLoggerコマンドがなく
スクリプトで好きな種類のSyslogを送信できないかと思った所
PowerShellで良さげなのが無かったので作成してみました。

尚、逆にSyslogの受信も考えたんですが、以下 ebi216様が
実用的なコードを書いてくださっていたので、送信だけのコードを作成しました。

 @ebi216様 / PowershellでSyslogサーバを書く
 https://qiita.com/ebi216/items/3e5d18bd33c5e47ae3b5

1.概要/仕様

・PowerShellのみでSyslogを送信
・Syslogで一般的な仕様 RFC 3164 形式準拠(仕事でも使いたいので
・Facility/Severityを選べるように
・後に弄れるように生成メッセージも部品化

2.コード

SyslogTestSned.ps1
# 送信先SyslogサーバーのIPアドレス/ポート番号
$syslogServer = "192.168.100.1" # SyslogサーバーのIPアドレス
$syslogPort   = 514             # Syslogのデフォルトポート (UDP)

# ===== Syslogメッセージの詳細設定 =====
# RFC 3164 形式に準拠
# PRI = (Facility * 8) + Severity

$facility = 1 
# Facility (機能) コード: メッセージを生成したプログラムの種類
# 0: kernel messages (カーネルメッセージ)
# 1: user-level messages (ユーザーレベルメッセージ)
# 2: mail system (メールシステム)
# 3: system daemons (システムデーモン)
# 4: security/authorization messages (セキュリティ/認証メッセージ)
# 5: syslogd internal messages (syslogd内部メッセージ)
# 6: line printer subsystem (ラインプリンターサブシステム)
# 7: network news subsystem (ネットワークニュースサブシステム)
# 8: UUCP subsystem (UUCPサブシステム)
# 9: clock daemon (クロックデーモン)
# 10: security/authorization messages (認証/セキュリティメッセージ)
# 11: FTP daemon (FTPデーモン)
# 12: NTP subsystem (NTPサブシステム)
# 13: log audit (ログ監査)
# 14: log alert (ログアラート)
# 15: clock daemon (クロックデーモン)
# 16-23: local use (ローカル利用)

$severity = 1 
# Severity (重要度) コード: メッセージの重要度
# 0: Emergency (緊急) - システムが使用不能
# 1: Alert (警告) - 直ちに行動が必要
# 2: Critical (致命的) - クリティカルな状態
# 3: Error (エラー) - エラー状態
# 4: Warning (注意) - 警告状態
# 5: Notice (通知) - 正常だが注目すべき状態
# 6: Informational (情報) - 情報メッセージ
# 7: Debug (デバッグ) - デバッグレベルメッセージ

# 現在時刻の取得(UTC) / RFC 3164形式のタイムスタンプを作成: "Jan 23 12:34:56"
$now       = [DateTime]::UtcNow
$month     = $now.ToString("MMM", [System.Globalization.CultureInfo]::InvariantCulture) # 月の略称
$day       = $now.Day
$dayString = " $day" # 日付生成/RFC3164準拠(3桁)/日付1桁の場合はスペースで桁調整
$dayString = $dayString.Substring($dayString.Length - 2, 2)
$time      = $now.ToString("HH:mm:ss") # 時刻 (HH:mm:ss)
$timestamp = "$month $dayString $time"

# ホスト名: メッセージを送信しているホストのコンピュータ名
$hostname = $env:COMPUTERNAME

# アプリケーション名 (Tag): メッセージを生成したアプリケーションの名前
$appName = "PowerShell"

# プロセスID (PID): メッセージを生成したプロセスのID
$processId = $PID

# 実際のメッセージ内容
$message = "Test Syslog Message from PowerShell(RFC 3164 FORMAT)"

# ===== Syslogメッセージ作成 =====
# PRIORITY (PRI) 値の計算
# PRI = (Facility * 8) + Severity
$priority = ($facility * 8) + $severity
$pri      = "<$priority>"

# RFC3164 形式/Syslogメッセージ生成
# フォーマット: <PRI>TIMESTAMP HOSTNAME APP-NAME[PROCID]: MESSAGE
$syslogMessage = "$pri$timestamp $hostname $appName[$processId]: $message"

# ===== Syslogメッセージの送信 =====
# UDPクライアント定義
$udpClient = New-Object System.Net.Sockets.UdpClient

try {
    # Syslogサーバー接続 (UDPはコネクションレスだが、Connectでデフォルトのリモートエンドポイントを設定)
    $udpClient.Connect($syslogServer, $syslogPort)

    # Syslogメッセージ/バイト配列に変換
    # RFC3164 は ASCII が一般的/日本語不可
    $bytes = [System.Text.Encoding]::ASCII.GetBytes($syslogMessage)

    # メッセージ送信
    $udpClient.Send($bytes, $bytes.Length)

    # コンソールに送信完了メッセージ表示
    Write-Host "[送信先]     $($syslogServer):$($syslogPort)  宛にSyslogメッセージを送信しました。"
    Write-Host "[メッセージ]   $($syslogMessage)"

}
catch {
    # エラー発生時処理
    Write-Error "Syslogメッセージ送信中エラー: $($_.Exception.Message)"
    Write-Host  "エラーの種類: $($_.Exception.GetType().FullName)"
}
finally {
    # UDPクライアントを必ずクローズ/リソース解放
    if ($udpClient -ne $null) {
        $udpClient.Close()
        Write-Host "---> UDPクライアントをクローズ"
    }
}

3.結果

⬇️PowerShell ISE側の送信結果です。これを3回送りました。

PS C:\Powershell\SyslogTestSned.ps1
99
[送信先]     192.168.100.1:514  宛にSyslogメッセージを送信しました。
[メッセージ]   <9>May 24 14:33:49 01tecto PowerShell[20200]: Test Syslog Message from PowerShell(RFC 3164 FORMAT)
---> UDPクライアントをクローズ


⬇️OpenWrtのSyslogサーバ側のログです。
  実際にSyslogサーバで受信を確認できました。
 (見やすさや情報隠しにログの一部を若干弄ってます)

BusyBox v1.36.1 (2024-09-23 12:34:46 UTC) built-in shell (ash)

  _______                     ________        __
 |       |.-----.-----.-----.|  |  |  |.----.|  |_
 |   -   ||  _  |  -__|     ||  |  |  ||   _||   _|
 |_______||   __|_____|__|__||________||__|  |____|
          |__| W I R E L E S S   F R E E D O M
 -----------------------------------------------------
 OpenWrt 23.05.5, r24106-10cc5fcd00
 -----------------------------------------------------
root@OpenWrt_FG52E:~# 
root@OpenWrt_FG52E:~# 
root@OpenWrt_FG52E:~# cat /var/log/syslog.log

May 24 14:33:21 OpenWrt_FG52E dnsmasq-dhcp[1]: DHCPDISCOVER(br-lan) xx:xx:xx:xx:xx:xx:xx
May 24 14:33:21 OpenWrt_FG52E dnsmasq-dhcp[1]: DHCPOFFER(br-lan) 192.168.xx.xx xx:xx:xx:xx:xx:xx 

May 24 14:33:41 01Tecto PowerShell[20200]: Test Syslog Message from PowerShell(RFC 3164 FORMAT)
May 24 14:33:46 01Tecto PowerShell[20200]: Test Syslog Message from PowerShell(RFC 3164 FORMAT)
May 24 14:33:50 01Tecto PowerShell[20200]: Test Syslog Message from PowerShell(RFC 3164 FORMAT)

May 24 14:33:58 OpenWrt_FG52E odhcpd[1894]: A default route is present -略- don't announce a default route by overriding ra_lifetime!

4.備考

・✅ 改良案1:1実行1送信なので、連発したい場合は回数指定してループさせる必要あり

・✅ 改良案2:同じメッセージ連発はイマイチなので
      ランダムでFacility/Severityを変えた方がよさげ

・「Syslog Generator for Windows」や
 「Kiwi SyslogGen」なるフリーのSyslog送信ツールを見つけたので
 ちゃんとした業務で検証に使用するなら、そっちのツールの方が良いカーモ。

・そもそもLinuxのLoggerコマンドやその手のツールを使え、
 と思ったが方いれば仰る通りです。

・最初はもっとシンプルでとりあえず送信できるコードを書いたんですが
 せっかく投稿するなら「RFC3164」に準拠しようと盛ったら
 仕様の確認と理解の方にめっちゃ時間かかりました……。


それでは
       どこかの誰かの何かの足しになれば幸いです。
                          01000010 01011001 01000101

1
0
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
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?