感謝 Vmware 大方提供免費的 ESXi 供大家使用,目前幾乎所有的伺服器都轉成 VM 了。
隨著 ESXi 和 VM 的數量增多,常常不曉得那個 VM 在那個 host 上,要一個一個 host 連進去找。其實, 可透過 ESXi 的開放的 SOAP 界面取得資訊。在網路上找到使用 PHP + SoapClient 來取得 VM 訊息的程式,經稍作修改,列表如下,謹供大家參考。
<?phpdefine('DEBUG', false); // set to true is you want raw results to be displayed$serverIP = "10.1.1.139"; // Your VC IP address or dns name$username = "myid";$password = "mypasswd";class soapclientd extends SoapClient{ public $action = false; public function __construct($wsdl, $options = []) { try{ parent::__construct($wsdl, $options); } catch (Exception $e) { echo '<pre>'.$e.'</pre>'; exit; } } public function __doRequest($request, $location, $action, $version, $one_way = 0) { if (DEBUG){ echo '<pre>' . htmlspecialchars( str_replace( ['<ns', '></'], [PHP_EOL . '<ns', '>'.PHP_EOL.'</'], $request) ) . '</pre>'; } $resp = parent::__doRequest($request, $location, $action, $version, $one_way); if (DEBUG) { echo 'res: <pre>' . htmlspecialchars( str_replace( ['<ns', '></'], [PHP_EOL . '<ns', '>'.PHP_EOL.'</'], $resp) ) . '</pre>'; } return $resp; }}$client = new soapclientd ( "https://{$serverIP}/sdk/vimService.wsdl", ['location' => "https://{$serverIP}/sdk", 'trace' => 1 ] );try{ $request = [ '_this' => [ '_' => 'ServiceInstance', 'type' => 'ServiceInstance' ] ]; $response = $client->__soapCall( 'RetrieveServiceContent', [$request] );} catch (Exception $e){ echo $e->getMessage(); exit;}$ret = $response->returnval;if (DEBUG) { echo '<pre>'.print_r($ret, true).'</pre>';}$sm = $ret->sessionManager;// 內容等同如下// $sm = ['_' => 'ha-sessionmgr',// 'type' => 'SessionManager'];try{ $request = [ '_this' => $sm, // $ret->sessionManager; 'userName' => $username, 'password' => $password, ]; $response = $client->__soapCall('Login', [$request]);} catch (Exception $e){ echo $e->getMessage(); exit;}if (DEBUG) { echo 'response: <pre>'.print_r($response, true).'</pre>';}$ss1 = new soapvar(['name' => 'FolderTraversalSpec'], SOAP_ENC_OBJECT, null, null, 'selectSet', null );$ss2 = new soapvar(['name' => 'DataCenterVMTraversalSpec'], SOAP_ENC_OBJECT, null, null, 'selectSet', null );$a = ['name' => 'FolderTraversalSpec', 'type' => 'Folder', 'path' => 'childEntity', 'skip' => false, $ss1, $ss2 ];$ss = new soapvar(['name' => 'FolderTraversalSpec'], SOAP_ENC_OBJECT, null, null, 'selectSet', null);$b = ['name' => 'DataCenterVMTraversalSpec', 'type' => 'Datacenter', 'path' => 'vmFolder', 'skip' => false, $ss ];$res = null;//// 'config' : 取回 config 之下所有的 information// 'config.hardware.numCPU' : 則只取回 CPU 的 information//$pathSet = [ 'name', 'guest.ipAddress', 'guest.guestState', 'runtime.powerState', 'config', 'config.annotation', 'config.hardware.numCPU', 'config.hardware.memoryMB' ];try{ $request = [ '_this' => $ret->propertyCollector, 'specSet' => [ 'propSet' => [ ['type' => 'VirtualMachine', 'all' => 0, 'pathSet' => $pathSet, ], ], 'objectSet' => [ 'obj' => $ret->rootFolder, 'skip' => false, 'selectSet' => [ new soapvar($a, SOAP_ENC_OBJECT, 'TraversalSpec'), new soapvar($b, SOAP_ENC_OBJECT, 'TraversalSpec'), ], ] ] ]; $res = $client->__soapCall('RetrieveProperties', [$request]);} catch (Exception $e){ echo 'Error: '.$e->getMessage();}echo 'VMs: <pre>'.print_r($res, true).'</pre>';