はじめに
PowerShellでデータを扱う際、コンソールでの表示だけでは見づらいことがあります。そこで、Excelのようなグリッド形式でデータを表示・編集できる画面を作成する方法を備忘録として残します。
想定するユースケースの例
-
ファイルから特定の情報を即席で抽出して確認したい場面――たとえばコピー直後などに使えそうだと思い、この記事の実装を試してみました。
-
ログ解析や、LLMの出力データから特定の情報を頻繁に抜き出したいときにも便利です。
-
ツールのインストールが難しい環境でも、PowerShellが使える場合には有効な手段になりそうです。
環境
- Windws 10/11
- PowerShell 5.1以降
- .NET Framework(Windows標準搭載)
Out-GridViewコマンドレット
PowerShellには標準でOut-GridView
というコマンドレットが用意されており、簡単にグリッド表示を実現できます。
基本的な使い方
# プロセス一覧をグリッド表示
Get-Process | Out-GridView
フィルタリング機能付きグリッド
# サービス一覧を表示(フィルタリング可能)
Get-Service | Out-GridView -Title "サービス一覧"
選択結果を変数に格納
# 複数選択可能なグリッドから選択したアイテムを取得
$selectedItems = Get-Process | Out-GridView -PassThru -Title "プロセスを選択してください"
$selectedItems | ForEach-Object { Write-Host "選択されたプロセス: $($_.Name)" }
Windows Formsを使用したカスタムグリッド
より高度なカスタマイズが必要な場合は、Windows FormsのDataGridViewを使用します。
基本的なDataGridViewの実装
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# フォームの作成
$form = New-Object System.Windows.Forms.Form
$form.Text = "PowerShell データグリッド"
$form.Size = New-Object System.Drawing.Size(800, 600)
$form.StartPosition = "CenterScreen"
# DataGridViewの作成
$dataGridView = New-Object System.Windows.Forms.DataGridView
$dataGridView.Size = New-Object System.Drawing.Size(760, 520)
$dataGridView.Location = New-Object System.Drawing.Point(20, 20)
$dataGridView.AutoSizeColumnsMode = "Fill"
# データの準備
$data = @(
[PSCustomObject]@{ID=1; 名前="田中太郎"; 部署="営業部"; 年齢=28}
[PSCustomObject]@{ID=2; 名前="鈴木花子"; 部署="開発部"; 年齢=32}
[PSCustomObject]@{ID=3; 名前="佐藤次郎"; 部署="総務部"; 年齢=45}
)
# データをDataGridViewにバインド
$dataGridView.DataSource = [System.Collections.ArrayList]$data
# フォームにDataGridViewを追加
$form.Controls.Add($dataGridView)
# フォームを表示
$form.ShowDialog()
CSVファイルの読み込みと表示
# まず、サンプルデータをCSVファイルとして保存
$sampleData = @(
[PSCustomObject]@{ID=1; 名前="田中太郎"; 部署="営業部"; 年齢=28}
[PSCustomObject]@{ID=2; 名前="鈴木花子"; 部署="開発部"; 年齢=32}
[PSCustomObject]@{ID=3; 名前="佐藤次郎"; 部署="総務部"; 年齢=45}
)
# CSVファイルとして保存
$csvPath = "$env:TEMP\employee_data.csv"
$sampleData | Export-Csv -Path $csvPath -NoTypeInformation -Encoding UTF8
Write-Host "サンプルCSVファイルを作成しました: $csvPath"
# CSVファイルを読み込んでグリッド表示する関数
function Show-CSVInGrid {
param(
[string]$FilePath
)
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# CSVデータの読み込み
$csvData = Import-Csv -Path $FilePath -Encoding UTF8
# フォームの作成
$form = New-Object System.Windows.Forms.Form
$form.Text = "CSV Viewer - $(Split-Path $FilePath -Leaf)"
$form.Size = New-Object System.Drawing.Size(800, 600)
$form.StartPosition = "CenterScreen"
# DataGridViewの作成
$dataGridView = New-Object System.Windows.Forms.DataGridView
$dataGridView.Size = New-Object System.Drawing.Size(760, 520)
$dataGridView.Location = New-Object System.Drawing.Point(20, 20)
$dataGridView.AutoSizeColumnsMode = "Fill"
$dataGridView.AllowUserToAddRows = $false
# データテーブルの作成
$dataTable = New-Object System.Data.DataTable
# カラムの追加
$csvData[0].PSObject.Properties | ForEach-Object {
$dataTable.Columns.Add($_.Name) | Out-Null
}
# データの追加
foreach ($row in $csvData) {
$dataRow = $dataTable.NewRow()
$row.PSObject.Properties | ForEach-Object {
$dataRow[$_.Name] = $_.Value
}
$dataTable.Rows.Add($dataRow)
}
# DataGridViewにデータをバインド
$dataGridView.DataSource = $dataTable
# スタイル設定
$dataGridView.AlternatingRowsDefaultCellStyle.BackColor = [System.Drawing.Color]::LightGray
$dataGridView.ColumnHeadersDefaultCellStyle.Font = New-Object System.Drawing.Font("MS UI Gothic", 10, [System.Drawing.FontStyle]::Bold)
# フォームにDataGridViewを追加
$form.Controls.Add($dataGridView)
# フォームを表示
$form.ShowDialog()
}
# 作成したCSVファイルを表示
Show-CSVInGrid -FilePath $csvPath
編集可能なグリッドとデータの保存
function Show-EditableGrid {
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# フォームの作成
$form = New-Object System.Windows.Forms.Form
$form.Text = "編集可能なデータグリッド"
$form.Size = New-Object System.Drawing.Size(900, 650)
$form.StartPosition = "CenterScreen"
# DataGridViewの作成
$dataGridView = New-Object System.Windows.Forms.DataGridView
$dataGridView.Size = New-Object System.Drawing.Size(860, 550)
$dataGridView.Location = New-Object System.Drawing.Point(20, 20)
$dataGridView.AutoSizeColumnsMode = "Fill"
$dataGridView.AllowUserToAddRows = $true
$dataGridView.AllowUserToDeleteRows = $true
# 初期データ
$script:dataList = [System.Collections.ArrayList]@(
[PSCustomObject]@{商品名="ノートPC"; 価格=98000; 在庫=15}
[PSCustomObject]@{商品名="マウス"; 価格=2500; 在庫=50}
[PSCustomObject]@{商品名="キーボード"; 価格=8000; 在庫=30}
)
$dataGridView.DataSource = $script:dataList
# 保存ボタン
$saveButton = New-Object System.Windows.Forms.Button
$saveButton.Text = "CSVに保存"
$saveButton.Size = New-Object System.Drawing.Size(100, 30)
$saveButton.Location = New-Object System.Drawing.Point(780, 580)
$saveButton.Add_Click({
$saveDialog = New-Object System.Windows.Forms.SaveFileDialog
$saveDialog.Filter = "CSV files (*.csv)|*.csv|All files (*.*)|*.*"
$saveDialog.DefaultExt = "csv"
if ($saveDialog.ShowDialog() -eq "OK") {
$script:dataList | Export-Csv -Path $saveDialog.FileName -NoTypeInformation -Encoding UTF8
[System.Windows.Forms.MessageBox]::Show("保存しました", "情報")
}
})
# コントロールをフォームに追加
$form.Controls.Add($dataGridView)
$form.Controls.Add($saveButton)
# フォームを表示
$form.ShowDialog()
}
# 実行
Show-EditableGrid
保存ボタンで出力できる
WPFを使用したモダンなグリッド
より洗練されたUIが必要な場合は、WPFのDataGridを使用します。
Add-Type -AssemblyName PresentationFramework
Add-Type -AssemblyName PresentationCore
Add-Type -AssemblyName WindowsBase
[xml]$xaml = @"
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="WPF データグリッド" Height="600" Width="900">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<DataGrid Name="dataGrid" Grid.Row="0" Margin="10"
AutoGenerateColumns="True"
CanUserAddRows="True"
CanUserDeleteRows="True"
GridLinesVisibility="All"
AlternatingRowBackground="#F0F0F0"/>
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right" Margin="10">
<Button Name="loadButton" Content="データ読込" Width="100" Margin="5"/>
<Button Name="saveButton" Content="保存" Width="100" Margin="5"/>
</StackPanel>
</Grid>
</Window>
"@
$reader = (New-Object System.Xml.XmlNodeReader $xaml)
$window = [Windows.Markup.XamlReader]::Load($reader)
# コントロールの取得
$dataGrid = $window.FindName("dataGrid")
$loadButton = $window.FindName("loadButton")
$saveButton = $window.FindName("saveButton")
# サンプルデータ
$employees = @(
[PSCustomObject]@{社員ID="E001"; 氏名="山田太郎"; 部署="営業部"; 入社年=2018}
[PSCustomObject]@{社員ID="E002"; 氏名="田中花子"; 部署="開発部"; 入社年=2020}
[PSCustomObject]@{社員ID="E003"; 氏名="佐藤健"; 部署="人事部"; 入社年=2015}
)
$dataGrid.ItemsSource = $employees
# イベントハンドラ
$loadButton.Add_Click({
[System.Windows.MessageBox]::Show("データ読込機能を実装してください", "情報")
})
$saveButton.Add_Click({
[System.Windows.MessageBox]::Show("保存機能を実装してください", "情報")
})
$window.ShowDialog()
実用的なTips
1. 大量データの高速表示
# バーチャルモードを使用して大量データを効率的に表示
$dataGridView.VirtualMode = $true
$dataGridView.RowCount = 10000 # 表示する行数を設定
2. カラムのカスタマイズ
# 特定のカラムを読み取り専用に設定
$dataGridView.Columns["ID"].ReadOnly = $true
# カラム幅の自動調整
$dataGridView.AutoResizeColumns()
3. セルの書式設定
# 数値カラムの書式設定
$dataGridView.Columns["価格"].DefaultCellStyle.Format = "C0" # 通貨形式
# セルの色分け
$dataGridView.Add_CellFormatting({
param($sender, $e)
if ($e.ColumnIndex -eq 2 -and $e.Value -lt 10) {
$e.CellStyle.BackColor = "LightPink"
}
})
まとめ
PowerShellでExcelのようなグリッド画面を作成する方法をいくつか紹介しました。
- Out-GridView: 最も簡単で、基本的な表示・フィルタリングには十分
- Windows Forms: より細かいカスタマイズが可能で、編集機能も実装しやすい
- WPF: モダンなUIを実現でき、データバインディングが強力
用途に応じて適切な方法を選択することで、PowerShellでも使いやすいデータ管理ツールを作成できます。