#!/usr/bin/perl -w ################################################################## # Author: William Lam # Email: william2003[at]gmail[dot]com # 02/14/2009 # http://www.engineering.ucsb.edu/~duonglt/vmware/ ################################################################## use strict; use warnings; use Math::BigInt; use Tie::File; use POSIX qw/mktime/; use Getopt::Long; use VMware::VIRuntime; use VMware::VILib; #################################### # resource consumption warnings #################################### # yellow < 30 % my $yellow_warn = 30; # orange < 15 % my $orange_warn = 15; # red < 10% my $red_warn = 10; ###################################### # vm snapshot age warnings ###################################### # yellow < 15 days my $snap_yellow_warn = 15; # orange < 30 days my $snap_orange_warn = 30; # red < 60 days+ my $snap_red_warn = 60; ########### DO NOT MODIFY PAST HERE ########### ################################ # VERSION ################################ my $version = "1.0"; $Util::script_version = $version; ################################ # DEMO MODE # 0 = no, 1 = yes ################################ my $enable_demo_mode = 0; ################ #GLOBAL VARS ################ my $opt_type; 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 @health_list = (); my @nic_list = (); my @hosts_seen = (); my $datacenter_name; my @vm_delta_warn = (); my $hostd_log_print; my $randomHostName; my $content; my %portgroup_row_info = (); my $cdp_string = ""; my @dvs = (); my %opts = ( cluster => { type => "=s", help => "The name of a vCenter cluster", required => 0, }, datacenter => { type => "=s", help => "The name of a vCenter datacenter", required => 0, }, type => { type => "=s", help => "Type: [vcenter|datacenter|cluster|host|detail-hosts]\n", required => 1, }, report => { type => "=s", help => "The name of the report to output. Please add \".html\" extension", required => 0, }, logcount => { type => "=s", help => "The number of lines to output from hostd logs", 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')) { # get ServiceContent $content = Vim::get_service_content(); $host_type = $content->about->apiType; $opt_type = Opts::get_option('type'); #################### # SINGLE ESX HOST #################### if( ($opt_type eq 'host') && (!Opts::option_is_set('cluster')) && ($host_type eq 'HostAgent') ) { $host_view = Vim::find_entity_views(view_type => 'HostSystem'); if (!$host_view) { die "ESX/ESXi host was not found\n"; } } ##################### # vCENTER + CLUSTER ##################### elsif( ($opt_type eq 'cluster') && ($host_type eq 'VirtualCenter') ) { 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: \"$cluster_name\" was not found\n"; } } else { Fail("\n--cluster parameter required with the name of a valid vCenter Cluster\n\n"); } } ######################## # vCENTER + DATACENTER ######################## elsif( ($opt_type eq 'datacenter') && ($host_type eq 'VirtualCenter') ) { if ( Opts::option_is_set('datacenter') ) { $datacenter_name = Opts::get_option('datacenter'); my $datacenter_view = Vim::find_entity_view(view_type => 'Datacenter',filter => { name => $datacenter_name}); if(!$datacenter_view) { die "Datacenter: \"$datacenter_name\" was not found\n"; } $cluster_views = Vim::find_entity_views(view_type => 'ClusterComputeResource',begin_entity => $datacenter_view); if(!$cluster_views) { die "No clusters were found in this datacenter\n"; } } else { Fail("\n--datacenter parameter required with the name of a valid vCenter Datacenter\n\n"); } } ######################### # vCENTER HOST DETAIL ######################### elsif( ($opt_type eq 'detail-hosts') && (!Opts::option_is_set('cluster')) && ($host_type eq 'VirtualCenter') ) { $cluster_views = Vim::find_entity_views(view_type => 'ClusterComputeResource'); Fail ("No clusters found.\n") unless (@$cluster_views); } ################## # vCENTER ALL ################## elsif( ($opt_type eq 'vcenter') && (!Opts::option_is_set('cluster')) && ($host_type eq 'VirtualCenter') ) { $cluster_views = Vim::find_entity_views(view_type => 'ClusterComputeResource'); Fail ("No clusters found.\n") unless (@$cluster_views); } ####################################### # VM DISK INFO INDIVIDUAL HOSTS ONLY ###################################### elsif( ($opt_type eq 'vmfrag') && (!Opts::option_is_set('cluster')) && ($host_type eq 'HostAgent') ) { $host_view = Vim::find_entity_views(view_type => 'HostSystem'); if (!$host_view) { die "ESX/ESXi host was not found\n"; } } else { die "Invalid Input, ensure your selection is one of the supported use cases on the VMTN Doc\n\n\tServer: vCenter => [vcenter|datacenter|cluster|detail-hosts]\n\tServer: ESX/ESXi Host => [host|vmfrag]\n"; } #if report name is not specified, default output if (Opts::option_is_set ('report')) { $report_name = Opts::get_option('report'); } else { $report_name = "vmware_health_report.html"; } #if use case is with hostd logs, set log count or default to 15 if( Opts::option_is_set('logcount') ) { $hostd_log_print = Opts::get_option('logcount'); } else { $hostd_log_print = 15; } } ### CODE START ### ################################# # PRINT HTML HEADER/CSS ################################# printStartHeader(); ######################################### # PRINT vCENTER or HOST BUILD/SUMMARY ######################################### printBuildSummary(); ######################################### # PRINT vCENTER INFO ######################################### if ($opt_type eq 'vcenter') { foreach my $cluster (@$cluster_views) { $cluster_count += 1; printClusterSummary($cluster); my $hosts = Vim::get_views (mo_ref_array => $cluster->host); if(@$hosts) { printHostHardwareInfo($hosts); printHostLun($hosts); printHostDatastoreInfo($hosts); printPG(); printDVS(); printHostVM($hosts); printVMDatastore(); printVMNetwork(); printVMSnapshot(); printVMSnapshotDeltaOlderThan(); printVMNPIV(); printVMRDM(); printVMCDrom(); printVMFloppy(); cleanUp(); } } } ######################################### # PRINT SPECIFIC DATACENTER INFO ######################################### elsif ($opt_type eq 'datacenter') { printDatacenterName($datacenter_name); foreach my $cluster (@$cluster_views) { $cluster_count += 1; printClusterSummary($cluster); my $hosts = Vim::get_views (mo_ref_array => $cluster->host); if(@$hosts) { printHostHardwareInfo($hosts); printHostLun($hosts); printHostDatastoreInfo($hosts); printPG(); printDVS(); printHostVM($hosts); printVMDatastore(); printVMNetwork(); printVMSnapshot(); printVMSnapshotDeltaOlderThan(); printVMNPIV(); printVMRDM(); printVMCDrom(); printVMFloppy(); cleanUp(); } } } ######################################### # PRINT SPECIFIC CLUSTER INFO ######################################### elsif ($opt_type eq 'cluster') { $cluster_count += 1; printClusterSummary($cluster_view); my $hosts = Vim::get_views (mo_ref_array => $cluster_view->host); if(@$hosts) { printHostHardwareInfo($hosts); printHostLun($hosts); printHostDatastoreInfo($hosts); printPG(); printDVS(); printHostVM($hosts); printVMDatastore(); printVMNetwork(); printVMSnapshot(); printVMSnapshotDeltaOlderThan(); printVMNPIV(); printVMRDM(); printVMCDrom(); printVMFloppy(); cleanUp(); } } ######################################### # PRINT SINGLE HOST INFO ######################################### elsif ($opt_type eq 'host' ) { printHostHardwareInfo($host_view); printHostLun($host_view); printHostDatastoreInfo($host_view); printHostPortgroup($host_view); printHostVM($host_view); queryVMDisk($host_view); printVMDatastore(); printVMNetwork(); printVMSnapshot(); printVMSnapshotDeltaOlderThan(); printVMNPIV(); printVMRDM(); printVMCDrom(); printVMFloppy(); cleanUp(); } ######################################### # PRINT DETAIL HOSTS INFO ######################################### elsif ($opt_type eq 'detail-hosts') { foreach my $cluster (@$cluster_views) { $cluster_count += 1; printClusterSummary($cluster); my $hosts = Vim::get_views (mo_ref_array => $cluster->host); if(@$hosts) { printHostHardwareInfo($hosts); printHostLun($hosts); printHostDatastoreInfo($hosts); printPG(); printDVS(); printVMSnapshot(); printVMSnapshotDeltaOlderThan(); printVMNPIV(); printVMRDM(); printVMCDrom(); printVMFloppy(); cleanUp(); } } } ######################################### # PRINT VM DISK INFO ######################################### elsif ($opt_type eq 'vmfrag') { queryVMDisk($host_view); cleanUp(); } ################################# # CLOSE HTML REPORT ################################# printCloseHeader(); Util::disconnect(); ### CODE END ### ########################### # # HELPER FUNCTIONS # ########################### sub queryVMDisk { my ($host_view) = @_; foreach my $host (@$host_view) { my $vm_views = Vim::get_views (mo_ref_array => $host->vm); if($opt_type eq 'vmfrag') { push @jump_tags,"VM(s) VMDK Disk Information
\n"; } else { push @jump_tags,"                VM(s) VMDK Disk Information
\n"; } print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

VM(s) VMDK Disk Information:

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; foreach my $vm (@$vm_views) { #skip if vm is disconnected next if(!defined($vm->layout)); my $disks = $vm->layout->disk; my $vdm_mgr = Vim::get_view(mo_ref => Vim::get_service_content()->virtualDiskManager); foreach(@$disks) { my $disk_files = $_->diskFile; my $disk_string = ""; foreach(@$disk_files) { eval { $vdm_mgr->QueryVirtualDiskFragmentation(name => $_); }; if(!$@) { my $disk_frag = $vdm_mgr->QueryVirtualDiskFragmentation(name => $_); my $disk_geom = $vdm_mgr->QueryVirtualDiskGeometry(name => $_); my $disk_uuid = $vdm_mgr->QueryVirtualDiskUuid(name => $_); if(!defined($disk_frag)) { $disk_frag = "N/A"; } print REPORT_OUTPUT "","\n"; } } } } print REPORT_OUTPUT "
VMFRAGMENTATIONVMDKDISK CYLINDERDISK HEADDISK SECTORUUID
",$vm->config->name,"".$disk_frag."".$_."".$disk_geom->cylinder."".$disk_geom->head."".$disk_geom->sector."".$disk_uuid."
\n"; } } sub printVMNPIV { ########################### # PRINT NPIV INFO ########################### if(@npiv_vms) { my $npiv_count = $#npiv_vms; $npiv_count += 1; if($opt_type eq 'detail-hosts') { push @jump_tags,"VM(s) w/NPIV enabled
\n"; } else { push @jump_tags,"                VM(s) w/NPIV enabled
\n"; } print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

$npiv_count VM(s) w/NPIV enabled:

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; foreach (@npiv_vms) { print REPORT_OUTPUT "",$_,"\n"; } print REPORT_OUTPUT "
VMNPIV NODE WWNNPIV PORT WWNGENERATED FROM
\n"; } @npiv_vms = (); } sub printVMSnapshotDeltaOlderThan { ########################### # PRINT DELTA INFO ########################### if(@vm_delta_warn) { my $snap_delta_count = $#vm_delta_warn; $snap_delta_count +=1; if($opt_type eq 'detail-hosts') { push @jump_tags,"VM(s) w/Snapshot Delta(s) Older Than $snap_yellow_warn+ days
\n"; } else { push @jump_tags,"                VM(s) w/Snapshot Delta(s) Older Than $snap_yellow_warn+ days
\n"; } print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

$snap_delta_count VM(s) w/Snapshot Delta(s) Older Than $snap_yellow_warn+ Days:

\n"; print REPORT_OUTPUT "
COLOR LEGENDYELLOW > $snap_yellow_warn daysORANGE > $snap_orange_warn daysRED > $snap_red_warn days
\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; foreach(@vm_delta_warn) { print REPORT_OUTPUT "",$_,"\n"; } print REPORT_OUTPUT "
DATASTOREVM DELTAAGESIZECREATED
\n"; } @vm_delta_warn = (); } sub printVMSnapshot { ########################### # PRINT SNAPSHOT INFO ########################### if(@snapshot_vms) { my $snap_count = $#snapshot_vms; $snap_count += 1; if($opt_type eq 'detail-hosts') { push @jump_tags,"VM(s) w/Snapshot(s)
\n"; } else { push @jump_tags,"                VM(s) w/Snapshot(s)
\n"; } print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

$snap_count VM(s) w/Snapshot(s):

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; foreach (@snapshot_vms) { print REPORT_OUTPUT "",$_,"\n"; } print REPORT_OUTPUT "
VMSNAPSHOT NAMESNAPSHOT DESCCREATEDSTATEQUIESCED
\n"; } @snapshot_vms = (); } sub printVMRDM { ########################### # PRINT RDM INFO ########################### if(@rdm_vms) { my $rdm_count = $#rdm_vms; $rdm_count += 1; if($opt_type eq 'detail-hosts') { push @jump_tags,"VM(s) w/RDM(s)
\n"; } else { push @jump_tags,"                VM(s) w/RDM(s)
\n"; } print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

$rdm_count VM(s) w/RDM(s):

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; foreach (@rdm_vms) { print REPORT_OUTPUT "",$_,"\n"; } print REPORT_OUTPUT "
VMCOMPAT MODEDEVICEDISK MODELUN UUIDVIRTUAL DISK UUID
\n"; } @rdm_vms = (); } sub printVMCDrom { ########################### # PRINT CDROM INFO ########################### if(@connected_cdrom_vms) { my $cdrom_count = $#connected_cdrom_vms; $cdrom_count += 1; if($opt_type eq 'detail-hosts') { push @jump_tags,"VM(s) w/connected CD-ROM(s)
\n"; } else { push @jump_tags,"                VM(s) w/connected CD-ROM(s)
\n"; } print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

$cdrom_count VM(s) w/connected CD-ROM(s):

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; foreach (@connected_cdrom_vms) { print REPORT_OUTPUT "\n"; } print REPORT_OUTPUT "
VM
",$_,"
\n"; } @connected_cdrom_vms = (); } sub printVMFloppy { ########################### # PRINT FLOPPY INFO ########################### if(@connected_floppy_vms) { my $floppy_count = $#connected_floppy_vms; $floppy_count += 1; if($opt_type eq 'detail-hosts') { push @jump_tags,"VM(s) w/connected Floppy(s)
\n"; } else { push @jump_tags,"                VM(s) w/connected Floppy(s)
\n"; } print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

$floppy_count VM(s) w/connected Floppy(s):

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; foreach (@connected_floppy_vms) { print REPORT_OUTPUT "\n"; } print REPORT_OUTPUT "
VM
",$_,"
\n"; } @connected_floppy_vms = (); } sub printVMNetwork { #################################### # PRINT VM NETWORK SUMMARY #################################### if(%net_vms) { push @jump_tags,"                VM(s) Network Summary
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

VM(s) Network Summary:

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; foreach ( sort keys %net_vms ) { my $vm_net = $net_vms{$_}; print REPORT_OUTPUT "",$vm_net,"\n"; } print REPORT_OUTPUT "
VMIP(s)MAC ADDRESSPORTGROUPCONNECTED
",$_,"
\n"; } %net_vms = (); } sub printVMDatastore { #################################### # PRINT VM DISK/DATASTORE SUMMARY #################################### if(%vms_storage) { push @jump_tags,"                VM(s) Storage Summary
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

VM(s) Storage Summary:

\n"; print REPORT_OUTPUT "
COLOR LEGENDYELLOW < $yellow_warn %ORANGE < $orange_warn %RED < $red_warn %
\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; foreach ( sort keys %vms_storage ) { my $vm_ds = $vms_storage{$_}; my $vm_disk = $vms_disks{$_}; if(!$vm_disk) { $vm_disk = ""; } print REPORT_OUTPUT "",$vm_disk,"\n"; } print REPORT_OUTPUT "
VMDATASTORE
DISK INFOFREE SPACECAPACITY% FREE
not available
",$_,"",$vm_ds,"
\n"; } %vms_storage = (); } sub printLimitedVMInfo { my ($host) = @_; my $hostName; if($enable_demo_mode eq 1) { $hostName = $randomHostName; } else { $hostName = $host->summary->config->name; } ########################### # PRINT LIMITED VM SUMMARY ########################### my $seen_vm = 0; push @jump_tags,"                Virtual Machines
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

Virtual Machines:

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; my $vm_views = Vim::get_views (mo_ref_array => $host->vm); foreach my $vm (@$vm_views) { #skip if vm is disconnected next if(!defined($vm->config)); print REPORT_OUTPUT ""; if($enable_demo_mode eq 1) { print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; } else { print REPORT_OUTPUT ""; if (defined($vm->guest->hostName)) {print REPORT_OUTPUT ""; } else { print REPORT_OUTPUT ""; } } $seen_vm = 1; print REPORT_OUTPUT ""; if (defined($vm->summary->config->numVirtualDisks)) {print REPORT_OUTPUT ""; } else {print REPORT_OUTPUT ""; } if (defined($vm->summary->config->numCpu)) {print REPORT_OUTPUT ""; } else {print REPORT_OUTPUT ""; } if (defined($vm->summary->config->memorySizeMB)) {print REPORT_OUTPUT ""; } else {print REPORT_OUTPUT ""; } print REPORT_OUTPUT ""; 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=""; 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 .= ""; $npiv_string .= ""; 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); } } } print REPORT_OUTPUT "
VMHOSTNAMEPOWER STATE# OF DISK(s)# OF vCPU(s)MEMVMX LOCATION
",$vm->config->name,"HIDE ME!",$vm->config->name,"",$vm->guest->hostName,"UNKNOWN",$vm->runtime->powerState->val,"",$vm->summary->config->numVirtualDisks,"UNKNOWN",$vm->summary->config->numCpu,"UNKNOWN",prettyPrintData($vm->summary->config->memorySizeMB,'M'),"UNKNOWN",$vm->config->files->vmPathName,"
$vm_name$compat_mode$vmhba$disk_mode$lun_uuid$vm_uuid$n_vm"; foreach (@$nwwns) { my $nwwn = (Math::BigInt->new($_))->as_hex(); $nwwn =~ s/^..//; $nwwn = join(':', unpack('A2' x 8, $nwwn)); if($enable_demo_mode eq 1) { $npiv_string .= "XX:XX:XX:XX:XX:XX:XX:XX
"; } else { $npiv_string .= "$nwwn
"; } } $npiv_string .= "
"; foreach (@$pwwns) { my $pwwn = (Math::BigInt->new($_))->as_hex(); $pwwn =~ s/^..//; $pwwn = join(':', unpack('A2' x 8, $pwwn)); if($enable_demo_mode eq 1) { $npiv_string .= "XX:XX:XX:XX:XX:XX:XX:XX
"; } else { $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
\n"; } sub printHostVM { my ($local_hosts) = @_; ########################### # PRINT VM SUMMARY ########################### my $seen_vm = 0; push @jump_tags,"        Virtual Machines
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

Virtual Machines:

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\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) { #skip if vm is disconnected next if(!defined($vm->config)); print REPORT_OUTPUT ""; my $vm_host_view = Vim::get_view(mo_ref=>$vm->summary->runtime->host, properties => ['name']); if($enable_demo_mode eq 1) { print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; } else { print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; if (defined($vm->guest->hostName)) {print REPORT_OUTPUT ""; } else { print REPORT_OUTPUT ""; } } $seen_vm = 1; my $vm_health = $vm->summary->overallStatus->val; if ($vm_health eq 'green') { print REPORT_OUTPUT ""; } elsif ($vm_health eq 'red') { print REPORT_OUTPUT ""; } elsif ($vm_health eq 'yellow') { print REPORT_OUTPUT ""; } print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; if (defined($vm->summary->config->numVirtualDisks)) {print REPORT_OUTPUT ""; } else {print REPORT_OUTPUT ""; } if (defined($vm->summary->config->numCpu)) {print REPORT_OUTPUT ""; } else {print REPORT_OUTPUT ""; } if (defined($vm->summary->config->memorySizeMB)) {print REPORT_OUTPUT ""; } else {print REPORT_OUTPUT ""; } my $isTemplate = $vm->config->template; if (!$isTemplate) { if (defined($vm->summary->quickStats->overallCpuUsage)) {print REPORT_OUTPUT ""; } else {print REPORT_OUTPUT ""; } if (defined($vm->summary->quickStats->guestMemoryUsage)) {print REPORT_OUTPUT ""; } else {print REPORT_OUTPUT ""; } if (defined($vm->summary->config->cpuReservation)) {print REPORT_OUTPUT ""; } else {print REPORT_OUTPUT ""; } if (defined($vm->summary->config->memoryReservation)) {print REPORT_OUTPUT ""; } else {print REPORT_OUTPUT ""; } } else { print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; } if (defined($vm->summary->config->numEthernetCards)) {print REPORT_OUTPUT ""; } else {print REPORT_OUTPUT ""; } if (! $isTemplate) { if (defined($vm->summary->guest->toolsVersionStatus)) {print REPORT_OUTPUT ""; } else {print REPORT_OUTPUT ""; } if (defined($vm->config->tools->syncTimeWithHost)) { print REPORT_OUTPUT ""; } else {print REPORT_OUTPUT ""; } if (defined($vm->config->tools->toolsVersion)) {print REPORT_OUTPUT ""; } else {print REPORT_OUTPUT ""; } if (defined($vm->config->tools->toolsUpgradePolicy)) {print REPORT_OUTPUT ""; } else {print REPORT_OUTPUT ""; } print REPORT_OUTPUT ""; if (defined($vm->summary->guest->guestFullName)) {print REPORT_OUTPUT ""; } else {print REPORT_OUTPUT ""; } } else { print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; } print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; 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=""; 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 .= ""; $npiv_string .= ""; 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 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 => $_, properties => ['summary.name']); $vms_storage{$vm->config->name} = $ds->{'summary.name'}; } } #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 = prettyPrintData($disk->freeSpace,'B'); my $vm_disk_cap = prettyPrintData($disk->capacity,'B'); my $vm_perc_free = &restrict_num_decimal_digits((($disk->freeSpace / $disk->capacity) * 100),2); my $perc_string = getColor($vm_perc_free); $disk_string .= ""; } } if(defined($vm_name)) { $vms_disks{$vm_name} = $disk_string; } #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} = ""; $execute_flag = 0; } $seen_vm = 0; } } print REPORT_OUTPUT "
ESX/ESXi HOSTVMHOSTNAMEVM STATUSCONNECTION STATEFT STATERECORD/REPLAY STATEPOWER STATE# OF DISK(s)# OF vCPU(s)MEMCPU USAGEMEM USAGECPU RESRVMEM RESRV# OF vNIC(s)VMware Tools StatusTIME SYNC w/HOSTTOOLS VERTOOLS UPGRADE POLICYTOOLS MOUNTEDGUEST OSIS TEMPLATECLEAN LAST POWEROFF
HIDE ME!",$vm->config->name,"HIDE ME!",$vm_host_view->name,"",$vm->config->name,"",$vm->guest->hostName,"UNKNOWNVM is OKVM has a problemVM"; } else { print REPORT_OUTPUT "UNKNOWN",$vm->runtime->connectionState->val,"",$vm->runtime->faultToleranceState->val,"",$vm->runtime->recordReplayState->val,"",$vm->runtime->powerState->val,"",$vm->summary->config->numVirtualDisks,"UNKNOWN",$vm->summary->config->numCpu,"UNKNOWN",prettyPrintData($vm->summary->config->memorySizeMB,'M'),"UNKNOWN",prettyPrintData($vm->summary->quickStats->overallCpuUsage,'MHZ'),"UNKNOWN",prettyPrintData($vm->summary->quickStats->guestMemoryUsage,'M'),"UNKNOWN",prettyPrintData($vm->summary->config->cpuReservation,'MHZ'),"UNKNOWN",prettyPrintData($vm->summary->config->memoryReservation,'M'),"UNKNOWNN/AN/AN/AN/A",$vm->summary->config->numEthernetCards,"UNKNOWN",$vm->summary->guest->toolsVersionStatus,"UNKNOWN",($vm->config->tools->syncTimeWithHost) ? "YES" : "NO","UNKNOWN",$vm->config->tools->toolsVersion,"UNKNOWN",$vm->config->tools-> toolsUpgradePolicy,"UNKNOWN",($vm->runtime->toolsInstallerMounted) ? "YES" : "NO" ,"",$vm->summary->guest->guestFullName,"UNKNOWNN/AN/AN/AN/AN/AN/A",($isTemplate) ? "YES" : "NO" ,"",($vm->summary->runtime->cleanPowerOff) ? "YES" : "NO" ,"
$vm_name$compat_mode$vmhba$disk_mode$lun_uuid$vm_uuid$n_vm"; foreach (@$nwwns) { my $nwwn = (Math::BigInt->new($_))->as_hex(); $nwwn =~ s/^..//; $nwwn = join(':', unpack('A2' x 8, $nwwn)); if($enable_demo_mode eq 1) { $npiv_string .= "XX:XX:XX:XX:XX:XX:XX:XX
"; } else { $npiv_string .= "$nwwn
"; } } $npiv_string .= "
"; foreach (@$pwwns) { my $pwwn = (Math::BigInt->new($_))->as_hex(); $pwwn =~ s/^..//; $pwwn = join(':', unpack('A2' x 8, $pwwn)); if($enable_demo_mode eq 1) { $npiv_string .= "XX:XX:XX:XX:XX:XX:XX:XX
"; } else { $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$perc_string
$vm_disk_path$vm_disk_free$vm_disk_cap
".$vm_ip_string."".$vm_mac_string."".$vm_pg_string."".$vm_conn_string."
\n"; } sub printHostDatastoreInfo { my ($local_hosts) = @_; ########################### # PRINT DATASTORE SUMMARY ########################### push @jump_tags,"        ESX/ESXi Datastore(s)
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

ESX/ESXi Datastore(s):

\n"; print REPORT_OUTPUT "
COLOR LEGENDYELLOW < $yellow_warn %ORANGE < $orange_warn %RED < $red_warn %
\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; my @datastores_seen = (); my %datastores = (); my %datastore_row_info = (); my $ctr = 0; 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) { my $ds_row = ""; if($ds->summary->accessible) { #capture unique datastores seen in cluster if (!grep {$_ eq $ds->info->name} @datastores_seen) { push @datastores_seen,$ds->info->name; my $perc_free; my $perc_string = ""; my $ds_used; my $ds_free; my $ds_cap; my $ds_uncommit; 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 = prettyPrintData(($ds->summary->capacity - $ds->summary->freeSpace),'B'); $ds_free = &restrict_num_decimal_digits(($ds->summary->freeSpace/1024/1000),2); if($ds->summary->uncommitted) { $ds_uncommit = prettyPrintData(($ds->summary->uncommitted),'B'); } else { $ds_uncommit = "N/A"; } $perc_free = &restrict_num_decimal_digits(( 100 * $ds_free / $ds_cap),2); $perc_string = getColor($perc_free); } else { $perc_free = "UNKNOWN"; $ds_used = "UNKNOWN"; $ds_free = "UNKNOWN"; $ds_uncommit = "UNKNOWN"; } $ds_row = "$perc_string"; $datastore_row_info{$ds->info->name} = $ds_row; #capture VM dir contents w/delta files my $browser = Vim::get_view (mo_ref => $ds->browser); my $ds_path = "[" . $ds->info->name . "]"; my $file_query = FileQueryFlags->new(fileOwner => 0, fileSize => 1,fileType => 0,modification => 1); my $searchSpec = HostDatastoreBrowserSearchSpec->new(details => $file_query,matchPattern => ["*.vmsn", "*-delta.vmdk"]); my $search_res = $browser->SearchDatastoreSubFolders(datastorePath => $ds_path,searchSpec => $searchSpec); if ($search_res) { foreach my $result (@$search_res) { my $files = $result->file; if ($files) { foreach my $file (@$files) { if($file->path =~ /-delta.vmdk/ ) { my ($vm_snapshot_date,$vm_snapshot_time) = split('T',$file->modification); #my $todays_date =`date +\%Y-\%m-\%d`; my $todays_date = giveMeDate('YMD'); chomp($todays_date); my $diff = days_between($vm_snapshot_date, $todays_date); my $snap_time = $vm_snapshot_date." ".$vm_snapshot_time; setSnapColor($diff,$result->folderPath,$file->path,$file->fileSize,$snap_time); } } } } } } $datastores{$ds->info->name} .= $host->summary->config->name. "_" . $ctr++ .","; } } } #logic to check which hosts can see all datastores while ( my ($ds, $value) = each(%datastores) ) { my @pairs = split(',',$value); my $pair_count = @pairs; my @hosts_to_datastores = (); for (my $x=0;$x < $pair_count;$x++) { (my $hostname,my $count) = split('_',$pairs[$x],2); push @hosts_to_datastores, $hostname; } #logic to figure out which hosts can not see this datastore my @intersection = (); my @difference = (); my %count = (); foreach my $element (@hosts_to_datastores, @hosts_seen) { $count{$element}++ } foreach my $element (keys %count) { push @{ $count{$element} > 1 ? \@intersection : \@difference }, $element; } my $print_string = ""; if(@difference) { foreach (@difference) { $print_string .= $_." "; } } if($print_string eq '') { $print_string = ""; } else { if($enable_demo_mode eq 1) { $print_string .= ""; } else { $print_string = ""; } } $datastore_row_info{$ds} .= $print_string; @hosts_to_datastores = (); } #final print of datastore summary for my $datastore ( sort keys %datastore_row_info ) { my $value = $datastore_row_info{$datastore}; print REPORT_OUTPUT "",$value,"\n"; } print REPORT_OUTPUT "
DATASTORECAPACITYCONSUMEDFREE% FREEUNCOMMITTEDDS TYPEHOST(s) NOT ACCESSIBLE TO DATASTORE
".(prettyPrintData($ds->summary->capacity,'B'))."".$ds_used."".prettyPrintData($ds->summary->freeSpace,'B')."$ds_uncommit".$ds->summary->type."Accessible by all hosts in this clusterHIDE ME!".$print_string."
",$datastore,"
\n"; } #http://www.perlmonks.org/?node_id=17057 sub days_between { my ($start, $end) = @_; my ($y1, $m1, $d1) = split ("-", $start); my ($y2, $m2, $d2) = split ("-", $end); my $diff = mktime(0,0,0, $d2-1, $m2-1, $y2 - 1900) - mktime(0,0,0, $d1-1, $m1-1, $y1 - 1900); return $diff / (60*60*24); } sub printHostLun { my ($local_hosts) = @_; my %lun_row_info = (); my %luns = (); foreach my $host (@$local_hosts) { my $luns = $host->config->storageDevice->scsiLun; foreach (sort {$a->canonicalName cmp $b->canonicalName} @$luns) { my $lun_row = ""; if($_->isa('HostScsiDisk')) { $luns{$_->uuid} .= $host->summary->config->name . "_" . $_->canonicalName . "," ; $lun_row .= "".$_->canonicalName.""; if($_->queueDepth) { $lun_row .= "".$_->queueDepth."operationalState; foreach (@$states) { $state_string .= $_." "; } $lun_row .= "".$state_string."".$_->vendor.""; $lun_row_info{$_->uuid} = $lun_row; } } } #logic to check which hosts can see all luns while ( my ($uuid, $value) = each(%luns) ) { my @pairs = split(',',$value); my $pair_count = @pairs; my @hosts_to_luns = (); for (my $x=0;$x < $pair_count;$x++) { (my $hostname,my $vmhba) = split('_',$pairs[$x],2); push @hosts_to_luns, $hostname; } #logic to figure out which hosts can not see this datastore my @intersection = (); my @difference = (); my %count = (); foreach my $element (@hosts_to_luns, @hosts_seen) { $count{$element}++ } foreach my $element (keys %count) { push @{ $count{$element} > 1 ? \@intersection : \@difference }, $element; } my $print_string = ""; if(@difference) { foreach (@difference) { $print_string .= $_." "; } } if($print_string eq '') { $print_string = "Accessible by all hosts in this cluster"; } else { if($enable_demo_mode eq 1) { $print_string .= "HIDE ME!"; } else { $print_string = "".$print_string.""; } } $lun_row_info{$uuid} .= $print_string; @hosts_to_luns = (); } ########################### # PRINT LUN SUMMARY ########################### push @jump_tags,"        ESX/ESXi LUN(s)
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

ESX/ESXi LUN(s):

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; for my $lun ( sort keys %lun_row_info ) { my $value = $lun_row_info{$lun}; print REPORT_OUTPUT "",$value,"\n"; } print REPORT_OUTPUT "
UUIDLUNQUEUE DEPTHSTATUSVENDORHOST(s) NOT ACCESSIBLE TO LUN
",$lun,"
\n"; } sub printMultipathing { my ($host) = @_; my $hostName; if($enable_demo_mode eq 1) { $hostName = $randomHostName; } else { $hostName = $host->summary->config->name; } ########################### # PRINT MULTIPATH SUMMARY ########################### if($opt_type eq 'detail-hosts') { push @jump_tags,"                Disk Multipathing Info
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

Disk Multipathing Info:

\n"; } else { push @jump_tags,"        ESX/ESXi Disk Multipathing Info
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

ESX/ESXi Disk Multipathing Info:

\n"; } print REPORT_OUTPUT "\n"; my $ss = Vim::get_view (mo_ref => $host->configManager->storageSystem); my $verbose; my $luns = $ss->storageDeviceInfo->scsiLun; my $hbas = $ss->storageDeviceInfo->hostBusAdapter; my $mpLuns = $ss->storageDeviceInfo->multipathInfo->lun; foreach my $mpLun (@$mpLuns) { my $paths = $mpLun->path; my $numPaths = scalar(@$paths); my $lun = find_by_key($luns, $mpLun->lun); my $pol = $mpLun->policy; my $polPrefer; if (defined($pol) && defined($pol->{prefer})) { $polPrefer = $pol->prefer; } my $cap = $lun->{capacity}; my $deviceUuidPath = defined($lun->{uuid}) ? ("vml." . $lun->uuid) : ""; print REPORT_OUTPUT "
\n"; print REPORT_OUTPUT "\n"; foreach my $path (@$paths) { my $hba = find_by_key($hbas, $path->adapter); my $isFC = $hba->isa("HostFibreChannelHba"); my $state = ($path->{pathState} ? (($path->pathState eq "active") ? "On active" : $path->pathState) : ""); my $pciString = get_pci_string($hba); if($enable_demo_mode eq 1) { print REPORT_OUTPUT "\n"; } else { print REPORT_OUTPUT "\n"; } } print REPORT_OUTPUT "
",(defined($lun->{lunType}) ? $lun->lunType : "")," ",(defined($lun->{canonicalName}) ? $lun->canonicalName : ""),($verbose ? " $deviceUuidPath" : "")," ",(defined($cap) ? " ( " . int($cap->block * $cap->blockSize / (1024*1024)) . " MB )" : " ( 0 MB )")," == # of Paths: ",$numPaths," Policy: ",((defined($pol) && defined($pol->{policy})) ? $pol->policy : ""),"
",($isFC ? "FC" : "Local")," ",$pciString," ","HIDE MY NWWN <-> HIDE MY PWWN"," ",$path->name," ",$state," ",((defined($polPrefer) && ($path->name eq $polPrefer)) ? "preferred" : ""),"
",($isFC ? "FC" : "Local")," ",$pciString," ",($isFC ? $hba->nodeWorldWideName . "<->" . $hba->portWorldWideName : "")," ",$path->name," ",$state," ",((defined($polPrefer) && ($path->name eq $polPrefer)) ? "preferred" : ""),"

\n"; } print REPORT_OUTPUT "\n"; } sub get_pci_string { my $hba = shift; my $pciString = defined($hba) ? $hba->pci : ""; # defect 173631 if ($pciString =~ /([a-fA-F0-9]+):([a-fA-F0-9]+)\.([a-fA-F0-9]+)$/) { $pciString = hexstr_to_int($1) . ":" . hexstr_to_int($2) . "." . hexstr_to_int($3); } return $pciString } sub hexstr_to_int { my ($hexstr) = @_; die "Invalid hex string: $hexstr" if $hexstr !~ /^[0-9A-Fa-f]{1,8}$/; my $num = hex($hexstr); return $num >> 31 ? $num - 2 ** 32 : $num; } sub find_by_key { my ($list, $key) = @_; foreach my $item (@$list) { if ($key eq $item->key) { return $item; } } return undef; } sub printHostPortgroup { my ($local_hosts) = @_; my @hosts_to_portgroups = (); my %portgroup_row_info = (); foreach my $host (@$local_hosts) { my $portgroup_views = Vim::get_views (mo_ref_array => $host->network); foreach my $portgroup (sort {$a->summary->name cmp $b->summary->name} @$portgroup_views) { my $pg_row = ""; if($portgroup->summary->accessible) { my $host_mounts = $portgroup->host; foreach (@$host_mounts) { push @hosts_to_portgroups,$host->name; } #logic to figure out which hosts can not see this portgroup my @intersection = (); my @difference = (); my %count = (); foreach my $element (@hosts_to_portgroups, @hosts_seen) { $count{$element}++ } foreach my $element (keys %count) { push @{ $count{$element} > 1 ? \@intersection : \@difference }, $element; } if(@difference) { my $hosts_not_accessible = ""; foreach (@difference) { $hosts_not_accessible .= $_." "; } if($enable_demo_mode eq 1) { $pg_row .= "HIDE ME!"; } else { $pg_row .= "$hosts_not_accessible"; } } else { $pg_row .= "Accessible by all hosts in this cluster"; } $portgroup_row_info{$portgroup->name} = $pg_row; } } } @hosts_to_portgroups = (); #final print of portgroup summary ########################### # PRINT PORTGROUP SUMMARY ########################### push @jump_tags,"        ESX/ESXi Portroup(s)
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "

ESX/ESXi Portroup(s):

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; for my $portgroup ( sort keys %portgroup_row_info ) { my $value = $portgroup_row_info{$portgroup}; if($enable_demo_mode eq 1) { $portgroup = "HIDE MY PG!"; } print REPORT_OUTPUT "",$value,"\n"; } print REPORT_OUTPUT "
PORTGROUPHOST(s) NOT ACCESSIBLE TO PORTGROUP
",$portgroup,"
\n"; } sub clusterPG { my ($cluster) = @_; my @hosts_in_cluster = (); my @hosts_in_portgroup = (); my $pg_row = ""; my $pg_name; my $hic = Vim::get_views(mo_ref_array => $cluster->host, properties => ['name']); foreach(@$hic) { push @hosts_in_cluster,$_->{'name'}; } my $pg = Vim::get_views(mo_ref_array => $cluster->network); foreach(@$pg) { my $hosts = Vim::get_views(mo_ref_array => $_->host, properties => ['name']); $pg_name = $_->name; foreach(@$hosts) { push @hosts_in_portgroup,$_->{'name'}; } #logic to figure out which hosts can not see this portgroup my @intersection = (); my @difference = (); my %count = (); foreach my $element (@hosts_in_portgroup, @hosts_in_cluster) { $count{$element}++ } foreach my $element (keys %count) { push @{ $count{$element} > 1 ? \@intersection : \@difference }, $element; } my @hosts_not_prop_configured = (); my @difference_2 = (); %count = (); foreach my $element (@difference, @hosts_in_cluster) { $count{$element}++ } foreach my $element (keys %count) { push @{ $count{$element} > 1 ? \@hosts_not_prop_configured : \@difference_2 }, $element; } if(@hosts_not_prop_configured) { my $hosts_not_accessible = ""; foreach (@hosts_not_prop_configured) { $hosts_not_accessible .= $_." "; } if($enable_demo_mode eq 1) { $pg_row .= "HIDE ME!"; } else { $pg_row .= "$hosts_not_accessible"; } } else { $pg_row .= "Accessible by all hosts in this cluster"; } $portgroup_row_info{$pg_name} = $pg_row; $pg_row = ""; @hosts_in_portgroup = (); } @hosts_in_cluster = (); } sub printPG { #final print of portgroup summary ########################### # PRINT PORTGROUP SUMMARY ########################### push @jump_tags,"        ESX/ESXi Portroup(s)
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "

ESX/ESXi Portroup(s):

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; for my $portgroup ( sort keys %portgroup_row_info ) { my $value = $portgroup_row_info{$portgroup}; if($enable_demo_mode eq 1) { $portgroup = "HIDE MY PG!"; } print REPORT_OUTPUT "",$value,"\n"; } print REPORT_OUTPUT "
PORTGROUPHOST(s) NOT ACCESSIBLE TO PORTGROUP
",$portgroup,"
\n"; %portgroup_row_info = (); } sub getDVS { my ($cluster) = @_; my %seen_dvs = (); my $dvs_target; my $dvs_string = ""; my $dvs_mgr = Vim::get_view(mo_ref => $content->dvSwitchManager); if ($content->about->apiType eq 'VirtualCenter') { my $hosts = Vim::get_views(mo_ref_array => $cluster->host); foreach my $host (@$hosts) { $dvs_target = $dvs_mgr->DVSManagerQueryDvsConfigTarget(host => $host); my $dvs = $dvs_target->distributedVirtualSwitch; if($dvs) { foreach(@$dvs) { my $sName = defined $_->switchName ? $_->switchName : "N/A"; $seen_dvs{$sName} = 1; if($seen_dvs{$sName} eq 1 ) { my $sUuid = defined $_->switchUuid ? $_->switchUuid : "N/A"; my $dv_switch = Vim::get_view(mo_ref => $_->distributedVirtualSwitch); my $desc = defined $dv_switch->summary->description ? $dv_switch->summary->description : "N/A"; my $contact_name = defined $dv_switch->summary->contact->name ? $dv_switch->summary->contact->name : "N/A"; my $contact_con = defined $dv_switch->summary->contact->contact ? $dv_switch->summary->contact->contact : ""; my $contact_info = $contact_name . " " . $contact_con; my $build = defined $dv_switch->summary->productInfo->build ? $dv_switch->summary->productInfo->build : "N/A"; my $bid = defined $dv_switch->summary->productInfo->bundleId ? $dv_switch->summary->productInfo->bundleId : "N/A"; my $burl = defined $dv_switch->summary->productInfo->bundleUrl ? $dv_switch->summary->productInfo->bundleUrl : "N/A"; my $fclass = defined $dv_switch->summary->productInfo->forwardingClass ? $dv_switch->summary->productInfo->forwardingClass : "N/A"; my $vendor = defined $dv_switch->summary->productInfo->vendor ? $dv_switch->summary->productInfo->vendor : "N/A"; my $version = defined $dv_switch->summary->productInfo->version ? $dv_switch->summary->productInfo->version : "N/A"; my $ports = defined $dv_switch->summary->numPorts ? $dv_switch->summary->numPorts : "N/A"; $dvs_string = "".$sName."".$desc."".$contact_info."".$vendor."".$version."".$sUuid."".$build."".$bid."".$build."".$burl."".$fclass."".$ports."\n"; push @dvs, $dvs_string; } } } } } } sub printDVS { ########################### # PRINT DVS SUMMARY ########################### if(@dvs) { push @jump_tags,"        ESX/ESXi Distributed vSwitch(s)
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "

ESX/ESXi Distributed vSwitch(s):

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; foreach(@dvs) { print REPORT_OUTPUT $_; } print REPORT_OUTPUT "
NAMEDESCRIPTIONCONTACT INFOVENDORVERSIONUUIDBUILDBUNDLE IDBUNDLE BUILDBUNDLE URLFORWARDING CLASSPORTS
\n"; } @dvs = (); } sub printHostHardwareInfo { my ($local_hosts) = @_; ########################### # PRINT HOST HARDWARE ########################### push @jump_tags,"        ESX/ESXi hardware configuration
\n"; print REPORT_OUTPUT "
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\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 ""; if($enable_demo_mode eq 1) { print REPORT_OUTPUT ""; } else { print REPORT_OUTPUT ""; } print REPORT_OUTPUT ""; my $additional_vendor_info = ""; if($local_host->summary->hardware->otherIdentifyingInfo) { my $add_info = $local_host->summary->hardware->otherIdentifyingInfo; foreach (@$add_info) { $additional_vendor_info .= $_->identifierType->key.": ".$_->identifierValue." "; } if($additional_vendor_info eq '') { $additional_vendor_info = "UNKNOWN"; } } print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT "\n"; #capture unique hosts for later use push @hosts_seen,$local_host->summary->config->name; #get health getHealthInfo($local_host); #get nic getNICInfo($local_host); #get hba getHBAInfo($local_host); } print REPORT_OUTPUT "
HOSTNAMEVENDORADDITIONAL VENDOR INFOCPU INFOHT AVAILABLE/ENABLEDCPU SPEEDCPU USAGECPU PACKAGE(s)CPU CORE(s)CPU THREAD(s)MEMORYMEMORY USAGENIC(s)HBA(s)
HIDE ME!",$local_host->summary->config->name,"",$local_host->summary->hardware->vendor,"",$additional_vendor_info,"",$local_host->summary->hardware->cpuModel,"",($local_host->config->hyperThread->available) ? "YES" : "NO"," / "; print REPORT_OUTPUT ($local_host->config->hyperThread->active) ? "YES" : "NO","",prettyPrintData($local_host->summary->hardware->numCpuCores*$local_host->summary->hardware->cpuMhz,'MHZ'),"",prettyPrintData($local_host->summary->quickStats->overallCpuUsage,'MHZ'),"",$local_host->summary->hardware->numCpuPkgs,"",$local_host->summary->hardware->numCpuCores,"",$local_host->summary->hardware->numCpuThreads,"",prettyPrintData($local_host->summary->hardware->memorySize,'B'),"",prettyPrintData($local_host->summary->quickStats->overallMemoryUsage,'M'),"",$local_host->summary->hardware->numNics,"",$local_host->summary->hardware->numHBAs,"
\n"; ########################### # PRINT HEALTH STATUS ########################### printHealth(); ########################### # PRINT NIC INFO ########################### printNIC(); ########################### # PRINT HBA INFO ########################### printHBA(); ########################### # PRINT HOST STATE ########################### print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

ESX/ESXi state:

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; foreach my $local_host (sort {$a->summary->config->name cmp $b->summary->config->name} @$local_hosts) { print REPORT_OUTPUT ""; if($enable_demo_mode eq 1) { print REPORT_OUTPUT ""; } else { print REPORT_OUTPUT ""; } my $host_health = $local_host->overallStatus->val; if ($host_health eq 'green') { print REPORT_OUTPUT ""; } elsif ($host_health eq 'red') { print REPORT_OUTPUT ""; } elsif ($host_health eq 'yellow') { print REPORT_OUTPUT ""; } else { print REPORT_OUTPUT ""; } print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT "\n"; } print REPORT_OUTPUT "
HOSTNAMEOVERALL STATUSPOWER STATECONNECTION STATEMAINTENANCE MODEVMOTION ENABLEDVERSION
HIDE ME!",$local_host->summary->config->name,"HOST is OKHOST has a problemHOST might have a problemUNKNOWN",$local_host->runtime->powerState->val,"",$local_host->runtime->connectionState->val,"",($local_host->summary->runtime->inMaintenanceMode) ? "YES" : "NO" ,"",($local_host->summary->config->vmotionEnabled) ? "YES" : "NO" ,"",${$local_host->summary->config->product}{'fullName'},"
\n"; ########################### # PRINT HOST CONFIG ########################### if($opt_type ne 'detail-hosts') { print REPORT_OUTPUT "\n"; push @jump_tags,"        ESX/ESXi Configurations
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

ESX/ESXi Configurations:

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; } foreach my $local_host (sort {$a->summary->config->name cmp $b->summary->config->name} @$local_hosts) { if($enable_demo_mode eq 1) { $randomHostName = "ESX-DEV-HOST-".int(rand(100)).".primp-industries.com"; } if($opt_type eq 'detail-hosts') { my $hostName; if($enable_demo_mode eq 1) { $hostName = $randomHostName; } else { $hostName = $local_host->summary->config->name; } print REPORT_OUTPUT "
HOSTNAMEUUIDSERVICE CONSOLE MEMORYAUTOSTART MANAGERDisk.UseDeviceResetDisk.UseLunResetDisk.SchedNumReqOutstanding
\n"; push @jump_tags,"        $hostName configurations
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

$hostName configurations:

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; } print REPORT_OUTPUT ""; if($enable_demo_mode eq 1) { print REPORT_OUTPUT ""; } else { print REPORT_OUTPUT ""; } print REPORT_OUTPUT ""; if(defined($local_host->config->consoleReservation)) { print REPORT_OUTPUT ""; } else { print REPORT_OUTPUT ""; } print REPORT_OUTPUT ""; #advconfigs my $advconfigs = Vim::get_view (mo_ref => $local_host->configManager->advancedOption); my $options_ref = $advconfigs->setting; my $d_udr = "UNKNOWN"; my $d_ulr = "UNKNOWN"; my $d_snro = "UNKNOWN"; foreach my $option (@$options_ref) { my $key = $option->key; my $value = $option->value; if($key eq 'Disk.UseDeviceReset') { $d_udr = $value; } if($key eq 'Disk.UseLunReset') { $d_ulr = $value; } if($key eq 'Disk.SchedNumReqOutstanding') { $d_snro = $value; } } print REPORT_OUTPUT ""; if($opt_type eq 'detail-hosts') { print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "
HOSTNAMEUUIDSERVICE CONSOLE MEMORYAUTOSTART MANAGERDisk.UseDeviceResetDisk.UseLunResetDisk.SchedNumReqOutstanding
HIDE ME!",$local_host->summary->config->name,"",$local_host->summary->hardware->uuid,"",prettyPrintData($local_host->config->consoleReservation->serviceConsoleReserved,'B'),"UNKNOWN",($local_host->config->autoStart->defaults->enabled) ? "YES" : "NO","",$d_udr,"",$d_ulr,"",$d_snro,"
\n"; printDetailHostConfigurations($local_host); printLimitedVMInfo($local_host); } elsif($opt_type eq 'host') { printDetailHostConfigurations($local_host); } } if($opt_type ne 'detail-hosts') { print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; } } sub printDetailHostConfigurations { my ($host) = @_; print REPORT_OUTPUT "
\n"; ## SERVICE CONSOLE / VMOTION ## if ($host->summary->config->vmotionEnabled) { print REPORT_OUTPUT "\n"; if($enable_demo_mode eq 1) { print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; } else { print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; } } ## GATEWAY ## my $network_system; eval { $network_system = Vim::get_view(mo_ref => $host->configManager->networkSystem); }; if(!$@) { if($enable_demo_mode eq 1) { print REPORT_OUTPUT "\n"; } else { if($network_system->consoleIpRouteConfig->defaultGateway) { print REPORT_OUTPUT "\n"; } else { print REPORT_OUTPUT "\n"; } if($network_system->consoleIpRouteConfig->ipV6DefaultGateway) { print REPORT_OUTPUT "\n"; } else { print REPORT_OUTPUT "\n"; } if($network_system->ipRouteConfig->defaultGateway) { print REPORT_OUTPUT "\n"; } else { print REPORT_OUTPUT "\n"; } if($network_system->ipRouteConfig->ipV6DefaultGateway) { print REPORT_OUTPUT "\n"; } else { print REPORT_OUTPUT "\n"; } } } ## SOFTWARE iSCSI ## print REPORT_OUTPUT "\n"; ## IPV6 ENABLED ## print REPORT_OUTPUT "\n"; ## FT ENABLED ## print REPORT_OUTPUT "\n"; ## SSL THUMBPRINT ## my $sslprint = defined $host->summary->config->sslThumbprint ? $host->summary->config->sslThumbprint : "N/A"; print REPORT_OUTPUT "\n"; ## DNS ## my $s_domains = $host->config->network->dnsConfig->searchDomain; my $s_string = ""; foreach(@$s_domains) { $s_string .= "search ".$_."
"; } my $dns_add = $host->config->network->dnsConfig->address; my $dns_string = ""; foreach(@$dns_add) { $dns_string .= "nameserver ".$_."
"; } if($enable_demo_mode eq 1) { print REPORT_OUTPUT "\n"; } else { print REPORT_OUTPUT "\n"; } ## UPTIME ## my ($host_date,$host_time) = split('T',$host->runtime->bootTime); my $todays_date = giveMeDate('YMD'); chomp($todays_date); my $up_time = days_between($host_date, $todays_date); print REPORT_OUTPUT "\n"; ## OFFLOAD CAPABILITIES ## my $offload_string = ""; $offload_string .= ""; print REPORT_OUTPUT "\n"; ## DIAGONISTIC PARITION ## if($host->config->activeDiagnosticPartition) { my $diag_string = ""; $diag_string .= ""; print REPORT_OUTPUT "\n"; } ## SERVICES ## my $services = $host->config->service->service; my $service_string = ""; foreach(@$services) { $service_string .= ""; } print REPORT_OUTPUT "\n"; ## NTP ## if($host->config->dateTimeInfo) { my $ntps = $host->config->dateTimeInfo->ntpConfig->server; my $ntp_string = ""; if($ntps) { foreach (@$ntps) { $ntp_string .= "$_
"; } } else { $ntp_string = "NONE CONFIGURED"; } $ntp_string = ""; $ntp_string .= ""; print REPORT_OUTPUT "\n"; } ## VSWIF ## if($host->config->network->consoleVnic) { my $vswif_string = ""; my $console_vnics = $host->config->network->consoleVnic; foreach(@$console_vnics) { if($enable_demo_mode eq 1) { $vswif_string .= ""; } else { $vswif_string .= ""; } } print REPORT_OUTPUT "\n"; } ## VMKERNEL ## if($host->config->network->vnic) { my $vmk_string = ""; my $vmks = $host->config->network->vnic; foreach(@$vmks) { if($enable_demo_mode eq 1) { $vmk_string .= ""; } else { $vmk_string .= ""; } } print REPORT_OUTPUT "\n"; } ## VSWITCH ## getVswitchInfo($host); ## SNMP ## my $snmp_system; eval { $snmp_system = Vim::get_view (mo_ref => $host->configManager->snmpSystem); }; if(!$@) { if($snmp_system->configuration->enabled) { my $snmp_string = ""; $snmp_string .= ""; my $snmp_traps = $snmp_system->configuration->trapTargets; foreach(@$snmp_traps) { print "Community: ", $_->commmunity, " Hostname: ", $_->hostName, " Port: ",$_->port,"\n"; } print REPORT_OUTPUT "\n"; } } ## FIREWALL ## if($host->config->firewall) { my $fw_sys = $host->config->firewall; my $fw_rules = $fw_sys->ruleset; my $fw_known_string = ""; my $fw_rule_string = ""; foreach(@$fw_rules) { if($_->enabled) { $fw_known_string .= ""; } } print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; } ## CPU POWER MANAGMENT ## if($host->hardware->cpuPowerManagementInfo) { my $cpu_power_info = ""; $cpu_power_info .= ""; print REPORT_OUTPUT "\n"; } ## END OF CUSTOME DETAIL INFO ## print REPORT_OUTPUT "
VMOTION ENABLED YES
IP ADDRESS X.X.X.X
NETMASK X.X.X.X
IP ADDRESS ",$host->config->vmotion->ipConfig->ipAddress," => ",$host->summary->config->name,"
NETMASK ",$host->config->vmotion->ipConfig->subnetMask,"
GATEWAY X.X.X.X
GATEWAY ",$network_system->consoleIpRouteConfig->defaultGateway,"
GATEWAY 0.0.0.0
IPv6 GATEWAY ",$network_system->consoleIpRouteConfig->ipV6DefaultGateway,"
IPv6 GATEWAY 0.0.0.0
VMKERNEL GATEWAY ",$network_system->ipRouteConfig->defaultGateway,"
VMKERNEL GATEWAY 0.0.0.0
VMKERNEL IPv6 GATEWAY ",$network_system->ipRouteConfig->ipV6DefaultGateway,"
VMKERNEL IPv6 GATEWAY 0.0.0.0
SOFTWAE iSCSI ENABLED",($host->config->storageDevice->softwareInternetScsiEnabled ? "YES" : "NO"),"
IPv6 ENABLED",($host->config->network->ipV6Enabled ? "YES" : "NO"),"
FT ENABLED",($host->summary->config->faultToleranceEnabled ? "YES" : "NO"),"
SSL THUMBPRINT",$sslprint,"
DNSdomain X.domain.com
search Y.domain.com
nameserver Z.domain.com
DNS","domain ", $host->config->network->dnsConfig->domainName,"
",$s_string,$dns_string,"
UPTIME",$up_time," Days - ",$host->runtime->bootTime,"
".($host->config->offloadCapabilities->csumOffload ? "YES" : "NO")."".($host->config->offloadCapabilities->tcpSegmentation ? "YES" : "NO")."".($host->config->offloadCapabilities->zeroCopyXmit ? "YES" : "NO")."
OFFLOAD CAPABILITIES",$offload_string,"
CHECKSUMTCP SEGMENTATIONZERO COPY TRANSMIT
".$host->config->activeDiagnosticPartition->diagnosticType."".$host->config->activeDiagnosticPartition->id->diskName.$host->config->activeDiagnosticPartition->id->partition."".$host->config->activeDiagnosticPartition->storageType."
DIAGNOSTIC PARTITION",$diag_string,"
TYPEPARITIONSTORAGE TYPE
".$_->label."".$_->policy."".(($_->running) ? "YES" : "NO")."
SERVICE(s)",$service_string,"
NAMEPOLICY TYPERUNNING
".$ntp_string."".$host->config->dateTimeInfo->timeZone->description."".$host->config->dateTimeInfo->timeZone->gmtOffset."".$host->config->dateTimeInfo->timeZone->name."
NTP",$ntp_string,"
NTP SERVERSTIME ZONEGMT OFFSETLOCATION
".$_->device."HIDE MY PGX.X.X.X".$_->spec->ip->subnetMask."".$_->spec->mac."".(($_->spec->ip->dhcp) ? "YES" : "NO")."
".$_->device."".$_->portgroup."".$_->spec->ip->ipAddress."".$_->spec->ip->subnetMask."".$_->spec->mac."".(($_->spec->ip->dhcp) ? "YES" : "NO")."
VSWIF(s)",$vswif_string,"
NAMEPORTGROUPIP ADDRESSNETMASKMACDHCP
".$_->device."HIDE MY PGX.X.X.X".$_->spec->ip->subnetMask."".$_->spec->mac."".(($_->spec->ip->dhcp) ? "YES" : "NO")."
".$_->device."".$_->portgroup."".$_->spec->ip->ipAddress."".$_->spec->ip->subnetMask."".$_->spec->mac."".(($_->spec->ip->dhcp) ? "YES" : "NO")."
VMKERNEL(s)",$vmk_string,"
INTERFACEPORTGROUPIP ADDRESSNETMASKMACDHCP
".$snmp_system->configuration->port."".$snmp_system->configuration->readOnlyCommunities."
SNMP",$snmp_string,"
SNMP PORTRO COMMUNITIESTARGETS
".$_->label."
FIREWALL
KNOWN SERVICES ENABLED
",$fw_known_string,"
FIREWALL
DEFAULT INCOMING ENABLED
",($fw_sys->defaultPolicy->incomingBlocked ? "YES" : "NO"),"
FIREWALL
DEFAULT OUTGOING ENABLED
",($fw_sys->defaultPolicy->outgoingBlocked ? "YES" : "NO"),"
".($host->hardware->cpuPowerManagementInfo->currentPolicy)."".($host->hardware->cpuPowerManagementInfo->hardwareSupport)."
CPU POWER MGMT INFO",$cpu_power_info,"
CURRENT POLICYHARDWARE SUPPORT
\n"; ## CDP ## printCDPInfo($host->name); ## MULTI-PATHING ## printMultipathing($host); ## HOSTD LOGS ## printHostdLogs($host); ## LATEST TASK ## printTasks($host); } sub printCDPInfo { my ($hostName) = @_; if($cdp_string ne "") { if($opt_type eq 'detail-hosts') { push @jump_tags,"                CDP Info
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

CDP Info:

\n"; } else { push @jump_tags,"        ESX/ESXi CDP Info
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

ESX/ESXi CDP Info:

\n"; } print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT $cdp_string; print REPORT_OUTPUT "
DEVICEMGMT ADDRESSDEVICE ADDRESSIP PREFIXLOCATIONSYSTEM NAMESYSTEM VERSIONSYSTEM OIDPLATFORMDEVICE IDCDP VERFULL DUPLEXMTUTIMEOUTTTLVLAN IDSAMPLES
\n"; } $cdp_string = ""; } sub printHostdLogs { my ($host) = @_; my $hostName; if($enable_demo_mode eq 1) { $hostName = $randomHostName; } else { $hostName = $host->summary->config->name; } my $logData; my $logKey = "hostd"; my $diagmgr_view = Vim::get_view(mo_ref => Vim::get_service_content()->diagnosticManager); if($opt_type eq 'detail-hosts') { $logData = $diagmgr_view->BrowseDiagnosticLog(key => $logKey, host => $host, start => "999999999"); } else { $logData = $diagmgr_view->BrowseDiagnosticLog(key => $logKey,start => "999999999"); } my $lineEnd = $logData->lineEnd; my $start = $lineEnd - $hostd_log_print; if($opt_type eq 'detail-hosts') { $logData = $diagmgr_view->BrowseDiagnosticLog(key => $logKey,host => $host, start => $start,lines => $hostd_log_print); } else { $logData = $diagmgr_view->BrowseDiagnosticLog(key => $logKey,start => $start,lines => $hostd_log_print); } if ($logData->lineStart != 0) { if($opt_type eq 'detail-hosts') { push @jump_tags,"                Hostd Logs - Last $hostd_log_print lines
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

Hostd Logs - Last $hostd_log_print lines:

\n"; } else { push @jump_tags,"        ESX/ESXi Hostd Logs - Last $hostd_log_print lines
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

ESX/ESXi Hostd Logs - Last $hostd_log_print lines:

\n"; } print REPORT_OUTPUT "\n"; my $hostd_string = ""; foreach my $line (@{$logData->lineText}) { $hostd_string .= $line."
\n"; } if($enable_demo_mode eq 1) { $hostd_string = "HIDE MY IMPORTANT LOGS"; } print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "
",$hostd_string,"
\n"; } } sub printTasks { my ($host) = @_; my $hostName; my $task_string; if($enable_demo_mode eq 1) { $hostName = $randomHostName; } else { $hostName = $host->summary->config->name; } my $task_view = Vim::get_view(mo_ref => Vim::get_service_content()->taskManager); my $tasks = Vim::get_views(mo_ref_array => $task_view->recentTask); $task_string = ""; foreach(@$tasks) { my $progress = $_->info->progress; if(!defined($progress)) { $progress = "COMPLETED"; } $task_string .= "".$_->info->descriptionId."".$_->info->queueTime."".$_->info->startTime."".$_->info->completeTime."".$progress."".$_->info->state->val."\n"; } if($task_string ne "") { if($opt_type eq 'detail-hosts') { push @jump_tags,"                Recent Tasks
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

Recent Tasks:

\n"; } else { push @jump_tags,"        ESX/ESXi Recent Tasks
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

ESX/ESXi Recent Tasks:

\n"; } print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; } if($task_string ne "") { if($enable_demo_mode eq 1) { $task_string = "HIDE MY RECENT TASKS"; } print REPORT_OUTPUT $task_string; print REPORT_OUTPUT "
DESCRIPTIONQUEUE TIMESTART TIMECOMPLETION TIMEPROGRESSSTATE
\n"; } } sub printHBA { if(@hba_list) { push @jump_tags,"        ESX/ESXi HBA(s)
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

ESX/ESXi HBA(s)

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; foreach (@hba_list) { print REPORT_OUTPUT "",$_,"\n"; } print REPORT_OUTPUT "
HOSTHBA TYPEDEVICEPCIMODELDRIVERSTATUSADDITIONAL INFO
\n"; } @hba_list = (); } sub printNIC { if(@nic_list) { push @jump_tags,"        ESX/ESXi NIC(s)
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

ESX/ESXi NIC(s)

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; foreach (@nic_list) { print REPORT_OUTPUT "",$_,"\n"; } print REPORT_OUTPUT "
HOSTDEVICEPCIDRIVERDUPLEXSPEEDWOL ENABLEDMAC
\n"; } @nic_list = (); } sub printHealth { if(@health_list) { push @jump_tags,"        ESX/ESXi Health Status
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

ESX/ESXi Health Status

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; foreach (@health_list) { print REPORT_OUTPUT $_; } print REPORT_OUTPUT "
SENSOR NAMEREADINGSTATUS
\n"; } @health_list = (); } sub getHealthInfo { my ($host) = @_; if(defined($host->runtime->healthSystemRuntime)) { if(defined($host->runtime->healthSystemRuntime->systemHealthInfo)) { my $health_string = ""; $health_string .= "".$host->name."\n"; my $sensors = $host->runtime->healthSystemRuntime->systemHealthInfo->numericSensorInfo; my $sensor_health_color = ""; foreach(sort {$a->name cmp $b->name} @$sensors) { my $sensor_health = $_->healthState->key; if ($sensor_health eq 'Green' || $sensor_health eq 'green') { $sensor_health_color="OK"; } elsif ($sensor_health_color eq 'Red' || $sensor_health_color eq 'red') { $sensor_health_color="PROBLEM"; } elsif ($sensor_health_color eq 'Yellow' || $sensor_health_color eq 'yellow') { $sensor_health_color="WARNING"; } else { $sensor_health_color="UNKNOWN"; } my $reading; if(defined($_->rateUnits)) { $reading = $_->currentReading . " " . $_->baseUnits . "/" . $_->rateUnits; } else { $reading = $_->currentReading . " " . $_->baseUnits; } $health_string .= "".$_->name."".$reading."".$sensor_health_color."\n"; } push @health_list,$health_string; } } } 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 DUPLEX" : "HALF-DUPLEX")."".$nic->linkSpeed->speedMb." MB"; } else { $nic_string .= "UNKNOWNUNKNOWN"; } $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."SPEED ".$hba->speed.""; } 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 ($host) = @_; my %cdp_blob = (); my $netMgr = Vim::get_view(mo_ref => $host->configManager->networkSystem); my @physicalNicHintInfo = $netMgr->QueryNetworkHint(); foreach (@physicalNicHintInfo){ foreach ( @{$_} ){ if(defined($_->connectedSwitchPort)) { my $device = $_->device; my $port = $_->connectedSwitchPort->portId; my $address = defined $_->connectedSwitchPort->address ? $_->connectedSwitchPort->address : "N/A"; my $cdp_ver = defined $_->connectedSwitchPort->cdpVersion ? $_->connectedSwitchPort->cdpVersion : "N/A"; my $devid = defined $_->connectedSwitchPort->devId ? $_->connectedSwitchPort->devId : "N/A"; my $duplex = defined $_->connectedSwitchPort->fullDuplex ? ($_->connectedSwitchPort->fullDuplex ? "YES" : "NO") : "N/A"; my $platform = defined $_->connectedSwitchPort->hardwarePlatform ? $_->connectedSwitchPort->hardwarePlatform : "N/A"; my $prefix = defined $_->connectedSwitchPort->ipPrefix ? $_->connectedSwitchPort->ipPrefix : "N/A"; my $location = defined $_->connectedSwitchPort->location ? $_->connectedSwitchPort->location : "N/A"; my $mgmt_addr = defined $_->connectedSwitchPort->mgmtAddr ? $_->connectedSwitchPort->mgmtAddr : "N/A"; my $d_mtu = defined $_->connectedSwitchPort->mtu ? $_->connectedSwitchPort->mtu : "N/A"; my $samples = defined $_->connectedSwitchPort->samples ? $_->connectedSwitchPort->samples : "N/A"; my $sys_ver = defined $_->connectedSwitchPort->softwareVersion ? $_->connectedSwitchPort->softwareVersion : "N/A"; my $sys_name = defined $_->connectedSwitchPort->systemName ? $_->connectedSwitchPort->systemName : "N/A"; my $sys_oid = defined $_->connectedSwitchPort->systemOID ? $_->connectedSwitchPort->systemOID : "N/A"; my $timeout = defined $_->connectedSwitchPort->timeout ? $_->connectedSwitchPort->timeout : "N/A"; my $ttl = defined $_->connectedSwitchPort->ttl ? $_->connectedSwitchPort->ttl : "N/A"; my $vlan = defined $_->connectedSwitchPort->vlan ? $_->connectedSwitchPort->vlan : "N/A"; if($enable_demo_mode eq 1) { $address = "HIDE MY DEVICE IP!"; $prefix = "HIDE MY IP PREFIX!"; $mgmt_addr = "HIDE MY MGMT IP!"; $vlan = "HIDE MY VLAN ID!"; $devid = "HIDE MY DEVICE ID!"; $sys_name = "HIDE MY SYSTEM NAME!"; $sys_ver = "HIDE MY SYSTEM VERSION!"; $platform = "HIDE MY PLATFORM!"; } my $blob .= "".$device."".$mgmt_addr."".$address."".$prefix."".$location."".$sys_name."".$sys_ver."".$sys_oid."".$platform."".$devid."".$cdp_ver."".$duplex."".$d_mtu."".$timeout."".$ttl."".$vlan."".$samples."\n"; $cdp_blob{$device} = $blob; $cdp_enabled{$device} = $port; } } } my $vswitches = $host->config->network->vswitch; my $vswitch_string = ""; foreach my $vSwitch (@$vswitches) { my $pNicName = ""; my $mtu = ""; my $cdp_vswitch = ""; 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}); $vswitch_string .= "VSWITCH NAMENUM OF PORTSUSED PORTSMTUUPLINKSCDP ENABLED".$vSwitch->name."".$vSwitch->numPorts."".($vSwitch->numPorts - $vSwitch->numPortsAvailable)."".$vSwitch->{mtu}."".$pNicName."".$cdp_vswitch.""; $vswitch_string .= "PORTGROUP NAMEVLAN IDUSED PORTSUPLINKS"; my $portGroups = $vSwitch->portgroup; foreach my $port (@$portGroups) { my $pg = FindPortGroupbyKey ($netMgr, $vSwitch->key, $port); next unless (defined $pg); my $usedPorts = (defined $pg->port) ? $#{$pg->port} + 1 : 0; if($enable_demo_mode eq 1) { $vswitch_string .= "HIDE MY PGHIDE MY VLAN ID".$usedPorts."".$pNicName.""; } else { $vswitch_string .= "".$pg->spec->name."".$pg->spec->vlanId."".$usedPorts."".$pNicName.""; } } } print REPORT_OUTPUT "VSWITCH(s)",$vswitch_string,"
\n"; for my $key ( keys %cdp_blob ) { my $value = $cdp_blob{$key}; $cdp_string .= $value; } } 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_health = $local_cluster->overallStatus->val; my $cluster_host_cnt = $local_cluster->summary->numHosts; my $cluster_avail_host = $local_cluster->summary->numEffectiveHosts; my $cluster_cpu_cnt = prettyPrintData($local_cluster->summary->totalCpu,'MHZ'); my $cluster_mem_cnt = prettyPrintData($local_cluster->summary->totalMemory,'B'); my $cluster_avail_cpu = prettyPrintData($local_cluster->summary->effectiveCpu,'MHZ'); my $cluster_avail_mem = prettyPrintData($local_cluster->summary->effectiveMemory,'M'); my $cluster_drs = $local_cluster->configuration->drsConfig->enabled; my $cluster_ha = $local_cluster->configuration->dasConfig->enabled; my $cluster_dpm = $local_cluster->configurationEx->dpmConfigInfo->enabled; my $cluster_vm_mon = $local_cluster->configuration->dasConfig->vmMonitoring; my $cluster_host_mon = $local_cluster->configuration->dasConfig->hostMonitoring; my $cpu_perc_string = ""; my $mem_perc_string = ""; my $evc; if($local_cluster->summary->currentEVCModeKey) { $evc = $local_cluster->summary->currentEVCModeKey; } else { $evc = "DISABLED"; } my $vmotions = $local_cluster->summary->numVmotions; clusterPG($local_cluster); getDVS($local_cluster); print REPORT_OUTPUT "
\n"; ########################### # PRINT CLUSTER SUMMARY ########################### push @jump_tags,"CLCluster: $cluster_name
\n"; print REPORT_OUTPUT "\n\n"; print REPORT_OUTPUT "

Cluster: $cluster_name

\n"; print REPORT_OUTPUT "

Cluster Statistics:

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT ""; if($cluster_health eq 'gray' ) { print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "
CLUSTER HEALTHAVAILABLE HOST(s)AVAILABLE CPUAVAILABLE MEMDRS ENABLEDHA ENABLEDDPM ENABLEDEVC ENABLEDVM MONITORINGHOST MONITORING# OF vMOTIONS
UNKNOWN"; } if($cluster_health eq 'green' ) { print REPORT_OUTPUT "CLUSTER OK"; } if($cluster_health eq 'red' ) { print REPORT_OUTPUT "CLUSTER HAS PROBLEM"; } if($cluster_health eq 'yellow' ) { print REPORT_OUTPUT "CLUSTER MIGHT HAVE PROBLEM"; } print REPORT_OUTPUT "",$cluster_avail_host,"/",$cluster_host_cnt,"",$cluster_avail_cpu,"",$cluster_avail_mem,"",($cluster_drs) ? "YES" : "NO","",($cluster_ha) ? "YES" : "NO" ,"",($cluster_dpm) ? "YES" : "NO" ,"",$evc,"",$cluster_vm_mon,"",$cluster_host_mon,"",$vmotions,"
\n"; ########################### # PRINT HA INFO ########################### if($cluster_ha) { print REPORT_OUTPUT "\n

HA CONFIGURATIONS:

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "
FAILOVER LEVELADMISSION CONTROLED ENABLEDISOLATION RESPONSERESTART PRIORITY
",$local_cluster->configuration->dasConfig->failoverLevel,"",($local_cluster->configuration->dasConfig->admissionControlEnabled) ? "YES" : "NO","",$local_cluster->configuration->dasConfig->defaultVmSettings->isolationResponse,"",$local_cluster->configuration->dasConfig->defaultVmSettings->restartPriority,"
\n"; } ########################### # PRINT DRS INFO ########################### if($cluster_drs) { print REPORT_OUTPUT "\n

DRS CONFIGURATIONS:

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT ""; print REPORT_OUTPUT ""; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "
DRS BEHAVIORVMOTION RATE
",$local_cluster->configuration->drsConfig->defaultVmBehavior->val,"",$local_cluster->configuration->drsConfig->vmotionRate,"
\n"; } ########################### # PRINT DPM INFO ########################### if($cluster_dpm) { print REPORT_OUTPUT "\n

DRS CONFIGURATIONS:

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT ""; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "
DPM BEHAVIOR
",$local_cluster->configurationEx->dpmConfigInfo->defaultDpmBehavior->val,"
\n"; } ########################### # PRINT CLUSTER RULES ########################### my $rules = $local_cluster->configurationEx->rule; if($rules) { print REPORT_OUTPUT "\n

Cluster Rules:

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\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 "\n"; } print REPORT_OUTPUT "
RULE NAMERULE TYPEENABLED
",$rule_name,"",$rule_type,"",($is_enabled) ? "YES" : "NO","
\n"; } ########################### # PRINT RPS INFO ########################### my $root_rp = Vim::get_view (mo_ref => $local_cluster->resourcePool); my $rps = Vim::get_views (mo_ref_array => $root_rp->resourcePool); my $resource_pool_string = ""; my $vapp_string = ""; if(@$rps > 0) { foreach(@$rps) { if($_->isa('VirtualApp')) { my $vapp_name = $_->name; my $anno = defined $_->vAppConfig->annotation ? $_->vAppConfig->annotation : "N/A"; my $ec = $_->vAppConfig->entityConfig; my $vm_vapp_string = ""; foreach(@$ec) { my $order = $_->startOrder; my $tag = $_->tag; $vm_vapp_string .= "".$tag."".$order."\n"; } $vapp_string .= "".$vapp_name."\n"; $vapp_string .= "VMSTART ORDER\n"; $vapp_string .= $vm_vapp_string."\n"; } else { my $rp_name = $_->name; my $rp_status = $_->summary->runtime->overallStatus->val; if($rp_status eq 'gray') { $rp_status = "UNKNOWN"; } elsif($rp_status eq 'green') { $rp_status = "UNDERCOMMITTED"; } elsif($rp_status eq 'red') { $rp_status = "INCONSISTENT"; } elsif($rp_status eq 'yellow') { $rp_status = "OVERCOMMITTED"; } my $rp_cpu_use = prettyPrintData($_->summary->runtime->cpu->overallUsage,'MHZ'); my $rp_cpu_max = prettyPrintData($_->summary->runtime->cpu->maxUsage,'MHZ'); my $rp_cpu_lim = prettyPrintData($_->summary->config->cpuAllocation->limit,'MHZ'); my $rp_cpu_rsv = prettyPrintData($_->summary->config->cpuAllocation->reservation,'MHZ'); my $rp_mem_use = prettyPrintData($_->summary->runtime->memory->overallUsage,'B'); my $rp_mem_max = prettyPrintData($_->summary->runtime->memory->maxUsage,'B'); my $rp_mem_lim = prettyPrintData($_->summary->config->cpuAllocation->limit,'M'); my $rp_mem_rsv = prettyPrintData($_->summary->config->cpuAllocation->reservation,'M'); $resource_pool_string .= "".$rp_name."".$rp_status."".$rp_cpu_lim."".$rp_cpu_rsv."".$rp_mem_lim."".$rp_mem_rsv."".$rp_cpu_use."".$rp_cpu_max."".$rp_mem_use."".$rp_mem_max."\n"; } } } if($resource_pool_string ne "") { print REPORT_OUTPUT "\n

Root Resource Pool(s):

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT $resource_pool_string; print REPORT_OUTPUT "
POOL NAMESTATUSCPU LIMITCPU RESERVATIONMEM LIMITMEM RESERVATIONCPU USAGECPU MAXMEM USAGEMEM MAX
\n"; } ########################### # PRINT VAPP INFO ########################### if($vapp_string ne "") { print REPORT_OUTPUT "\n

vApp(s):

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT $vapp_string; print REPORT_OUTPUT "
\n"; } } sub printBuildSummary { my $print_type; if ($content->about->apiType eq 'VirtualCenter') { $print_type = "VMware vCenter"; } else { $print_type = "VMware ESX/ESXi"; } print REPORT_OUTPUT "

$print_type:

\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT ""; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT ""; print REPORT_OUTPUT "
BUILDVERSIONFULL NAME
",$content->about->build,"",$content->about->version,"",$content->about->fullName,"
\n"; ########################### # LICENSES ########################### my $lic_mgr = Vim::get_view (mo_ref => $content->licenseManager); my $feature_info_string = ""; my $features = ""; my $feature_string = ""; print REPORT_OUTPUT "

Licenses:

\n"; print REPORT_OUTPUT "\n"; if($content->about->apiType eq 'HostAgent' || $content->about->apiType eq 'VirtualCenter') { print REPORT_OUTPUT "\n"; my $licenses = $lic_mgr->licenses; foreach(@$licenses) { if($enable_demo_mode eq 1) { print REPORT_OUTPUT "\n"; } else { print REPORT_OUTPUT "\n"; my $prop = $_->properties; if($prop) { $feature_info_string .= "\n"; $feature_info_string .= "\n"; } foreach(@$prop) { if($_->key ne 'feature') { if($_->key eq 'expirationHours' ) { $feature_info_string .= ""; } if($_->key eq 'expirationMinutes' ) { $feature_info_string .= ""; } if($_->key eq 'expirationDate' ) { $feature_info_string .= "\n"; } } else { my $feature = $_->value; $features .= "\n"; } } } $feature_string .= $feature_info_string . $features; $feature_info_string = ""; $features = ""; } print REPORT_OUTPUT "
NAMEEDITIONLICENSECOST UNITTOTALCONSUMEDAVAILABLE
CONFIDENTIALCONFIDENTIALCONFIDENTIALCONFIDENTIALCONFIDENTIALCONFIDENTIALCONFIDENTIAL
",$_->name,"",$_->editionKey,"",$_->licenseKey,"",$_->costUnit,"",$_->total,"",$_->used,"",($_->total - $_->used),"
EDITION w/FEATURESEXPIRATION (HOURS)EXPIRATION (MINS)EXPIRATION DATE
".$_->editionKey."".$_->value."".$_->value."".$_->value."
".$feature->value."
\n"; } ########################### # FEATURES ########################### print REPORT_OUTPUT "

Features:

\n"; print REPORT_OUTPUT "\n"; if(!$enable_demo_mode eq 1) { print REPORT_OUTPUT $feature_string; } else { print REPORT_OUTPUT "\n"; } print REPORT_OUTPUT "
CONFIDENTIAL
\n"; ########################### # SESSIONS ########################### print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "

Active Session(s):

\n"; print REPORT_OUTPUT "\n"; if(!$enable_demo_mode eq 1) { my $sess_mgr = Vim::get_view (mo_ref => $content->sessionManager); my $sess_list = $sess_mgr->sessionList; foreach(@$sess_list) { print REPORT_OUTPUT "\n"; } } else { print REPORT_OUTPUT "\n"; } print REPORT_OUTPUT "
USERNAMEFULL NAMELOGON TIMELAST ACTIVE
",$_->userName,"",$_->fullName,"",$_->loginTime,"",$_->lastActiveTime,"
USER XXTIME YTIME Z

\n"; ########################### # HOST PROFILES ########################### my $hp_mgr; eval { $hp_mgr = Vim::get_view (mo_ref => $content->hostProfileManager); }; my $hp_string = ""; if(!$@) { print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "

Host Profile(s):

\n"; print REPORT_OUTPUT "\n"; my $profiles = Vim::get_views (mo_ref_array => $hp_mgr->profile); foreach(@$profiles) { my $description = "N/A"; if($_->config->annotation) { $description = $_->config->annotation; } print REPORT_OUTPUT "\n"; } print REPORT_OUTPUT "
PROFILE NAMEDESCRIPTIONCREATION TIMELAST MODIFIEDENABLEDCOMPLIANCE STATUS
",$_->name,"",$description,"",$_->createdTime,"",$_->modifiedTime,"",($_->config->enabled) ? "YES" : "NO","",$_->complianceStatus,"

\n"; } #please do not touch this, else the jump tags will break print REPORT_OUTPUT "\n//\n"; } sub printDatacenterName { my ($dc) = @_; print REPORT_OUTPUT "\n
\n

Datacenter: $dc

\n"; } sub printStartHeader { print "Generating VMware vSphere Health Report $version \"$report_name\" ...\n\n"; print "This can take a few minutes depending on environment size. \nGet a cup of coffee/tea and check out http://www.engineering.ucsb.edu/~duonglt/vmware/\n"; $my_time = "Date: ".giveMeDate('MDYHMS'); $start_time = time(); open(REPORT_OUTPUT, ">$report_name"); print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "VMware vSphere Health Check Report $version - $my_time\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n"; print REPORT_OUTPUT "\n

VMware vSphere Health Check Report $version

\n"; print REPORT_OUTPUT "$my_time\n"; } sub giveMeDate { my ($date_format) = @_; 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; if($date_format eq 'MDYHMS') { $my_time = "$dttime{mon}-$dttime{mday}-$dttime{year} $dttime{hour}:$dttime{min}:$dttime{sec}"; } elsif ($date_format eq 'YMD') { $my_time = "$dttime{year}-$dttime{mon}-$dttime{mday}"; } return $my_time; } sub printCloseHeader { print REPORT_OUTPUT "

\n"; print REPORT_OUTPUT "
Author: William Lam
\n"; print REPORT_OUTPUT "
http://engineering.ucsb.edu/~duonglt/vmware
\n"; print REPORT_OUTPUT "
Generated using: vmwarevSphereHealthCheck.pl
\n"; print REPORT_OUTPUT "
™Primp Industries
\n"; 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 < 60) { print "Duration : ",$run_time," Seconds\n\n"; } else { print "Duration : ",&restrict_num_decimal_digits($run_time/60,2)," Minutes\n\n"; } } sub cleanUp { @hosts_seen = (); } sub Fail { my ($msg) = @_; Util::disconnect(); die ($msg); exit (); } sub getColor { my ($val) = @_; my $color_string = ""; if($val < $red_warn) { $color_string = "".$val." %"; } elsif($val < $orange_warn) { $color_string = "".$val." %"; } elsif($val < $yellow_warn) { $color_string = "".$val." %"; } else { $color_string = "".$val." %"; } return $color_string; } sub setSnapColor { my ($val,$datastore,$snapshot,$size,$date) = @_; $size = prettyPrintData($size,'B'); my $snap_color_string = ""; if($val > $snap_red_warn) { $snap_color_string = "".$datastore."".$snapshot."".$val." days old".$size."".$date.""; } elsif($val > $snap_orange_warn) { $snap_color_string = "".$datastore."".$snapshot."".$val." days old".$size."".$date.""; } elsif($val > $snap_yellow_warn) { $snap_color_string = "".$datastore."".$snapshot."".$val." days old".$size."".$date.""; } if(!$snap_color_string eq '') { push @vm_delta_warn,$snap_color_string; } } #http://www.bryantmcgill.com/Shazam_Perl_Module/Subroutines/utils_convert_bytes_to_optimal_unit.html sub prettyPrintData{ my($bytes,$type) = @_; return '' if ($bytes eq '' || $type eq ''); return 0 if ($bytes <= 0); my($size); if($type eq 'B') { $size = $bytes . ' Bytes' if ($bytes < 1024); $size = sprintf("%.2f", ($bytes/1024)) . ' KB' if ($bytes >= 1024 && $bytes < 1048576); $size = sprintf("%.2f", ($bytes/1048576)) . ' MB' if ($bytes >= 1048576 && $bytes < 1073741824); $size = sprintf("%.2f", ($bytes/1073741824)) . ' GB' if ($bytes >= 1073741824 && $bytes < 1099511627776); $size = sprintf("%.2f", ($bytes/1099511627776)) . ' TB' if ($bytes >= 1099511627776); } elsif($type eq 'M') { $bytes = $bytes * (1048576); $size = sprintf("%.2f", ($bytes/1048576)) . ' MB' if ($bytes >= 1048576 && $bytes < 1073741824); $size = sprintf("%.2f", ($bytes/1073741824)) . ' GB' if ($bytes >= 1073741824 && $bytes < 1099511627776); $size = sprintf("%.2f", ($bytes/1099511627776)) . ' TB' if ($bytes >= 1099511627776); } elsif($type eq 'G') { $bytes = $bytes * (1073741824); $size = sprintf("%.2f", ($bytes/1073741824)) . ' GB' if ($bytes >= 1073741824 && $bytes < 1099511627776); $size = sprintf("%.2f", ($bytes/1099511627776)) . ' TB' if ($bytes >= 1099511627776); } elsif($type eq 'MHZ') { $size = sprintf("%.2f", ($bytes/1e-06)) . ' MHz' if ($bytes >= 1e-06 && $bytes < 0.001); $size = sprintf("%.2f", ($bytes*0.001)) . ' GHz' if ($bytes >= 0.001); } return $size; } # 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; }