みんなの「教えて(疑問・質問)」にみんなで「答える」Q&Aコミュニティ

こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

VBSで管理者モードのcmdにキーを送るには?

お世話になります。
業務上の必要に迫られているため、質問させて頂きます。
恐縮ですが、ご存じの方、御教示頂けますでしょぅか?

VBSでコマンドプロンプトを管理者モードで起動し、かつ、Robocopyコマンドをキー入力送信するVBSを作成したいのですが、上手く動きません。

※コピーしたいのは、HOSTSファイルで、コマンドプロンプトで手入力すると正常に動作しますが、バッチファイル(.bat)に記述すると「アクセスが拒否されました」が発生するため、VBSでコマンドプロンプト上にキーを入力させたいというのが、主旨です。


以下スクリプトを記述しますが、解決策をご存じの方、教えて頂けないでしょうか?
※c:\temp\hostsにおいたものをコピーさせることにしています。

-------------------
// 管理者モードでコマンドプロンプト起動
Set obj = Wscript.CreateObject("Shell.Application")
obj.ShellExecute "cmd.exe", "/k", "", "runas", 1


//robocopy 入力

Set objShell = WScript.CreateObject("WScript.Shell")
WScript.Sleep 3000
objShell.SendKeys "robocopy /copy:DT /ZB /R:100 /W:2 /is /xjf c:\temp\hosts c:\windows\system32\drivers\etc hosts"
objShell.SendKeys "{ENTER}"
-------------------

■実行結果:コマンドプロンプトは管理者モードで起動するが、文字は入力されない。

恐れ入りますが、何卒よろしくお願いいたします。

投稿日時 - 2016-11-09 08:41:38

QNo.9253395

すぐに回答ほしいです

質問者が選んだベストアンサー

管理者権限のないプログラムから
管理者権限のあるプログラムを操作することは
セキュリティ上の問題があるのでできません。

なので、VBS自体も管理者権限で実行しないとキーは送れません。
-------------------
Option Explicit

Sub runasCheck()
Dim objWMI, osInfo, objShell, os
Dim args
Set args = WScript.Arguments

If args.Count > 0 Then
If UCase(args.item(0)) = "/RUNAS" Then
Exit Sub
End If
End If

Set objShell = CreateObject("Shell.Application")
objShell.ShellExecute "wscript.exe", """" & WScript.ScriptFullName & """" & " /RUNAS", "", "runas", 1
Wscript.Quit
End Sub

'管理者権限付きで自分自身を実行し直す
call runasCheck()


Dim s
Set s = CreateObject("Shell.Application")
s.ShellExecute "cmd.exe", "", "", "runas", 1

Dim w
Set w = CreateObject("WScript.Shell")
WScript.Sleep(1000)
w.SendKeys "copy /y c:\temp\hosts C:\Windows\System32\drivers\etc\hosts"
w.SendKeys "{Enter}"
Set s = Nothing
Set w = Nothing
-------------------

ただ、私の環境(Windows 10)だとcopyコマンドによるhostsのコピーは失敗しました。
あらかじめ管理者権限で起動しておいたコマンドプロンプトにsendkeysすると成功し。
VBSから管理者権限で起動したコマンドプロンプトに手入力は失敗したので、
VBSから起動したコマンドプロンプトでは駄目なのかもしれません。

VBSからコマンドプロンプトを起動すると32ビット版cmd.exeが起動するのが問題なのかと思い
64ビット版の C:\Windows\sysnative\cmd.exe を代わりに指定してもダメでした。

投稿日時 - 2016-11-12 18:16:27

お礼

ご回答ありがとうございます。

VBS自体を管理者権限で起動するというのは、完全に盲点でした。
聞けば確かに仰るとおりと思いますが、ここに意識が働かず、袋小路に迷い込んでおりました。

頂いたソースでWindows7の自機で行ったところ、意図通りに動きました。
私がやりたかったことを全て実現して頂きありがとうございました。
(パスまで私の環境まで合わせて頂きありがとうございます)

投稿日時 - 2016-11-14 09:04:34

このQ&Aは役に立ちましたか?

0人が「このQ&Aが役に立った」と投票しています

回答(7)

ANo.7

SendKeysはOSに対してキーボードに見せかけてるわけではないので
管理者権限を持ってないプロセスから管理者権限を持つウィンドウへのSendkeysは
普通にUACに止められます。

hostsファイルを上書きコピーで置き換えたいだけならcmdを経由せずに
以下のように直接コピープログラムを起動するのではだめですか?

Set obj = Wscript.CreateObject("Shell.Application")
obj.ShellExecute "xcopy.exe", "/Y d:\hosts C:\Windows\System32\drivers\etc", "", "runas", 1

投稿日時 - 2016-11-13 01:31:51

補足

ご回答ありがとうございます。
コピーさせるだけならご回答内容で良いのですが、いくつかコピー後に実行したいこともあるため、type出来るようにしたいという意図がありました。
参考にさせて頂きます。

投稿日時 - 2016-11-14 09:00:25

ANo.5

今、私なりに実験してみましたが、

Set s = CreateObject("Shell.Application")
s.ShellExecute "cmd.exe"
Set w = CreateObject("WScript.Shell")
WScript.Sleep(1000)
w.SendKeys "Dir"
w.SendKeys "{Enter}"
Set s = Nothing
Set w = Nothing

ですと、ちゃんと「Dir」が実行されました。

Set obj = Wscript.CreateObject("Shell.Application")

の「WScript」や

Set objShell = WScript.CreateObject("WScript.Shell")

の「WScirpt」が不要なのではないでしょうか?

ちなみに、「"Dir" & "{Enter}"」でも実行されました。

投稿日時 - 2016-11-10 10:32:02

補足

ご回答ありがとうございます。
確かに管理者権限でないコマンドプロンプトだとこれで出来るようです。
試しに、管理者権限でコマンドプロンプト起動vbsでさせてみましたが、結果はTypeされませんでした。


------
Set s = CreateObject("Shell.Application")
s.ShellExecute "cmd.exe", "/k", "", "runas", 0

Set w = CreateObject("WScript.Shell")
WScript.Sleep(1000)
w.SendKeys "Dir"
w.SendKeys "{Enter}"
Set s = Nothing
Set w = Nothing
-----
結果:コマンドプロンプトは管理者で起動するが、文字はやはり入力されない。

投稿日時 - 2016-11-11 17:51:12

ANo.4

>※コピーしたいのは、HOSTSファイルで、・・・

hostsファイルは普通に読み書きできますので、
コピーするだけなら、普通のコマンドでいいです。
例:下記のcphosts.batを実行すればc:\mybatフォルダにhostsがコピーされます。
copy C:\Windows\System32\drivers\etc\hosts c:\mybat

投稿日時 - 2016-11-09 17:18:23

補足

スミマセン。質問文が良くなかったです。
要はやりたいのはHostsの書き換えなのです。
(上記文の場合、C:\temp\hosts\hostsをC:\Windows\System32\drivers\etc\にコピー)
C:\Windows\System32\drivers\etc\hosts を別のフォルダにコピーが出来ることは理解しています。

ところが、単純にcmdを立ち上げてコマンドでコピーすると書き込み不能に陥り、管理者モードでcmd起動してコマンド入力すればコピーされるが、BATファイルを読み込ませるとなぜかコピーされない、という現象に陥ったのです(おそらく環境によるもの)
このため、ややこしいですが、管理者モードでcmd起動してvbsでキーパンチさせたいというのが趣旨になります。

投稿日時 - 2016-11-10 09:33:04

ANo.3

--- runas.bat ---
@echo off
powershell.exe -Command Start-Process """hostscpy.bat""" -Verb Runas

--- hostscpy.bat ---
@echo off
copy c:\temp\hosts c:\windows\system32\drivers\etc\

上記のように2つのバッチファイルを作成し、runas.batをダブルクリック(またはVBSで起動)すれば良い。

なお、hostscpy.batを右クリックして「管理者として実行」を選んでも良い。

投稿日時 - 2016-11-09 10:34:40

補足

ご回答ありがとうございます。
PowerShellから管理者で起動させる方法ですね。
実は、試したのですが、環境のせいか、バッチで組むと「アクセス拒否」が出てしまい、コマンド手入力だと実行完了する、という現象に苛まれています。

このため、VBSで管理者モードでcmdを起動してキーを入力させるという方法を模索しています。
何か良い知恵がございましたら、御教示下さい。

投稿日時 - 2016-11-09 12:28:41

ANo.2

sendkeyなんて使わなくても
その作ったバッチファイルをcmd.exeに渡せば良い気がします。

obj.ShellExecute "cmd.exe", "/k call ""C:test.bat""", "", "runas", 1

コマンドが1つだけなら、/kか/cオプションの引数に直にコマンドを書いても良いですね。

投稿日時 - 2016-11-09 09:19:15

補足

ご回答ありがとうございます。
理者モードでcmdを起動してバッチ実行すると拒否されるのですが、管理者モードでcmd起動後、コマンドを手入力すると実行されるので、キー入力の方法を探っています。

"/k call ""C:test.bat"""

の部分を参考にしたいと思いますが、キー入力の方法があれば御教示下さい。

投稿日時 - 2016-11-09 11:45:26

ANo.1

VBスクリプト 管理者権限
このキーワードで検索すると、
関連する情報がヒットします。ご確認ください。



以下は別の方法のご案内です。

タスクスケジューラを挟むと、
管理者権限は与えやすいです。
まずタスクスケジューラで新規タスクを作成し、
管理者での実行をオンにします。
そしてバッチファイルなどを指定しておきます。

SchTasksコマンドでタスクスケジューラの制御。
https://technet.microsoft.com/ja-jp/windows/ff467963.aspx

VBスクリプトからはSchTasksでタスクを実行するだけです。

もしVBスクリプトから引数を渡したいなら、
タスクに指定したバッチファイルを
スクリプトから編集することで対応はできると思います。

投稿日時 - 2016-11-09 09:18:01

補足

ご回答ありがとうございます。
各PC毎にユーザーに実行してもらうことを想定しているため、タスクスケジューラーでの実行は考えていませんでした。
要は、HOSTSを書き換えたいのですが、単純にcmdを起動してコピーコマンドやECHOコマンドだと、拒否させてしまいます。
(環境のせいとは思いますが、管理者モードでcmdを起動してバッチ実行すると拒否されるが、管理者モードでcmd起動後、コマンドを手入力すると実行される)
このため、回りくどい方法を取っています。

投稿日時 - 2016-11-09 11:43:40

あなたにオススメの質問