
まず、基本的な事項をいくつか説明します。
- サービス ServiceA として実行されるデータベース サーバー アプリケーションを実行しています。
- ServiceAはServer1とServer2にインストールされています
- ServiceA は、一度に 2 つのサーバーのうちの 1 つでのみ実行されます (これらは冗長サーバーであり、1 つのサーバーに障害が発生した場合、もう 1 つのサーバーの ServiceA が自動的に起動します)。
- コードServiceAを制御できません
- ServiceAはローカルシステムアカウントとしてログオンします
- ServiceBはServer1とServer2の両方で実行する必要がある
- ServiceBはローカルシステムアカウントとしてログオンします
- ServiceAデータベースに構成オブジェクトを作成できます。オブジェクトの1つのタイプは、ServiceAが実行するスクリプト言語のようなものです。
- スクリプト言語には、ローカルシステム上でのファイル操作やコマンドの実行を可能にする関数(OPEN_FILE()、WRITE_FILE()、CLOSE_FILE()、SYSTEM())があります。
- これらのコマンドを実行すると、ローカルシステムアカウントの資格情報を使用して実行されます。
- ServiceAは上記のファイル操作コマンドを使用してServiceBの設定ファイルを生成します。
- 新しい構成ファイルを作成する前に、ServiceB をシャットダウンする必要があります (実際には、一時フォルダーに構成ファイルを作成し、ServiceB をシャットダウンしてファイルをコピーし、ServiceB を起動します)
- Server1とServer2はどちらもWindows 7 Enterpriseです
- Server1とServer2は両方とも同じドメインにあります
ServiceA に次のことを実行させようとしています:
- Server1とServer2の両方でServiceBをシャットダウンします。
- いくつかのファイルをServer1とServer2にコピーする
- Server1とServer2の両方でServiceBを起動します。
私がしたこと:
- パスワード (PasswordZ) を持つドメイン アカウント (DomainX/UserY) を作成しました
- 両方のサーバーに共有を作成しました (ShareW)
- 両方のサーバーでShareWにアクセスするためのDomainX/UserY権限を付与
- OPEN_FILE()、WRITE_FILE()、CLOSE_FILE() を使用して INSTALL.BAT ファイルを作成しました
- SYSTEM('C:\Temp\INSTALL.BAT >> C:\Temp\INSTALL.LOG 2>&1') を使用して INSTALL.BAT (ローカル システムとしてサービス A によって実行) を実行し、デバッグ ログを作成しました。
BATファイル内で機能するもの
NET USE \\Server1\ShareW PasswordZ /USER:DomainX/UserY
NET USE \\Server2\ShareW PasswordZ /USER:DomainX/UserY
DEL /F /Q "\\Server1\ShareW\*.*
DEL /F /Q "\\Server2\ShareW\*.*
XCOPY /Y "C:\Temp\*.*" "\\Server1\ShareW\"
XCOPY /Y "C:\Temp\*.*" "\\Server2\ShareW\"
NET USE \\Server1\ShareW /DELETE
NET USE \\Server2\ShareW /DELETE
共有と権限が正しく設定されている
私の問題は、INSTALL.BAT内からサービスBを停止および開始しようとしていることです。
私が試してみました:
NET USE \\Server1\IPC$ PasswordZ /USER:DomainX/UserY
SC \\Server1 STOP "Service B"
NET USE \\Server1\IPC$ /DELETE
NET USE \\Server2\IPC$ PasswordZ /USER:DomainX/UserY
SC \\Server2 STOP "Service B"
NET USE \\Server2\IPC$ /DELETE
SC コマンドはローカル マシンでは機能しますが、リモート マシンでは失敗します。これは、Server2 で実行されている INSTALL.BAT からの出力です。
C:\Windows\system32>NET USE \\Server1\IPC$ PasswordZ /USER:DomainX/UserY
The command completed successfully.
C:\Windows\system32>SC \\Server1 STOP ServiceB
[SC] OpenService FAILED 5:
Access is denied.
(Server1 と Server2 で ServiceA を実行してみましたが、結果は同じでした。ローカルでは動作しますが、リモートでは失敗します)
「別のユーザーとして実行」を使用して CMD.EXE を DomainX/UserY として実行すると、SC コマンドは完全に機能します。したがって、Server2 で、CMD.EXE から DomainX/UserY として INSTALL.BAT を実行すると、次のようになります。
C:\Temp>NET USE \\Server1\IPC$ PasswordZ /USER:DomainX/UserY
The command completed successfully.
C:\Temp>SC \\Server1 START ServiceB
SERVICE_NAME: ServiceB
TYPE : 110 WIN32_OWN_PROCESS (interactive)
STATE : 2 START_PENDING
(NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
WIN32_EXIT_CODE : 0 (0x0)
SERVICE_EXIT_CODE : 0 (0x0)
CHECKPOINT : 0x1
WAIT_HINT : 0xbb8
PID : 4856
FLAGS :
したがって、DomainX/UserY には、リモート サーバー上のサービスを停止および開始するために必要な権限があります。これは、ローカル システム アカウントからの権限昇格を何らかの方法でブロックしているように見えます。
HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System\ の LocalAccountTokenFilterPolicy を 1 に設定して再起動するという方法を読んだことがあります。これを実行しましたが、結果は変わりませんでした。
psservice.exe を使用してみましたが、実質的に同じ結果でした (Server2 の ServiceA によって実行された INSTALL.BAT からの出力)
C:\Windows\system32>C:\Utilities\psservice.exe \\Server1 -u DomainX/UserY -p PasswordZ -accepteula stop ServiceB
PsService v2.24 - Service information and configuration utility
Copyright (C) 2001-2010 Mark Russinovich
Sysinternals - www.sysinternals.com
Access is denied.
Access is denied.
Error querying services on Server1:
Error opening ServiceB on Server1:
次に、psexecを使用しようとしました(すべてのログをトラップするためにかなり複雑な方法で)
インストール2.BAT
C:\Utilities\psexec -accepteula -u DomainX/UserY -p PasswordZ C:\Temp\INSTALL3.BAT >> C:\Temp\INSTALL3.LOG 2>&1
インストール3.BAT
C:\Temp\INSTALL.BAT >> C:\Temp\INSTALL.LOG 2>&1
コマンドラインから INSTALL2.BAT を実行すると (DomainX/UserY として実行)、すべて正常に動作します。
しかし、ServiceA から実行すると、INSTALL3.LOG に次の内容が表示されます:
PsExec v2.11 - Execute processes remotely
Copyright (C) 2001-2014 Mark Russinovich
Sysinternals - www.sysinternals.com
Access is denied.
PsExec could not start C:\Temp\INSTALL3.BAT:
そこで、3 つの BAT ファイルすべてのセキュリティに、フル コントロールを持つ DomainX/UserY を明示的に追加しました。結果は同じでした (INSTALL3.LOG でアクセスが拒否されました)。
UACをオフにしてみましたが、目立った影響はありませんでした
それで、私は今かなり行き詰まっています - ローカル システムとして実行されているサービスによって BAT ファイルが実行され、別のユーザーになりすましてリモート マシン上のサービスを停止および開始できるようにするにはどうすればよいでしょうか?
答え1
答えは非常に簡単です。psexecの-hオプションを使用するのです。
ServiceA によって実行されるスクリプトの SYSTEM() コマンドは次のようになります。
C:\Utilities\psexec -accepteula -h -u DomainX/UserY -p PasswordZ C:\Temp\INSTALL.BAT >> C:\Temp\INSTALL.LOG 2>&1
完璧に動作します