免费版的VMWare ESXi 从v3.5 u3开始,禁止了SDK和vCli的“写”调用。


也就是说,从ESXi 3.5u3开始,我们不能用SDK或者vCLI命令行,控制免费版ESXi上运行的虚拟机了,不能对其进行重起,关机等任何“写”操作。


后来无意中在网上发现了一个叫esxi-control.pl的脚本,可以用来控制免费版ESXi上的虚拟机,地址如下


http://blog.peacon.co.uk/esxi-control-pl-script-vm-actions-on-free-licensed-esxi/



脚 本是用Perl写的,通过模拟vSphere Client发出的SOAP消息来控制ESXi.但是这个Perl脚本 仍然需要调用Perl-vCLI去获得虚拟机的id信息。我想既然能够模拟SOAP的控制消息,那也一定能模拟读取虚拟机信息的消息啊,但是平时用 Perl很少,所以干脆就用JAVA写了一个实现。



先说说程序的原理,


程序调用Apache的httpclient来完成SOAP消息的发送与接受。



$ $ PASSWORD$为ESXi主机的登陆用户名和密码


1. < soap:Envelope xmlns:xsd= "http://www.w3.org/2001/XMLSchema" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" > 
2. < soap:Body>
3. < Login xmlns= "urn:internalvim25" >
4. < _this xsi:type= "SessionManager" type= "SessionManager" serverGuid= "" > ha-sessionmgr< / _this>
5. < userName> $ USERNAME$< / userName>
6. < password> $ PASSWORD$< / password>
7. < locale> en_US< / locale>
8. < / Login>
9. < / soap:Body>
10. < / soap:Envelope>


第二步,获取当前已连接主机上的虚拟机列表,SOAP消息如下


    1. < soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd= "http://www.w3.org/2001/XMLSchema" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" > 
    2. < soapenv:Body>
    3. < RetrieveProperties xmlns= "urn:vim25" >
    4. < _this type= "PropertyCollector" > ha-property-collector< / _this>
    5. < specSet>
    6. < propSet>
    7. < type> HostSystem< / type>
    8. < all> 0< / all>
    9. < pathSet> vm< / pathSet>
    10. < / propSet>
    11. < objectSet>
    12. < obj type= "HostSystem" > ha-host< / obj>
    13. < / objectSet>
    14. < / specSet>
    15. < / RetrieveProperties>
    16. < / soapenv:Body>
    17. < / soapenv:Envelope>


    第 三步,第二步返回的消息里面只有虚拟机的ID,但是用户一般是不知道虚拟机的ID是干啥的,所以,我们需要虚拟机的名称等其它信息,所以发送下面的消息用 来获取虚拟机其它的信息,包括虚拟机的名称,虚拟机的网络名称,IP地址,开关机状态以及VMWareTool的运行情况。


    其中的$VMID$就是要获取具体信息的虚拟机ID


    可以有多个 <objectSet>,用来一次性获取多台虚拟机的信息


    1. < soapenv:Envelope xmlns:soapenv= "http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd= "http://www.w3.org/2001/XMLSchema" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" > 
    2. < soapenv:Body>
    3. < RetrieveProperties xmlns= "urn:vim25" >
    4. < _this type= "PropertyCollector" > ha-property-collector< / _this>
    5. < specSet>
    6. < propSet>
    7. < type> VirtualMachine< / type>
    8. < all> 0< / all>
    9. < pathSet> name< / pathSet>
    10. < pathSet> guest. hostName< / pathSet>
    11. < pathSet> runtime. powerState< / pathSet>
    12. < pathSet> guest. ipAddress< / pathSet>
    13. < pathSet> guest. toolsRunningStatus< / pathSet>
    14. < / propSet>
    15. < objectSet>
    16. < obj type= "VirtualMachine" > $ VM1ID$< / obj>
    17. < / objectSet>
    18. < objectSet>
    19. < obj type= "VirtualMachine" > $ VM2ID$< / obj>
    20. < / objectSet>
    21. < / specSet>
    22. < / RetrieveProperties>
    23. < / soapenv:Body>
    24. < / soapenv:Envelope>


    第四步,到这里,我们的准备工作就结束了,可以发送SOAP的控制消息,控制虚拟机的开关机/重起等操作了,这部分SOAP消息esxi-control.pl做得比较深入,值得借鉴。


    这里只举一个重起虚拟机的SOAP消息做例子, $VMID$就是要被重起的虚拟机的ID

    1. < soap:Envelope xmlns:xsd= "http://www.w3.org/2001/XMLSchema" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" > 
    2. < soap:Body>
    3. < ResetVM_Task xmlns= "urn:internalvim25" >
    4. < _this xsi:type= "VirtualMachine" type= "VirtualMachine" serverGuid= "" > $ VMID$< / _this>
    5. < / ResetVM_Task>
    6. < / soap:Body>
    7. < / soap:Envelope>

    第五步,断开连接

    1. < soap:Envelope xmlns:xsd= "http://www.w3.org/2001/XMLSchema" xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance" xmlns:soap= "http://schemas.xmlsoap.org/soap/envelope/" > 
    2. < soap:Body>
    3. < Logout xmlns= "urn:internalvim25" >
    4. < _this xsi:type= "ManagedObjectReference" type= "SessionManager" serverGuid= "" > ha-sessionmgr< / _this>
    5. < / Logout>
    6. < / soap:Body>
    7. < / soap:Envelope>

    JAVA实现代码如下

    1. package java_vc; 
    2. 
    3. /**
    4.   * 
    5.   * @author yyz_tj_cn@sina.com.cn 
    6.   */ 
    7. 
    8. import org . apache. http. Header;
    9. import org . apache. http. HttpEntity;
    10. import org . apache. http. HttpResponse;
    11. import org . apache. http. client. methods. HttpPost;
    12. import org . apache. http. impl. client. DefaultHttpClient;
    13. import org . apache. http. util . EntityUtils;
    14. import javax . net . ssl . SSLContext ;
    15. import org . apache. http. conn. ssl . SSLSocketFactory ;
    16. import javax . net . ssl . TrustManager ;
    17. import javax . net . ssl . X509TrustManager ;
    18. import java . security . cert . X509Certificate ;
    19. import java . security . cert . CertificateException ;
    20. import org . apache. http. conn. scheme. Scheme;
    21. import org . apache. http. entity . StringEntity;
    22. import org . apache. http. client. params . ClientPNames;
    23. import org . apache. http. client. params . CookiePolicy;
    24. import org . w3c . dom . Document ;
    25. import org . w3c . dom . NodeList ;
    26. import javax . xml . parsers . * ;
    27. import java . util . * ;
    28. 
    29. 
    30. public class Vmoperation {
    31. 
    32. //This Embeded Class is used to store Virtual Machine information
    33. public class Vminfo {
    34. private String id = null ;
    35. private String name = null ;
    36. private String networkName = null ;
    37. private String ipv4 = null ;
    38. private String powerState = null ;
    39. private String vmToolRunningSattus = null ;
    40. 
    41. public Vminfo( ) {
    42. 
    43. }
    44. public String getID ( ) {
    45. return id ;
    46. }
    47. public void setID ( String val) {
    48. id = val. trim ( ) ;
    49. }
    50. 
    51. public String getName ( ) {
    52. return name ;
    53. }
    54. public void setName ( String val) {
    55. name = val. trim ( ) ;
    56. }
    57. 
    58. public String getNetworkName( ) {
    59. return networkName;
    60. }
    61. public void setNetworkName( String val) {
    62. = val. trim ( ) ;
    63. }
    64. 
    65. public String getIpAddress( ) {
    66. return ipv4;
    67. }
    68. public void setIpAddress( String val) {
    69. = val. trim ( ) ;
    70. }
    71. 
    72. public String getPowerState( ) {
    73. return powerState;
    74. }
    75. public void setPowerState( String val) {
    76. = val. trim ( ) ;
    77. }
    78. 
    79. public String getVMToolRunningSattus( ) {
    80. return vmToolRunningSattus;
    81. }
    82. public void setVMToolRunningSattus( String val) {
    83. = val. trim ( ) ;
    84. }
    85. }
    86. 
    87. //Vmoperation Class start...
    88. private boolean debug = true;
    89. private boolean connected = false;
    90. private DefaultHttpClient httpclient = null ;
    91. private TrustManager easyTrustManager = null ;
    92. private ArrayList vmList = null ;
    93. private String hostURL = null ;
    94. private String xml_login = "<soap:Envelope xmlns:xsd=/"http://www.w3.org/2001/XMLSchema/" xmlns:xsi=/"http://www.w3.org/2001/XMLSchema-instance/" xmlns:soap=/"http://schemas.xmlsoap.org/soap/envelope//"> " +
    95. "<soap:Body>" +
    96. "<Login xmlns=/"urn:internalvim25/">" +
    97. "<_this xsi:type=/"SessionManager/" type=/"SessionManager/" serverGuid=/"/">ha-sessionmgr</_this>" +
    98. "<userName>$USERNAME$</userName>" +
    99. "<password>$PASSWORD$</password>" +
    100. "<locale>en_US</locale>" +
    101. "</Login>" +
    102. "</soap:Body>" +
    103. "</soap:Envelope>" ;
    104. private String xml_logout = "<soap:Envelope xmlns:xsd=/"http://www.w3.org/2001/XMLSchema/" xmlns:xsi=/"http://www.w3.org/2001/XMLSchema-instance/" xmlns:soap=/"http://schemas.xmlsoap.org/soap/envelope//">" +
    105. "<soap:Body>" +
    106. "<Logout xmlns=/"urn:internalvim25/">" +
    107. "<_this xsi:type=/"ManagedObjectReference/" type=/"SessionManager/" serverGuid=/"/">ha-sessionmgr</_this>" +
    108. "</Logout>" +
    109. "</soap:Body>" +
    110. "</soap:Envelope>" ;
    111. private String xml_poweroff = "<soap:Envelope xmlns:xsd=/"http://www.w3.org/2001/XMLSchema/" xmlns:xsi=/"http://www.w3.org/2001/XMLSchema-instance/" xmlns:soap=/"http://schemas.xmlsoap.org/soap/envelope//">" +
    112. "<soap:Body>" +
    113. "<PowerOffVM_Task xmlns=/"urn:internalvim25/">" +
    114. "<_this xsi:type=/"VirtualMachine/" type=/"VirtualMachine/" serverGuid=/"/">$VMID$</_this>" +
    115. "</PowerOffVM_Task>" +
    116. "</soap:Body>" +
    117. "</soap:Envelope>" ;
    118. private String xml_poweron = "<soap:Envelope xmlns:xsd=/"http://www.w3.org/2001/XMLSchema/" xmlns:xsi=/"http://www.w3.org/2001/XMLSchema-instance/" xmlns:soap=/"http://schemas.xmlsoap.org/soap/envelope//">" +
    119. "<soap:Body>" +
    120. "<PowerOnVM_Task xmlns=/"urn:internalvim25/">" +
    121. "<_this xsi:type=/"VirtualMachine/" type=/"VirtualMachine/" serverGuid=/"/">$VMID$</_this>" +
    122. "</PowerOnVM_Task>" +
    123. "</soap:Body>" +
    124. "</soap:Envelope>" ;
    125. private String xml_reset = "<soap:Envelope xmlns:xsd=/"http://www.w3.org/2001/XMLSchema/" xmlns:xsi=/"http://www.w3.org/2001/XMLSchema-instance/" xmlns:soap=/"http://schemas.xmlsoap.org/soap/envelope//">" +
    126. "<soap:Body>" +
    127. "<ResetVM_Task xmlns=/"urn:internalvim25/">" +
    128. "<_this xsi:type=/"VirtualMachine/" type=/"VirtualMachine/" serverGuid=/"/">$VMID$</_this>" +
    129. "</ResetVM_Task>" +
    130. "</soap:Body>" +
    131. "</soap:Envelope>" ;
    132. 
    133. private String xml_getVMIDs = "<soapenv:Envelope xmlns:soapenv=/"http://schemas.xmlsoap.org/soap/envelope//" xmlns:xsd=/"http://www.w3.org/2001/XMLSchema/" xmlns:xsi=/"http://www.w3.org/2001/XMLSchema-instance/">" +
    134. "<soapenv:Body>" +
    135. "<RetrieveProperties xmlns=/"urn:vim25/">" +
    136. "<_this type=/"PropertyCollector/">ha-property-collector</_this>" +
    137. "<specSet>" +
    138. "<propSet>" +
    139. "<type>HostSystem</type>" +
    140. "<all>0</all>" +
    141. "<pathSet>vm</pathSet>" +
    142. "</propSet>" +
    143. "<objectSet>" +
    144. "<obj type=/"HostSystem/">ha-host</obj>" +
    145. "</objectSet>" +
    146. "</specSet>" +
    147. "</RetrieveProperties>" +
    148. "</soapenv:Body>" +
    149. "</soapenv:Envelope>" ;
    150. 
    151. private String xml_getVMInfo = "<soapenv:Envelope xmlns:soapenv=/"http://schemas.xmlsoap.org/soap/envelope//" xmlns:xsd=/"http://www.w3.org/2001/XMLSchema/" xmlns:xsi=/"http://www.w3.org/2001/XMLSchema-instance/">" +
    152. "<soapenv:Body>" +
    153. "<RetrieveProperties xmlns=/"urn:vim25/">" +
    154. "<_this type=/"PropertyCollector/">ha-property-collector</_this>" +
    155. "<specSet>" +
    156. "<propSet>" +
    157. "<type>VirtualMachine</type>" +
    158. "<all>0</all>" +
    159. "<pathSet>name</pathSet>" +
    160. "<pathSet>guest.hostName</pathSet>" +
    161. "<pathSet>runtime.powerState</pathSet>" +
    162. "<pathSet>guest.ipAddress</pathSet>" +
    163. "<pathSet>guest.toolsRunningStatus</pathSet>" +
    164. "</propSet>" +
    165. "$VMIDLISTOBJ$" +
    166. "</specSet>" +
    167. "</RetrieveProperties>" +
    168. "</soapenv:Body>" +
    169. "</soapenv:Envelope>" ;
    170. 
    171.       
    172. //Connect to ESXi Host
    173. public String Connect ( String IPAddress, String Username, String Password) throws Exception {
    174. 
    175. //Clear previous connection, if any.
    176. if ( connected) {
    177. Disconnect ( ) ;
    178. ( ) ;
    179. }
    180. 
    181. ( "Connecting to host " + ip2URL( IPAddress) ) ;
    182. //Init new connection
    183. = ip2URL( IPAddress) ;
    184. = new DefaultHttpClient( ) ;
    185. //Init a customer X509TrustManager to trust any certificates
    186. = new X509TrustManager ( ) {
    187. Override
    188. public void checkClientTrusted (
    189. X509Certificate [ ] chain,
    190. String authType) throws CertificateException {
    191. // Oh, I am easy!
    192. }
    193. Override
    194. public void checkServerTrusted (
    195. X509Certificate [ ] chain,
    196. String authType) throws CertificateException {
    197. // Oh, I am easy!
    198. }
    199. Override
    200. public X509Certificate [ ] getAcceptedIssuers ( ) {
    201. return null ;
    202. }
    203. } ;
    204. 
    205. SSLContext sslcontext = SSLContext . getInstance ( "TLS" ) ;
    206. sslcontext . init ( null , new TrustManager [ ] { easyTrustManager } , null ) ;
    207. //Init SSLSocketFactory to accept any hostname and any certificates
    208. SSLSocketFactory sf = new SSLSocketFactory ( sslcontext , SSLSocketFactory . ALLOW_ALL_HOSTNAME_VERIFIER) ;
    209. = new Scheme( "https" , 443, sf) ;
    210. . getConnectionManager( ) . getSchemeRegistry( ) . register ( sch) ;
    211. . getParams ( ) . setParameter ( ClientPNames. COOKIE_POLICY, CookiePolicy. BROWSER_COMPATIBILITY) ;
    212. 
    213. //Send Hello Message
    214. = xml_login. replace ( "$USERNAME$" , Username) ;
    215. = xml_login. replace ( "$PASSWORD$" , Password) ;
    216. result ;
    217. result = sendXML( hostURL, xml_login) ;
    218. if ( debug) dispalyHttpResponse( result ) ; else EntityUtils. consume ( result . getEntity ( ) ) ;
    219. 
    220. //If not HTTP 200 returned, error occured.
    221. if ( result . getStatusLine( ) . toString ( ) . trim ( ) . equals ( "HTTP/1.1 200 OK" ) ) connected= true;
    222. 
    223. //Get Virtual Machine List
    224. if ( connected) vmList= getVMList( ) ;
    225.           
    226. //Return connect result
    227. return result . getStatusLine( ) . toString ( ) ;
    228. }
    229. 
    230. //disconnect from ESXi Host
    231. public String Disconnect ( ) throws Exception {
    232. String ret = null ;
    233. if ( debug) System . out. println ( "Disconnecting from host " + hostURL) ;
    234. if ( connected) {
    235. result = null ;
    236. result = sendXML( hostURL, xml_logout) ;
    237. if ( debug) dispalyHttpResponse( result ) ; else EntityUtils. consume ( result . getEntity ( ) ) ;
    238. //If not HTTP 200 returned, error occured.
    239. if ( result . getStatusLine( ) . toString ( ) . trim ( ) . equals ( "HTTP/1.1 200 OK" ) ) {
    240. ( ) ;
    241. }
    242. = result . getStatusLine( ) . toString ( ) ;
    243. }
    244. //Return connect result
    245. return ret;
    246. }
    247. 
    248. //Display Virtual Machine List on connected ESXi Host
    249. public void DisplayVMList ( ) {
    250. ( "Displaying Virtual Machine List..." ) ;
    251. //init Column Width
    252. int width1= 3, width2= 12, width3= 12, width4= 10, width5= 12, width6= 21;
    253. 
    254. if ( vmList ! = null ) {
    255. //Get Col width
    256. for ( int i= 0; i< vmList. size ( ) ; i+ + ) {
    257. = null ;
    258. = ( Vminfo) vmList. get ( i) ;
    259. if ( VMNode. getID ( ) ! = null ) width1 = Math . max ( VMNode. getID ( ) . length ( ) , width1) ;
    260. if ( VMNode. getName ( ) ! = null ) width2 = Math . max ( VMNode. getName ( ) . length ( ) , width2) ;
    261. if ( VMNode. getNetworkName( ) ! = null ) width3 = Math . max ( VMNode. getNetworkName( ) . length ( ) , width3) ;
    262. if ( VMNode. getIpAddress( ) ! = null ) width4 = Math . max ( VMNode. getIpAddress( ) . length ( ) , width4) ;
    263. if ( VMNode. getPowerState( ) ! = null ) width5 = Math . max ( VMNode. getPowerState( ) . length ( ) , width5) ;
    264. if ( VMNode. getVMToolRunningSattus( ) ! = null ) width6 = Math . max ( VMNode. getVMToolRunningSattus( ) . length ( ) , width6) ;
    265. }
    266. //Output Result
    267. //Title
    268. String title = "" ;
    269. + = formatData( "ID" , width1) ;
    270. + = formatData( "Machine Name" , width2) ;
    271. + = formatData( "Network Name" , width3) ;
    272. + = formatData( "IP Address" , width4) ;
    273. + = formatData( "Power Status" , width5) ;
    274. + = formatData( "VMTool running Status" , width6) ;
    275. + = "/n" ;
    276. for ( int i= 0; i< = width1+ width2+ width3+ width4+ width5+ width6+ 6; i+ + ) {
    277. + = "-" ;
    278. }
    279. System . out. println ( title) ;
    280. //Data
    281. for ( int i= 0; i< vmList. size ( ) ; i+ + ) {
    282. = null ;
    283. String output = "" ;
    284. = ( Vminfo) vmList. get ( i) ;
    285. output + = formatData( VMNode. getID ( ) , width1) ;
    286. output + = formatData( VMNode. getName ( ) , width2) ;
    287. output + = formatData( VMNode. getNetworkName( ) , width3) ;
    288. output + = formatData( VMNode. getIpAddress( ) , width4) ;
    289. output + = formatData( VMNode. getPowerState( ) , width5) ;
    290. output + = formatData( VMNode. getVMToolRunningSattus( ) , width6) ;
    291. System . out. println ( output ) ;
    292. }
    293. }
    294. }
    295. 
    296. //Power-Off virtual machine on connected ESXi host
    297. public String PowerOffVM ( String VMName) throws Exception {
    298. String ret = null ;
    299. ( "Powering Off " + VMName) ;
    300. if ( connected) {
    301. String xmldata = xml_poweroff. replace ( "$VMID$" , getVMId ( VMName) ) ;
    302. result ;
    303. result = sendXML( hostURL, xmldata) ;
    304. if ( debug) dispalyHttpResponse( result ) ; else EntityUtils. consume ( result . getEntity ( ) ) ;
    305. = result . getStatusLine( ) . toString ( ) ;
    306. }
    307. //Return result
    308. return ret;
    309. }
    310. 
    311. //Power-On virtual machine on connected ESXi host
    312. public String PowerOnVM ( String VMName) throws Exception {
    313. String ret = null ;
    314. ( "Powering On " + VMName) ;
    315. if ( connected) {
    316. String xmldata = xml_poweron. replace ( "$VMID$" , getVMId ( VMName) ) ;
    317. result ;
    318. result = sendXML( hostURL, xmldata) ;
    319. if ( debug) dispalyHttpResponse( result ) ; else EntityUtils. consume ( result . getEntity ( ) ) ;
    320. = result . getStatusLine( ) . toString ( ) ;
    321. }
    322. //Return result
    323. return ret;
    324. }
    325. 
    326. //Reset virtual machine on connected ESXi host
    327. public String ResetVM ( String VMName) throws Exception {
    328. String ret = null ;
    329. ( "Reseting " + VMName) ;
    330. if ( connected) {
    331. String xmldata = xml_reset. replace ( "$VMID$" , getVMId ( VMName) ) ;
    332. result ;
    333. result = sendXML( hostURL, xmldata) ;
    334. if ( debug) dispalyHttpResponse( result ) ; else EntityUtils. consume ( result . getEntity ( ) ) ;
    335. = result . getStatusLine( ) . toString ( ) ;
    336. }
    337. //Return result
    338. return ret;
    339. }
    340. 
    341. public boolean getConnected( ) {
    342. return this . connected;
    343. }
    344. 
    345. private void finalCleanup( ) {
    346. if ( httpclient!=null) httpclient. getConnectionManager( ) . shutdown ( ) ;
    347. = false;
    348. = null ;
    349. = null ;
    350. = null ;
    351. = null ;
    352. }
    353. //Get VMID from given virtual machine name
    354. private String getVMId ( String VMName) {
    355. String result = null ;
    356. Iterator it = vmList. iterator ( ) ;
    357. while ( it. hasNext ( ) ) {
    358. = null ;
    359. = ( Vminfo) it. next ( ) ;
    360. if ( VMName. toLowerCase ( ) . trim ( ) . equals ( VMNode. getName ( ) . toLowerCase ( ) ) ) {
    361. result = VMNode. getID ( ) ;
    362. break ;
    363. }
    364. }
    365. return result ;
    366. }
    367. //Get All Virtual Machine Information on connected ESXi host
    368. private ArrayList getVMList( ) throws Exception {
    369. ArrayList result = new ArrayList ( ) ;
    370. = null ;
    371. = sendXML( hostURL, genXML_getVMInfo( getVMIDs ( ) ) ) ;
    372. //Parse returned XML and store information in vmList
    373. //NEED MORE SMART!!!
    374. 
    375. //Returned XML sample
    376. /*
    377.          <returnval> 
    378.          <obj type="VirtualMachine">128</obj> 
    379.          <propSet><name>guest.hostName</name><val xsi:type="xsd:string">aaa.ccc.bbb</val></propSet> 
    380.          <propSet><name>guest.ipAddress</name><val xsi:type="xsd:string">aaa.ccc.bbb</val></propSet> 
    381.          <propSet><name>guest.toolsRunningStatus</name><val xsi:type="xsd:string">guestToolsRunning</val></propSet> 
    382.          <propSet><name>name</name><val xsi:type="xsd:string">aaa.ccc.bbb</val></propSet> 
    383.          <propSet><name>runtime.powerState</name><val xsi:type="VirtualMachinePowerState">poweredOn</val></propSet> 
    384.          </returnval> 
    385. 
    386. 
    387.          <returnval> 
    388.          <obj type="VirtualMachine">240</obj> 
    389.          <propSet><name>guest.toolsRunningStatus</name><val xsi:type="xsd:string">guestToolsNotRunning</val></propSet> 
    390.          <propSet><name>name</name><val xsi:type="xsd:string">vSphere Management Assistant (vMA)</val></propSet> 
    391.          <propSet><name>runtime.powerState</name><val xsi:type="VirtualMachinePowerState">poweredOff</val></propSet> 
    392.          </returnval> 
    393.           * 
    394.           * 
    395.           */ 
    396. DocumentBuilderFactory dbf = DocumentBuilderFactory . newInstance ( ) ;
    397. DocumentBuilder db = dbf. newDocumentBuilder ( ) ;
    398. Document doc = db. parse ( rspVMList. getEntity ( ) . getContent ( ) ) ;
    399. NodeList nl1 = doc . getElementsByTagName ( "returnval" ) ;
    400. //<returnval>
    401. for ( int i= 0; i< nl1. getLength ( ) ; i+ + ) {
    402. if ( nl1. item ( i) . hasChildNodes ( ) ) {
    403. = new Vminfo( ) ;
    404. NodeList nl2 = nl1. item ( i) . getChildNodes ( ) ;
    405. //<obj>&<proSet>
    406. for ( int j= 0; j< nl2. getLength ( ) ; j+ + ) {
    407. if ( nl2. item ( j) . getNodeName ( ) . trim ( ) . equals ( "obj" ) ) {
    408. . setID ( nl2. item ( j) . getTextContent ( ) ) ;
    409. }
    410. else {
    411. if ( nl2. item ( j) . hasChildNodes ( ) ) {
    412. NodeList nl3 = nl2. item ( j) . getChildNodes ( ) ;
    413. //<proset>
    414. //There are 2 childnodes in <proset>, one is for value name, another is value, it's a pair. so k+=2
    415. for ( int k= 0; k< nl3. getLength ( ) ; k+ = 2) {
    416. if ( nl3. item ( k) . getTextContent ( ) . trim ( ) . toLowerCase ( ) . equals ( "name" ) & & nl3. item ( k+ 1) . getNodeName ( ) . trim ( ) . toLowerCase ( ) . equals ( "val" ) ) {
    417. . setName ( nl3. item ( k+ 1) . getTextContent ( ) ) ;
    418. } else if ( nl3. item ( k) . getTextContent ( ) . trim ( ) . toLowerCase ( ) . equals ( "guest.hostname" ) & & nl3. item ( k+ 1) . getNodeName ( ) . trim ( ) . toLowerCase ( ) . equals ( "val" ) ) {
    419. . setNetworkName( nl3. item ( k+ 1) . getTextContent ( ) ) ;
    420. } else if ( nl3. item ( k) . getTextContent ( ) . trim ( ) . toLowerCase ( ) . equals ( "runtime.powerstate" ) & & nl3. item ( k+ 1) . getNodeName ( ) . trim ( ) . toLowerCase ( ) . equals ( "val" ) ) {
    421. . setPowerState( nl3. item ( k+ 1) . getTextContent ( ) ) ;
    422. } else if ( nl3. item ( k) . getTextContent ( ) . trim ( ) . toLowerCase ( ) . equals ( "guest.toolsrunningstatus" ) & & nl3. item ( k+ 1) . getNodeName ( ) . trim ( ) . toLowerCase ( ) . equals ( "val" ) ) {
    423. . setVMToolRunningSattus( nl3. item ( k+ 1) . getTextContent ( ) ) ;
    424. } else if ( nl3. item ( k) . getTextContent ( ) . trim ( ) . toLowerCase ( ) . equals ( "guest.ipaddress" ) & & nl3. item ( k+ 1) . getNodeName ( ) . trim ( ) . toLowerCase ( ) . equals ( "val" ) ) {
    425. . setIpAddress( nl3. item ( k+ 1) . getTextContent ( ) ) ;
    426. }
    427. }
    428. }
    429. }
    430. }
    431. result . add ( VMNode) ;
    432. ( "1 VM Added. VMID=" + VMNode. getID ( ) + " VMName=" + VMNode. getName ( ) + " VMNetworkName=" + VMNode. getNetworkName( ) + " VMIP=" + VMNode. getIpAddress( ) + " VMPower=" + VMNode. getPowerState( ) + " ToolStatus=" + VMNode. getVMToolRunningSattus( ) ) ;
    433. }
    434. }
    435. return result ;
    436. }
    437. 
    438. private void debugOutput ( String msg) {
    439. if ( debug) System . out. println ( "/n<DEBUG TYPE=MSG>/n" + msg+ "/n</DEBUG>" ) ;
    440. }
    441. //Get VMID list on a connected ESXi
    442. private String [ ] getVMIDs ( ) throws Exception {
    443. String [ ] result = null ;
    444. //Sent xml to host to get VM ID list
    445. = sendXML( hostURL, xml_getVMIDs) ;
    446. //Parse returned XML
    447. DocumentBuilderFactory dbf = DocumentBuilderFactory . newInstance ( ) ;
    448. DocumentBuilder db = dbf. newDocumentBuilder ( ) ;
    449. Document doc = db. parse ( rspVMIDList. getEntity ( ) . getContent ( ) ) ;
    450. NodeList nl1 = doc . getElementsByTagName ( "ManagedObjectReference" ) ;
    451. //init the return value array
    452. result = new String [ nl1. getLength ( ) ] ;
    453. //set return array
    454. for ( int i= 0; i< nl1. getLength ( ) ; i+ + ) {
    455. //make sure the ID is for Virtual Machine
    456. if ( nl1. item ( i) . hasChildNodes ( ) & &
    457. . item ( i) . getAttributes ( ) . getNamedItem ( "type" ) . toString ( ) . trim ( ) . equals ( "type=/"VirtualMachine/"" ) ) {
    458. result [ i] = nl1. item ( i) . getFirstChild ( ) . getNodeValue ( ) . toString ( ) . trim ( ) ;
    459. ( "VMID=" + result [ i] ) ;
    460. }
    461. }
    462. return result ;
    463. }
    464. private String genXML_getVMInfo( String [ ] vmIDList) {
    465. String result ;
    466. String tmpxml= "" ;
    467. for ( int i= 0; i< vmIDList. length ; i+ + ) {
    468. + = "<objectSet><obj type=/"VirtualMachine/">" + vmIDList[ i] + "</obj></objectSet>" ;
    469. }
    470. result = xml_getVMInfo. replace ( "$VMIDLISTOBJ$" , tmpxml) ;
    471. ( result ) ;
    472. return result ;
    473. }
    474. private void dispalyHttpResponse ( HttpResponse rsp) throws Exception {
    475. entity = rsp. getEntity ( ) ;
    476. System . out. println ( "********************<HTTP Response>********************" ) ;
    477. System . out. println ( "----------------------<HEADERS>------------------------" ) ;
    478. System . out. println ( rsp. getStatusLine( ) ) ;
    479. [ ] headers = rsp. getAllHeaders( ) ;
    480. for ( int i = 0; i < headers. length ; i+ + ) {
    481. System . out. println ( headers[ i] ) ;
    482. }
    483. System . out. println ( "-----------------------<BODYS>-------------------------" ) ;
    484. if ( entity ! = null ) {
    485. System . out. println ( EntityUtils. toString ( entity ) ) ;
    486. }
    487. System . out. println ( "************************<END>*************************" ) ;
    488. System . out. println ( ) ;
    489. System . out. println ( ) ;
    490. }
    491. private HttpResponse sendXML( String URL , String xml ) throws Exception {
    492. = new HttpPost( URL ) ;
    493. = new StringEntity( xml ) ;
    494. . addHeader( "Content-Type" , "text/xml; charset=/"utf-8/"" ) ;
    495. . addHeader( "User-Agent" , "VMware VI Client/4.1.0" ) ;
    496. . addHeader( "SOAPAction" , "/"urn:internalvim25/4.0/"" ) ;
    497. . setEntity( myEntity) ;
    498. if ( debug) System . out. println ( "executing request to " + httppost) ;
    499. = httpclient. execute ( httppost) ;
    500. return rsp;
    501. }
    502. private String ip2URL ( String IPAddress) {
    503. return "HTTPS://" + IPAddress+ "/sdk/" ;
    504. }
    505. private String formatData ( String data, int width ) {
    506. String result ;
    507.           
    508. if ( data!=null) {
    509. result = data;
    510. } else {
    511. result = "N/A" ;
    512. }
    513. //Append space
    514. for ( int i= result . length ( ) ; i< = width ; i+ + ) {
    515. result + = " " ;
    516. }
    517. return result ;
    518. }
    519.       
    520. public static void main( String [ ] args) throws Exception {
    521. 
    522. = new Vmoperation( ) ;
    523. 
    524. 
    525. System . out. println ( temp. Connect ( "<Your ESXi IP>" , "<Username>" , "<Password>" ) ) ;
    526. System . in . read ( ) ;
    527. System . out. println ( temp. PowerOffVM( "New Virtual Machine" ) ) ;
    528. System . in . read ( ) ;
    529. . DisplayVMList( ) ;
    530. System . in . read ( ) ;
    531. System . out. println ( temp. PowerOnVM( "New Virtual Machine" ) ) ;
    532. System . in . read ( ) ;
    533. System . out. println ( temp. ResetVM( "New Virtual Machine" ) ) ;
    534. System . in . read ( ) ;
    535. System . out. println ( temp. Disconnect ( ) ) ;
    536. 
    537. }
    538. }




    注:以上仅用于学术研究,禁止用于实际生产环境。否则将导致违反VMWare License Agreement. VMWare可能随时改变XML的定义,导致程序不能正常工作。