PHP调用ESXi SOAP API登录成功后Logout失败求助
问题:PHP SOAP调用ESXi时Logout失败,提示对象已删除
我正在编写PHP脚本重置ESXi主机「myhost」的root密码,旧密码存储在$oldpass,新密码存储在$newpass,测试环境为全新部署的嵌套ESXi 8.0.2b。折腾数月,尝试多种方法甚至AI工具仍未解决问题。
据了解,实现该操作需通过SOAP调用直接连接ESXi,以root身份认证到SOAP代理。我基于SoapClient编写的代码如下:
class ESXI_SOAP extends SoapClient { private $ServiceInstance; private $session; public function __construct( $url , $user , $pass ) { try { parent::__construct( $url . '/vimService.wsdl' , [ 'trace' => true , 'exceptions' => true , "location" => $url , 'stream_context' => stream_context_create( [ 'ssl' => [ 'verify_peer' => false , 'verify_peer_name' => false , 'allow_self_signed' => true ] ] ) ] ) ; $this->ServiceInstance = $this->RetrieveServiceContent( [ "_this" => new SoapVar( "ServiceInstance", XSD_STRING , "ServiceInstance" ) ] )->returnval ; $this->session = $this->Login( [ '_this' => $this->ServiceInstance->sessionManager , 'userName' => $user , 'password' => $pass ] )->returnval ; echo "login successful\n\nServiceInstance:\n" ; var_dump($this->ServiceInstance); echo "\nSession:\n"; var_dump( $this->session ) ; } catch( Exception $e ) { printf("%s\n",$e->__toString() ) ; return false ; } echo $this->__getLastResponseHeaders(); /*** Logout ***/ try{ echo "attempting logout()\n"; $result = $this->Logout( [ "_this" => $this->ServiceInstance ] ) ; } catch (Exception $e) { printf("%s\n",$e->__toString()); return false; } echo "logout successful\n"; }
登录操作成功,但会话似乎立即超时,Session对象无法使用,甚至执行即时Logout也报错:
login successful ServiceInstance: object(stdClass)#4 (26) { (...) ["about"]=> object(stdClass)#8 (14) { ["name"]=> string(11) "VMware ESXi" ["fullName"]=> string(32) "VMware ESXi 7.0.3 build-20328353" ["vendor"]=> string(12) "VMware, Inc." ["version"]=> string(5) "7.0.3" ["patchLevel"]=> string(4) "0.55" ["build"]=> string(8) "20328353" ["localeVersion"]=> string(4) "INTL" ["localeBuild"]=> string(3) "000" ["osType"]=> string(9) "vmnix-x86" ["productLineId"]=> string(11) "embeddedEsx" ["apiType"]=> string(9) "HostAgent" ["apiVersion"]=> string(7) "7.0.3.0" ["licenseProductName"]=> string(17) "VMware ESX Server" ["licenseProductVersion"]=> string(3) "7.0" } (...) } Session: object(stdClass)#2 (11) { ["key"]=>string(36) "5223f016-7f92-c38c-0870-6fb25219ef71" ["userName"]=>string(4) "root" ["fullName"]=>string(13) "Administrator" ["loginTime"]=>string(27) "2024-07-11T19:26:13.116449Z" ["lastActiveTime"]=>string(27) "2024-07-11T19:26:13.116466Z" ["locale"]=>string(2) "en" ["messageLocale"]=>string(2) "en" ["extensionSession"]=>bool(false) ["ipAddress"]=>string(10) "(redacted)" ["userAgent"]=>string(26) "PHP-SOAP/7.4.3-4ubuntu2.23" ["callCount"]=>int(0) } HTTP/1.1 200 OK Date: Thu, 11 Jul 2024 19:26:13 GMT Set-Cookie: vmware_soap_session="4f71046b2b4285b476a11ca548f61a690bba1a89"; Path=/; HttpOnly; Secure; Cache-Control: no-cache Connection: Keep-Alive Content-Type: text/xml; charset=utf-8 X-Frame-Options: DENY Content-Length: 815 attempting logout() SoapFault exception: [ServerFaultCode] The object 'vmodl.ManagedObject:' has already been deleted or has not been completely created in /var/www/html/interfaces/RootPasswordChange/SOAP.php:45 Stack trace: #0 /var/www/html/interfaces/RootPasswordChange/SOAP.php(45): SoapClient->__call() #1 /var/www/html/interfaces/RootPasswordChange/SOAP.php(73): ESXI_SOAP->__construct() #2 /var/www/html/interfaces/RootPasswordChange/SOAP.php(90): ESXI_Test()
我怀疑是$ServiceInstance的存储或传递给Logout方法时出现问题,目前仅需实现可正常运行的$this->Logout()。
解决方案
问题出在Logout方法的调用参数错误:必须传入SessionManager的ManagedObject引用,而非整个ServiceInstance对象。
ESXi的SOAP API中,Logout是SessionManager对象的专属方法,你登录时已经正确使用了$this->ServiceInstance->sessionManager作为Login方法的_this参数,注销时需要保持一致。
修正后的Logout代码段:
/*** Logout ***/ try{ echo "attempting logout()\n"; $result = $this->Logout( [ "_this" => $this->ServiceInstance->sessionManager ] ) ; } catch (Exception $e) { printf("%s\n",$e->__toString()); return false; } echo "logout successful\n";
补充说明
- 你看到的"会话立即超时"并非真的超时,只是因为调用Logout时传入了错误的对象引用,导致API无法识别有效会话
- 修正参数后,即可正常注销已建立的SOAP会话,后续也能基于该会话执行密码重置等其他操作
内容的提问来源于stack exchange,提问作者догонят
相关产品推荐
相关产品推荐

