Help us understand the problem. What is going on with this article?

バッチファイルから PowerShell を呼び出す方法

More than 5 years have passed since last update.

背景

PowerShell でスクリプトを書くメリットの一つとしては、Windows7 以降ならデフォルトで入っているので、Windows を使っている人になら書いたスクリプトを渡して、そのまま使えることにあると思っている。(しかも .NET が使える)
ただデフォルトの設定だと PowerShell のスクリプトを実行できなかったり、ダブルクリックで実行できないのも、ちょっと不便だなと感じるので、その回避方法をメモする。

普通に引数で渡す

一番単純な方法は、PowerShell のスクリプトを呼び出すバッチファイルを、いっしょに置いておくことだと思う。
デフォルトだと ExecutionPolicy の値でスクリプトの実行ができないのでオプションで指定する。

hello.bat
powershell -NoProfile -ExecutionPolicy Unrestricted .\hello.ps1
hello.ps1
Write-Host "Hello, World!!"

ただちょっとした処理を書くために使いたいケースが多いのに、ファイルが 2 つに分かれてしまうのは、ちょっと嫌だなと感じる。

一行だけなら、こうも書ける

powershell -NoProfile -ExecutionPolicy Unrestricted -Command "& { echo 'Hello, World!!' }"

ただこれで書くと、少し量が増えただけでゴチャゴチャする。

1 つのファイルにまとめる

これが今回メモしておこうと思った内容。
最近、Scala を使いだしたら、Scala だとバッチファイルに、

::#!
@echo off
call scala %0 %*
goto :eof
::!#

println("Hello, World!!")

とか書くと、Scala がインストールされている環境なら動いてしまう。
これがなぜ動くを、よく見てみると PowerShell でもできるのではないかと思った。
ググってみると、 stackoverflow に説明してあるのがあった。
さらにググってみると、 Make it easier to wrap powershell scripts in batch files というのを見つけた。

@powershell -NoProfile -ExecutionPolicy Unrestricted "$s=[scriptblock]::create((gc \"%~f0\"|?{$_.readcount -gt 1})-join\"`n\");&$s" %*&goto:eof

Write-Host "Hello, World!!"

とりあえず、これで動くらしい。というか動く。
やってることは、両方ともバッチファイルの中で自分自身を呼び出して、その呼び出す記述を呼び出す側で無視するという感じ。

これなら多少コードが増えても、そこそこ使える気がする。

Base64 encode

ついでに、Base64 encode するというのもあった。
ちょっと面倒な気もするけど、これはこれで何かに使えるかもしれない。

powershell -NoProfile -ExecutionPolicy Unrestricted -EncodedCommand ZQBjAGgAbwAgACIAaABlAGwAbABvACIAOwAgAGUAYwBoAG8AIAAiAHcAbwByAGwAZAAiADsA

エンコードする PowerShell ワンライナー

# 文字コードは適宜調整すること
# 元にする PowerShell のコードは行末に ; を付けること
"powershell -NoProfile -ExecutionPolicy Unrestricted -EncodedCommand $([Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($(cat .\hello.ps1))))" | Out-File .\base64encoded.bat -Encoding Default
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした