Scripting

List VMs with Non Thick Disks

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
foreach ($vm in Get-VM)
{
    $badFormat = $false
    foreach ($hardDisk in (Get-HardDisk -VM $vm))
    {   
        if ($hardDisk.StorageFormat -ne "Thick")
        {
            $badFormat = $true
        }   
    }
 
    if ($badFormat)
    {
        $vm.Name
    }
}

Require a minimum version of PowerCLI

A lot of the script that I have been writing rely on new cmdlets or properties in the current release of PowerCLI. Telling people to upgrade before running the scripts has not been enough so I am going to do the smart thing and check that the appropriate version is running.

Here is the code to that I am using to do the validation.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
# By default this will check that the running version of PowerCLI is greater
# than or equal to the specified version and throw an exception if not.
# For an exact match specify the -exact parameter.
function Require-PowerCliVersion
{
    param
    (
        [Int32]$build = $(throw "Require-PowerCliVersion: No build number specified."),
        [switch]$exact # If true requires the exact build number to match.
    )
 
    $passed = $false
 
    if (Get-Command Get-PowerCliVersion -ErrorAction SilentlyContinue)
    {
        $cliBuild = (Get-PowerCliVersion).Build
 
        if ($exact)
        {
            if ($build -eq $cliBuild)
            {
                $passed = $true
            }
        }
        elseif ($cliBuild -ge $build)
        {
            $passed = $true
        }
    }
 
    if (!$passed)
    {
        throw "Require-PowerCliVersion: Minimum PowerCLI version requirement not met."
    }
}

VMware vCLI “persistent login”

Here is a short convenience script that will simulate a persistent login to a VMware host system when using the vCLI on Windows. Typically you have to specify a lot of parameters that include login information or a session file. With this method you just run the script and provide the hostname, username, and password for the connection.

After running this script you can run commands like “vicfg-mpath.pl –list” without additional parameters.

There is much that could be done to improve this script; this is just a quick and dirty version to make my life easier. If I improve it in the future I will post updates.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#!/usr/bin/perl -w
 
use strict;
use warnings;
 
my $vcli_install_dir = "C:\\Program Files\\VMware\\VMware vSphere CLI\\bin";
chdir($vcli_install_dir) or die "Could not change to the vCLI directory: $vcli_install_dir";
 
print "Hostname:";
my $host_name = <STDIN>;
chomp($host_name);
 
$ENV{'VI_SERVER'} = $host_name;
my $session_file_name = $ENV{'TEMP'} . "\\vcli.session";
$ENV{'VI_SAVESESSIONFILE'} = $session_file_name;
 
system("..\\Perl\\apps\\session\\save_session.pl");
$ENV{'VI_SESSIONFILE'} = $session_file_name;
 
print "Spawning a logged in subshell.  Type exit to end the session.\n";
system("cmd.exe");
 
# Remove the session file.
unlink($session_file_name);

Maximum vSwitches in vSphere

There appears to be a discrepancy in the VMware documentation regarding the maximum number of vSwitches. The Configuration Maximums document states that the limit is 248. The configuration guide lists the maximum as 127 which is what it was in 3.5. I am not sure if I misunderstand what they mean by “Standard switches per host 248”. If you see the error of my ways let me know.

Here is some code that I used to see how many vSwitches I could put on a host. This will create 126 vSwitches, each with 8 usable ports, (I am assuming that vSwitch0 is already configured. Any attempts to add another one fail.

$vmhost = Get-VMhost <mytestHost>.local
1..126 | % {New-VirtualSwitch -VMHost $vmhost -Name vSwitch$_ -NumPorts 16}

Configure NTP on Multiple Hosts Using PowerShell

A handy script to correct NTP settings on multiple hosts.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#Usage: Get-VMHost | .\ConfigureNtpServer.ps1
 
BEGIN
{
    $ntpServers = @("ntpserver01","ntpserver02")
 
    $hostDateTimeConfig = New-Object Vmware.Vim.HostDateTimeConfig 
    $hostNtpConfig = New-Object VMware.Vim.HostNtpConfig 
    $hostDateTimeConfig.ntpConfig = $hostNtpConfig 
    $hostDateTimeConfig.ntpConfig.server = $ntpServers
}
 
 
PROCESS
{
    $vmHost = $_
    $vmHostView = Get-View $vmHost.ID
    $dateTimeSystem =  $vmHostView.ConfigManager.DateTimeSystem 
    $DateTimeSystemRef = Get-View  $dateTimeSystem
    $DateTimeSystemRef.updateDateTimeConfig($hostDateTimeConfig)
}