Archive

Quite some time ago I created a PowerCLI function to help me determine VMware Tools versions of queried VMs using PowerCLI. The tools version is returned as a 4 digit number by the vSphere API, and subsequently, so does PowerCLI. This makes determining VMware Tools versions at a glance, a bit of a hassle.

The original function was able to output Tools versions up to ESXi 4.1 u1 or u2, and this week was the first time I had a good use case for this script. I needed more up to date mappings, so I have updated the function to work with VMware tools versions all the way up to ESXi 5.5 now.

In a recent blog post, I showed a simple method of outputting a list of hosts with their friendly names, as well as their MoRef (Managed Object Reference) names alongside eachother, enabling you to match up which host belongs to which MoRef. I wanted to take that a little further, with a function that is able to return the friendly name of a host’s MoRef that is input into the function. I have used this is a larger reporting script, where I can only get the MoRef of a host via it’s property within a cluster object. Basically, I look for any Failover hosts (admission control policy), which is an array, and the hosts are listed as indexed objects of this array. They are also only displayed as MoRef names, so at this point, instead of inserting the MoRef into my results, I insert the MoRef into this function, return the friendly name, and input this instead. Which allows the person reading the report to easily identify the host! $cluster.ExtensionData.Configuration.DasConfig.AdmissionControlPolicy.FailoverHosts <- In this example, $cluster is a particular cluster using the “specify a failover host” policy, and “FailoverHosts” is the array, with each object within containing a host MoRef. For example FailoverHosts[0].Value would be one instance, and may equate to “HostSystem-host-28” for example. So here is the function. It takes two mandatory parameters: -MoRef (the MoRef of the host in question of course), and -Cluster (the name of the Cluster to do the lookup in) – the function loops through each host in this cluster to look for a host that matches the input MoRef.

Here is a quick sample of the output when called directly from the PowerCLI prompt (note the MoRef of “host-22” used to find the real host name of “esxi02.homelab.local”: Hopefully this may be of use to some – add it to your PowerCLI script/function toolkit or throw it into your PowerShell $profile for easy access in the future!

I am a big advocate of automation and saving time with a good script. Whenever I can find a task that is fairly lengthy, and is likely to be repeated in future, I always consider scripting it. There are many way to configure an ESXi host when it comes to writing build or automation scripts. In fact, I often feel we are quite spoilt for choice. Here are just some of the tools we have available to use:

PowerCLI

esxcli

vMA

vCLI

I was working on a build configuration script the other day using PowerCLI and found the need to edit some configuration files on the hosts. I wanted to edit the configuration file /etc/vmware/config during the execution of a single PowerCLI script without needing to stop the script or have an additional step to do myself. The following is what I came up with to achieve this:

Configure host as normal using PowerCLI

Use PowerCLI to start SSH service on host

execute plink script to connect to host, run command via SSH, then disconnect

Use PowerCLI to stop SSH service on host

Continue with rest of PowerCLI script

Plink is a command line connection tool – essentially a command line version of PuTTy. You can call it from dos prompt and issue it with a single, (or list) of commands to run once connected to a specified host. You can download Plink over here.

So without further ado, let’s take a look at the script as I described above.

As you can see, we start off by asking for the host IP or name, this is the only bit of manual input, but even this could be automated. The script then finds the SSH service on the host, and starts it. After this, the script calls the plink.exe file via cmd /c and connects using the root user@ the host’s IP as we entered at the beginning of the script over SSH. Plink is pointed to a commands.txt file (previously placed in the script execution folder), which contains the actual lines of bash script to be executed on the ESXi host via SSH.

Here is the content of the commands.txt file that I refer plink.exe to use (as an example, this bit of script enables copy/paste operations on all VMs running on this host in the guest OS’ console, as per VMware KB 1026437), but could contain any other commands you wish to execute on the ESXi host over SSH.

* Note two very useful techniques show by Alan in the comments section below, showing how to automatically download plink.exe if it is not available when the script is run, and also how to accept the SSH fingerprint key request by piping Y to plink.exe via the script – check out Alan’s blog post here for more detail.

A colleague was asking around for a PowerShell script that would fetch some inventory data for VMs on a Hyper-V cluster the other day. Not knowing too much about Hyper-V and having only ever briefly looked at what was out there in terms of PowerShell cmdlets for managing Hyper-V, I decided to dive in tonight after I got home.

Here is a function that will fetch Inventory data for all VMs in a specified Failover Cluster. This is what it fetches:

VM Name

VM CPU Count

VM CPU Socket Count

VM Memory configuration

VM State (Up or Down)

Cluster Name the VM resides on

Hyper-V Host name the VM resides on

Network Virtual Switch Name

NIC Mac Address

Total VHD file size in MB

Total VHD Count

Being a function, you can pipe in the name of the cluster you want, for example Get-Cluster | Get-HyperVInventory. Or you could do Get-HyperVInventory -ClusterName “ExampleClusterName”. You could also send it to an HTML Report by piping it to “ConvertTo-HTML | Out-File example.html”

The function includes help text and examples, so you can also issue the normal “Get-Help Get-HyperVInventory” or “Get-Help Get-HyperVInventory -Examples”. It is by no means perfect and could do with some improvements, for example if there is more than one Virtual Switch Network associated with a VM these would be listed in a row multiple times for each. Feel free to suggest any improvements or changes in the comments.

A few weeks ago, a colleague asked if I knew of a way to script the change or modification of the Registered Owner / Organization information on a Windows Server system (2003 or 2008). I knew that this could be achieved with PowerShell and had some initial ideas, so I spent a few minutes whipping up the script below.

For this to work, you should ideally have all systems on the same Windows Domain and have enabled PowerShell remoting on each system that needs to be changed. Of course you could also just run the script on a single workstation/server on its own without the need for PSRemoting.

# On all remote machines that need their info changed
Set-ExecutionPolicy RemoteSigned
Enable-PSRemoting # Say yes to all prompts

#region This part only needed if machines do not belong to the same domain...
# Note: This can be a security risk, only use if you are sure you want to allow any host as a trusted host. (e.g. fine for lab environments)
cd wsman::localhost\client
Set-Item .\TrustedHosts * # Say yes to all prompts
#endregion

So the above should update your registered owner and organization details for each server listed in the $computers array. (Specify your own host names here). The above script should be easy enough to modify if you are looking to change other registry entries. Finally, don’t forget that you should always be careful when updating registry, especially via script – make sure you have backups!

Now and then I find that I need to retrieve some useful information from a variety of VMs, this usually involves me doing a Get-VM with some selections and criteria to search for. However sometimes the information I require about a VM is listed in the advanced configuration and not as easy to get to with a single cmdlet. I thought it would be really handy to have a PowerCLI function that would easily pull the useful information out for me and summarise it for any given VM or set of VMs.

With that said, I recently read a great blog post by Jonathan Medd (Basic VMware Cluster Compatibility Check), and after reading it I thought it would be a great idea to create a set of functions that provide me with the information I often use. To start, I thought I would do a function that lists the most useful or common information about VMs that I often search for. As well as speeding up the process of retrieving information about VMs, I thought it would also be good PS/PowerCLI practise for me to write more functions. The reason being that I often tend to do PowerCLI reporting scripts rather than actual functions that accept input from the pipeline or other parameters. Below is my function to collect some useful information about Virtual Machines – you can specify a VM with the -VM parameter or pipe a list of VMs to it, using Get-VM | Get-VMUsefulStats. Jonathan’s post also had an interesting section about the order in which output is displayed. You’ll need to pipe the output to Select-Object to change the order the information is fed back in, otherwise it will list the information in the default order. This is not really a problem anyway, just good to know if you are fussy about the order in which the output comes back in!)

You can use the cmdlet to very easily retrieve information about a single VM or list of VMs. Examples:

Get-VMUsefulStats -VM NOOBS-VC01

Get-VM | Get-VMUsefulStats

To format the output in a neat table, pipe the above to Format-Table (ft) like so:

Get-VM | Get-VMUsefulStats | ft

The “MemShare” value is interesting – it is something I was specifically interested in, as some VMs I have worked with in the past have needed memory sharing to be specifically disabled, and this is something that needs to be changed with an advanced parameter on the VM. Therefore most (default) VMs will not have this entry at all and will appear blank in the output. (the parameter I am referring to for those interested is sched.mem.pshare.enable). Of course this most likely won’t be of any use to you, so feel free to omit this bit from the function, or feel free to customise the function to return information useful to your VMware deployment VMs. Here is an example of the output for one VM.

Anyway, I hope someone finds this useful, and please do let me know if you think of any improvements or better way of achieving a certain result.