PowerShellコマンドレット以外のプログラムを実行

PowerShellコマンドレットとスクリプトだけであらゆる処理を簡単に実行できればいいのですが、実際の運用では、従来型のWindowsアプリケーションやコマンドプロンプト用のプログラム(コマンド)と組み合わせて使う方が効率がよい場合が少なくありません。また、せっかく長年にわたって蓄積されてきたコマンドプロンプト用の従来型のコマンドにも便利なものは多く、それらを使わない手はありません。

これまで、PowerShell標準の世界だけを使った例を紹介しましたが、今回はこうした従来型コマンドをPowerShellで使う方法を紹介します。

exe形式のコマンド

Windows標準の外部コマンドをはじめとするexe実行ファイルであれば、コマンドプロンプトと同様に、PowerShellプロンプトで実行ファイル名をコマンドとして入力するだけです。たとえば、Windowsの「メモ帳」の実体はnotepad.exeという実行ファイルです。実行する時は拡張子exeを省略できますので、notepadというコマンド名で実行できます。

notepadと入力して、メモ帳を起動する例。

ただし、コマンド名がPowerShellのコマンドレット名と同名、あるいはコマンドレット名の一部である場合は、PowerShellはコマンドレットを優先して起動しようとします。このようなケースでexeプログラムを実行するには、パスを明確にします。

たとえば、Windows標準のファイル検索コマンドwhere.exeがあります。PowerShellのコマンドレットで単純に「where」と入力すると、PowerShellはWhere-Objectコマンドレットを起動します。where.exeを起動するためには、「\windows\system32\where.exe」というようにパスを明確にして起動します。

単にwhereと入力して実行すると、Where-Objectコマンドレットが起動。

パス付きで入力することで、where.exeコマンドが起動。

※ 環境変数Pathで指定されたパスにある外部コマンドの場合は、「where.exe」というように拡張子を付けるだけでコマンドを実行することもできます。

こうした実行方法は、マイクロソフト管理コンソールのコマンド(拡張子msc)も同様です。たとえば、「gpedit.msc」を実行すればローカルグループポリシーエディタを、「fsmgmt.msc」を実行すれば「共有フォルダー」管理コンソールを起動できます。また、コントロールパネルに登録されている拡張子cplのファイルについても同様です。ただし、cplファイルの場合は拡張子必須です。

fsmgmt.mscを実行すると「共有フォルダ」、ncpa.cplを実行すると「ネットワーク接続」を開きます。

外部コマンドを実行する時のフィルタ

PowerShellの優れた点は、PowerShellオブジェクトに全く対応していない従来型(コマンドプロンプト用に設計された)フィルタプログラムであってもフィルタとして使用できることです。

gci(Get-ChildItem)コマンドレットの出力を、パイプラインで外部コマンドのsed.exeに送り、文字列「address」を「住所」に置換。

ただし、これらのコマンドプロンプト用のフィルタプログラムでは、PowerShellのオブジェクトの受け渡しが出来ません。必然的にテキストデータに変換してパイプラインをつなぐことになります。たとえば、Get-ChildItemの出力をgrepやsed、awkで処理した場合、オブジェクトとしてのファイル情報は失われ、Get-ChildItemが表示するテキストデータのみがgrepやsed、awkに引き渡されます。

※ UNIX系のフィルタプログラムであるgrep、sed、awkなどはテキスト処理に非常に便利です。ただ、残念なことにWindowsには標準装備していません。インターネットなどでWindows用のプログラムを探して入手して下さい。また、Windows用のフィルタコマンドの多くはShift JISコードでテキストファイルを扱いますが、PowerShellは基本的にUnicodeを使用するため、日本語文字コードの扱いにも注意が必要です(当連載の第11回記事を参照)。

PowerShellでコマンドプロンプト用バッチコマンドを実行

コマンドプロンプト用に作成したバッチコマンドも、パスを指定することでPowerShellスクリプトと同様にPowerShellプロンプトから実行できます。

たとえば、カレントディレクトリに、e.bat あるいはe.cmdというバッチコマンドがあるとき、以下のようになります。

「e」とだけ実行するとエラー。

パスを指定して「.\e」と実行すると起動。(パス . はカレントディレクトリを意味します)

※ バッチコマンドの拡張子には、batとcmdがあります。DOSやDOS系Windows(Windows 1.0~3.1、Windows/95/98/Me)のシェル、command.comでは、バッチコマンドの拡張子はbatでした。NT系Windows(Windows NT/2000/XP/Vista/7、Windows Server)で新しく導入されたシェル、cmd.exeでは、バッチコマンドの拡張子にbatもcmdも使用できます。

コマンドプロンプトの内部コマンドの実行

一方、コマンドプロンプトの内部コマンド...copy、ren、del、dirなどを...を実行する時は、cmd.exeを起動しなければなりません。内部コマンドはシェルであるcmd.exe(あるいはcommand.com)自身が実行する機能であり、cmd.exeが実行プログラムファイルだからです。

その場合のコマンドライン書式は以下の通りです。

cmd  /c  '内部コマンドのコマンドライン'

/cは、内部コマンド実行後にcmd.exeを終了するオプションです。/cオプション無しで実行すると、単にcmd.exeを起動して、cmd.exeのコマンドプロンプになるだけです。そのとき、exitコマンドでcmd.exeを終了するとPowerShellプロンプトに戻ります。

/cオプションなしで実行すると、cmd.exeコマンドプロンプトを開きます。プロンプトの変化に注意。ここではexitコマンドで終了させています。

/cオプションで実行すると、dirコマンド終了後、cmd.exeを終了してPowerShellに戻ります。

次回は、コマンドプロンプトからPowerShellスクリプトを実行する方法を紹介します。

外部コマンドと内部コマンド

コマンドプロンプトの世界では、コマンドを外部コマンドと内部コマンドに大別します。

外部コマンドとは、拡張子EXEのファイルに代表される、コマンド単体で実行プログラム「ファイル」として存在するコマンドの総称です。Windowsアプリケーションやバッチコマンドも、外部コマンドと言えます。一方、コマンドプロンプトで使用できるコマンドのうち、copyコマンドやrenコマンド、delコマンドなどは、プログラムファイルとして存在ません。これらはコマンドプロンプトを実現しているcmd.exe自身が実行する機能で、こうしたコマンドを内部コマンドと呼びます。つまり、ここで言う内部/外部の区別は、cmd.exeの内部機能かcmd.exeの外部かという違いです。

なお、cmd.exeのようなコマンドプロンプトを実現するプログラムを、シェル(shell : システム本体を包み込む殻)または、コマンドインタプリタ(command interpriter : 命令翻訳機)と呼びます。WindowsではNT系Windows(Winodws NT、Windows 2000/XP/Vista/7、Windows Server)の標準シェルであるcmd.exeと、DOS系Windows(Windows 1.0~3.11、Windows 95/98/Me)との互換性のためのcommand.comという古いシェルの両方を装備しています。また、インターネットでは、特色あるサードパーティ製シェルも入手できます。Windows 2008から登場したPowerShellも、これらシェルの一種であり、最新最強のシェルの一つです。