デフォルトの状態でPowerShellのスクリプトを実行しようと、スクリプトファイルをダブルクリックしてもメモ帳が開き、右クリックから「PowerShellで実行」を選んでも実行ポリシーに引っかかってしまい、すんなり実行してくれません。
-ExecutionPolicy Unrestrictedのオプションを設定してPowerShellスクリプトを起動するためのバッチファイルを別途作って対応していたのですが、次のコードをバッチファイルの1行目に入れて、2行目以降にPowerShelのスクリプトを記述し、バッチファイルとして保存するとダブルクリックで実行してくれるようになるという記事を見ました。
@powershell -NoProfile -ExecutionPolicy Unrestricted "$s=[scriptblock]::create((gc \"%~f0\"|?{$_.readcount -gt 1})-join\"n\");&$s "%~dp0 %*&goto:eof
例えばこんなコードです。
1 2 3 |
@powershell -NoProfile -ExecutionPolicy Unrestricted "$s=[scriptblock]::create((gc \"%~f0\"|?{$_.readcount -gt 1})-join\"`n\");&$s "%~dp0 %*&goto:eof Write-Host Hello World! |
一見何をやっているのかよくわからなかったので読み解いてみました。簡単に言えば本バッチファイルの2行目以降を、PowerShellのスクリプトとして実行するという命令が書かれています。
@powershell
powershellを実行する。@マークはメッセージを画面に表示させない指定。
-NoProfile
PowerShellのプロファイルを使わない。プロファイルとは実行時に自動で事前実行されるスクリプトの事。詳細は省略。
-ExecutionPolicy Unrestricted
PowerShellを実行ポリシーの警告なしに実行させるオプション。
$s
[scriptblock]::createメソッドで作成されるスクリプトブロックを格納する変数。本バッチファイルの2行目以降の文字列をPowerShellとして実行できるようにしたものが入る。[scriptblock]::create
引数で指定された文字列をPowerShellとして実行できる形(スクリプトブロック)にする。
gc
Get-Contentのエイリアス。指定のファイルを読み込む。今回の場合はこのバッチファイル自身を読む。
\”%~f0\”
このバッチファイル自体のパスが展開される。gcで読み込むファイルの指定。
|
パイプ。gc \"%~f0\"の実行結果を次のコマンドへ渡してくれる。
?
Where-Objectのエイリアス。条件に合致するもののみ返す。
{$_.readcount -gt 1}
?の条件部分。gc \"%~f0\"の内容がパイプで1行ずつ$_に渡ってくるので、1行目よりも大きい-gt(Greater Than)という条件を指定している。
-join\"n\"
バッチファイル内の2行目以降の内容を1行毎に改行(\n)で区切って取得する
&$s
&でスクリプトブロックの$sを実行させる。
“%~dp0
スクリプトブロックへの引数。スクリプトブロックからバッチ自体の場所が取れないので、引数でこのバッチ自体のパスを渡しておく。
%*
バッチ自身への引数も渡す。
&goto:eof
2行目以降のPowerShellスクリプトはバッチとしては実行させないので最後まで飛ぶ。
以下のエラーが表示されて、
管理者権限無しでps1ファイルに書いたPowerShellスクリプトを実行した時と同じ結果になりました。
<表示されたエラー>
‘?{$_.readcount’ は、内部コマンドまたは外部コマンド、
操作可能なプログラムまたはバッチ ファイルとして認識されていません。
>> 通りすがりさん
コードをコピペされている場合はダブルクォーテーションが全角になっていないかチェックしてみてください。
Wordpressが余計なお節介をしてくれてる可能性があります。
[…] PowerShellをダブルクリックで実行させる […]