概要
システム構築の自動化をしていると Windows で別のユーザー権限でコマンドを実行したいときが出てくる。そういうときには真っ先に別ユーザーとして実行するコマンドの runas
を思い浮かべるかもしれないが、これは入力プロンプトが表示されるので自動化には向かない。こういうときは schtasks
を使うようだが普通に書くとスクリプトが汚れるので schtasks
で実行する部分を取り出したスクリプトを書いてみた。
実行スクリプト
下記スクリプトを schexec.ps1
として保存する。
schexec.ps1
Param(
[string]$jobUser,
[string]$jobPassword,
[string]$execCommand
)
# Changes the active console code page to Shift-JIS (932).
chcp 932 | Out-Null
$taskname = "SCHEXEC.TASK.$(Get-Random).$(get-date -f 'yyyy-MM-dd_hh_mm_ss')"
$taskscript = "${Env:TEMP}\${taskname}.ps1"
$donefile = "${taskscript}.done.txt"
Write-Host "Create task script"
echo @"
Param(
)
chcp 932 | Out-Null
Set-Location -Path "$((Get-Item -Path ".\" -Verbose).FullName)" -PassThru
Write-Host "Start task script."
`$arguments = @("/c", "$execCommand")
`$proc = Start-Process "cmd.exe" -ArgumentList `$arguments -PassThru -Wait
`$proc.WaitForExit()
"done" | Out-File "$donefile"
"@ >$taskscript
Write-Host "Create job"
schtasks.exe /CREATE /RU "$jobUser" /RP "$jobPassword" /SC DAILY /TN "$taskname" /TR "powershell -file $taskscript" /ST "00:00:00" /F
Write-Host "Run job"
schtasks.exe /RUN /TN "$taskname"
Write-Host "Waiting for job to be done..."
while (!(Test-Path "$donefile")) { Start-Sleep 1 }
Write-Host "Delete job"
schtasks /DELETE /TN "$taskname" /F
使い方
Powershell スクリプト, もしくは Bat ファイルで shchexec.ps1
ファイルを以下のように呼び出す。
schexec.ps1 [実行したいユーザー名] [実行したいユーザーのパスワード] [実行したいコマンド]