この記事は以下のシリーズの14番目の記事です。
この記事でやること
VBSでは、ユーザーにメッセージを表示したり、入力を求めたりするために MsgBox や InputBox をよく使います。
たとえば、次のような処理です。
MsgBox "処理が完了しました"
name = InputBox("名前を入力してください")
MsgBox "こんにちは、" & name & "さん"
PowerShellでも、メッセージ表示や入力受付はできます。
ただし、PowerShellをタスクスケジューラで実行する場合や、無人実行する場合は、対話処理が原因で止まることがあります。
この記事では、次の内容を整理します。
| 内容 | 目的 |
|---|---|
| Write-Host | 画面にメッセージを表示する |
| Read-Host | ユーザーから入力を受け取る |
| Windows FormsのMessageBox | GUIのメッセージボックスを出す |
| 入力処理を避ける設計 | タスクスケジューラ向けにする |
| CSVや設定ファイルで代替する方法 | 無人実行に寄せる |
まず結論
PowerShellでは、VBSの MsgBox / InputBox をそのまま置き換えることはできます。
ただし、実務では次のように考えた方が安全です。
| VBSでやっていたこと | PowerShellでの扱い |
|---|---|
| 処理完了を表示する |
Write-Host またはログ出力 |
| ユーザー入力を受け取る | Read-Host |
| GUIメッセージを出す | Windows FormsのMessageBox |
| 定期実行で入力を求める | 避ける |
| タスクスケジューラでMsgBoxを出す | 避ける |
| 入力値を使って処理する | CSV・設定ファイル・引数で渡す |
つまり、手動実行なら対話処理は使えるが、定期実行・無人実行では避けるという考え方です。
Write-Hostでメッセージを表示する
PowerShellで画面にメッセージを出す基本は Write-Host です。
Write-Host "処理を開始します"
Write-Host "処理が完了しました"
VBSの MsgBox のようにダイアログは出ません。
PowerShellの画面に文字を表示します。
手動実行で、処理状況を見せたい場合に使います。
Write-Host "ファイルコピーを開始します"
Copy-Item -Path ".\sample.txt" -Destination ".\backup\sample.txt" -Force
Write-Host "ファイルコピーが完了しました"
ただし、タスクスケジューラで実行する場合、画面表示は見えないことが多いです。
そのため、実務では Write-Host だけに頼らず、ログに残す方が安全です。
ログにメッセージを残す
タスクスケジューラや無人実行では、画面表示よりログ出力を使います。
$logPath = Join-Path $PSScriptRoot "process.log"
Add-Content -Path $logPath -Value "処理開始: $(Get-Date)" -Encoding UTF8
Add-Content -Path $logPath -Value "処理完了: $(Get-Date)" -Encoding UTF8
ログ関数にすると使いやすくなります。
$logPath = Join-Path $PSScriptRoot "process.log"
function Write-Log {
param(
[string]$Message
)
$now = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
Add-Content -Path $logPath -Value "[$now] $Message" -Encoding UTF8
}
Write-Log "処理開始"
Write-Log "処理完了"
VBSでは MsgBox で「完了しました」と表示していた処理も、PowerShellではログ出力に置き換えた方が運用しやすいことがあります。
Read-Hostで入力を受け取る
PowerShellでユーザー入力を受け取る基本は Read-Host です。
$name = Read-Host "名前を入力してください"
Write-Host "こんにちは、$name さん"
VBSの InputBox に近い用途です。
たとえば、コピー元ファイルを入力させることもできます。
$sourcePath = Read-Host "コピー元ファイルのパスを入力してください"
$destPath = Read-Host "コピー先ファイルのパスを入力してください"
Copy-Item -Path $sourcePath -Destination $destPath -Force
Write-Host "コピーしました"
ただし、このような対話入力は、手動実行向けです。
タスクスケジューラで実行すると、入力待ちになって止まる可能性があります。
パスワード入力には-AsSecureStringを使う
パスワードのように画面に表示したくない入力は、-AsSecureString を使えます。
$password = Read-Host "パスワードを入力してください" -AsSecureString
ただし、認証情報をスクリプトで扱う場合は注意が必要です。
初心者向けの段階では、パスワードをスクリプトに直書きするのは避けるべきです。
避けたい例です。
$password = "P@ssw0rd"
社内運用では、資格情報の管理方法を別途検討する必要があります。
GUIのMessageBoxを出す
PowerShellでも、Windows Formsを使えばVBSの MsgBox に近いダイアログを出せます。
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.MessageBox]::Show("処理が完了しました")
タイトルやボタンを指定することもできます。
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.MessageBox]::Show(
"処理を実行しますか?",
"確認",
[System.Windows.Forms.MessageBoxButtons]::OKCancel,
[System.Windows.Forms.MessageBoxIcon]::Question
)
戻り値を受け取ることもできます。
Add-Type -AssemblyName System.Windows.Forms
$result = [System.Windows.Forms.MessageBox]::Show(
"処理を実行しますか?",
"確認",
[System.Windows.Forms.MessageBoxButtons]::OKCancel,
[System.Windows.Forms.MessageBoxIcon]::Question
)
if ($result -eq [System.Windows.Forms.DialogResult]::OK) {
Write-Host "OKが選択されました"
}
else {
Write-Host "キャンセルされました"
}
ただし、GUIのMessageBoxは、手動実行向けです。
タスクスケジューラや無人実行では基本的に避けます。
InputBoxに近いものを出す場合
PowerShell標準だけでは、VBSの InputBox と同じようなGUI入力ボックスは簡単には出せません。
Windows Formsで自作することはできますが、初心者向け・実務自動化向けとしてはあまりおすすめしません。
理由は、コードが長くなり、自動化の本質から外れやすいからです。
手動実行なら、まずは Read-Host で十分です。
$inputValue = Read-Host "値を入力してください"
Write-Host "入力値: $inputValue"
GUI入力がどうしても必要な場合は、PowerShellだけで頑張るより、簡易フォームアプリ、Power Automate、AppSheetなど別の選択肢を検討した方がよい場合があります。
タスクスケジューラでは対話処理を避ける
タスクスケジューラで実行するPowerShellでは、次のような処理は避けます。
Read-Host "入力してください"
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.MessageBox]::Show("確認してください")
これらは、ユーザーの操作を待つ処理です。
タスクスケジューラは、夜間や無人で実行されることが多いため、入力待ちになると処理が止まります。
タスクスケジューラ向けのPowerShellでは、必要な値を以下のように外から渡す設計にします。
| 方法 | 向いているケース |
|---|---|
| CSV | 複数件の処理対象を渡す |
| 設定ファイル | 固定設定を渡す |
| 引数 | 実行時に値を渡す |
| 環境変数 | 実行環境ごとの値を使う |
| ログ | 結果を確認する |
CSVで入力値を渡す
ユーザーに毎回入力させる代わりに、CSVに処理対象を書いておく方法があります。
たとえば、次のようなCSVを用意します。
SourcePath,DestinationPath
C:\work\input\a.txt,C:\work\backup\a.txt
C:\work\input\b.txt,C:\work\backup\b.txt
PowerShellでは次のように読み込みます。
$csvPath = Join-Path $PSScriptRoot "copy_list.csv"
Import-Csv -Path $csvPath |
ForEach-Object {
Copy-Item -Path $_.SourcePath -Destination $_.DestinationPath -Force
}
この形なら、タスクスケジューラでも無人実行しやすくなります。
InputBox で毎回入力していた内容を、CSVに移すイメージです。
設定ファイルで入力値を渡す
固定の設定値なら、JSONファイルやCSVファイルにしておく方法もあります。
たとえば、JSONで設定を書きます。
{
"TargetDir": "C:\\work\\input",
"BackupDir": "C:\\work\\backup"
}
PowerShellで読み込みます。
$configPath = Join-Path $PSScriptRoot "config.json"
$config = Get-Content $configPath -Raw | ConvertFrom-Json
$targetDir = $config.TargetDir
$backupDir = $config.BackupDir
Write-Host "対象フォルダ: $targetDir"
Write-Host "バックアップ先: $backupDir"
毎回 InputBox で聞くよりも、設定ファイルで管理した方が自動実行に向いています。
引数で値を渡す
PowerShellスクリプトには、引数を渡すこともできます。
たとえば、次のような sample.ps1 を作ります。
param(
[string]$Name
)
Write-Host "こんにちは、$Name さん"
実行時に値を渡します。
.\sample.ps1 -Name "佐藤"
タスクスケジューラから実行する場合も、引数に含めることができます。
-NoProfile -ExecutionPolicy Bypass -File "C:\work\sample.ps1" -Name "佐藤"
ただし、パスワードや秘密情報を引数で渡すのは避けた方がよいです。
タスクスケジューラの設定画面や履歴から見える可能性があります。
VBSからの置き換え例
VBSの MsgBox は、PowerShellでは用途に応じて置き換えます。
VBS
MsgBox "処理が完了しました"
PowerShell:手動実行向け
Write-Host "処理が完了しました"
PowerShell:運用向け
$logPath = Join-Path $PSScriptRoot "process.log"
Add-Content -Path $logPath -Value "処理完了: $(Get-Date)" -Encoding UTF8
VBSの InputBox は、PowerShellでは Read-Host に近いです。
VBS
name = InputBox("名前を入力してください")
MsgBox "こんにちは、" & name & "さん"
PowerShell:手動実行向け
$name = Read-Host "名前を入力してください"
Write-Host "こんにちは、$name さん"
PowerShell:自動実行向け
param(
[string]$Name
)
$logPath = Join-Path $PSScriptRoot "process.log"
Add-Content -Path $logPath -Value "処理対象: $Name" -Encoding UTF8
実行時に次のように渡します。
.\sample.ps1 -Name "佐藤"
実務での判断基準
MsgBox や InputBox をPowerShellに置き換えるときは、まず次のように判断します。
| 状況 | 推奨 |
|---|---|
| 手動で使う小さなツール |
Write-Host / Read-Host
|
| タスクスケジューラで実行 | ログ / CSV / 設定ファイル |
| ユーザーに確認させたい | GUIよりも処理前の設定ファイル確認 |
| 複数件を処理したい | CSV |
| 固定設定を使いたい | JSONなどの設定ファイル |
| 入力画面が必要 | PowerShell以外の手段も検討 |
| 処理結果を確認したい |
MsgBox よりログ |
特に重要なのは、タスクスケジューラで動かす処理に対話入力を入れないことです。
やってはいけない例
タスクスケジューラでRead-Hostを使う
$name = Read-Host "名前を入力してください"
これは、無人実行では入力待ちになって止まる可能性があります。
タスクスケジューラでMessageBoxを出す
Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.MessageBox]::Show("処理が完了しました")
画面が見えない、または操作できない状態になる可能性があります。
完了通知をMsgBoxだけにする
[System.Windows.Forms.MessageBox]::Show("処理が完了しました")
処理履歴が残らないため、後から確認できません。
運用ではログに残す方が安全です。
実務で使いやすい最小テンプレート
手動実行向けなら、次のような形です。
$targetPath = Read-Host "対象ファイルのパスを入力してください"
if (Test-Path $targetPath) {
Write-Host "対象ファイルが存在します: $targetPath"
}
else {
Write-Host "対象ファイルが見つかりません: $targetPath"
}
タスクスケジューラ向けなら、入力ではなく設定ファイルや引数を使います。
param(
[string]$TargetPath
)
$logPath = Join-Path $PSScriptRoot "process.log"
function Write-Log {
param(
[string]$Message
)
Add-Content -Path $logPath -Value "[$(Get-Date)] $Message" -Encoding UTF8
}
Write-Log "処理開始"
if (Test-Path $TargetPath) {
Write-Log "対象ファイルが存在します: $TargetPath"
}
else {
Write-Log "対象ファイルが見つかりません: $TargetPath"
}
Write-Log "処理終了"
実行例です。
.\sample.ps1 -TargetPath "C:\work\input\data.csv"
タスクスケジューラでは、引数に次のように指定できます。
-NoProfile -ExecutionPolicy Bypass -File "C:\work\sample.ps1" -TargetPath "C:\work\input\data.csv"
まとめ
VBSの MsgBox / InputBox は、PowerShellでも似たことはできます。
ただし、実務ではそのまま置き換えるのではなく、実行形態に合わせて考える必要があります。
| 目的 | PowerShellでの選択肢 |
|---|---|
| 画面に表示したい | Write-Host |
| 入力を受け取りたい | Read-Host |
| GUIメッセージを出したい | Windows FormsのMessageBox |
| 処理結果を残したい | ログ出力 |
| 複数件の入力を扱いたい | CSV |
| 固定設定を使いたい | JSONなどの設定ファイル |
| 定期実行したい | 対話処理を避ける |
手動実行なら、Write-Host や Read-Host は便利です。
しかし、タスクスケジューラや無人実行では、MsgBox や InputBox 的な対話処理は避けるべきです。
PowerShellで実務自動化を作る場合は、次のように考えると安定します。
表示するより、ログに残す。
入力させるより、CSVや設定ファイルから読む。
確認させるより、事前に設定を分離する。
VBSからPowerShellへ移行するときは、単なる文法変換ではなく、対話前提の処理を無人実行できる形に変えることが重要です。