VMware Cloud Community
pamiller21
Enthusiast
Enthusiast
Jump to solution

VMDK Report

I am trying to figure out what I got wrong on this report.  It isn't going thru all the VMs just the last one and its not pulling the disks correctly either.  This was an older script, maybe I am missing something.

 

#############################
# Connect to vCenter #
#############################
Import-Module -Name VMware.PowerCLI
Set-PowerCLIConfiguration -DisplayDeprecationWarnings $false -InvalidCertificateAction ignore -confirm:$false
$vc = 'FQDN'
$Cred = Import-Clixml creds.xml

Connect-VIServer $VC -Credential $Cred

#############################
# Variables #
#############################
$date=Get-Date -format "yyyy-MMM-d"
$datetime=Get-Date
$filelocation="/var/www/VMDK/VMDK-$date.htm"

#############################
# Content #
#############################

#Determine if already connected to VCenter and if not connect
#if ( $DefaultVIServers.Length -lt 1 )
#{
# Connect-VIServer -Server $ESXserver -User $ESXuser -Password $ESXpassword -WarningAction SilentlyContinue | Out-Null
#}

# Format html report
$htmlReport = @"
<style type='text/css'>
.heading {
color:#0B1ABF;
font-size:14.0pt;
font-weight:700;
font-family:Verdana, sans-serif;
text-align:left;
vertical-align:middle;
height:20.0pt;
width:416pt;
}
.colnames {
color:white;
font-size:11.0pt;
font-weight:700;
font-family:Tahoma, sans-serif;
text-align:center;
vertical-align:middle;
border:.5pt solid windowtext;
background:#730000;
}
.lblueback {
color:windowtext;
font-size:10.0pt;
font-family:Arial;
text-align:left;
vertical-align:middle;
border:.5pt solid windowtext;
background:#B8CCE4;
}
.greyback {
color:windowtext;
font-size:10.0pt;
font-family:Arial;
text-align:left;
vertical-align:middle;
border:.5pt solid windowtext;
#background:#D8D8D8;
}

</style>
<table style='border-collapse:collapse;table-layout:auto;width:auto;padding:5px'>
<tr style='height:15.0pt'>
<th colspan=6 height=40 width=auto class="heading">
<center> VM Datastore Report </center></th>
</tr>
<tr>
<th class="colnames">VM Name</th>
<th class="colnames">Host</th>
<th class="colnames">DataStore</th>
<th class="colnames">Folder</th>
<th class="colnames">FileName</th>
<th class="colnames">Size/GB</th>
</tr>
"@

#get a list of VMs
$vmlist = Get-VM -Server $VC | where { $_.Name -notmatch "_replica" } | Sort-Object

#counter to manage alternating row color
$colorcounter = 0

#Master part of the script, loops through each VM and creates table with data
ForEach ($vm in $vmlist)
{
#If loop to determine color of Rows related to given VM
if ($colorcounter%2 -eq 0)
{
$tablecell = @"
<td class='lblueback'>
"@
}
else
{
$tablecell = @"
<td class='greyback'>
"@
}
}
# Grab VMDK information and the Datastores tied to them.
$vmdisk = Get-VM $vm | Get-harddisk

# Split out disks where a VM has more than a single disk, also split out the name of the Datastore
# from the name/path of the vmdk file, then split the Folder Name from the VMDK name.
$vmdiskDatastore=($vmdisk | %{$_.Filename.Split('[]')[1]})
$vmdiskfilename=($vmdisk | %{$_.Filename.Split('[]')[2]})
$vmdiskFolder=($vmdiskfilename | %{$_.Split('/')[0]})
$vmdiskVMDK=($vmdiskfilename | %{$_.Split('/')[1]})
$vmdisksize=($vmdisk | %{$_.CapacityKB})

# determine the length of the array so we know if there was more than one hard drive for a given VM.
$count = $vmdiskfilename.count - 1

# Begin building the html report, inserting the name of the VM in the 1st Column and Host Name into the 2nd
$htmlReport = $htmlReport +
"<tr>" + $tablecell + $vm.Name + "</td>" +
$tablecell + $vm.host.Name + "</td>"

# Based on the number of hard drives in the count value the report is generated in one of two ways
if($count -le 0)
{
# There is only one hard drive so the values will not be in an array we just need to build the table row with data
$htmlReport = $htmlReport +
$tablecell + $vmdiskDatastore + "</td>" +
$tablecell + $vmdiskFolder + "</td>" +
$tablecell + $vmdiskVMDK + "</td>" +
$tablecell + $vmdisksize / 1MB + "</tr>"
} else
{{
# There is more than one hard drive, because of table formatting we handle the 1st row different from the 2nd row. Data is in an array.
$htmlReport = $htmlReport +
$tablecell + $vmdiskDatastore[0] + "</td>" +
$tablecell + $vmdiskFolder[0] + "</td>" +
$tablecell + $vmdiskVMDK[0] + "</td>" +
$tablecell + $vmdisksize[0] / 1MB + "</tr>"

# There is more than one hard drive so we will loop through the array and and place them in the report
$x=1
While($x -le $count)
{
$htmlReport = $htmlReport +
"<tr>" + $tablecell + "" + "</td>" +
$tablecell + "" + "</td>" +
$tablecell + $vmdiskDatastore[$x] + "</td>" +
$tablecell + $vmdiskFolder[$x] + "</td>" +
$tablecell + $vmdiskVMDK[$x] + "</td>" +
$tablecell + $vmdisksize[$x] / 1MB + "</tr>"
$x= $x+1
}
}
# value used in conjunction with Foreach and if loop to rotate color in table
$colorcounter = $colorcounter + 1
}

$htmlreport | Out-File -Append $filelocation

#############################
# Add Text to the HTML file #
#############################
ConvertTo-Html -title "VMware VMDK Check " -body "<H1>VMware VMDK Check</H1>" -head "<link rel='stylesheet' href='style.css' type='text/css' />" | Out-File -Append $filelocation
ConvertTo-Html -title "VMware VMDK Check " -body "<H4>Date and time</H4>",$datetime -head "<link rel='stylesheet' href='style.css' type='text/css' />" | Out-File -Append $filelocation

##############################
# Disconnect session from VC #
##############################
disconnect-viserver -confirm:$false

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Your previous Split calls are incorrect, the delimiter needs to be 1 character, you are using 2.
You can achieve what I think your trying to do with the -split operator and use a scriptblock.

 

$vmdiskDatastore = $vmdisk | % { ($_.Filename -split {$_ -eq '[' -or $_ -eq ']'})[1] }
$vmdiskfilename = $vmdisk | % { ($_.Filename -split {$_ -eq '[' -or $_ -eq ']'})[2] }

 


Note that your values in $vmdiskfilename will have a blank at the start.
You can remove that with TrimStart.

$vmdiskfilename = $vmdisk | % { (($_.Filename -split {$_ -eq '[' -or $_ -eq ']'})[2] ).TrimStart(' ')}

 


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
3 Replies
LucD
Leadership
Leadership
Jump to solution

You seem to have misplaced the closing curly brace on the loop through all the VMs.
And the rest of the code after that incorrect closing curly brace, the content of $vm is the last VM in $vmlist

 

#Master part of the script, loops through each VM and creates table with data
ForEach ($vm in $vmlist) {
    #If loop to determine color of Rows related to given VM
    if ($colorcounter % 2 -eq 0) {
        $tablecell = @"
<td class='lblueback'>
"@
    } else {
        $tablecell = @"
<td class='greyback'>
"@
    }
}  # <== THIS CLOSES the ForEach loop

# Grab VMDK information and the Datastores tied to them.
$vmdisk = Get-VM $vm | Get-HardDisk

 

 


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
pamiller21
Enthusiast
Enthusiast
Jump to solution

Ah gotcha, but now I get this while running:

 

$vmdiskFolder=($vmdiskfilename | %{$_.Split('/')[0]})
| ~~~~~~~~~~~~~~~~
| You cannot call a method on a null-valued expression.
InvalidOperation:

And here is the report output:

pamiller21_0-1643306281102.png

 

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Your previous Split calls are incorrect, the delimiter needs to be 1 character, you are using 2.
You can achieve what I think your trying to do with the -split operator and use a scriptblock.

 

$vmdiskDatastore = $vmdisk | % { ($_.Filename -split {$_ -eq '[' -or $_ -eq ']'})[1] }
$vmdiskfilename = $vmdisk | % { ($_.Filename -split {$_ -eq '[' -or $_ -eq ']'})[2] }

 


Note that your values in $vmdiskfilename will have a blank at the start.
You can remove that with TrimStart.

$vmdiskfilename = $vmdisk | % { (($_.Filename -split {$_ -eq '[' -or $_ -eq ']'})[2] ).TrimStart(' ')}

 


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos