應用在Windows系統中的自動化部署實踐


  因為公司的產品有linux 和windows兩套部署環境,領導安排我先來做windows的自動化部署。由於本人對windows 的dos命令基本沒啥概念,所以在最終完成之前,走了很多彎路,在這里記載下來,希望能夠對看到這篇文章的人,有所幫助。

  好了,廢話少說,直接上步驟。

  Background :

  開發給過來的就是一個server.jar,雙擊server.jar,可以選擇安裝路徑,選擇licence,並最終安裝完成。安裝完成之后還需要做三個配置:

    配置1):配置數據庫信息 [在Dos窗口打開安裝目錄下的DBconnection.bat,輸入相應數據庫信息,輸入完畢以后會自動測試是否鏈接成功]

    配置2):升級數據庫 [如果數據庫和產品的version不一致,則需要執行dbupgrade.bat]

    配置3):修改Run.bat中的某些參數

  部署架構圖:[從Host 部署到 各個 slave中去]

  

  我的想法是這樣的:

  首先在Host 機器上手工執行server.jar並安裝到某個目錄,比如 C:\programs\baseDir\,然后把baseDir 復制到 各個slave機器【怎么復制過去讓我吃了不少苦頭】上去,當然復制之前會做好各種配置,最后通過host調用slave上的某個東東去執行已經復制過去的run.bat.【這里的 “某個東東”讓我破費周折,呵呵,這是后話,暫且按下不表

  本地配置這里就不詳細描述了,主要是用VBS調用Bat,如果bat需要交互的話,就用Wscript.SendKeys。

  這里主要說一下我碰到的兩個難題。

  難題一:把文件夾復制到Slave機器上去:

  經過摸索,我發現dos有一個命令,Xcopy,是一個非常強大的拷貝命令,支持本地和遠程拷貝,當然拷貝的時候還包含子目錄和子文件夾,比如我現在想把 C:\programs\baseDir 這個文件夾拷貝到遠程機器上去,可以用如下命令:

   1 xcopy c:\programs\baseDir \\RemoteIp\remotefolder\ 

  但是這樣做,有一個前提,是 RemoteIp所對應的機器需要把 remotefolder設置為共享,並且允許可寫,如果每次都復制到這個目錄還好,如果我臨時想換一個目錄,那么又要新建一個目錄,並設置共享,這 “顯然不美” (最近在看《測試之美》,呵呵,只有美的東西才容易被別人喜歡,比如美女),所以我換了一種方式,直接xcopy 到Remote機器上的根目錄,比如如下所示:

   1 xcopy c:\programs\baseDir \\RemoteIp\c$\dirA\dirB\ 

  這樣只需要知道對方的IP,至少一個盤符(比如C盤,就用C$),那么就可以復制到任意文件夾下面,xcopy如果檢測到在相應盤符下面沒有文件夾,會自動創建,但是如果直接執行這個命令的話,很有可能會碰到如下提示:

   1 Access Is Dennied 

  除了這個提示以外,沒有任何其它提示,在此表示微軟的bug report封裝的太厲害了,經過苦苦搜索,終於解決了這個問題,Xcopy如果直接拷貝到對方絕對路徑,需要先授權,在這里授權 用 net use 命令:(如果 不熟悉此命令,可以在Dos窗口 輸入 net use /? 來看說明)

   1 Net use \\RemoteIp\Admin$ password /user:username 

  注意這里的Admin$,這個應該是windows的默認共享,選中computer--右鍵 manage--System Tools --Share Folders--Shares 可以看得到,

如果這里不加Admin$的話,可能會提示:

  

1 Invalid drive specification
2 0 File(s) copied

 

執行net use之后,dos窗口應該有提示:

   1 The command completed successfully. 

  此時再執行xcopy應該就沒有問題了,如果不是successfully,而仍然是 Access Is Dennied,那么可能和 “簡單文件共享” 有關,試試下面這個神器吧:

  MicrosoftFixit50053.msi

  下載鏈接 : http://support.microsoft.com/kb/307874/zh-cn

把這個文件在相關機器上都執行一遍,此時在  net use,再 xcopy ,OK了

!!!!!收工!!!!!!!

  難題二 :現在把所有的文件都拷貝到遠程機器上去了,那么怎么啟動呢?

  策略1)因為啟動文件是一個Bat文件,我最先想到的是利用telnet命令,並暗自竊喜,原來一切都這么簡單。。,但是很快發現 telnet消耗的是本地資源,我啟動一個應用都至少消耗1.5G的內存,我要同時啟動那么多機器,用telnet的方式全部消耗本地資源,顯然不現實。

  策略2)放棄telent,轉而把目光投向遠程服務,我在host機器上向slave機器發起一個命令,在slave機器上創建一個服務,用這個服務去調用對應的 bat文件,想法很好,但是很快被一個錯誤打擊了,沒找到解決方案,具體是什么錯誤忘記了。。。

  策略3)再研究,發現 schtasks 這玩意是個好東西,可以利用host發送schtasks命令在slave機器上創建服務,然后還可以隨時啟動服務和停止服務,為了盡可能的不要讓任務自己運行,而是在收到我指令的時候才運行,我把這個任務設置成每12個月運行一次。。。

   1 schtasks /create /S RemoteIp /u admin /p password /sc monthly /mo 12 /tn TaskName /tr C:\dirA\dirB\Slave1Run.bat /F 

  此時會顯示創建成功,然后去觸發這個任務

   1 schtasks /Run /S RemoteIp /u username /p password /tn taskname 

  然后在遠程win7機器上也運行了,可以看到界面,然而,當Win7 向 Win Xp 發起請求的時候,Access is dennied 又出來了。。。搜遍中外網站 (國外網站請用goagent,你懂的),最后在微硬的社區發現這樣一段話:

  

I suspect you are running from/To Win7/Vista to XP

 

 

 

SchTasks.exe are not the same between these systems and it won't work. It took me a while to figure it out.

 

  好吧,Schtasks 你好,Schtasks 再見。

  策略4)繼續搜。。,最后搜到一個神器 psexec

  下載地址:http://technet.microsoft.com/en-us/sysinternals/bb897553.aspx

  Utilities like Telnet and remote control programs like Symantec's PC Anywhere let you execute programs on remote systems, but they can be a pain to set up and require that you install client software on the remote systems that you wish to access. PsExec is a light-weight telnet-replacement that lets you execute processes on other systems, complete with full interactivity for console applications, without having to manually install client software. PsExec's most powerful uses include launching interactive command-prompts on remote systems and remote-enabling tools like IpConfig that otherwise do not have the ability to show information about remote systems.

   好吧,死馬當活馬醫,立即嘗試!,把psexec配置好以后,執行以下命令:

   1 psexec \\RemoteIp -u username -p password -i -d c:\dirA\Run.bat 

發現在有的機器上成功,有的機器上顯示Access is dennied。。。看來微硬對這個log很喜歡啊。。,此時再次搬出之前的神器MicrosoftFixit50053.msi

  參看URL :

    http://forum.sysinternals.com/topic15919.html

    http://davidchuprogramming.blogspot.com/2009/12/psexecexe-access-denied.html

  執行完以后,啟動成功!

!!!!!收工!!!!!!!

 

最后,附加幾個VBS方法,May be helpful or not。

獲取系統中正在運行的cmd.exe的個數:

 1 '================================================================================
 2 'Function Name : CountNumberOfCMD
 3 'Summary : 
 4 '    Count All cmd processes in system
 5 '===================================================================================
 6 Function CountNumberOfCMD()
 7     Dim objWMIService, processItems, processName
 8     processName = "cmd.exe"
 9     Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
10     Set processItems = objWMIService.ExecQuery("Select * from Win32_Process where Name='"  & processName & "'")
11     CountNumberOfCMD = processItems.Count
12 End Function

獲取當前位置:

 1 '==========================================================================
 2 'Function Name: GetTestDataFileAbsolutePath
 3 'Summary: Get The Config Excel's Absolute Path
 4 '==========================================================================
 5 Function GetTestDataFileAbsolutePath()
 6     Dim ws    
 7     set ws=CreateObject("Scripting.FileSystemObject") 
 8     GetTestDataFileAbsolutePath = ws.GetFile(Wscript.ScriptFullName).ParentFolder.Path & "\Config\Config.xls"
 9     'GetTestDataFileAbsolutePath = "C:\AD\Config\Config.xls"
10     Set ws = Nothing
11 End Function

打開一個excel

1 '===========================================================================
2 'Function Name: openExcel
3 'Summary: Open Excel File
4 '===========================================================================
5 Function openExcel()
6     Set xlsApp = CreateObject("Excel.Application") '創建Excel對象
7     xlsApp.Visible = False 'true 為顯示excel對象,false為不顯示
8     Set xlsWorkBook = xlsApp.Workbooks.Open (GetTestDataFileAbsolutePath()) '打開指定路徑的Excel表格
9 End Function

關閉excel

Function closeExcel()
    xlsWorkBook.Close
    xlsApp.Quit
    Set RowCount = Nothing
    Set xlsSheet = Nothing
    Set xlsWorkBook = Nothing '釋放內存
    Set xlsApp = Nothing  '釋放Excel對象    
End Function

VBS 調用Dos命令

 1 '===============================================================================
 2 'Name: NetUseToSlave
 3 'Summary: Net use to slave to get the cotrol privilege
 4 '
 5 '================================================================================
 6 Function NetUseToSlave(ObjSlave)
 7     
 8     Dim oShell
 9     Set oShell = CreateObject("WScript.Shell")
10     oShell.Run ("%comspec% /c " & "NET USE \\" & ObjSlave.SlaveIp &"\Admin$ /delete /yes"),1,True
11     WScript.Sleep(2000)
12     oShell.Run ("%comspec% /c " & "NET USE \\" & ObjSlave.SlaveIp & "\Admin$ " & Passowrd &" /user:" & Username),1,True
13     WScript.Sleep(1000)
14     Set oShell = Nothing
15     
16 End Function

vbs判斷文件是否存在:

 1 '======================================================================
 2 'Function Name:CheckFileExists
 3 'Summary: Check file exists or not
 4 'FolderPath: Absolute path, as D:\server\bin\db.log
 5 '=====================================================================
 6 Function CheckFileExists(FilePath)
 7     Dim fso
 8     set fso=createobject("scripting.filesystemobject") 
 9     if fso.FileExists(FilePath) then
10        CheckFileExists = True
11     else 
12        CheckFileExists = False
13     end If
14     Set fso =Nothing
15 End Function 

vbs判斷文件夾是否存在:

'======================================================================
'Function Name:CheckFolderExists
'Summary: Check folder exists or not
'FolderPath: Absolute path, as c:\dir
'=====================================================================
Function CheckFolderExists(FolderPath)
    Dim fso
    set fso=createobject("scripting.filesystemobject") 
    if fso.FolderExists(FolderPath) then
       CheckFolderExists = True
    else 
        CheckFolderExists = False
    end If
    Set fso =Nothing
End Function 

vbs正則修改文件內容

Function ModifyLaunch(slave)
    
    Dim FileName,FS, FileStream,OutStream,FileContents,RFileContensts
    FileName = slave.CopyFromDir & "\bin\launch.bat"
    Set FS = CreateObject("Scripting.FileSystemObject")   
    on error resume Next   
    Set FileStream = FS.OpenTextFile(FileName)   
    FileContents = FileStream.ReadAll

    'Sub1 : replace Ip
    Dim regEx
    Set regEx = New RegExp 
    
    regEx.Pattern = "1.7.7.\d+"
    RFileContensts = regEx.Replace(FileContents,"228.7.7." & Split(slave.SlaveIp,".")(3))
    
    on error resume Next
    Set OutStream = FS.OpenTextFile(FileName, 2, True)   
    OutStream.Write RFileContensts
    
    Set FS = Nothing 
    Set FileStream = Nothing 
    Set OutStream = Nothing
    
End Function

 

Dim xlsApp,xlsWorkBook,xlsSheet
Dim RowCount
Dim excelpath : excelpath = "D:\CollineAutomation\trunk\Config\TestSuites.xls"
Dim arr : arr = Array("2868","3600","3609","4669","4671","4672","4673","4996","5131","5132","6151","6202","6220","6221","6232","6271","6419","6594","6603","6623","6644","6660","6664","6698","6712","6714","6715","6716","6717","6718","6781","6886","6887","6895","7011","7128","7131","7132","7133","7135","7140","7155","7396","7397","7398","7399","7400","7408","7899","7908","7912","14502","14504","14509","14517","14584","14589","14802","14846","14847","14863","14865","20366","20578","20850","20900","20970","23466","23470","3602","4591","4753","4793","4909","4974","5160","6183","6289","6290","6341","6417","6418","6448","6543","6545","6546","6547","6548","6549","6604","6607","6608","6609","6624","6625","6662","6663","6691","6734","6882","6898","6940","6957","6958","6959","7043","7130","7139","7165","7338","7339","7342","7351","7401","7581","7582","7693","14498","14499","14501","14516","14810","14831","14833","14857","16413","16414","19532","20204","20527","20528","20530","23474","23477","23481","23487","23492","6120","6174","6175","6237","6305","6306","6326","6327","6343","6380","6551","6571","6572","6635","6897","6941","6942","7102","7107","7141","7164","7340","7343","7348","7402","7409","7654","7656","7658","7679","7898","7939","7941","14505","14513","14514","14515","14585","14586","14587","14588","14792","14793","14796","14797","14798","14799","14800","14845","14855","14856","14858","14860","14861","14894","14895","14896","16420","16421","20199","20533","20556","23459","23461","3611","4675","4792","4825","6236","6286","6588","6638","6701","6702","6729","6767","6864","7158","7160","7161","7346","7660","7662","7663","7680","7897","7977","14506","14511","14512","14790","14791","14795","14851","20538","20539","20856","23454","23462","23464","23489","23493","23573","6763","6764","6748","6766")


Set xlsApp = CreateObject("Excel.Application") '創建Excel對象
xlsApp.Visible = False 'true 為顯示excel對象,false為不顯示
Set xlsWorkBook = xlsApp.Workbooks.Open (excelpath) '打開指定路徑的Excel表格
Set xlsSheet = xlsWorkBook.Sheets("TestCases") '選擇指定Sheet
RowCount = xlsSheet.usedRange.Rows.Count '獲取sheet中有內容的Rowcount行數
 

Dim caseId

For j=0 To UBound(arr)
    caseId = arr(j)
    For i = 2 To RowCount
        Dim TESTCASEID
        TESTCASEID = Trim(xlsSheet.cells(i,4))
        If InStr(TESTCASEID, caseId) = 1 Then
            xlsSheet.cells(i,7) = "Expired"
        End If
        
    Next
Next

xlsWorkBook.Save

xlsWorkBook.Close
xlsApp.Quit
Set RowCount = Nothing
Set xlsSheet = Nothing
Set xlsWorkBook = Nothing
Set xlsApp = Nothing

 

  


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM