Monday, July 11, 2016

Setting QFullSampleSize and QFullThreshold by script in ESXi 5.1

[Repost of old entry that died under the weight of spam]

With ESXi 5.1, VMware have changed things a bit for Controlling LUN queue depth throttling in VMware ESX/ESXi
- see Controlling LUN queue depth throttling in VMware ESX/ESXi

Previously it was a global setting on the host, configured in the Advanced Settings - and could be checked and set using PowerCLI. eg :

To check values :

Get-VMHostAdvancedConfiguration -vmhost <host> -name Disk.QFullSampleSize
Get-VMHostAdvancedConfiguration -vmhost <host> -name Disk.QFullThreshold

To set values :

Set-VMHostAdvancedConfiguration -vmhost <host> -name Disk.QFullSampleSize -value <int>
Set-VMHostAdvancedConfiguration -vmhost <host> -name Disk.QFullThreshold -value <int>

That’s no longer the case. Now, it’s per LUN and not global. So, each LUN you present will need setting (if you use this), and on each host.

We use 3Par storage, and do set the values recommended :

QFullSampleSize = 32.
QFullThreshold = 4

The question was asked whether these settings were retained on a host that had them, and was then upgraded to 5.1. An upgrade in one of the test labs seems to indicate they’re not - all LUNs were set to 0 for these parameters.

So, I decided to try and script something. The result is below.

Basically, I read the LUN device ID from a text file (one entry per line), and then apply the change to it. The problem then is generating the text file - we have 50+ LUNs per host typically. For this, I used RV Tools , and exported the vDatastore tab, which includes the value I need - second column labelled Address. I take those values, and stick them in the text file - cumbersome, but it works.

I call the script, and chmod +x it to set the execute bit.


usage() {
        echo "Usage : ./ filename.txt"
        echo "Where filename.txt is the file with the list of naa ids, eg test.txt"

# File with the naa entries. One per line.

# Check script is invoked with correct number of arguments, ie, filename.txt
# If not, give usage details then exit.
[[ $# -ne 1 ]] && usage && exit 1

# Check if the file specified exists, if not, exit
if [ ! -f $filename ]
        echo "$filename does not exist. Exiting"
        exit 1

# Set the values, working through the input file one line at a time.
echo "Reading in the file $filename"
cat $filename | while read line
        echo "Running the following ... esxcli storage core device set --device $line -q=4 -s=32"
        esxcli storage core device set --device $line -q=4 -s=32

echo "Completed the changes ... exiting"

How to run :
# ./
Usage : Set3Par filename.txt
Where filename.txt is list of naa ids, eg test.txt

Sample input file : (values changed for writeup purposes)
# more test.txt

Sample run:
# ./ test.txt
Reading in the file test.txt
Running the following … esxcli storage core device set –device naa.50002aaaaaaaaaaa -q=4 -s=32
Running the following … esxcli storage core device set –device naa.50002bbbbbbbbbbb -q=4 -s=32
Running the following … esxcli storage core device set –device naa.50002ccccccccccc -q=4 -s=32
Running the following … esxcli storage core device set –device naa.50002ddddddddddd -q=4 -s=32
Running the following … esxcli storage core device set –device naa.50002eeeeeeeeeee -q=4 -s=32
Completed the changes … exiting

Monday, May 25, 2015

Enable or disable CBT

Implementing a new client solution recently based on vSphere 6, there was a request from our backup team to enable CBT on the VMs that were to be backed up. This basically meant around about 160 VMs from the overall solution.

Per the VMware KB article, this would entail shutting down the VM, adding the ctkEnabled parameter and then set its value to true and then Add Row, add scsi0:0.ctkEnabled, and set its value to true. Finally, power the VM back on.

To disable, again, power down the VMs.

This is a bit tedious obviously for 160 VMs, not to mention the downtime incurred for the client solution. However, in the KB article is some PowerCLI script to achieve the same end result, but without powering down the VM.

So, for ease, I took this and just put it into a simple loop to read in the list of VMs from a .txt file (1 VM per line) and make the change. It’s easy enough to have another script to disable the change and do it enmasse. Even better given the (now apparently resolved via latest patch) issue described here.

Also, there’s a one line to list out whether CBT is enabled on all the VMs in the environment.


# Enable CBT on number of VMs based on .txt file
# 1 VM per line - name as per vSphere client
# Based on the code from

$vmlist = Read-Host "Enter the name of the file with the list of VMs"

$vmname = get-content $vmlist

ForEach ($vm in (Get-VM $vmname))

    $vmtest = Get-vm $vm| get-view
    $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec

    # enable ctk
    $vmConfigSpec.changeTrackingEnabled = $true
    $snap=New-Snapshot $vm -Name "Enable CBT"
    $snap | Remove-Snapshot -confirm:$false



# Disable CBT on number of VMs based on .txt file
# 1 VM per line - name as per vSphere client
# Based on the code from

$vmlist = Read-Host "Enter the name of the file with the list of VMs"

$vmname = get-content $vmlist

ForEach ($vm in (Get-VM $vmname))

    $vmtest = Get-vm $vm| get-view
    $vmConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec

    #disable ctk
    $vmConfigSpec.changeTrackingEnabled = $false
    $snap=New-Snapshot $vm -Name "Disable CBT"
    $snap | Remove-Snapshot -confirm:$false



# Check CBT status on all VMs
get-vm  | Get-View | Sort Name| Select Name, @{N="CBT State";E={$_.Config.ChangeTrackingEnabled}} | ft -AutoSize

Tuesday, October 16, 2012

Quick check on number of VMs powered on and off in multiple VCs

Recently there was a need to quickly report the number of VMs in all VCs, ideally with numbers for powered on and powered off VMs. We have multiple VCs (10 plus), not in linked mode, so it meant connecting to each and counting or exporting the information.

It’s fairly easy to get this information, but figured a script may be in order, in case the request was made again in the future, so this is what I came up with. It’s rough and ready, but did what I needed it to do. And yes, there are other scripts and tools (RVTools, PowerGUI with the VMware powerpack etc) that can do it, but this is partly an exercise in trying to get to grips with Powershell and PowerCLI.

It also spits out a couple of CSV files with a basic host report and VM report per VC in files named per VC. Assumes credentials are sorted in some way for conveniance - ie, credentials store.

The VCs to check are listed in the vclist.txt file

$currVC = Get-Content "vclist.txt"
foreach ($targetVC in $currVC) {
        Connect-VIServer $targetVC
        $hostCount = Get-VMhost
        write-host "Total number of hosts in $targetVC :" ($hostCount).count
# VM's, powered on and memory count
        Write-Host "Collecting VM information"
        $OutputFile = $targetVC + ".csv"
        $totalvms = get-vm | where{$_.powerstate -eq "PoweredOn" } |`
                select name, powerstate, numcpu, memorymb | `
                export-csv -NoTypeInformation $outputFile | out-null
        $pvms = Get-VM
        write-host "Powered on: " ($pvms | where {$_.PowerState -eq "PoweredOn"}
        write-host "Powered off: " ($pvms | where {$_.PowerState -eq "PoweredOff

# VMhost details
        Write-Host "Collecting host information"
        $HostOutputFile = $targetVC + "-vmhost.csv"
        $totalHosts = get-vmhost | select name, numcpu, CPUTotalMHz, MemoryTotal
MB, MemoryUsageMB, Parent |`
                Export-Csv -NoTypeInformation  $HostOutputFile | out-null
Disconnect-VIServer -Confirm:$false

Monday, October 15, 2012

Using PowerCLI to retrieve IP from VM annotations

In our environment, we have a lot of VMs on NAT’d addresses. On occassion, I need acccess to their public IP - eg, for pinging to verify guests are still running if we put a host into maintenance mode. Grabbing the address from the internal system for each VM is time consuming and somewhat annoying. vSphere reports the private IP in the GUI which isn’t what I want. You can extract the info from the VM with PowerCLI, but again, it’s a little awkward (for my skill level). And we don’t label the VMs by their DNS name, it’s more an internal system, which again, makes identifying a particular machine harder than I would like, but that’s the way the system is.

Luckily, when we create VMs, we add annotations. One of which contains the public IP (or it should if people fill in the details :-)

That allows a way to grab the public IP with a one liner (here the assumption is the annotation field is called Public IP).

For VM called “foo” :

get-vm  foo|  get-annotation | where-object {$ -eq "Public IP"}

For all VMs in a VC :

get-vm | get-annotation | where-object {$ -eq "Public IP"}

Or, if we want just the powered on VMs :

get-vm | where-object {$_.powerstate -eq "PoweredOn"} | get-annotation | where-object {$ -eq "Public IP"}

I export them to .csv, and now have a more manageable way of quickly being able to call upon the relevant IPs

New role …

Recently started a new position, as a VMware guy in a managed service provider.

There are various challenges involved (mainly process oriented), but one challenge is scale. It’s a much larger environment than I had previously administered.

So, it means different ways of doing things, and makes me appreciate more the value of automation and the use of PowerCLI.

Problem is, I suck at coding. Always have, always will. But still, I feel I need to do it to make the role manageable. So, I’m going to start posting some bits and pieces I’ve been writing to try and help me and solve problems as they arise or as I see them. The code will almost invariably suck, but hey ho.

I use a lot of the “standard” resources. Google, Alan Renouf’s site, the PowerCLI book (I have it through my OReilly Safari account). Pretty much anything I do has (almost certainly) been done before (and better), but future entries will have some of my dabblings (primarily for my reference).