Hello,
I have been trying to come up with a workflow to run esxicli commands on an ESXi host, I am aware of the different solutions out there including the one that uses the vMA as an SSH server, but I would like to give it a try with the PowerShell plugin. So far I can connect to the vCenter, get the host and even get the esxcli object using the different examples already on the PowerShell plugin library.
But my problem is that after I get the esxcli object it is on the PowerShellRemotePSObject format and I don't know how to work with it.
var sess;
try {
sess = host.openSession()
sess.addCommandFromString("Add-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue");
var invResult = sess.invokePipeline();
//Show result
System.log( invResult.getHostOutput() );
sess.addCommandFromString('Connect-VIServer '+vcenter+' -User user@domain -Password "passw0rd" -Force');
var invResult = sess.invokePipeline();
//Show result
System.log( invResult.getHostOutput() );
// Get PowerShellRemotePSObject
sess.addCommandFromString('Get-VMHost -Name '+esxi+' -Server '+vcenter);
var invResult = sess.invokePipeline();
//Show result
System.log( invResult.getHostOutput() );
var psObject = invResult.getResults();
if (invResult.invocationState == 'Failed'){
System.error(invResult.getErrors());
}
else {
var cmd = sess.addCommandFromString('Get-EsxCli')
cmd.addParameter('Server', vcenter);
cmd.addParameter('VMHost', psObject);
var sessionId = sess.getSessionId();
var esxcli = System.getModule("com.vmware.library.powershell").invokeCommand(host,sessionId);
System.log(esxcli);
}
} catch ( ex ) {
System.log (ex);
} finally {
if (sess) {
host.closeSession( sess.getSessionId());
}
}
Given the esxcli object is accessed for instance like $esxcli.software.vib.list() in PowerShell I don't know how to use the PowerShellPSObject to access the information or execute methods on it.
Any help is appreciated.
Thank you,
Juan.
Hi Juan,
I'm not sure you can call methods against PowerShellPsObjects returned by VCO. By then, they have been serialzed into XML from the PowerShell script then reserialized back in VCO. I'm pretty sure you lose any methods when this happens.
What I did for similar purposes is use the WF template that calls a PowerShell script externally. I put all my my logic and method calls in the external PoSH script and at the very end pass back the final results to VCO. I'm far better with PoSH than VCO, so I put as much of the smarts in the PoSH as possible.
Hi Juan,
The PowerShellRemotePSObject is an object containing the output of a PS command.
For example when running [Get-EsxCli -VMHost esx-mgmt-a-11.vmware.com] the output (shown on screnshot1) is your PowerShellRemotePSObject.
// ----- output from Get-EsxCli -VMHost esx-mgmt-a-11.vmware.com
================================
EsxCli: esx-mgmt-a-11.vmware.com
Elements:
---------
device
esxcli
fcoe
graphics
hardware
iscsi
network
sched
software
storage
system
vm
vsan
// ----- end of output
For example you can parse it as JSON to verify successful execution or use it as an input (in PS words "Pipe it") for another ps command.
...
var psOutput_temp = PSOut.getAsJson();
if( psOutput_temp.search('success') {
...
Let me simplify your code and give you another example. If i put all the commands in your code in one single PS script (commands on one line separated by ; ) this would look something like this:
Add-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue; Connect-VIServer <vCenterServerName> -user <vCenterAdmin> -Password <vCenterAdminPAssword> ; Get-EsxCli -VMHost <esxiHost>
Now use the [invoke a powershell script] wf to run this script. Th output is the same as above (shown on screenshot2). Again this is your PowerShellRemotePSObject which you can parse or pipe to another ps command.
Note that connecting to vCenter server might require CredSSP enabled on the PS host. For more info visit, Using CredSSP with the vCO PowerShell Plugin | Spas Kaloferov's Blog
If interested in more PS example WF's , visit http://kaloferov.com/blog/com-spaskaloferov-vco-vro-workflow-library-package/
BR,
Spas Kaloferov
www.kaloferov.com
Thanks for the help Spas. I ended up using the vMA as an SSH host, then added the vCenter servers to the credstore so I don't have to pass credentials, now I can run the full esxcli command from the vMA, in my particular case I wanted to run unmap, so I get the ESXi servers and the datastores names from the vCO inventory and send the command string like this:
esxcli --server [vcenter name] --vihost [esxi name] storage vmfs unmap -l [datastore name]
I am although curious on how I can invoke the same esxcli command having it stored as a PSobject.
Thank you,
Juan.
Hi Juan,
I'm not sure you can call methods against PowerShellPsObjects returned by VCO. By then, they have been serialzed into XML from the PowerShell script then reserialized back in VCO. I'm pretty sure you lose any methods when this happens.
What I did for similar purposes is use the WF template that calls a PowerShell script externally. I put all my my logic and method calls in the external PoSH script and at the very end pass back the final results to VCO. I'm far better with PoSH than VCO, so I put as much of the smarts in the PoSH as possible.
in that case you only need to extent the command i used before with something like this:
Add-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue; Connect-VIServer <vCenterServer> -user <UserName> -Password <Password> ; $esxcli = Get-EsxCli -VMHost <ESXiHost>; $esxcli.storage.vmfs.unmap(200, "<DatastoreName>", $null)
BR,
Spas Kaloferov
I think you are right, I'll have to put the logic on the PoSH script and process the final result on vCO. Thank you.
Thank you Spas, another way of accomplish the task is by doing this in conjunction with your CredSSP instructions.
Hi,
you don't have nesecery use use external script. Check the [Piped vROCmdlet execution (Example 1) (vROCmdlet)] workflow part of the package i pointed above.
This WF example shows how to open a PS session and then use the PowerShell.PowerShellRemotePSObject and pipe command output from one PS command to another within vRO and then close the session.