適材適所

WindowsやPowerShellやネットワーク、IBMなどのシステム系の話やポイ活など気になったことも載せているブログです。

【PowerShell】文字列をコマンドとして実行する【Invoke-Expression】

文字列をコマンドとして実行したい!そんなときはInvoke-Expressionコマンドレットが使えます。

Invoke-Expressionコマンドレットとは

オンラインヘルプによれば、

ローカル コンピューター上でコマンドまたは式を実行します。

構文は

 
Invoke-Expression
      [-Command] <String>
      [<CommonParameters>]

となっています。

コマンド本体だけでなくパラメタもちゃんと解釈してくれるのが便利

パラメタ無しでコマンド本体だけを実行したい場合は、「&」を使っても同じように実行することができます。

 
& "Get-ChildItem"

しかし、この方法ではパラメータを使おうとするとエラーになってしまいます。

 
& 'Get-ChildItem -Recurse'
& : 用語 'Get-ChildItem -recurse' は、コマンドレット、関数、スクリプト ファイル、または操作可能なプログ
ラムの名前として認識されません。名前が正しく記述されていることを確認し、パスが含まれている場合はそのパス
が正しいことを確認してから、再試行してください。
発生場所 行:1 文字:3
+ & 'Get-ChildItem -recurse'
+   ~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (Get-ChildItem -recurse:String) [], CommandNotFoundExcept
   ion
    + FullyQualifiedErrorId : CommandNotFoundException

&でパラメータ付きのコマンドを指定しまうと、パラメータを含めて一つのコマンドとして解釈されているようです。

それに対してInvoke-Expressionコマンドレットはパラメータを含めたコマンドを指定しても正しく解釈され、意図通りに動いてくれます。

 
 Invoke-Expression 'Get-ChildItem -Recurse'

ちなみに「&」は「呼び出し演算子」と呼ぶらしいです。下記のリンクで私も初めて知りました。

演算子について - PowerShell | Microsoft Learn

過去のコマンド履歴を全て実行する

コマンドの履歴を保存しておく設定になっていれば、その履歴を参照して全てのコマンドを連続で実行するなんてこともできます。

いちおう、下記に例を示しますが、どんなコマンドがあるかは実行環境に依存しますので、実行される前に事前によく確認をお願いします。責任は持てません。

 
Get-Content (Get-PSReadlineOption).HistorySavePath -Encoding UTF8 | Invoke-Expression

「過去のコマンドの全部じゃなくて一部だけ実行したいんだけど…」というときは、下記の通り、配列で指定してあげるといいかもしれません。

例えば履歴の最初の10件を実行する例です。

 
Invoke-Expression (Get-Content ((Get-PSReadlineOption).HistorySavePath) -Encoding UTF8)[0..9]

終わりに

文字列をコマンドとして実行してくれるという、そこまで需要はないかような気がするコマンドレットですが、ニッチなところを突いてくるPowerShellらしいコマンドで私は好きです。

というわけでここまでお読み頂きましてありがとうございました。

参考