今回はPowerShell上でコマンドを実行する場合の注意点に関してです。PowerShell上で色々な作業を行う便利さに慣れてくると、コマンドプロンプトは全く使わずにPowerShell上で作業を完結させるようになってきます。が、このときにちょっとした落とし穴があります。

私がはまったのはwbadminコマンドの利用時でした。wbadminコマンドはPowerShellのコマンドレットではない、純粋なコマンドプロンプト上で動作するプログラムです。Windows Server 2008のバックアップを行うことができます。

PowerShell上からwbadminコマンドを実行しようとしたところ以下のような現象が発生しました。「きちんと入力しているのに、文法ミスと言われてしまう」というものです。

 1: PS C:\Windows\System32> wbadmin start systemstatebackup -backuptarget:f:

 

 2: wbadmin 1.0 - バックアップ コマンド ライン ツール

 

 3: (C) Copyright 2004 Microsoft Corp.

 

 4:

 

 5:

 

 6: エラー - オプション: backuptarget の値がありません。以下の使用法を参照してください。

 

 7:

 

 8: 使用法: WBADMIN START SYSTEMSTATEBACKUP

 

 9:     -backupTarget:{ボリューム名}

 

 10:     [-quiet]

 

 11:

 

 12: 指定されたオプションに基づいてシステム状態のバックアップを実行します。

 

 13:

 

 14: -backupTarget   バックアップの記憶域の場所です。記憶域のドライブ文字が

 

 15:                 必要です。

 

 16:

 

 17: -quiet          ユーザー プロンプトなしでコマンドを実行します。

 

 18:

 

 19: 例:

 

 20: WBADMIN START SYSTEMSTATEBACKUP -backupTarget:f:

 

例のところに書かれているオプションをそのままコピー&ペーストしても動きません!原因がわからずかなり悩んでしまいました。しかも、全く同じコマンドをコマンドプロンプト上で実行すると正常に動作するのです。

結局原因はPowerShellの「式モード」と「コマンドモード」の違いにありました。結局以下のように入力すればうまく動くことがわかりました。

 1: wbadmin start systemstatebackup "-backuptarget:f:"

 

原因は-bakuptarget:f:という文字列をPowerShellに直接入力してみるとわかります。

 1: PS C:\Windows\System32> -backuptarget:f:

 

 2: 単項演算子 '-' の後に式が存在しません。

 

 3: 発生場所 行:1 文字:2

 

 4: + -b 

このようにPowerShellが”-“という文字を単項演算しとして認識してしまい、それが原因でコマンドとして成立していなかった、というわけです。
### 「式モード」と「コマンドモード」
PowerShellでは「式モード(expression mode)」と「コマンドモード(command mode)」の2つがあります。詳細は以下のリンク先の辺りをご確認ください。(#私自身まだきちんと整理できていません。整理できたらわかりやすく書こうと思います。)

	- [Expression mode v. Command mode in PowerShell - Windows Live](http://row5is.spaces.live.com/blog/cns!AE3775C67DE2245F!289.entry)
	- [式モードとコマンドモード:PowerShell log:So-net blog](http://kawasaki-shingo-ps.blog.so-net.ne.jp/2009-03-19)
	- [基礎知識 (Windows PowerShell)](http://ufcpp.net/study/powershell/basic.html#mode)

### まとめ
今回の件のまとめです。

	- 通常のDosのコマンドとその引数をそのまま記述した場合、それは式モードで解釈される
	- 特に特別な文字等が含まれない場合にはそれはそのまま実行される(計算式なら実行される、Dosコマンドなら実行される)
	- 特別な意味を持つ文字が含まれる場合には「計算」されてしまう
	- 「計算」されることを防ぐにはダブルクォーテーションで囲うなりして、「文字列」として認識させる必要がある。