この記事はPowerShell Advent Calendar 2017の25日目です。
ある時バッチからPowershellコマンドレットを実行しようとした際、バッチの変数をコマンドに入れる必要性が出てきました。
そこで対処した処理方法の備忘録です。
PS1を実行する方針でも良いですがExecutionPolicyを変更できない環境とか、スクリプトを一つにしたいという制約を受ける環境の方には有効かと思います。
ユースケース
例えば、以下のような処理をする場合が考えられます。
- バッチ内の処理で一次処理ファイルを生成する。
バッチで何らかのコマンド実行結果をテキストファイル(ファイル名をバッチの変数で指定)に出力
- Powershellコマンドで、一次処理ファイルを指定して二次処理を行う。
テキストファイルをPowershellで読み込み次の処理を実行
バッチの内容と説明
いきなりですが、バッチの中身です。
バッチの中に記述のコメントがユースケースで説明したような処理を説明しています。
@ECHO OFF
SETLOCAL
CD %~DP0
REM ---
REM 実行時間をTIMESTAMP変数に格納。一桁で空白となる数値は0埋め。
REM ---
SET TIMESTAMP=%DATE:/=%-%TIME:~0,2%%TIME:~3,2%%TIME:~6,2%
SET TIMESTAMP=%TIMESTAMP: =0%
REM ---
REM 実行時間を一次処理用ファイル名と最終処理結果用ファイル名として命名
REM ---
SET TEMPNAME=%TIMESTAMP%_%COMPUTERNAME%.txt
SET FILENAME=%TIMESTAMP%_%COMPUTERNAME%.csv
REM ---
REM ★★ここがポイント★★
REM 実行したいPowershellコマンドレットを生成し、PSCMDLET変数にダブルクォーテーション付きで格納
REM 処理内容:一次処理用ファイル(内容は後述)を読み込み→プロパティ情報から必要情報をフィルタして最終処理結果用ファイルにCSV出力
REM ---
SET PSCMDLET="Get-Content .\%TEMPNAME% | Get-ChildItem | Select-Object FullName,Length,CreationTIme,LastAccessTime,LastWriteTime,VersionInfo | Export-Csv -Encoding ASCII -Path .\%FILENAME%"
REM ---
REM [一次処理]
REM CドライブのEXEファイルだけを一次処理用ファイルにフルパスで書き出し
REM ---
DIR /S /B C: | FIND ".exe" >> %TEMPNAME%
REM ---
REM [最終処理]
REM PSCMDLET変数がPowershellコマンドレットとして実行される
REM ---
POWERSHELL -C %PSCMDLET%
REM ---
REM 一次処理用ファイルは不要なため、削除
REM ---
DEL %TEMPNAME%
ENDLOCAL
あとがき
当初、最終処理のコマンドレット部に直接バッチの変数を入れていました。しかし意図した動作とならず、思いあぐねて上記対処方法を考えつきました。
お困りの方にとって、本Postが一助になれば幸いです。
なお上記のサンプルスクリプトは、Windows Server 2012 R2 / Powershell 4.0 の環境で動作確認をしています。
使用しているコマンドは一般的なものなので、Windows 7以降であればそのまま実行できるかと思います。