#!/usr/bin/perl -w
##################################################################
# Author: William Lam
# Email: william2003[at]gmail[dot]com
# 01/26/2009
# http://www.engineering.ucsb.edu/~duonglt/vmware/
##################################################################
use strict;
use warnings;
use Math::BigInt;
use Tie::File;
use Getopt::Long;
use VMware::VIRuntime;
use VMware::VILib;
################################
# disk consumption warnings
################################
# yellow < 30 %
my $yellow_warn = 30;
# orange < 15 %
my $orange_warn = 15;
# red < 10%
my $red_warn = 10;
########### DO NOT MODIFY PAST HERE ###########
################################
# VERSION
################################
my $version = "v0.3";
################################
# DEMO MODE
# 0 = no, 1 = yes
################################
my $enable_demo_mode = 0;
################
#GLOBAL VARS
################
my $host_type;
my $host_view;
my $host_views;
my $cluster_view;
my $cluster_views;
my $cluster_count = 0;
my $report_name;
my @snapshot_vms = ();
my @connected_cdrom_vms = ();
my @connected_floppy_vms = ();
my @rdm_vms = ();
my @npiv_vms = ();
my %net_vms = ();
my %vms_storage = ();
my %vms_disks = ();
my $execute_flag = 0;
my $start_time;
my $end_time;
my $run_time;
my $my_time;
my @jump_tags = ();
my %cdp_enabled = ();
my @hba_list = ();
my @nic_list = ();
my %opts = (
cluster => {
type => "=s",
help => "The name of a vCenter cluster",
required => 0,
},
type => {
type => "=s",
help => "Type: [vcenter|cluster|host]\n",
required => 1,
},
report => {
type => "=s",
help => "The name of the report to output",
required => 0,
},
);
# validate options, and connect to the server
Opts::add_options(%opts);
# validate options, and connect to the server
Opts::parse();
Opts::validate();
Util::connect();
############################
# PARSE COMMANDLINE OPTIONS
#############################
if (Opts::option_is_set ('type')) {
$host_type = Opts::get_option('type');
####################
# SINGLE ESX HOST
####################
if( ($host_type eq "host") && (!Opts::option_is_set('cluster')) ) {
$host_view = Vim::find_entity_views(view_type => 'HostSystem');
if (!$host_view) {
die "ESX/ESXi host was not found\n";
}
}
#####################
# vCENTER + CLUSTER
#####################
elsif( $host_type eq "cluster" ) {
if ( Opts::option_is_set('cluster') ) {
my $cluster_name = Opts::get_option('cluster');
$cluster_view = Vim::find_entity_view(view_type => 'ClusterComputeResource',filter => { name => $cluster_name });
if(!$cluster_view) {
die "\"$cluster_name\" was not found\n";
}
}
else {
Fail("\n--cluster parameter required with the name of a valid vCenter Cluster\n\n");
}
}
##################
# vCENTER ALL
##################
elsif( ($host_type eq "vcenter") && (!Opts::option_is_set('cluster')) ) {
$cluster_views = Vim::find_entity_views(view_type => 'ClusterComputeResource');
Fail ("No clusters found.\n") unless (@$cluster_views);
}
#if report name is not specified, default output
if (Opts::option_is_set ('report')) {
$report_name = Opts::get_option('report');
}
else {
$report_name = "report.html";
}
}
### CODE START ###
#################################
# PRINT HTML HEADER/CSS
#################################
printStartHeader();
#########################################
# PRINT vCENTER or HOST BUILD/SUMMARY
#########################################
printBuildSummary();
#########################################
# PRINT vCENTER INFO
#########################################
if ($host_type eq 'vcenter') {
foreach my $cluster (@$cluster_views) {
$cluster_count += 1;
printClusterSummary($cluster);
my $hosts = Vim::get_views (mo_ref_array => $cluster->host);
printHostHardwareInfo($hosts);
printHostDatastoreInfo($hosts);
printHostVM($hosts);
printVMDatastore();
printVMNetwork();
printVMSnapshot();
printVMNPIV();
printVMRDM();
printVMCDrom();
printVMFloppy();
}
}
#########################################
# PRINT SPECIFIC CLUSTER INFO
#########################################
elsif ($host_type eq 'cluster') {
$cluster_count += 1;
printClusterSummary($cluster_view);
my $hosts = Vim::get_views (mo_ref_array => $cluster_view->host);
printHostHardwareInfo($hosts);
printHostDatastoreInfo($hosts);
printHostVM($hosts);
printVMDatastore();
printVMNetwork();
printVMSnapshot();
printVMNPIV();
printVMRDM();
printVMCDrom();
printVMFloppy();
}
#########################################
# PRINT SINGLE HOST INFO
#########################################
else {
printHostHardwareInfo($host_view);
printHostDatastoreInfo($host_view);
printHostVM($host_view);
printVMDatastore();
printVMNetwork();
printVMSnapshot();
printVMNPIV();
printVMRDM();
printVMCDrom();
printVMFloppy();
}
#################################
# CLOSE HTML REPORT
#################################
printCloseHeader();
Util::disconnect();
### CODE END ###
###########################
#
# HELPER FUNCTIONS
#
###########################
sub printVMNPIV {
###########################
# PRINT NPIV INFO
###########################
if(@npiv_vms) {
my $npiv_count = $#npiv_vms;
$npiv_count += 1;
push @jump_tags," VM(s) w/NPIV enabled
";
print REPORT_OUTPUT "";
print REPORT_OUTPUT "
$npiv_count VM(s) w/NPIV enabled:
\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "VM | NPIV NODE WWN | NPIV PORT WWN | GENERATED FROM |
";
foreach (@npiv_vms) {
print REPORT_OUTPUT "",$_,"
";
}
print REPORT_OUTPUT "
\n";
}
@npiv_vms = ();
}
sub printVMSnapshot {
###########################
# PRINT SNAPSHOT INFO
###########################
if(@snapshot_vms) {
my $snap_count = $#snapshot_vms;
$snap_count += 1;
push @jump_tags," VM(s) w/Snapshot(s)
";
print REPORT_OUTPUT "";
print REPORT_OUTPUT "$snap_count VM(s) w/Snapshot(s):
\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "VM | SNAPSHOT NAME | SNAPSHOT DESC | CREATED | STATE | QUIESCED |
";
foreach (@snapshot_vms) {
print REPORT_OUTPUT "",$_,"
";
}
print REPORT_OUTPUT "
\n";
}
@snapshot_vms = ();
}
sub printVMRDM {
###########################
# PRINT RDM INFO
###########################
if(@rdm_vms) {
my $rdm_count = $#rdm_vms;
$rdm_count += 1;
push @jump_tags," VM(s) w/RDM(s)
";
print REPORT_OUTPUT "";
print REPORT_OUTPUT "$rdm_count VM(s) w/RDM(s):
\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "VM | COMPAT MODE | DEVICE | DISK MODE | LUN UUID | VIRTUAL DISK UUID |
";
foreach (@rdm_vms) {
print REPORT_OUTPUT "",$_,"
";
}
print REPORT_OUTPUT "
\n";
}
@rdm_vms = ();
}
sub printVMCDrom {
###########################
# PRINT CDROM INFO
###########################
if(@connected_cdrom_vms) {
my $cdrom_count = $#connected_cdrom_vms;
$cdrom_count += 1;
push @jump_tags," VM(s) w/connected CD-ROM(s)
";
print REPORT_OUTPUT "";
print REPORT_OUTPUT "$cdrom_count VM(s) w/connected CD-ROM(s):
\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "VM |
";
foreach (@connected_cdrom_vms) {
print REPORT_OUTPUT "",$_," |
";
}
print REPORT_OUTPUT "
\n";
}
@connected_cdrom_vms = ();
}
sub printVMFloppy {
###########################
# PRINT FLOPPY INFO
###########################
if(@connected_floppy_vms) {
my $floppy_count = $#connected_floppy_vms;
$floppy_count += 1;
push @jump_tags," VM(s) w/connected Floppy(s)
";
print REPORT_OUTPUT "";
print REPORT_OUTPUT "$floppy_count VM(s) w/connected Floppy(s):
\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "VM |
";
foreach (@connected_floppy_vms) {
print REPORT_OUTPUT "",$_," |
";
}
print REPORT_OUTPUT "
\n";
}
@connected_floppy_vms = ();
}
sub printVMNetwork {
####################################
# PRINT VM NETWORK SUMMARY
####################################
if(%net_vms) {
push @jump_tags," VM(s) Network Summary
";
print REPORT_OUTPUT "";
print REPORT_OUTPUT "VM(s) Network Summary:
\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "VM | IP(s) | MAC ADDRESS | PORTGROUP | CONNECTED |
";
foreach ( sort keys %net_vms ) {
my $vm_net = $net_vms{$_};
print REPORT_OUTPUT "",$_," | ",$vm_net,"
\n";
}
print REPORT_OUTPUT "
\n";
}
%net_vms = ();
}
sub printVMDatastore {
####################################
# PRINT VM DISK/DATASTORE SUMMARY
####################################
if(%vms_storage) {
push @jump_tags," VM(s) Storage Summary
";
print REPORT_OUTPUT "";
print REPORT_OUTPUT "VM(s) Storage Summary:
\n";
print REPORT_OUTPUT "COLOR LEGEND | YELLOW < $yellow_warn % | ORANGE < $orange_warn % | RED < $red_warn % |
";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "VM | DATASTORE | DISK INFO | FREE SPACE | CAPACITY | PERCENT FREE |
|
";
foreach ( sort keys %vms_storage ) {
my $vm_ds = $vms_storage{$_};
my $vm_disk = $vms_disks{$_};
if(!$vm_disk) {
$vm_disk = "not available | ";
}
print REPORT_OUTPUT "",$_," | ",$vm_ds," | ",$vm_disk,"
\n";
}
print REPORT_OUTPUT "
\n";
}
%vms_storage = ();
}
sub printHostVM {
my ($local_hosts) = @_;
###########################
# PRINT VM SUMMARY
###########################
my $seen_vm = 0;
push @jump_tags," Virtual Machines
";
print REPORT_OUTPUT "";
print REPORT_OUTPUT "Virtual Machines:
\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "ESX/ESXi HOST | VM | HOSTNAME | VM STATUS | CONNECTION STATE | POWER STATE | # OF DISK(s) | # OF vCPU(s) | MEM | CPU USAGE | MEM USAGE | CPU RESRV | MEM RESRV | # OF vNIC(s) | VMware Tools Status | TIME SYNC w/HOST | TOOLS VER | TOOLS UPGRADE POLICY | TOOLS MOUNTED | GUEST OS | IS TEMPLATE |
\n";
foreach my $host (@$local_hosts) {
my $vm_views = Vim::get_views (mo_ref_array => $host->vm);
#clear seen vms hash
foreach my $vm (@$vm_views) {
print REPORT_OUTPUT "\n";
my $vm_host_view = Vim::get_view (mo_ref => $vm->runtime->host);
if($enable_demo_mode eq 1) {
print REPORT_OUTPUT "HIDE ME! | ";
print REPORT_OUTPUT "",$vm->config->name," | ";
print REPORT_OUTPUT "HIDE ME! | ";
}
else {
print REPORT_OUTPUT "",$vm_host_view->summary->config->name," | ";
print REPORT_OUTPUT "",$vm->config->name," | ";
if (defined($vm->guest->hostName)) {print REPORT_OUTPUT "",$vm->guest->hostName," | "; }
else { print REPORT_OUTPUT "UNKNOWN | "; }
}
$seen_vm = 1;
my $vm_health = $vm->summary->overallStatus->val;
if ($vm_health eq 'green') { print REPORT_OUTPUT "VM is OK | "; }
elsif ($vm_health eq 'red') { print REPORT_OUTPUT "VM has a problem | "; }
elsif ($vm_health eq 'yellow') { print REPORT_OUTPUT "VM"; }
else { print REPORT_OUTPUT "UNKNOWN | "; }
print REPORT_OUTPUT "",$vm->runtime->connectionState->val," | ";
print REPORT_OUTPUT "",$vm->runtime->powerState->val," | ";
if (defined($vm->summary->config->numVirtualDisks)) {print REPORT_OUTPUT "",$vm->summary->config->numVirtualDisks," | "; }
else {print REPORT_OUTPUT "UNKNOWN | "; }
if (defined($vm->summary->config->numCpu)) {print REPORT_OUTPUT "",$vm->summary->config->numCpu," | "; }
else {print REPORT_OUTPUT "UNKNOWN | "; }
if (defined($vm->summary->config->memorySizeMB)) {print REPORT_OUTPUT "",$vm->summary->config->memorySizeMB," MB | "; }
else {print REPORT_OUTPUT "UNKNOWN | "; }
my $isTemplate = $vm->config->template;
if (! $isTemplate) {
if (defined($vm->summary->quickStats->overallCpuUsage)) {print REPORT_OUTPUT "",$vm->summary->quickStats->overallCpuUsage," Mhz | "; }
else {print REPORT_OUTPUT "UNKNOWN | "; }
if (defined($vm->summary->quickStats->guestMemoryUsage)) {print REPORT_OUTPUT "",$vm->summary->quickStats->guestMemoryUsage," MB | "; }
else {print REPORT_OUTPUT "UNKNOWN | "; }
if (defined($vm->summary->config->cpuReservation)) {print REPORT_OUTPUT "",$vm->summary->config->cpuReservation," Mhz | "; }
else {print REPORT_OUTPUT "UNKNOWN | "; }
if (defined($vm->summary->config->memoryReservation)) {print REPORT_OUTPUT "",$vm->summary->config->memoryReservation," MB | "; }
else {print REPORT_OUTPUT "UNKNOWN | "; }
}
else {
print REPORT_OUTPUT "N/A | ";
print REPORT_OUTPUT "N/A | ";
print REPORT_OUTPUT "N/A | ";
print REPORT_OUTPUT "N/A | ";
}
if (defined($vm->summary->config->numEthernetCards)) {print REPORT_OUTPUT "",$vm->summary->config->numEthernetCards," | "; }
else {print REPORT_OUTPUT "UNKNOWN | "; }
if (! $isTemplate) {
if (defined($vm->summary->guest->toolsStatus->val)) {print REPORT_OUTPUT "",$vm->summary->guest->toolsStatus->val," | "; }
else {print REPORT_OUTPUT "UNKNOWN | "; }
if (defined($vm->config->tools->syncTimeWithHost)) { print REPORT_OUTPUT "",($vm->config->tools->syncTimeWithHost) ? "YES" : "NO"," | "; }
else {print REPORT_OUTPUT "UNKNOWN | "; }
if (defined($vm->config->tools->toolsVersion)) {print REPORT_OUTPUT "",$vm->config->tools->toolsVersion," | "; }
else {print REPORT_OUTPUT "UNKNOWN | "; }
if (defined($vm->config->tools->toolsUpgradePolicy)) {print REPORT_OUTPUT "",$vm->config->tools-> toolsUpgradePolicy," | "; }
else {print REPORT_OUTPUT "UNKNOWN | "; }
print REPORT_OUTPUT "",($vm->runtime->toolsInstallerMounted) ? "YES" : "NO" ," | ";
if (defined($vm->summary->guest->guestFullName)) {print REPORT_OUTPUT "",$vm->summary->guest->guestFullName," | "; }
else {print REPORT_OUTPUT "UNKNOWN | "; }
}
else {
print REPORT_OUTPUT "N/A | ";
print REPORT_OUTPUT "N/A | ";
print REPORT_OUTPUT "N/A | ";
print REPORT_OUTPUT "N/A | ";
print REPORT_OUTPUT "N/A | ";
print REPORT_OUTPUT "N/A | ";
}
print REPORT_OUTPUT "",($isTemplate) ? "YES" : "NO" ," | ";
print REPORT_OUTPUT " |
\n";
#retrieve vms w/connected CDROM/FLOPPY
my $devices = $vm->config->hardware->device;
foreach my $device (@$devices) {
my $device_name = $device->deviceInfo->label;
if ( ($device->isa('VirtualCdrom')) && ($device->connectable->connected == 1) ) {
if($seen_vm eq 1) {
push @connected_cdrom_vms,$vm->config->name;
}
}
if ( ($device->isa('VirtualFloppy')) && ($device->connectable->connected == 1) ) {
if($seen_vm eq 1) {
push @connected_floppy_vms,$vm->config->name;
}
}
if ( ($device->isa('VirtualDisk')) && ($device->backing->isa('VirtualDiskRawDiskMappingVer1BackingInfo')) ) {
if($seen_vm eq 1) {
my $vm_name = $vm->config->name;
my $compat_mode = $device->backing->compatibilityMode;
my $vmhba = $device->backing->deviceName;
my $disk_mode = $device->backing->diskMode;
my $lun_uuid = $device->backing->lunUuid;
my $vm_uuid = $device->backing->uuid;
my $rdm_string = "";
if(!$vm_uuid) { $vm_uuid="N/A"; }
$rdm_string="$vm_name | $compat_mode | $vmhba | $disk_mode | $lun_uuid | $vm_uuid | ";
push @rdm_vms,$rdm_string;
}
}
}
#retrieve vms w/NPIV
my $nwwns = $vm->config->npivNodeWorldWideName;
my $pwwns = $vm->config->npivPortWorldWideName;
my $n_type = $vm->config->npivWorldWideNameType;
if( ($nwwns) && ($seen_vm eq 1) ) {
my $npiv_string = "";
my $n_vm = $vm->config->name;
$npiv_string .= "$n_vm | ";
$npiv_string .= "";
foreach (@$nwwns) {
my $nwwn = (Math::BigInt->new($_))->as_hex();
$nwwn =~ s/^..//;
$nwwn = join(':', unpack('A2' x 8, $nwwn));
$npiv_string .= "$nwwn "
}
$npiv_string .= " | ";
foreach (@$pwwns) {
my $pwwn = (Math::BigInt->new($_))->as_hex();
$pwwn =~ s/^..//;
$pwwn = join(':', unpack('A2' x 8, $pwwn));
$npiv_string .= "$pwwn "
}
if($n_type eq 'vc') { $n_type = "Virtual Center"; }
elsif($n_type eq 'external') { $n_type = "External Source"; }
elsif($n_type eq 'host') { $n_type = "ESX or ESXi"; }
$npiv_string .= " | $n_type | ";
push @npiv_vms,$npiv_string;
}
#retrieve vms w/snapshots
if(defined($vm->snapshot)) {
if($seen_vm eq 1) {
print_tree ($vm->config->name,$vm->snapshot->currentSnapshot, $vm->snapshot->rootSnapshotList);
}
}
#retrieve disk summary from VM
my $disks = $vm->guest->disk;
my $vm_name;
my $disk_string = "";
foreach my $disk (@$disks) {
if($seen_vm eq 1) {
$vm_name = $vm->config->name;
my $vm_disk_path = $disk->diskPath;
my $vm_disk_free = &restrict_num_decimal_digits(($disk->freeSpace/1024/1000),2);
my $vm_disk_cap = &restrict_num_decimal_digits(($disk->capacity/1024/1000),2);
my $vm_perc_free = &restrict_num_decimal_digits((($vm_disk_free / $vm_disk_cap) * 100),2);
my $perc_string = "";
if($vm_perc_free lt $yellow_warn) {
$perc_string = "".$vm_perc_free." % | ";
}
elsif ($vm_perc_free lt $orange_warn) {
$perc_string = "".$vm_perc_free." % | ";
}
elsif ($vm_perc_free lt $red_warn) {
$perc_string = "".$vm_perc_free." % | ";
}
else {
$perc_string = "".$vm_perc_free." % | ";
}
$disk_string .= "$vm_disk_path | $vm_disk_free MB | $vm_disk_cap MB | $perc_string
| ";
}
}
if (defined($vm_name)) {
$vms_disks{$vm_name} = $disk_string;
}
#retrieve datastore summary from VM
my $vm_datastore_view = $vm->datastore;
foreach (@$vm_datastore_view) {
if($seen_vm eq 1) {
my $ds = Vim::get_view(mo_ref => $_);
$vms_storage{$vm->config->name} = $ds->summary->name;
}
}
#retrieve network summary from VM
my $vm_nets = $vm->guest->net;
my $vm_conn_string = "";
my $vm_ip_string = "";
my $vm_mac_string = "";
my $vm_pg_string = "";
foreach my $vm_net (@$vm_nets) {
if($seen_vm eq 1) {
$execute_flag = 1;
my $net_conn = $vm_net->connected;
if($net_conn eq '1') { $net_conn = "YES"; } else { $net_conn = "NO"; }
$vm_conn_string .= $net_conn."
";
my $ip_arr = $vm_net->ipAddress;
foreach (@$ip_arr) {
if($enable_demo_mode eq 1) {
$vm_ip_string .= "HIDE ME!
";
}
else {
$vm_ip_string .= $_."
";
}
}
my $net_mac = $vm_net->macAddress;
my $net_pg = $vm_net->network;
if($enable_demo_mode eq 1) {
$net_mac .= "HIDE MY MAC!
";
$vm_pg_string .= "HIDE MY PG!
";
}
else {
$vm_mac_string .= $net_mac."
";
$vm_pg_string .= $net_pg."
";
}
if($vm_ip_string eq '') { $vm_ip_string="UNKNOWN
"; }
if($vm_mac_string eq '') { $vm_mac_string="UNKNOWN
"; }
if($vm_pg_string eq '') { $vm_pg_string="UNKNOWN
"; }
if($vm_conn_string eq '') { $vm_conn_string="UNKNOWN
"; }
}
}
#could not retrieve network info (no VMware tools or not online)
if(!@$vm_nets) {
$vm_ip_string="UNKNOWN
";
$vm_mac_string="UNKNOWN
";
$vm_pg_string="UNKNOWN
";
$vm_conn_string="UNKNOWN
";
}
if($execute_flag eq 1) {
$net_vms{$vm->config->name} = "".$vm_ip_string." | ".$vm_mac_string." | ".$vm_pg_string." | ".$vm_conn_string." | ";
$execute_flag = 0;
}
$seen_vm = 0;
}
}
print REPORT_OUTPUT "
\n";
}
sub printHostDatastoreInfo {
my ($local_hosts) = @_;
###########################
# PRINT DATASTORE SUMMARY
###########################
push @jump_tags," ESX/ESXi Datastore(s)
";
print REPORT_OUTPUT "";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "ESX/ESXi Datastore(s):
\n";
print REPORT_OUTPUT "COLOR LEGEND | YELLOW < $yellow_warn % | ORANGE < $orange_warn % | RED < $red_warn % |
";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "DATASTORE | CAPACITY | CONSUMED | FREE | % FREE | DS TYPE |
";
my @datastores_seen = ();
foreach my $host (@$local_hosts) {
my $ds_views = Vim::get_views (mo_ref_array => $host->datastore);
foreach my $ds (sort {$a->info->name cmp $b->info->name} @$ds_views) {
#if ($ds->summary->multipleHostAccess ) {
if (!grep {$_ eq $ds->info->name} @datastores_seen) {
push @datastores_seen,$ds->info->name;
my $perc_free;
my $ds_used;
my $ds_free;
my $ds_cap;
my $perc_string = "";
if ( ($ds->summary->freeSpace gt 0) || ($ds->summary->capacity gt 0) ) {
$ds_cap = &restrict_num_decimal_digits($ds->summary->capacity/1024/1000,2);
$ds_used = &restrict_num_decimal_digits((($ds->summary->capacity - $ds->summary->freeSpace)/1024/1000),2);
$ds_free = &restrict_num_decimal_digits(($ds->summary->freeSpace/1024/1000),2);
$perc_free = &restrict_num_decimal_digits(( 100 * $ds_free / $ds_cap),2);
if($perc_free lt $yellow_warn) {
$perc_string = "".$perc_free." % | ";
}
elsif ($perc_free lt $orange_warn) {
$perc_string = "".$perc_free." % | ";
}
elsif ($perc_free lt $red_warn) {
$perc_string = "".$perc_free." % | ";
}
else {
$perc_string = "".$perc_free." % | ";
}
}
else {
$perc_free = "UNKNOWN";
$ds_used = "UNKNOWN";
$ds_free = "UNKNOWN";
}
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "",$ds->info->name," | ";
print REPORT_OUTPUT "",$ds_cap," MB | ";
print REPORT_OUTPUT "",$ds_used," MB | ";
print REPORT_OUTPUT "",$ds_free," MB | ";
print REPORT_OUTPUT $perc_string;
print REPORT_OUTPUT "",$ds->summary->type," | ";
print REPORT_OUTPUT "
\n";
}
#}
}
}
print REPORT_OUTPUT "
\n";
}
sub printHostHardwareInfo {
my ($local_hosts) = @_;
###########################
# PRINT HOST HARDWARE
###########################
push @jump_tags," ESX/ESXi hardware configuration
";
print REPORT_OUTPUT "";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "HOSTNAME | VENDOR | CPU INFO | HT AVAILABLE/ENABLED | CPU SPEED | CPU USAGE | CPU PACKAGE(s) | CPU CORE(s) | CPU THREAD(s) | MEMORY | MEMORY USAGE | NIC(s) | HBA(s) |
\n";
print REPORT_OUTPUT "ESX/ESXi hardware configuration:
\n";
foreach my $local_host (sort {$a->summary->config->name cmp $b->summary->config->name} @$local_hosts) {
print REPORT_OUTPUT "\n";
if($enable_demo_mode eq 1) {
print REPORT_OUTPUT "HIDE ME! | ";
}
else {
print REPORT_OUTPUT "",$local_host->summary->config->name," | ";
}
print REPORT_OUTPUT "",$local_host->summary->hardware->vendor," | ";
print REPORT_OUTPUT "",$local_host->summary->hardware->cpuModel," | ";
print REPORT_OUTPUT "",($local_host->config->hyperThread->available) ? "YES" : "NO"," / ";
print REPORT_OUTPUT ($local_host->config->hyperThread->active) ? "YES" : "NO"," | ";
print REPORT_OUTPUT "",&restrict_num_decimal_digits($local_host->summary->hardware->numCpuCores*$local_host->summary->hardware->cpuMhz,2)," Mhz | ";
print REPORT_OUTPUT "",&restrict_num_decimal_digits($local_host->summary->quickStats->overallCpuUsage,2)," Mhz | ";
print REPORT_OUTPUT "",$local_host->summary->hardware->numCpuPkgs," | ";
print REPORT_OUTPUT "",$local_host->summary->hardware->numCpuCores," | ";
print REPORT_OUTPUT "",$local_host->summary->hardware->numCpuThreads," | ";
print REPORT_OUTPUT "",&restrict_num_decimal_digits($local_host->summary->hardware->memorySize/1024/1000,2)," MB | ";
print REPORT_OUTPUT "",&restrict_num_decimal_digits($local_host->summary->quickStats->overallMemoryUsage,2)," MB | ";
print REPORT_OUTPUT "",$local_host->summary->hardware->numNics," | ";
print REPORT_OUTPUT "",$local_host->summary->hardware->numHBAs," | ";
print REPORT_OUTPUT "
\n";
#get vswitch/cdp info
#getVswitchInfo($local_host);
#get nic
getNICInfo($local_host);
#get hba
getHBAInfo($local_host);
}
print REPORT_OUTPUT "
\n";
#print nic
###########################
# PRINT NIC INFO
###########################
printNIC();
###########################
# PRINT HBA INFO
###########################
printHBA();
#print cdp
###########################
# PRINT HOST STATE
###########################
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "ESX/ESXi state:
\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "HOSTNAME | OVERALL STATUS | POWER STATE | CONNECTION STATE | MAINTENANCE MODE | VMOTION ENABLED | VERSION |
\n";
foreach my $local_host (sort {$a->summary->config->name cmp $b->summary->config->name} @$local_hosts) {
print REPORT_OUTPUT "\n";
if($enable_demo_mode eq 1) {
print REPORT_OUTPUT "HIDE ME! | ";
}
else {
print REPORT_OUTPUT "",$local_host->summary->config->name," | ";
}
my $host_health = $local_host->overallStatus->val;
if ($host_health eq 'green') { print REPORT_OUTPUT "HOST is OK | "; }
elsif ($host_health eq 'red') { print REPORT_OUTPUT "HOST has a problem | "; }
elsif ($host_health eq 'yellow') { print REPORT_OUTPUT "HOST might have a problem | "; }
else { print REPORT_OUTPUT "UNKNOWN | "; }
print REPORT_OUTPUT "",$local_host->runtime->powerState->val," | ";
print REPORT_OUTPUT "",$local_host->runtime->connectionState->val," | ";
print REPORT_OUTPUT "",($local_host->summary->runtime->inMaintenanceMode) ? "YES" : "NO" ," | ";
print REPORT_OUTPUT "",($local_host->summary->config->vmotionEnabled) ? "YES" : "NO" ," | ";
print REPORT_OUTPUT "",${$local_host->summary->config->product}{'fullName'}," | ";
print REPORT_OUTPUT "
\n";
}
print REPORT_OUTPUT "
\n";
###########################
# PRINT HOST CONFIG
###########################
print REPORT_OUTPUT "\n";
push @jump_tags," ESX/ESXi Config (WIP)
";
print REPORT_OUTPUT "";
print REPORT_OUTPUT "ESX/ESXi Config (WIP):
\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "HOSTNAME | SC MEMORY | NTP SERVER(s) | TIME ZONE | GMT OFFSET | LOCATION |
| AUTOSTART MANAGER | LVM ENABLE RESIGNATURE | LVM DISALLOW SNAPSHOTLUN |
\n";
foreach my $local_host (sort {$a->summary->config->name cmp $b->summary->config->name} @$local_hosts) {
print REPORT_OUTPUT "\n";
if($enable_demo_mode eq 1) {
print REPORT_OUTPUT "HIDE ME! | ";
}
else {
print REPORT_OUTPUT "",$local_host->summary->config->name," | ";
}
if(defined($local_host->config->consoleReservation)) {
print REPORT_OUTPUT "",&restrict_num_decimal_digits($local_host->config->consoleReservation->serviceConsoleReserved/1024/1000,2)," MB | ";
}
else {
print REPORT_OUTPUT "UNKNOWN | ";
}
my $ntps = $local_host->config->dateTimeInfo->ntpConfig->server;
my $ntp_string = "";
if($ntps) {
print REPORT_OUTPUT "\n";
foreach (@$ntps) {
$ntp_string .= "$_ ";
}
print REPORT_OUTPUT "",$ntp_string," | ";
print REPORT_OUTPUT "",$local_host->config->dateTimeInfo->timeZone->description," | ";
print REPORT_OUTPUT "",$local_host->config->dateTimeInfo->timeZone->gmtOffset," Sec(s) | ";
print REPORT_OUTPUT "",$local_host->config->dateTimeInfo->timeZone->name," | ";
print REPORT_OUTPUT "
| \n";
}
else {
print REPORT_OUTPUT "UNKNOWN | ";
}
print REPORT_OUTPUT "",($local_host->config->autoStart->defaults->enabled) ? "YES" : "NO"," | ";
#advconfigs
my $advconfigs = Vim::get_view (mo_ref => $local_host->configManager->advancedOption);
my $options_ref = $advconfigs->setting;
foreach my $option (@$options_ref) {
my $key = $option->key;
my $value = $option->value;
if($key eq 'LVM.EnableResignature') {
print REPORT_OUTPUT "",($value) ? "YES" : "NO"," | ";
}
if($key eq 'LVM.DisallowSnapshotLun') {
print REPORT_OUTPUT "",($value) ? "YES" : "NO"," | ";
}
}
}
print REPORT_OUTPUT "
\n";
}
sub printHBA {
if(@hba_list) {
push @jump_tags," ESX/ESXi HBA(s)
";
print REPORT_OUTPUT "";
print REPORT_OUTPUT "ESX/ESXi HBA(s)
\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "HOST | HBA TYPE | DEVICE | PCI | MODEL | DRIVER | STATUS | ADDITIONAL INFO |
";
foreach (@hba_list) {
print REPORT_OUTPUT "",$_,"
";
}
print REPORT_OUTPUT "
\n";
}
@hba_list = ();
}
sub printNIC {
if(@nic_list) {
push @jump_tags," ESX/ESXi NIC(s)
";
print REPORT_OUTPUT "";
print REPORT_OUTPUT "ESX/ESXi NIC(s)
\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "HOST | DEVICE | PCI | DRIVER | DUPLEX | SPEED | WOL ENABLED | MAC |
";
foreach (@nic_list) {
print REPORT_OUTPUT "",$_,"
";
}
print REPORT_OUTPUT "
\n";
}
@nic_list = ();
}
sub getNICInfo {
my ($host) = @_;
my $nics = $host->config->network->pnic;
foreach my $nic (@$nics) {
my $nic_string = "";
if($enable_demo_mode eq 1) {
$nic_string = "HIDE ME! | ";
}
else {
$nic_string = "".$host->name." | ";
}
$nic_string .= "".$nic->device." | ".$nic->pci." | ".$nic->driver." | ";
if($nic->linkSpeed) {
$nic_string .= "".(($nic->linkSpeed->duplex) ? "FULL DUPEX" : "HALF-DUPLEX")." | ".$nic->linkSpeed->speedMb." MB | ";
}
else {
$nic_string .= "UNKNOWN | UNKNOWN | ";
}
$nic_string .= "".(($nic->wakeOnLanSupported) ? "YES" : "NO")." | ";
if($enable_demo_mode eq 1) {
$nic_string .= "XX:XX:XX:XX:XX:XX | ";
}
else {
$nic_string .= "".$nic->mac." | ";
}
push @nic_list,$nic_string;
}
}
sub getHBAInfo {
my ($host) = @_;
my $hbas = $host->config->storageDevice->hostBusAdapter;
foreach my $hba (@$hbas) {
my $hba_string = "";
if($enable_demo_mode eq 1) {
$hba_string = "HIDE ME! | ";
}
else {
$hba_string = "".$host->name." | ";
}
if ($hba->isa("HostFibreChannelHba")) {
my $nwwn = (Math::BigInt->new($hba->nodeWorldWideName))->as_hex();
my $pwwn = (Math::BigInt->new($hba->portWorldWideName))->as_hex();
$nwwn =~ s/^..//;
$pwwn =~ s/^..//;
$nwwn = join(':', unpack('A2' x 8, $nwwn));
$pwwn = join(':', unpack('A2' x 8, $pwwn));
if($enable_demo_mode eq 1) {
$nwwn = "XX:XX:XX:XX:XX:XX:XX:XX";
$pwwn = "XX:XX:XX:XX:XX:XX:XX:XX";
}
$hba_string .= "FC | ".$hba->device." | ".$hba->pci." | ".$hba->model." | ".$hba->driver." | ".$hba->status." | NWWN ".$nwwn." | PWWN ".$pwwn." | PORT TYPE ".$hba->portType->val." | ";
} elsif ($hba->isa("HostInternetScsiHba")) {
$hba_string .= "iSCSI | ".$hba->device." | ".$hba->pci." | ".$hba->model." | ".$hba->driver." | ".$hba->status." | ".(($hba->authenticationProperties->chapAuthEnabled) ? "CHAP ENABLED" : "CHAP DISABLED")." | ";
}
elsif ($hba->isa("HostParallelScsiHba")) {
$hba_string .= "SCSI | ".$hba->device." | ".$hba->pci." | ".$hba->model." | ".$hba->driver." | ".$hba->status." | ";
}
elsif ($hba->isa("HostBlockHba")) {
$hba_string .= " | BLOCK | ".$hba->device." | ".$hba->pci." | ".$hba->model." | ".$hba->driver." | ".$hba->status." | ";
}
push @hba_list,$hba_string;
}
}
sub getVswitchInfo {
my $netMgr = Vim::get_view(mo_ref => $_->configManager->networkSystem);
my @physicalNicHintInfo = $netMgr->QueryNetworkHint();
foreach (@physicalNicHintInfo){
foreach ( @{$_} ){
if(defined($_->connectedSwitchPort)) {
my $device = $_->device;
my $port = $_->connectedSwitchPort->portId;
$cdp_enabled{$device} = $port;
}
}
}
my $vswitches = $_->config->network->vswitch;
foreach my $vSwitch (@$vswitches) {
my $pNicName = "";
my $mtu = "";
my $cdp_vswitch = "";
print "Switch Name Num Ports Used Ports MTU Uplinks CDP Enabled\n";
my $pNics = $vSwitch->pnic;
my $pNicKey = "";
foreach (@$pNics) {
$pNicKey = $_;
if ($pNicKey ne "") {
$pNics = $netMgr->networkInfo->pnic;
foreach my $pNic (@$pNics) {
if ($pNic->key eq $pNicKey) {
$pNicName = $pNicName ? ("$pNicName," . $pNic->device) : $pNic->device;
if($cdp_enabled{$pNic->device}) {
$cdp_vswitch = $cdp_enabled{$pNic->device};
}
else {
$cdp_vswitch = "";
}
}
}
}
}
$mtu = $vSwitch->{mtu} if defined($vSwitch->{mtu});
printf("%-16.14s%-16s%-16s%-8s%-16s%-16s\n\n", $vSwitch->name,
$vSwitch->numPorts,
$vSwitch->numPorts - $vSwitch->numPortsAvailable,
$vSwitch->{mtu},
$pNicName,
$cdp_vswitch);
my $portGroups = $vSwitch->portgroup;
print " PortGroup Name VLAN ID Used Ports Uplinks\n";
foreach my $port (@$portGroups) {
my $pg = FindPortGroupbyKey ($netMgr, $vSwitch->key, $port);
next unless (defined $pg);
my $usedPorts = (defined $pg->port) ? $#{$pg->port} + 1 : 0;
printf(" %-22s%-10s%-16s%-16s\n", $pg->spec->name,
$pg->spec->vlanId, $usedPorts, $pNicName);
}
print "\n";
}
}
sub FindPortGroupbyKey {
my ($network, $vSwitch, $key) = @_;
my $portGroups = $network->networkInfo->portgroup;
foreach my $pg (@$portGroups) {
return $pg if (($pg->vswitch eq $vSwitch) && ($key eq $pg->key));
}
return undef;
}
sub printClusterSummary {
my ($local_cluster) = @_;
my $cluster_name = $local_cluster->name;
my $cluster_host_cnt = $local_cluster->summary->numHosts;
my $cluster_avail_host = $local_cluster->summary->numEffectiveHosts;
my $cluster_cpu_cnt = $local_cluster->summary->totalCpu;
my $cluster_mem_cnt = &restrict_num_decimal_digits($local_cluster->summary->totalMemory/1024/1000,2);
my $cluster_avail_cpu = $local_cluster->summary->effectiveCpu;
my $cluster_avail_mem = &restrict_num_decimal_digits($local_cluster->summary->effectiveMemory,2);
my $cluster_drs = $local_cluster->configuration->drsConfig->enabled;
my $cluster_ha = $local_cluster->configuration->dasConfig->enabled;
my $cluster_dpm = $local_cluster->configurationEx->dpmConfigInfo->enabled;
print REPORT_OUTPUT "
\n";
###########################
# PRINT CLUSTER SUMMARY
###########################
push @jump_tags,"CLCluster: $cluster_name ";
print REPORT_OUTPUT "";
print REPORT_OUTPUT "Cluster: $cluster_name\n";
print REPORT_OUTPUT "Cluster Statistics:\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "AVAILABLE HOST(s) | AVAILABLE CPU | AVAILABLE MEM | DRS ENABLED | HA ENABLED | DPM ENABLED | \n";
print REPORT_OUTPUT "";
print REPORT_OUTPUT "",$cluster_avail_host,"/",$cluster_host_cnt," | ";
print REPORT_OUTPUT "",$cluster_avail_cpu,"/",$cluster_cpu_cnt," Mhz | ";
print REPORT_OUTPUT "",$cluster_avail_mem,"/",$cluster_mem_cnt," MB | ";
print REPORT_OUTPUT "",($cluster_drs) ? "YES" : "NO"," | ";
print REPORT_OUTPUT "",($cluster_ha) ? "YES" : "NO" ," | ";
print REPORT_OUTPUT "",($cluster_dpm) ? "YES" : "NO" ," | ";
print REPORT_OUTPUT " \n";
###########################
# PRINT HA INFO
###########################
if($cluster_ha) {
print REPORT_OUTPUT "HA CONFIGURATIONS:\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "FAILOVER LEVEL | ADMISSION CONTROLED ENABLED | ISOLATION RESPONSE | RESTART PRIORITY | \n";
print REPORT_OUTPUT "",$local_cluster->configuration->dasConfig->failoverLevel," | ";
print REPORT_OUTPUT "",($local_cluster->configuration->dasConfig->admissionControlEnabled) ? "YES" : "NO"," | ";
print REPORT_OUTPUT "",$local_cluster->configuration->dasConfig->defaultVmSettings->isolationResponse," | ";
print REPORT_OUTPUT "",$local_cluster->configuration->dasConfig->defaultVmSettings->restartPriority," | ";
print REPORT_OUTPUT " \n";
}
###########################
# PRINT DRS INFO
###########################
if($cluster_drs) {
print REPORT_OUTPUT "DRS CONFIGURATIONS:\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "DRS BEHAVIOR | VMOTION RATE | \n";
print REPORT_OUTPUT "",$local_cluster->configuration->drsConfig->defaultVmBehavior->val," | ";
print REPORT_OUTPUT "",$local_cluster->configuration->drsConfig->vmotionRate," | ";
print REPORT_OUTPUT " \n";
}
###########################
# PRINT DPM INFO
###########################
if($cluster_dpm) {
print REPORT_OUTPUT "DRS CONFIGURATIONS:\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "DPM BEHAVIOR | \n";
print REPORT_OUTPUT "",$local_cluster->configurationEx->dpmConfigInfo->defaultDpmBehavior->val," | ";
print REPORT_OUTPUT " \n";
}
###########################
# PRINT CLUSTER RULES
###########################
my $rules = $local_cluster->configurationEx->rule;
if($rules) {
print REPORT_OUTPUT "Cluster Rules:\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "RULE NAME | RULE TYPE | ENABLED | \n";
foreach (@$rules) {
my $rule = $_;
my $is_enabled = $rule->enabled;
my $rule_name = $rule->name;
my $rule_type;
if(ref($rule) eq 'ClusterAffinityRuleSpec') {
$rule_type = "AFFINITY";
}
elsif (ref($rule) eq 'ClusterAntiAffinityRuleSpec') {
$rule_type = "ANTI-AFFINITY";
}
print REPORT_OUTPUT "",$rule_name," | ",$rule_type," | ",($is_enabled) ? "YES" : "NO"," | ";
}
print REPORT_OUTPUT " \n";
}
}
sub printBuildSummary {
# get ServiceContent
my $content = Vim::get_service_content();
my $print_type;
if ($content->about->apiType eq 'VirtualCenter') {
$print_type = "VMware vCenter";
}
else {
$print_type = "VMware ESX/ESXi";
}
#print $content->name;
print REPORT_OUTPUT "$print_type:\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "BUILD | VERSION | FULL NAME | \n";
print REPORT_OUTPUT "
---|
";
print REPORT_OUTPUT "",$content->about->build," | ",$content->about->version," | ",$content->about->fullName," | \n";
print REPORT_OUTPUT " ";
print REPORT_OUTPUT " \n";
#please do not touch this, else the jump tags will break
print REPORT_OUTPUT "\n//\n";
}
sub printStartHeader {
print "Generating VMware Health Report \"$report_name\" (this can take a few minutes depending on environment size. Get a cup of coffee/tea and come back) ...\n";
### begin_: initialize DateTime values
my %dttime = ();
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
### begin_: initialize DateTime number formats
$dttime{year } = sprintf "%04d",($year + 1900); ## four digits to specify the year
$dttime{mon } = sprintf "%02d",($mon + 1); ## zeropad months
$dttime{mday } = sprintf "%02d",$mday; ## zeropad day of the month
$dttime{wday } = sprintf "%02d",$wday + 1; ## zeropad day of week; sunday = 1;
$dttime{yday } = sprintf "%02d",$yday; ## zeropad nth day of the year
$dttime{hour } = sprintf "%02d",$hour; ## zeropad hour
$dttime{min } = sprintf "%02d",$min; ## zeropad minutes
$dttime{sec } = sprintf "%02d",$sec; ## zeropad seconds
$dttime{isdst} = $isdst;
$my_time = "Date: $dttime{mon}-$dttime{mday}-$dttime{year} $dttime{hour}:$dttime{min}:$dttime{sec}";
$start_time = time();
open(REPORT_OUTPUT, ">$report_name");
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "VMware Health Check Report $version - $my_time\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "\n";
print REPORT_OUTPUT "VMware Health Check Report $version\n";
print REPORT_OUTPUT "$my_time\n";
}
sub printCloseHeader {
print REPORT_OUTPUT "
\n";
print REPORT_OUTPUT "Author: William Lam";
print REPORT_OUTPUT "Generated using: vmwareHealthCheck.pl";
print REPORT_OUTPUT "Primp Industries";
close(REPORT_OUTPUT);
my @lines;
my $jump_string = "";
tie @lines, 'Tie::File', $report_name or die;
for (@lines) {
if (//) {
foreach (@jump_tags) {
if( ($_ =~ /^CL/) ) {
my $tmp_string = substr($_,2);
$jump_string .= $tmp_string;
}
else {
$jump_string .= $_;
}
}
$_ = "\n$jump_string";
last;
}
}
untie @lines;
$end_time = time();
$run_time = $end_time - $start_time;
print "\nStart Time: ",&formatTime(str => scalar localtime($start_time)),"\n";
print "End Time: ",&formatTime(str => scalar localtime($end_time)),"\n";
if ($run_time gt 60) {
print "Duration : ",&restrict_num_decimal_digits($run_time/60,2)," Minutes\n\n";
}
else {
print "Duration : ",$run_time," Seconds\n\n";
}
}
sub Fail {
my ($msg) = @_;
Util::disconnect();
die ($msg);
exit ();
}
# restrict the number of digits after the decimal point
#http://guymal.com/mycode/perl_restrict_digits.shtml
sub restrict_num_decimal_digits {
my $num=shift;#the number to work on
my $digs_to_cut=shift;# the number of digits after
if ($num=~/\d+\.(\d){$digs_to_cut,}/) {
$num=sprintf("%.".($digs_to_cut-1)."f", $num);
}
return $num;
}
#http://www.infocopter.com/perl/format-time.html
sub formatTime(%) {
my %args = @_;
$args{'str'} ||= ''; # e.g. Mon Jul 3 12:59:28 2006
my @elems = ();
foreach (split / /, $args{'str'}) {
next unless $_;
push(@elems, $_);
}
my ($weekday, $month, $mday, $time, $yyyy) = split / /, join(' ', @elems);
my %months = ( Jan => 1, Feb => 2, Mar => 3, Apr => 4, May => 5, Jun => 6,
Jul => 7, Aug => 8, Sep => 9, Oct => 10, Nov => 11, Dec => 12 );
my $s = substr($time, 6,2);
my $m = substr($time, 3,2);
my $h = substr($time, 0, 2);
my $dd = sprintf('%02d', $mday);
my $mm_num = sprintf('%02d', $months{$month});
my $formatted = "$mm_num\-$dd\-$yyyy $h:$m:$s";
#my $formatted = "$yyyy$mm_num$dd$h$m$s";
$formatted;
}
sub print_tree {
my ($vm, $ref, $tree) = @_;
my $head = " ";
foreach my $node (@$tree) {
$head = ($ref->value eq $node->snapshot->value) ? " " : " " if (defined $ref);
my $quiesced = ($node->quiesced) ? "YES" : "NO";
my $desc = $node->description;
if($desc eq "" ) { $desc = "NO DESCRIPTION"; }
push @snapshot_vms," | ".$vm." | ".$node->name." | ".$desc." | ".$node->createTime." | ".$node->state->val." | ".$quiesced." | ";
print_tree ($vm, $ref, $node->childSnapshotList);
}
return;
}
=head1 NAME
vmwareHealthCheck.pl - Generate VMware health check against vCenter Cluster(s).
=head1 SYNOPSIS
vmwareHealthCheck.pl [--cluster "CLUSTER_NAME"]
=head1 DESCRIPTION
This script will generate a health check html report on each of the vCenter Cluster(s) for all residing ESX/ESXi hosts.
=head1 OPTIONS
=head1 EXAMPLES
List all of the connected cdrom devices on host abc.
vmwareHealthCheck.pl --server "vCENTER_SERVER" --username "vCenter_USERNAME" --password "vCENTER_PASSWORD"
=head1 SUPPORTED PLATFORMS
All operations are supported on ESX 3.5 and VirtualCenter 2.5 and better.