質問者
vbscriptのrunasの使い方の基本がどうしてもりかいできません。

質問
-
いつも御面倒をおかけします。
今までバッチファイルで挑戦していたなのですが、タイムアウトでバッチファイルが終了してしまうので、vbscriptの使用を考えました。
動かしたいアプリはdism.exeで管理者権限が必要です。
set shell=wscript.createobject("wscript.shell")
shell.runメソッドを使って、実行するアプリに管理者権限を与えるのにrunasを使えばよいことは分かったのですが、どうもうまく動いてくれません。
shell.run "runas user:administrator dism.exe 引数",,true
だとはじかれてしまいます。
第3引数の終了待ちもtrueにして、うまく実行させる方法をご教授ください。
実行環境は、win10で作ったwinpeです。
cscriptのパスは通っているようで、、
set shell=wscript.createobject("wscript.shell")
shell.run "wpeutil.exe reboot.exe reboot"
とすると、しっかり再起動してくれます。
あとはdism.exeがイメージを作ってくれればとりあえずokです。
どうかよろしくお願いします。
すべての返信
-
© ウィンドウズスクリプトプログラマ - Windows Script Programmer 2017
wscript.shellのexec()とshell.applicationのshellexecute()を勘違いしてませんか?
wscript.shellのexec()では、runas.exeで起こすプロセスの待ち合わせは、runas.exeのプロセスの待ち合わせではできません。その間は非同期です。
shell.applicationのshellexecute()では、
set shell=createobject("shell.application")
を実行してみれば分かりますが、これも非同期です。
shell.shellexecute "cmd.exe",,,"runas"
msgbox 1
- 編集済み ウィンドウズスクリプトプログラマ 2017年11月24日 4:08
-
アドバイスありがとうございます。
非同期なのは承知のうえで、管理者権限がほしいので、runasを使いたいのです。
プロセス監視は、
do while exec.status=0
wscript.sleep 5000
loop
のようにしようと考えています。
しかし、
set shell=wscript.createobject("wscript.shell")
set exec=shell.exec("dism.exe /capture-image /capturedir:c:\ /imagefile:g:\bkprt\anychk.wim /compress:maximum /name:""anything checked""",,,runas)
としたとき、2行目の1列目でエラーになり、プロパティの指定が間違っている、引数の数が合わないと表示される理由が分かりません。
いったいなにが悪いのでしょうか。私の感覚から言えば、それではなぜ1行目でエラーが出ないのかというのが疑問です。
どうぞよろしくお願いします。
-
非同期なのは承知のうえで、管理者権限がほしいので、runasを使いたいのです。
最初に管理者権限に昇格させて、以降のスクリプト処理を全部管理者権限で実行したら、と 別スレッドで提案されていますよね。
今困っているのは、「管理者権限で実行したプロセスが完了した後に何かしたい」なので、「最初に、スクリプトを非同期で管理者権限で実行し、以降はそちらに任せる、処理を待ってから次に進む部分も管理者権限で実行されているスクリプト側に書けば良い」という風に回避すれば良いのでは? と。
現状のイメージ
- runas で実行するプロセスを待つ
- シャットダウンや再起動など
待つことができず、処理が完了する前にシャットダウンしてしまう。
改善案のイメージ
- runas でスクリプトを実行する
- このスクリプトは以降何もせずに終了(シャットダウンや再起動もしない)
runas で実行されたスクリプト:
- 待ちたい処理を実行する ※すでに昇格済みなので runas 不要
- 待った上でシャットダウンや再起動する
- 編集済み AzuleanMVP 2017年11月24日 14:29
-
アドバイスありがとうございます。
私がやりたいのは、
1.管理者に昇格する
2.dismで全ての指定されたパーティションがキャプチャされるのを待つ
3.終わったことを確認してキャプチャの場合は再起動、適応の場合はブートエントリーを書き込んで再起動
ということになるような気がします。
もちろん、引数はないので、キャプチャとアプライは分けるつもりです。
キャプチャもアプライもいくつのパーティションを行うのか、保存先は日時からファイル名を作成し保存先とパーティションはそれぞれ、配列で管理処理できるようにしたいと考えています。
またエラー内容もファイルに出力するところまでいきたいと思っています。
勉強することが沢山あります。
どうか、ご指導のほどよろしくお願いします。
-
set shell=createobject("shell.application")
set exec=shell.application.shellexecute("dism /capture-image ...",,,"runas")
という感じでしょうか?
アプリ経書んとありますが、コマンドは実行できますか?
またpidやステータスも利用できますか?
確かに勘違いしていたようです。
set obj=createobject("shell.application")
set ret=obj.shellexecute("dism.exe /capture-image ...",,,"runas")
で、vbscriptの実行はできました。
しかし、コマンドが見つかりません。正しく入力したかもう一度確かめて実行してください。
これはなんという有様。。。
いったい何が悪いのだと?
何をどうすればいいのか、途方に暮れています。
どうか、御助言をお願いします。
プロセス監視はなんとかサンプルの関数を見つけました。
- 編集済み win10-syoshinsya 2017年11月25日 6:00
-
© ウィンドウズスクリプトプログラマ - Windows Script Programmer 2017
第4引数を知ってるのだから、その仕様は見てますよね。
Shell.ShellExecute method (Windows)
返すのはエラーコードだけです。待ち合わせ方法はありません。
何を使おうが、昇格させて、それを待ち合わせるのは、筋が悪いので、無理でしょう。処理全体を昇格させて、処理の中で待ち合わせるように、発想を変えないと無理でしょう。 -
たびたびのアドバイス感謝します。
if wscript.arguments.count<=0 then
set shell=createobject("shell.application")
shell.shellexecute "cscript.exe",wscript.scriptfullname+" /a",,"runas"
end if
set shell =wscript.createobject("wscript.shell")
shell.run "dism.exe /capture-image /capturedir:""c:\program files\"" /imagefile:g:\bkprt\anychk.wim /compress:maximum /name:""anythingchecked""",,1
shell.run "dism.exe /capture-image /capturedir:""c:\program files\"" /imagefile:g:\bkprt\vrfchk.wim /verify /compress:maximum /name:""verified""",,1
shell.run "dism.exe /capture-image /capturedir:""c:\program files\"" /imagefile:g:\bkprt\allchk.wim /checkintegrity /verify /compress:maximum /name:""allchecked"" /k",,1
shell.run("wpeutil.exe reboot")これでvbscriptが管理者権限に昇格できたと考えていますが、間違っていればご指摘ください。
また、dismのところは()で括ると怒られるのに、
最も下の行はなぜ()で囲まないと動作しないのか、その差がわかりません。
そして、dismが実行された形跡がありません。なぜなら、x:\windows\logs\dism\dism.logをhddにコピーしようとしましたが、ファイルが見つからないようです。
どうぞよろしくお願いします。
-
毎度お世話になります。
下のように変更してみたところ、再起動さえ行われなくなりました。
再呼び出しが実行されていることは、テスト段階でmsgbox(wscript.arguments(0))で引数が表示されることを確認しています。
if wscript.arguments.count<=0 then
set shell=createobject("shell.application")
shell.shellexecute "cscript.exe",wscript.scriptfullname+" /a",,"runas"
else
set shell =wscript.createobject("wscript.shell")
shell.run "dism.exe /capture-image /capturedir:""c:\program files\"" /imagefile:g:\bkprt\anychk.wim /compress:maximum /name:""anythingchecked""",,true
shell.run"dism.exe /capture-image /capturedir:""c:\program files\"" /imagefile:g:\bkprt\vrfchk.wim /verify /compress:maximum /name:""verified""",,true
shell.run "dism.exe /capture-image /capturedir:""c:\program files\"" /imagefile:g:\bkprt\allchk.wim /checkintegrity /verify /compress:maximum /name:""allchecked""",,true
shell.run "copy x:\windows\logs\dism\dism.log g:\*.*",,true
shell.run("wpeutil.exe reboot")
end if上のアドバイスはとても見落としがちなことだったので、大変参考になりました。
最初はwscript.quitを入れてみたのですが、なぜかwinpe自体が終了してしまいました。
-
© ウィンドウズスクリプトプログラマ - Windows Script Programmer 2017
最も下の行はなぜ()で囲まないと動作しないのか、その差がわかりません。
は、たぶん、
shell.run"dism.exe /capture-image /capturedir:""c:\program files\"" /imagefile:g:\bkprt\vrfchk.wim /verify /compress:maximum /name:""verified""",,true
と同じく、shell.runの後に空白類がないせいでしょう。()で囲めば、空白類がなくてもよい。
- 編集済み ウィンドウズスクリプトプログラマ 2017年11月26日 10:39