質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

Q&A

解決済

2回答

11671閲覧

バッチファイルからPowerShellのコマンドを使いたい

退会済みユーザー

退会済みユーザー

総合スコア0

Windows 10

Windows 10は、マイクロソフト社がリリースしたOSです。Modern UIを標準画面にした8.1から、10では再びデスクトップ主体に戻され、UIも変更されています。PCやスマホ、タブレットなど様々なデバイスに幅広く対応していることが特徴です。

PowerShell

Windows PowerShellはコマンドラインインターフェースであり、システム管理を含むWindowsタスク自動化のためのスクリプト言語です。

バッチファイル

バッチファイル(Batch File)は、Windowsのコマンドラインインタープリターによって複数のコマンドを実行させる事が出来るスクリプトファイルです。

0グッド

0クリップ

投稿2020/04/16 06:18

前提・実現したいこと

Qiitaにいい記事があったのですが、何をやっているのか分からないので困っています。
バッチファイルから PowerShell を呼び出す方法という記事のコードなのですが

batch

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

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

わかりません・・・。

わかること

  • @でコマンドプロンプトに一行目のコードを出力させないようにしている
  • powershell -NoProfile -ExecutionPolicy Unrestrictedは余計な設定を読み込まず、実行時ポリシーを無視して無理やり実行させるのに必要
  • $s=[scriptblock]::create() 変数sに@scriptblock型Objectを生成して代入
  • ;はVBでいう_とかC系言語(?)でいう;と同じ
  • gc \"%~f0\"でカレントディレクトリのファイルやフォルダのリストを取得してパイプで右側に結果を渡している

わからないこと

  • ?{$_.readcount -gt 1}

予測もつきません・・・どういう構文で、何をしているのでしょう

  • -join\"`n\"

の部分は文字列のオプションとしてjoinがあり、続く文字列をつけ足してくれているのでしょうか

  • &$s

は全然わかりません。この時点では変数sは宣言されていないと思うのですが・・・

  • %*&goto:eof

も全然わかりません。どこで区切れるのかすら分かりません。
というか""の外側なので別の引数なのでしょうか。パラメーターか何か?

  • Write-Host "Hello, World!!"

どうしてそんなところにPowerShellのコマンドレットが・・・。



どうぞよろしくお願いいたします。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

  • Windows 10 64bit

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2020/04/27 08:03 編集

> Write-Host "Hello, World!!" > どうしてそんなところにPowerShellのコマンドレットが・・・。 どうしてもこうしても、PowerShell スクリプトを拡張子 bat で書こうとしているだけです。だから二行目以降は PowerShell の文法で書きます。
Zuishin

2020/04/16 06:39

具体的には、呼び出したバッチファイルの二行目以降を読み取り、それを PowerShell で実行しています。
退会済みユーザー

退会済みユーザー

2020/04/16 06:59

具体的な内容が分かれば追いやすくなります。ありがとうございます。ワンライナーで書かれると読む側も一朝一夕程度の勉強では理解が追いつきませんね・・・。
Zuishin

2020/04/16 07:10

最後の %*&goto:eof ですが、%* はバッチファイルの引数全てをスペースで区切ったものを表すバッチの変数です。 ここまでが PowerShell の引数になります。 & はコマンド区切りで、これ以前とこれ以降で別のコマンドになります。つまり、バッチファイルに二行に渡って書く物を一行にまとめるときに使います。 goto:eof はバッチの最終行にジャンプせよという意味で、これ以降は PowerShell のコマンドで、バッチで処理できないのでスキップするよう指示しています。
guest

回答2

0

?{$_.readcount -gt 1}

予測もつきません・・・どういう構文で、何をしているのでしょう

?は Where-Object の省略形です。

上の文はパイプラインで渡されたオブジェクトのうち、readcountプロパティが1より大きいものだけ……つまり2行目以降を抽出するという意味です。

-join\"`n\"

の部分は文字列のオプションとしてjoinがあり、続く文字列をつけ足してくれているのでしょうか

いいえ。区切り文字に改行を利用して、配列を1つの文字列に結合するという意味です。

&$s

は全然わかりません。

&は起動演算子です。

上は、変数$sに格納されているスクリプトブロックを実行せよという意味になります。

この時点では変数sは宣言されていないと思うのですが・・・

$s=[scriptblock]::create(~ で$sに値が格納されています。

%*&goto:eof

も全然わかりません。どこで区切れるのかすら分かりません。
というか""の外側なので別の引数なのでしょうか。パラメーターか何か?

はい。これはpowershellではなくバッチファイルの記述です。

これは%*&goto:eofがそれぞれ意味を持っています。

%*はバッチファイルに与えられた引数を表し、引数をそのままpwoershellの引数として与えるために書かれています。

&は1行で複数のコマンドを実行するための区切り文字です。

goto:eofは、実行されることで次に実行される行をファイルの最後に設定するという命令です。ファイルの最後にはこれ以上コマンドは書かれていませんので、そこでバッチ処理は終了されることになります。

Write-Host "Hello, World!!"

どうしてそんなところにPowerShellのコマンドレットが・・・。

まとめて言うと、@powershell -NoProfile ~の1行は以下のような意味を持ちます。
『このファイル自身の2行目以降の内容を、powershellのスクリプトとして実行したあと、2行目以降はスキップしてバッチ処理を終了しろ』

投稿2020/04/28 07:31

編集2020/04/28 07:35
ku__ra__ge

総合スコア4524

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

Zuishin

2020/04/28 07:41

この質問者さんが何も続報を書かず放置しているので回答されたんでしょうが、実は自力で調べて Qiita に記事を書いていました。 少し問題のある表現があったので修正を提案したところ、記事は削除されましたが。
退会済みユーザー

退会済みユーザー

2020/05/08 06:29

回答ありがとうございます。 丁寧な解説をいただいて恐縮です。 Zuishinさんのおっしゃる通りヒントをいただけたのでその先は自力で調査し、結果をQiitaに投稿していました。(質問の追記修正の欄にZuishinさんに書き込んでいただいた情報が大変有用でしたのでスムーズに調査が行えました) 当質問におきましてはベストアンサーをgentaroさんの回答に対してつけておりますのでその時点でクローズという形をとらせていただいております。ご了承ください。
guest

0

ベストアンサー

Qiitaの記事なんだからそこにコメントすればいいのに。

ちゃんと読んでませんが、ぱっと見た感じでざっくりやってる事を解釈すると、1行目のPowerShellでの呼び出しで、そのバッチファイルに書いてある1行目だけ飛ばして、それ以降をスクリプトとして実行する、という感じだと思いますが。

色々とここがわからない、と書いてありますが、それぞれPowerShellのリファレンス等は読まれましたでしょうか?

?{$_.readcount -gt 1}
予測もつきません・・・どういう構文で、何をしているのでしょう

これとか、?の意味(where)、比較演算子(greater than)など、調べればわかるとは思います。

逆にPowerShellが全くわかってない状態でこういうテクニックを理解しようというのは無謀だと思うので、まずはPowerShellの入門記事とかを読むところから始められては。

投稿2020/04/16 06:41

gentaro

総合スコア8949

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2020/04/16 07:03 編集

ちょっと調べてちょっと使うくらいでは解読できないことは分かりました。便利そうなのでじっくり勉強してみます。ありがとうございます。 Qiitaで聞かないのは、Qiitaは質問サイトではないですし2年投稿のないユーザの5年前の記事に質問を投げても回答は望み薄だと判断したためです。悪しからず。
len_souko

2020/04/27 06:14

Qiitaのコメントで質問してみて反応がなかったらこっちに質問を投げてQiitaのコメントに返事がないからこっちで聞いてますとリンクを張っておけば同じように検索してQiitaの記事にたどり着いたけどわかんないって人が助かるかもしれない。 記事を投稿していなくてもネタがなくて投稿していないだけで他の人の記事を見てはいるかもしれません。 その場合は通知が表示されるので気づくと思いますよ。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問