はじめに
PowerShellでGUIを作る際、「設定画面くらいしか作れない」と思っていませんか?
実はPropertyGridを使えば、驚くほど高機能なアプリケーションを簡単に作ることができます。
今回は、システムのリアルタイム監視ダッシュボードを作りながら、PropertyGridの真の実力をお見せします。このダッシュボードは:
- リアルタイムでシステム情報を更新
- 監視項目を動的にオン/オフ切り替え
- アラート機能付き
- 設定をファイル保存/読み込み
これらの機能を、たった100行程度のPowerShellコードで実現します。
画面イメージ
なぜPropertyGridなのか?
通常のGUI開発では、各コントロールを手動で配置し、イベントハンドラーを設定する必要があります。しかしPropertyGridを使えば:
- オブジェクトのプロパティを自動でGUI化
- 型に応じた適切なエディターを自動選択
- カテゴリ別の整理表示
- リアルタイム値更新が簡単
つまり、「データクラスを定義するだけで高機能GUIが完成」するのです。
実装:リアルタイム システム監視ダッシュボード
では早速、驚きのサンプルをご覧ください:
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# システム監視設定クラス
class SystemMonitor {
# === 監視対象設定 ===
[System.ComponentModel.Category("監視対象")]
[System.ComponentModel.DisplayName("CPU使用率監視")]
[System.ComponentModel.Description("CPU使用率をリアルタイム監視します")]
[bool]$MonitorCPU = $true
[System.ComponentModel.Category("監視対象")]
[System.ComponentModel.DisplayName("メモリ使用量監視")]
[System.ComponentModel.Description("メモリ使用量をリアルタイム監視します")]
[bool]$MonitorMemory = $true
[System.ComponentModel.Category("監視対象")]
[System.ComponentModel.DisplayName("ディスク容量監視")]
[System.ComponentModel.Description("ディスク使用量をリアルタイム監視します")]
[bool]$MonitorDisk = $true
[System.ComponentModel.Category("監視対象")]
[System.ComponentModel.DisplayName("プロセス数監視")]
[System.ComponentModel.Description("実行中のプロセス数を監視します")]
[bool]$MonitorProcessCount = $false
# === リアルタイム値(読み取り専用) ===
[System.ComponentModel.Category("📊 リアルタイム情報")]
[System.ComponentModel.DisplayName("🔥 CPU使用率")]
[System.ComponentModel.Description("現在のCPU使用率")]
[System.ComponentModel.ReadOnly($true)]
[string]$CurrentCPU = "取得中..."
[System.ComponentModel.Category("📊 リアルタイム情報")]
[System.ComponentModel.DisplayName("💾 メモリ使用量")]
[System.ComponentModel.Description("現在のメモリ使用量")]
[System.ComponentModel.ReadOnly($true)]
[string]$CurrentMemory = "取得中..."
[System.ComponentModel.Category("📊 リアルタイム情報")]
[System.ComponentModel.DisplayName("💽 ディスク使用量")]
[System.ComponentModel.Description("Cドライブの使用量")]
[System.ComponentModel.ReadOnly($true)]
[string]$CurrentDisk = "取得中..."
[System.ComponentModel.Category("📊 リアルタイム情報")]
[System.ComponentModel.DisplayName("⚙️ プロセス数")]
[System.ComponentModel.Description("実行中のプロセス数")]
[System.ComponentModel.ReadOnly($true)]
[string]$CurrentProcessCount = "取得中..."
[System.ComponentModel.Category("📊 リアルタイム情報")]
[System.ComponentModel.DisplayName("🕐 最終更新")]
[System.ComponentModel.Description("最後にデータを更新した時刻")]
[System.ComponentModel.ReadOnly($true)]
[string]$LastUpdate = "未更新"
# === アラート設定 ===
[System.ComponentModel.Category("🚨 アラート設定")]
[System.ComponentModel.DisplayName("CPU使用率アラート")]
[System.ComponentModel.Description("CPU使用率がこの値を超えるとアラート")]
[System.ComponentModel.DefaultValue(80)]
[int]$CPUAlertThreshold = 80
[System.ComponentModel.Category("🚨 アラート設定")]
[System.ComponentModel.DisplayName("メモリ使用率アラート")]
[System.ComponentModel.Description("メモリ使用率がこの値を超えるとアラート")]
[System.ComponentModel.DefaultValue(85)]
[int]$MemoryAlertThreshold = 85
[System.ComponentModel.Category("🚨 アラート設定")]
[System.ComponentModel.DisplayName("アラート有効")]
[System.ComponentModel.Description("アラート機能を有効にします")]
[bool]$EnableAlerts = $true
[System.ComponentModel.Category("🚨 アラート設定")]
[System.ComponentModel.DisplayName("アラート音")]
[System.ComponentModel.Description("アラート時に音を鳴らします")]
[bool]$PlayAlertSound = $true
# === 表示設定 ===
[System.ComponentModel.Category("⚙️ 表示設定")]
[System.ComponentModel.DisplayName("更新間隔(秒)")]
[System.ComponentModel.Description("データ更新の間隔(秒)")]
[System.ComponentModel.DefaultValue(2)]
[int]$UpdateInterval = 2
[System.ComponentModel.Category("⚙️ 表示設定")]
[System.ComponentModel.DisplayName("テーマカラー")]
[System.ComponentModel.Description("ダッシュボードのテーマカラー")]
[System.Drawing.Color]$ThemeColor = [System.Drawing.Color]::DodgerBlue
}
# システム情報取得クラス
class SystemInfo {
static [double] GetCPUUsage() {
$cpu = Get-WmiObject Win32_Processor | Measure-Object -Property LoadPercentage -Average
return [Math]::Round($cpu.Average, 1)
}
static [hashtable] GetMemoryInfo() {
$os = Get-WmiObject Win32_OperatingSystem
$totalMB = [Math]::Round($os.TotalVisibleMemorySize / 1024)
$freeMB = [Math]::Round($os.FreePhysicalMemory / 1024)
$usedMB = $totalMB - $freeMB
$usagePercent = [Math]::Round(($usedMB / $totalMB) * 100, 1)
return @{
UsedMB = $usedMB
TotalMB = $totalMB
UsagePercent = $usagePercent
}
}
static [hashtable] GetDiskInfo() {
$disk = Get-WmiObject Win32_LogicalDisk -Filter "DeviceID='C:'"
$totalGB = [Math]::Round($disk.Size / 1GB, 1)
$freeGB = [Math]::Round($disk.FreeSpace / 1GB, 1)
$usedGB = $totalGB - $freeGB
$usagePercent = [Math]::Round(($usedGB / $totalGB) * 100, 1)
return @{
UsedGB = $usedGB
TotalGB = $totalGB
UsagePercent = $usagePercent
}
}
static [int] GetProcessCount() {
return (Get-Process).Count
}
}
# メイン関数
function Start-SystemMonitorDashboard {
# フォーム作成
$form = New-Object System.Windows.Forms.Form
$form.Text = "🖥️ リアルタイム システム監視ダッシュボード"
$form.Size = New-Object System.Drawing.Size(550, 700)
$form.StartPosition = "CenterScreen"
$form.BackColor = [System.Drawing.Color]::FromArgb(240, 248, 255)
# PropertyGrid作成
$propertyGrid = New-Object System.Windows.Forms.PropertyGrid
$propertyGrid.Size = New-Object System.Drawing.Size(520, 580)
$propertyGrid.Location = New-Object System.Drawing.Point(10, 10)
$propertyGrid.PropertySort = "Categorized"
$propertyGrid.BackColor = [System.Drawing.Color]::White
# ボタンパネル
$buttonPanel = New-Object System.Windows.Forms.Panel
$buttonPanel.Size = New-Object System.Drawing.Size(520, 80)
$buttonPanel.Location = New-Object System.Drawing.Point(10, 600)
# 各種ボタン
$startButton = New-Object System.Windows.Forms.Button
$startButton.Text = "▶️ 監視開始"
$startButton.Size = New-Object System.Drawing.Size(100, 35)
$startButton.Location = New-Object System.Drawing.Point(10, 10)
$startButton.BackColor = [System.Drawing.Color]::LightGreen
$stopButton = New-Object System.Windows.Forms.Button
$stopButton.Text = "⏹️ 監視停止"
$stopButton.Size = New-Object System.Drawing.Size(100, 35)
$stopButton.Location = New-Object System.Drawing.Point(120, 10)
$stopButton.BackColor = [System.Drawing.Color]::LightCoral
$stopButton.Enabled = $false
$saveButton = New-Object System.Windows.Forms.Button
$saveButton.Text = "💾 設定保存"
$saveButton.Size = New-Object System.Drawing.Size(100, 35)
$saveButton.Location = New-Object System.Drawing.Point(230, 10)
$loadButton = New-Object System.Windows.Forms.Button
$loadButton.Text = "📁 設定読込"
$loadButton.Size = New-Object System.Drawing.Size(100, 35)
$loadButton.Location = New-Object System.Drawing.Point(340, 10)
$aboutButton = New-Object System.Windows.Forms.Button
$aboutButton.Text = "ℹ️ About"
$aboutButton.Size = New-Object System.Drawing.Size(70, 35)
$aboutButton.Location = New-Object System.Drawing.Point(450, 10)
# 監視オブジェクト作成
$monitor = [SystemMonitor]::new()
$propertyGrid.SelectedObject = $monitor
# タイマー作成
$timer = New-Object System.Windows.Forms.Timer
$timer.Interval = $monitor.UpdateInterval * 1000
# タイマーイベント
$timer.Add_Tick({
try {
if ($monitor.MonitorCPU) {
$cpuUsage = [SystemInfo]::GetCPUUsage()
$monitor.CurrentCPU = "${cpuUsage}%"
if ($monitor.EnableAlerts -and $cpuUsage -gt $monitor.CPUAlertThreshold) {
if ($monitor.PlayAlertSound) { [Console]::Beep(800, 200) }
$form.BackColor = [System.Drawing.Color]::LightPink
} else {
$form.BackColor = [System.Drawing.Color]::FromArgb(240, 248, 255)
}
}
if ($monitor.MonitorMemory) {
$memInfo = [SystemInfo]::GetMemoryInfo()
$monitor.CurrentMemory = "$($memInfo.UsedMB)MB / $($memInfo.TotalMB)MB ($($memInfo.UsagePercent)%)"
if ($monitor.EnableAlerts -and $memInfo.UsagePercent -gt $monitor.MemoryAlertThreshold) {
if ($monitor.PlayAlertSound) { [Console]::Beep(600, 200) }
}
}
if ($monitor.MonitorDisk) {
$diskInfo = [SystemInfo]::GetDiskInfo()
$monitor.CurrentDisk = "$($diskInfo.UsedGB)GB / $($diskInfo.TotalGB)GB ($($diskInfo.UsagePercent)%)"
}
if ($monitor.MonitorProcessCount) {
$processCount = [SystemInfo]::GetProcessCount()
$monitor.CurrentProcessCount = "${processCount} プロセス"
}
$monitor.LastUpdate = Get-Date -Format "HH:mm:ss"
$timer.Interval = $monitor.UpdateInterval * 1000
$propertyGrid.Refresh()
}
catch {
$monitor.LastUpdate = "エラー: $($_.Exception.Message)"
$propertyGrid.Refresh()
}
})
# イベントハンドラー
$startButton.Add_Click({
$timer.Start()
$startButton.Enabled = $false
$stopButton.Enabled = $true
$form.Text = "🖥️ リアルタイム システム監視ダッシュボード [監視中]"
})
$stopButton.Add_Click({
$timer.Stop()
$startButton.Enabled = $true
$stopButton.Enabled = $false
$form.Text = "🖥️ リアルタイム システム監視ダッシュボード"
$form.BackColor = [System.Drawing.Color]::FromArgb(240, 248, 255)
})
$saveButton.Add_Click({
$saveDialog = New-Object System.Windows.Forms.SaveFileDialog
$saveDialog.Filter = "Monitor Config (*.json)|*.json"
$saveDialog.DefaultExt = "json"
$saveDialog.FileName = "monitor_config.json"
if ($saveDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
$config = @{
MonitorCPU = $monitor.MonitorCPU
MonitorMemory = $monitor.MonitorMemory
MonitorDisk = $monitor.MonitorDisk
MonitorProcessCount = $monitor.MonitorProcessCount
CPUAlertThreshold = $monitor.CPUAlertThreshold
MemoryAlertThreshold = $monitor.MemoryAlertThreshold
EnableAlerts = $monitor.EnableAlerts
PlayAlertSound = $monitor.PlayAlertSound
UpdateInterval = $monitor.UpdateInterval
ThemeColor = $monitor.ThemeColor.Name
}
$config | ConvertTo-Json | Out-File -FilePath $saveDialog.FileName -Encoding UTF8
[System.Windows.Forms.MessageBox]::Show("設定を保存しました!", "保存完了", "OK", "Information")
}
})
$aboutButton.Add_Click({
$aboutText = @"
🖥️ リアルタイム システム監視ダッシュボード
PowerShell + PropertyGrid で作成された
高機能システム監視ツールです。
✨ 主な機能:
• リアルタイム監視
• カスタマイズ可能なアラート
• 設定の保存/読み込み
• 直感的なGUI操作
Created with PowerShell ❤️
"@
[System.Windows.Forms.MessageBox]::Show($aboutText, "About", "OK", "Information")
})
# コントロール追加
$buttonPanel.Controls.AddRange(@($startButton, $stopButton, $saveButton, $loadButton, $aboutButton))
$form.Controls.AddRange(@($propertyGrid, $buttonPanel))
# フォーム終了時処理
$form.Add_FormClosing({
$timer.Stop()
$timer.Dispose()
})
# フォーム表示
Write-Host "🚀 システム監視ダッシュボードを起動中..."
$form.ShowDialog()
}
# 実行
Start-SystemMonitorDashboard
まとめ
このサンプルを実行すると、PowerShellでここまでできるのかと驚くはずです。特に:
- 設定変更が即座に反映される操作感
- 見た目のUI
- リアルタイム監視機能
- アラート機能まで搭載
これらすべてが、わずか150行程度のコードで実現できます。PropertyGridを使えば、PowerShellでも本格的なアプリケーションが簡単に作れるのです。
ぜひこのコードをコピー&ペーストして実行してみてください。システム監視の数値がリアルタイムで更新される様子に、きっと「おっ!」と驚くはずです。
PowerShellでのGUI開発の可能性を、PropertyGridで大きく広げてみませんか?