Archive for the ‘VMware’ Category
Follow up on ESXCLI with PowerCLI
In a previous post here, Applying Patches to ESXi 5 with the help of PowerCLI, I showed how simple it was to call ESXCLI that is part of vCLI through a PowerCLI script, but did you know that ESXCLI is also part of PowerCLI?
ESXCLI is actually part of the VMware API for an ESXi host. Note: While the API for vSphere 4 also had ESXCLI included, it is much more robust with vSphere 5. Most if not all of the commands I show will only work against vSphere 5. PowerCLI has a cmdlet called Get-EsxCli that can be used when connected directly to an ESXi host.
First, connect to an ESXi host through PowerCLI.
Connect-VIServer
Next, lets run the Get-EsxCli cmdlet.
$esxcli = Get-EsxCli
Now we have our ESXCLI object. Now what can we do with it? Well basically anything that you would do with ESXCLI through vCLI or local to the ESXi host. So let’s say our host is running on a Cisco UCS system, and we wanted to verify the enic driver version loaded on the host. We could issue the following command to view the driver version.
$esxcli.system.module.get("enic").version
Now, to follow-up on the previous post, we could use the $esxcli object obtained through PowerCLI to issue the commands to view the vibs on the host and apply vibs to the host in the same manor that we were calling ESXCLI before. If we wanted to see all the VIBs installed on a host, we can issue the following command to give us the name, vendor, and version of all VIBs installed on the host in formatted table output.
$esxcli.software.vib.list() | ft Name,Vendor,Version
Let’s look at the example from the previous blog post. Here we set the patch name and location of the patch on the datastore that the host could access.
$patch = "PatchFile.zip" #patch file we want to apply
$datastore = "datastore1" #datastore where we want to store the patch
$remoteLocation = "/vmfs/volumes/" + $datastore + "/" + $patch #remote location of patch
Now once the patch is on the datastore, which I covered in the previous post, you could install it with the command
$esxcli.software.vib.install($remoteLocation)
Here is another tip as well for PowerShell and PowerCLI. If you are unsure of the arguments that a function takes, such as the command above, you can run
$esxcli.software.vib.install
and the command will output some useful data about the method. One particular useful output is Value. This tells you what the expected value type will be given the proper inputs. For the above command, you can see the output as follows:
Hopefully this proves useful to someone.
ESXi 5, Nexus 1000V, Custom ISO…oh my…
So a quick post today on an issue I ran into (and was also told about by @kendrickcoleman). After building a custom VMware ESXi 5 ISO with the Cisco Nexus 1000V vib, EMC PowerPath 5.7 vibs, and the vSphere HA vib, I deployed out 3 hosts. After deployment, I noticed all three hosts had one CPU core spiked while the rest remained idle. It turns out, that once the host is added to the Cisco Nexus 1000V dVS, CPU usage returns to normal.
Just an FYI on this topic in case other people run into it.
Blog::Post.new
Over the past year, I dropped the ball on this blog. It’s been a busy time, but I’ll try over the next year to make a few more posts. So what has been going on? Here are a few of the items keeping me busy:
- Received the results on the VCAP-DCA; did not pass. The equipment I was using was also moved, so I did not get the opportunity to prepare and take it again.
- Made a couple of trips to Ireland and spent about a month in England.
- Moved back to Louisiana.
- Dabbled in PowerShell, PHP, Python, Scala, Ruby
- Changed managers about two or three times.
- Passed the VCP 5
So what’s in store in the coming year? Well hopefully a lot of cool projects. There are a few topics I want to blog about and hopefully post some useful tools. I’m looking to move everything I do to Ruby, though there may still be some internal PowerShell scripts for some items.
This is my short update. Hopefully everyone had a good year.
Applying patches to ESXi 5 with the help of PowerCLI
So today, Chris Colitti posted a blog article about patching ESXi 5 without VUM. If you haven’t read it, I suggest you click this link and read his post.
After reading this post, I was surprised to find out that esxcli did not support pushing patch or extension files remotely. Prior to ESXi 5, you could use vihostupdate via the vCLI to install the patch or extension zip files to a host. With vSphere 5, vihostupdate has been deprecated. The esxcli command supports installing a patch or extension from a remote depot url (VUM for instance) or from a local file path on the server, as Chris pointed out. Another option would be to host the actual vib files on an http or ftp server and use the -v option with esxcli to point to the remote location of these files. However, this is not the point of this blog post. This blog post will talk about using PowerShell and PowerCLI to assist esxcli in installing patches remotely. I will not provide a whole script, but just some useful commands.
First, to make things easier, we’ll set a couple of variables.
$esxcli = "C:\Program Files\VMware\VMware vSphere CLI\bin\esxcli.exe" #location of esxcli
$server = "192.168.1.10" #server we want to patch
$patch = "PatchFile.zip" #patch file we want to apply
$patchLocation = "C:\" #local path to patch"
$datastore = "datastore1" #datastore where we want to store the patch
$remoteLocation = "/vmfs/volumes/" + $datastore + "/" + $patch #remote location of patch
Now, we want to mount a datastore to our workstation. First we need to connect to the ESXi host before doing anything.
Connect-VIServer $server
New-PSDrive -name "mounteddatastore" -Root \ -PSProvider VimDatastore -Datastore (Get-Datastore $datastore)
After we mount our datastore, we can then copy the patch to the datastore.
Copy-Datastoreitem $patchLocation + $patch -Destination mounteddatastore:
Once our file is copied, we can then execute esxcli to install our patch
& $esxcli --server $server software vib install -d $remoteLocation
This will execute esxcli on your workstation to install the patch we just uploaded to the datastore. Once the patch is installed, we can remove the patch and disconnect the datastore from the workstation.
del mounteddatastore:$patch
Remove-PSDrive -name "mounteddatastore" -PSProvider VimDatastore
So with this little bit of knowledge, you could write a PS script to copy the patch to a datastore (preferably shared across hosts), and then call esxcli to install the patch on the required hosts.
Update: A new blog post is up detailing using the Get-EsxCli cmdlet in PowerCLI. This can be located here.
Setting time on ESXi hosts through PowerCLI
So you go and build your new ESXi hosts, set NTP, but notice your time is still off. Did you know you can set your ESXi host time through PowerCLI?
After connecting to a host, you can set the time with the following commands. Always make sure you use UTC time when setting the time on your host as ESXi does not use timezones.
$t = Get-Date
$dst = Get-VMHost | %{ Get-View $_.ExtensionData.ConfigManager.DateTimeSystem }
$dst.UpdateDateTime((Get-Date($t.ToUniversalTime()) -format u))
And there you go. Now your ESXi hosts will have the same time as the machine you ran your script on, so just make sure that machine has the correct time.
And on why I have not blogged in a while, well that is another blog post.
VCAP-DCA….Finally!
VMware has finally released the VCAP-DCA exam, and I was able to schedule it pretty fast (still not sure if that was good or bad with my work schedule). Unfortunately, you agree to an NDA for the exam, so I can not post detailed information from the exam, nor would I. Seriously, do not ask, and if you do, prepare to pay a $10 non-refundable fee for any answer you may get back in return.
Here are my thoughts after taking the exam. First, I felt a lot better about this exam than I did the VCP 4. Now if I passed, well, I won’t know that for another 10 days. Make that another stressful 10 days. It was a very fair exam. I think VMware did an excellent job with a 100% lab based exam. I will say that I did not finish the exam. Well I was close. I did skip a couple of questions because time was running short, mostly because I knew what the answer was, but did not know the exact parameter to configure. So I moved on.
So what can you do to prepare?
1. Build a lab.
2. Practice
3. Practice
4. Practice
Honestly, you will not pass this exam if you just study documentation. You need hands on work with vSphere. Why? It’s lab based and there is a time limit. There is no google to help you out. Either you know it, or you don’t. There is documentation available, but you will waste precious seconds if you have to continually look up commands.
Now if anyone knows people involved with the exam, please find out if they would like feedback on it and get their information to me. I was disappointed there wasn’t anything available after the exam was completed. I would have liked to provide feedback because there were some errors in questions, and some items just did not work. I hope this gets taken into account when the exam is scored.
Now to wait….
Using PHP5 SOAP with vSphere API
I will more blog later detailing better usage of PHP with vSphere API. This post is focused on how to use PHP5 Soap Client methods to interact with the vSphere API.
The vSphere API is SOAP based. First step is to download the WSDL from vCenter or the ESX(i) host. So how do we do this with PHP5?
First, we need a SOAP Client.
$connection = new SoapClient(“https://<hostname or ip/sdk/vimService.wsdl”, array(“trace” => 1, “location”=>”https://<hostname or ip>/sdk/”);
From this code snippet, we created a new SoapClient, $connection, set the location of the wsdl, set trace to 1 for debugging purposes, and set the location that we will send requests to. Next we need to create a SOAP message to send to the server.
$soapmsg[“_this”] = new SoapVar(“ServiceInstance”, XSD_STRING, “ServiceInstance”);
Basically every call to vSphere API will require a “_this” key. Most calls will require more information. From this code snippet, we are creating an array with a “_this” key and setting a SoapVar with data of “ServiceInstance” and type of “ServiceInstance”. Now, we are going to retrieve the Service Instance.
$result = $connection->RetrieveServiceContent($soapmsg);
And what do we get? Definitely not the result we were expecting. With trace enabled, we can actually view the SOAP request that was made to the server.
var_dump($connection->__getLastRequest());
What is the problem with the SOAP request? Well, PHP5 SOAP function sets the type of the SOAP message as “xsi:type”. The vSphere API expects a type of just “type”. How do we fix this? We must create our own class that extends SoapClient and overrides the __doRequest method. Here, we can strip “xsi:” out of the request and send the vSphere API the request it is expecting.
class mySoapClient extends SoapClient {
function __doRequest($request, $location, $action, $version) {
$request = str_replace(“xsi:”, “”, $request);
return parent::__doRequest($request, $location, $action, $version);
}
}
After altering the request, we can now successfully retrieve the Service Instance from the vSphere API.
Reconnecting ESX(i) hosts with 1000V installed
I follow a certain policy: “You break it; you fix it”. Why? When you break something, you learn a lot about why it broke and what it takes to fix it. Hopefully, you also learn how to prevent it from happening again. Two, I’m not stuck dealing with the problem someone else caused.
Tonight was one where I broke something, and now I needed to fix it.
I had to reconfigure a UCS system running 3 vSphere 4.1 ESXi hosts connected to a Cisco 1000V. Before powering down the hosts, I made some changes to the 1000v and the UCS. So far, so good. All the hosts were powered down along with vCenter and the 1000V VSMs, which were running on the UCS chassis. I made my configuration changes on the UCS and powered up the first host. No connectivity. Something was not jiving between the 1000V config on the host itself and the vNIC configuration from the UCS. It turned out to be a misconfiguration of the native vlan on the vNIC presented to the host and the native vlan configuration configured on the host by the 1000V. I returned some values to their previous settings, and the host came back up. I updated the 1000V config, which took the host back down, but I adjusted the UCS to the new configuration I wanted to bring the host back up. Great, except I still had to bring two more hosts back online.
This is where I dove into vemcmd on the ESXi host. When I brought up the next host, I opened a local console to the system. “vemcmd show port” showed me the native vlan configuration error that was causing my issue. So how do you fix this? It’s actually quite simple. When looking at the output of the previous command, you’ll notice three Trunk ports on the system. Two are the actual physical uplinks connected from the system. The third is the port channel that is formed between the two nics. To bring the system back online, you need to issue the following command: vemcmd set port-mode trunk native-vlan <native vlan> ltl <ltl of port-channel>. After issuing this command, the system was back online. You’ll notice that after issuing the command, the native vlan of the physical nics remains the same. After the VEM gets the updated configuration, the native vlan is now the correct on the physical nics.
Working with UCS and vCenter: IPMI Settings
In my last blog post, Working with Cisco UCS XML API, I went through the steps needed to login and logout of UCS Manager using PHP and PowerShell. Today, I decided to write the first PowerShell script I needed which would automatically update the IPMI settings on the ESX hosts with the settings from UCS Manager. In writing this script, I did come across this post from Mike Laverick on using PowerShell to enable DPM settings
Now, this script is important for two reasons. The first reason is that to configure IPMI on ESX hosts, you need both IP address and the MAC address of the CIMC controller from the UCS blades. When having to do this for multiple ESX hosts, a script is very handy. Now the second reason is more important. Currently in UCS, the CIMC IP is tied to the actual blade and not the service profile. This means if a service profile is associated with a new blade, the ESX host IPMI information is now pointing to the old blade. Not good!
With that said, here is the first version of this script as a PowerShell script. (This will also come as a PHP script and possibly other languages in the near future.) In order to run this script, you will need PowerCLI installed. You will also need IP and credentials for vCenter and UCS, as well as the IPMI user and password. This script has only been tested against UCS 1.3.1 and vSphere 4.1. I will be testing this shortly against vSphere 4.0. This is also a v0.1 script, so there is no error checking (who needs it right?). That will be coming in a future version.
###DISCLAIMER###
I provide this script for academic purposes only. Use at your own risk. I am not responsible for any damages it may cause.
###DISCLAIMER###
So what does the script do? The script first logs into vCenter and UCS Manager. It then grabs the UUID from each ESX host. Once done, it will pass this UUID to UCS to find the corresponding blade and return the CIMC IP and MAC for that blade. The script will then write these settings to the IPMI of the ESX host. Finally, it will log out of the UCS and vCenter.
#####################################################################
# UCS_VMware_IMPI.ps1 v0.01 By: Justin Guidroz
#
# This script will connect to UCS Manager, collect IPMI information
# for the provisioned blades, and update the appropriate IPMI
# information on the ESX hosts. The script can also be run to
# update the IPMI information if a service profile is moved to a
# different blade.
#
#####################################################################
Add-PSSnapin VMware.VimAutomation.Core### Needed variables
$ucsUrl = “”
$ucsUser = “”
$ucsPassword = “”
$vCenterUrl = “”
$vCenterUser = “”
$vCenterPassword = “”
$ipmiUser = “”
$ipmiPassword = “”### Function ucs_post
### Required variables: $url = UCS Url $data = XML to send to UCS
### Returns: XML response from UCS
function ucs_post($url,$data) {
$request = [System.Net.HttpWebRequest] [System.Net.HttpWebRequest]::Create(“http://” + $url +”/nuova”)
$request.Method = “POST”
$request.ContentType = “text/xml”
$sendData = new-object System.IO.StreamWriter($request.GetRequestStream())
$sendData.Write($data)
$sendData.Close()
$response = $request.GetResponse()
$sr = new-object System.IO.StreamReader($response.GetResponseStream())
$xml = [xml] $sr.ReadToEnd()
return $xml
}### Function ucs_login
### Required variables: $inName = UCS username $inPassword = UCS password $url = UCS url
### Returns: Cookie after login
### Todo: Error Checking
function ucs_login($inName, $inPassword, $url) {
$aaaLogin = “<aaaLogin inName='” + $inName + “‘ inPassword='” + $inPassword + “‘ />”
$xml = ucs_post $url $aaaLogin
$outCookie = $xml.aaaLogin.outCookie
return $outCookie
}### Function ucs_logout
### Required variables: $url = UCS url $inCookie = Cookie for session to logout
### Returns: Status of logout
### Todo: Error Checking
function ucs_logout($url, $inCookie) {
$aaaLogout = “<aaaLogout inCookie='” + $inCookie + “‘ />”
$xml = ucs_post $url $aaaLogout
$outStatus = $xml.aaaLogout.outStatus
return $outStatus
}### Function get_esx_hosts
### Required variables: $vCenter = $vCenter server object
### Returns: ESX hosts in vCenter
### ToDo: Error checking. More logic
function get_esx_hosts($vCenter) {
$esxhosts = @()
$VMHosts = Get-VMhost -server $vCenter
foreach ($h in $VMHosts) {
$esxhost = “” | Select-Object Name, Uuid, IpmiIp, IpmiMac
$esxhost.Name = $h.name
$v = Get-VMHost -Name $h | Get-View
$esxhost.Uuid = $v.Summary.Hardware.Uuid
$esxhosts += $esxhost
}
return $esxhosts
}### Function get_blade_dn
### Required variables: $uuid = ESX UUID $url = UCS url $cookie = UCS cookie for session
### Returns: DN of physical blade
### Todo: Error Checking
function get_blade_dn($uuid, $url, $cookie) {
$computeBlade = “<configResolveClass cookie='” + $cookie + “‘ inHierarchical=’false’ classId=’computeBlade’><inFilter><eq class=’computeBlade’ property=’uuid’ value='” + $uuid + “‘ /></inFilter> </configResolveClass>”
$bladeXml = ucs_post $url $computeBlade
return $bladeXml.configResolveClass.outConfigs.computeBlade.dn
}### Function get_blade_ipmi
### Required variables: $dn = DN of physical blade $url = UCS url $cookie = UCS cookie for session
### Returns: Management Interface XML response from UCS
### Todo: Error Checking
function get_blade_ipmi($dn, $url, $cookie) {
$mgmtIf = “<configResolveClass cookie='” + $cookie + “‘ inHierarchical=’false’ classId=’mgmtIf’><inFilter><eq class=’mgmtIf’ property=’dn’ value='” + $dn + “/mgmt/if-1′ /></inFilter> </configResolveClass>”
$mgmtIfXml = ucs_post $url $mgmtIf
return $mgmtIfXml
}### Function get_host_ipmi
### Required variables: $esxhost = ESX Host object $url = UCS url $cookie = UCS cookie for session
### Returns: Updated ESX host object
### Todo: Error checking
function get_host_ipmi($esxhost, $url, $cookie) {
$bladeDn = get_blade_dn $esxhost.Uuid $url $cookie
$mgmtIfXml = get_blade_ipmi $bladeDn $url $cookie
$esxhost.IpmiIp = $mgmtIfXml.configResolveClass.outConfigs.mgmtIf.extIp
$esxhost.IpmiMac = $mgmtIfXml.configResolveClass.outConfigs.mgmtIf.mac
return $esxhost
}### Function set_host_ipmi
### Required variables: $esxhost = ESX host object $vCenter = vCenter Server Object
### Returns: nothing (should be changed)
### Todo: Error checking
function set_host_ipmi($esxhost, $vCenter) {
$v = Get-VMHost -server $vCenter -Name $esxhost.Name | % {Get-View $_.Id}
$ipmi = New-Object Vmware.Vim.HostIpmiInfo
$ipmi.BmcIpAddress = $esxhost.IpmiIp
$ipmi.BmcMacAddress = $esxhost.IpmiMac
$ipmi.Login = $ipmiUser
$ipmi.Password = $ipmiPassword
$v.UpdateIpmi($ipmi)
}### Where the fun begins
### Lets log in to vCenter and UCS
$vCenter = Connect-VIServer -server $vCenterUrl -user $vCenterUser -password $vCenterPassword
$cookie = ucs_login $ucsUser $ucsPassword $ucsUrl### Grabbing ESX hosts from vCenter
Write-Host “Getting ESX Hosts from vCenter”
$esxhosts = get_esx_hosts $vCenter### Get the IPMI settings from UCS and update ESX hosts with information
Write-Host “Getting IPMI Settings from UCS and configuring ESX”
foreach ($h in $esxhosts) {
$h = get_host_ipmi $h $ucsUrl $cookie
set_host_ipmi $h $vCenter
}### Fun as ended, time to log out.
Write-Host “Logging out of UCS”
$outStatus = ucs_logout $ucsUrl $cookie
Write-Host $outStatus
Write-Host “Logging out of vCenter”
Disconnect-VIServer -server $server -confirm:$false
And here is the PowerShell file. UCS_VMware_IPMI.ps1.doc The .doc will need to be deleted from the end of the file (only way I could get the file uploaded).
Looks like I need to figure out a way to make code display on my blog. Another day.
Automating ESXi 4.1 continuation
William Lam has posted a great article on tips and tricks of automating ESXi 4.1 here. Go read his post first.
Seriously, go read his post first.
Ok, you’re back?
I wanted to add to his post with some issues and fixes I’ve run across with moving from ESX to ESXi automation.
With ESX 4.0, at the beginning of the ks.cfg file, you would specify an install line. Nothing else was needed as the url location of the install bits was passed in the PXE config line. No more. For ESX(i) 4.1, you must specify the url for the install location in the ks.cfg file.
Beginning with ESX(i) 4.1, ip append 2 in the PXE config boot line no longer works. What does this do exactly? This told the ESX(i) to use the same nic it booted from for downloading the install bits. If this was not specified, ESX(i) would try to use the first nic it detected, vmnic0. With ESX(i) 4.1, you must specify ksdevice=vmnic(x) if you are booting and installing from a different nic than vmnic0. I’m not sure why this behavior changed between 4.0 and 4.1.
William did mention vim-cmd. In ESX, the command is actually vmware-vim-cmd. For ESXi, be sure to update these commands to vim-cmd.
For disk setup, I have two lines in my ks.cfg file: clearpart –onfirstdisk –overwritevmfs and autopart –onfirstdisk –overwritevmfs. I did notice this will create the datastore name on each ESXi host as datastore. I need to investigate if this can be changed at this part, or add a line in the script to update that name.
In my working with scripting ESXi installations, I’ve found it much easier to have everything run after firstboot then trying to run the configurations before firstboot.
Plenty of advanced configurations (SNMP, Active Directory, adding to vCenter) can be handled through the scripted install, but involve writing a python script to handle. For some, it will be easier using the supplied commands in the vMA or writing PowerShell scripts.
Outside of these differences, scripted ESXi installs are awesome.