Ok, 接下來,來記錄一下過去這一個多月來坎苛的 RDP 服務串接歷程好了
首先,先來說明一下什麼是 RDP 服務串接
這名詞其實是我自已創造的,並不是某種 MS 的功能,請千萬別誤會了
這個 “服務” 的功用是
用來幫我上傳檔案到遠端某台主機上
- 東西要 go prod ,要先把檔案放上 某台主機上
- 只能用 windows RDP 的協定來傳輸檔案(FTP、http(s)、rsync 什麼的就都別想了)
- 有很多 RD 要上 code
這樣聽起來只要能建立起 RDP ,再把本機的資料夾 mount 上去,不就可以了吧
這樣說絕對沒錯!!
只是會出現下一個問題
我必需為每一個要上 code 的 RD 都申請一個帳號(不允許使用 domain name account)
但基於安全性考量,我並不想這麼做,再加上主機又不是我在管的
萬一被人玩壞就慘了
so 第一個 solution 出現
我自已有養個 ci-bot (hubot) 並放在公司 internal 的主機上
- 先把 RDP 連線存成檔案,並設好要 mount 的資料夾
寫個小script,讓我可以直接對 bot 下命令去打開這個遠端主機連線檔
12345678command = "mstsc \\path\\to\\file.rdp"@exec = require('child_process').exec@exec command, (error, stdout, stderr) ->if stderrreturn "ERROR (stderr): " + stderrif errorreturn "ERROR (error)" + errorreturn "更新完成 #{stdout}"開啟後直接執行 遠端主機上的某個 bat,直接開始 copy
到此為止,我感覺這世界是美好的

但美好的時光總是過的特快
某天被通知,prod 的主機群發現勒索病毒,且受災程度不小
在重建遠端主機後,我的惡夢就來了
為了怕再次重演這樣的事情
start program on connection 被禁止了….
新的 遠端主機不再允許連線時去執行 explorer.exe 以外的程式
也就是說只能開桌面了
wtf…..
在消沉了好幾天後,開始找其他的 solution
好吧!! 現在不能用自動執行 bat(copy)
那我用 手動 總行了吧
這下找上了 autoit (坑坑坑…)
ok 新的方案
- bot 收到指令後不再跑原生的 mstsc ,而是跑自已寫的 autoit script
再來用 auotit 寫個小的 exe 檔,這會開啟 rdp 的 file 並建立連線
1mstsc \\path\\to\\file.rdp等 rdp window 起來後,對遠端的主機送出 keyboard command
1run some bat file視窗關閉後,開始分析 copy log 並回傳結果
好啦!! 初步的 autoit script 很簡單
- auto_run_rdp_script.au31234567891011121314151617181920212223doLog("開始跑 rdp")RUN_MSTSC()Func RUN_MSTSC()Run("MSTSC.EXE .\file.RDP"); Wait 10 seconds for the Notepad window to appear.Local $hWnd = WinWaitActive("[CLASS:TscShellContainerClass]")If Not WinActivate($hWnd ) Then WinActivate($hWnd )doLog("等待連接中....")Sleep(10000)WinActivate($hWnd )doLog("送出指令....")Send($hWnd, "", "", "#r")Sleep(1000);WinActivate($hWnd )Send($hWnd, "", "", "copy.bat")Sleep(1000);Send($hWnd, "", "", "{ENTER}")EndFunc
script 很陽春,但卡在對 autoit 的不熟悉
接下來不停的遇到的問題 就是
- rdp 的 window 沒有取到 focus 造成 command 送不進去….
- 在主機沒有人連線的狀況下,RDP 的 window 無法 active ,造成後面的流程跑不下去
好吧… 但事情總是要解決
先來處理第一個問題
- rdp 的 window 沒有取到 focus
本來解決這個我是想用 WinWaitActive 這個函數來處理
等到 window active 後再來做下面的動作
但沒想到,卻因此產生第二個問題 - 非視窗模式下,WinWaitActive 不會有反應………
這可能是 window 的機制,這個我到是能了解
但這下我就只能回到最最最土砲的方式來做…
|
|
其實重點只有兩個
先還原主機的桌面
1Send("#d")把 WinWaitActive 改用 WinWait ,讓他不會受限於 window 沒有 active
但我想這應該還是會有不少問題….
只能見招拆招了