Another PowerCLI for the collection, this time a returning job of creating reports of the environment with specific information requested by Service Delivery or other IT management report. Basic PowerCLI (and with that basic powershell) outputs to the screen, but there are several cmdlets to help and export to a different output; in this case the ConvertTo-HTML cmdlet for export to a nice HTML output. This output can be send to an output file or send via e-mail.

We want a report of VM’s and their power state, vCPU count and vRAM. And specifically resources in a defined cluster. In the final report this shows the cluster resources in the top part and a breakdown of the VM’s in a lower part.

ConvertTo-HTML

ConvertTo-HTML takes the output of an inventory cmdlet (Get-VM for example) and converts the output to an HTML table. When using no formatting it actually creates a ready to use information HTML table. But with the management reports we also want to add some markup to show the information in a nice report.

Let see if we can get some of the wanted information. After we connect to a vCenter server:

$ClusterName = “Testlab”

Get-VM -Location (Get-Cluster -Name $ClusterName) | Select-Object Name,PowerState,NumCPU, MemoryGB | Sort-Object Name | ConvertTo-HTML | Out-File “testlab.html”

We set the clustername in a variable, and use the Get-VM cmdlet to get information of the VM’s in this cluster. With Select-Object we choose the VM Name, the power state, the number of vCPU’s and the configured Memory. We sort on the name of the VM’s and pipe to Convert-HTML to get a nice HTML markup. We pipe this yet again to Out-File for saving the HTML that we can view from disk in a HTML browser.

What output do we have:

image

Wasn’t this what was asked? Yes and no, the report needs to be displayed in a nicer format (you know management ;-)) and we were asked some totals as well.

Get more results and a nicer view

More results? Yes part of the job was to get the cumulative vCPU and vRAM of the cluster.

For this we check the cluster for the specific counts and add this to a total variable (that has been declared at 0 and added with a +=).

#Get VMHost info for CPU and Memory totals
$countcpu = 0
$countmem = 0
$MemoryGBtot = 0
$cpu=Get-VM -Location (Get-Cluster -Name $ClusterName) | Select-Object NumCPU
Foreach ($itemcpu in $cpu) { $countcpu += $itemcpu.NumCpu }

$memory=Get-VM -Location (Get-Cluster -Name $ClusterName) | Select-Object @{Name = ‘MemoryGBtot’; Expression = {“{0:N2}” -f ($_.MemoryGB)}}
Foreach ($itemmem in $memory) { $countmem += $itemmem.MemoryGBtot }
# Now we have $countcpu and $countmem for cluster totals
# Memory should be formatted to two decimals which is #done via Expression N2.

Next up creating a HTML style and markup. We declare a CSS stylesheet with colors in the organization colors. And place box objects where we put the information, this we use in the HTML line to add HTML code and information into the ConvertTo-HTML. A small snippet, in the total script you can see it all together (this part does not work on it’s own).

# Style of the Report in Css
$Css=”<style>
body {
font-family: Verdana, sans-serif;
font-size: 14px;
color: #666666;
background: #FEFEFE;
}
#title{
color:#FF0000;
font-size: 30px;
font-weight: bold;
padding-top:25px;
margin-left:35px;
height: 50px;
}

</style>”

And for some div boxes:

# HTML Markup
$PageBoxOpener=”<div id=’box1’>”
$ReportClusterStats=”<div id=’boxheader’>ClusterTotal $ClusterName</div>”
$ReportClusterHeader=”<table><tr><th>vCPU Count</th><th>Memory GB Total</th></tr>”
$BoxContentOpener=”<div id=’boxcontent’>”
$PageBoxCloser=”</div>”
$br=”<br>”
$ReportGetVmCluster=”<div id=’boxheader’>VM Details $ClusterName</div>”

Create some Div boxes with the styles as we defined and markup in the CSS.

We use these declarations in the report making:

# Create HTML report
$MyReport = ConvertTo-Html -Title “VM Details Report” -Head “<div id=’title’>VM CPU and Memory Reporting</div>$br<div id=’subtitle’>Report generated on: $(Get-Date)</div>” -Body ” $Css $PageBoxOpener $ReportClusterStats $BoxContentOpener $ReportClusterHeader <tr><td>$countcpu</td> <td>$countmem</td></tr> $PageBoxCloser </table> $br $ReportGetVmCluster $BoxContentOpener $GetVmCluster $PageBoxCloser”

The report is created as $MyReport with a ConvertTo-HTML to create a HTML format and with – title to give a title instead of HTML Table. in the Body we put the $Css style, the box parts and the collected information.

This creates the report in a nice markup as shown in the following screenshot:

image

To save or to send, that’s the question

Or both of course, if you want. We can use the earlier mentioned Out-File cmdlet to send pipelined output directly to a text file rather than displaying that output on screen. Well, as we will be directing the output to a variable we don’t see the output on screen, but we still can use this cmdlet to save to a file. A nice declaration of the file name and pipe the HTML report to Out-File.

$fileNameReport = “$OutputPathReportVMDetails-$ClusterName-$(Get-Date -Format o | foreach {$_ -replace “:”, “.”}).html”

and add | Out-File $fileNameReport to the report $MyReport line (add at the end after closing “) when wanting to save

FileNameReport marks up the filename with a clustername and date stamp.

We can also use an e-mail to inform our whomever it is that is interested in the report. For this will need some declaration of from and to adresses, mail title, a SMTP server. We send our HTML marked up report as body.

function Send-SMTPmail($to, $from, $subject, $smtpserver, $body) {
$mailer = new-object Net.Mail.SMTPclient($smtpserver)
$msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body)
$msg.IsBodyHTML = $true
$mailer.send($msg)
}

Write-Host “Sending e-mail” -foregroundcolor “red”
# Sending the report
Send-SMTPmail $EmailTo $EmailFrom “$ClusterName Capacity Report $(Get-Date)” $SMTPSRV $MyReport

We create a Send-SMTPmail function where we need input in the form of a to, from and subject, a SMTP server where the host where the script is run is allowed to relay and a $body. When we call this function we add this values via declared variables. The last is the Report that we put in an HTML markup.

Putting it all together

And to conclude we put this all together in the following script. I left out the saving as I want the report to the e-mail. The code is still in there. Here we go:

# Settings
# vCenter Connection details
$vCenterFQDN=”<vcenter>”
$vCenterUser=”<user>”
$vCenterPass=”<password>”
# Name of the Cluster on which you need to run the report
$ClusterName=”<cluster>”
#Location where you want to place generated report
$OutputPath=”<output path>”
# Set the SMTP Server address
$SMTPSRV = “<SMTP Server>”
# Set the Email address to recieve from
$EmailFrom = “<from email address>”
# Set the Email address to send the email to, comma separate when using multiple reciptients
$EmailTo = “<to e-mail address>”

Write-Host “Connecting to vCenter” -foregroundcolor “red”
Connect-VIServer -Server $vCenterFQDN -User $vCenterUser -Password $vCenterPass

# Style of the Report in Css
$Css=”<style>
body {
font-family: Verdana, sans-serif;
font-size: 14px;
color: #666666;
background: #FEFEFE;
}
#title{
color:#FF0000;
font-size: 30px;
font-weight: bold;
padding-top:25px;
margin-left:35px;
height: 50px;
}
#subtitle{
font-size: 11px;
margin-left:35px;
}
#main {
position:relative;
padding-top:10px;
padding-left:10px;
padding-bottom:10px;
padding-right:10px;
}
#box1{
position:absolute;
background: #F8F8F8;
border: 1px solid #DCDCDC;
margin-left:10px;
padding-top:10px;
padding-left:10px;
padding-bottom:10px;
padding-right:10px;
}
#boxheader{
font-family: Arial, sans-serif;
padding: 5px 20px;
position: relative;
z-index: 20;
display: block;
height: 30px;
color: #777;
text-shadow: 1px 1px 1px rgba(255,255,255,0.8);
line-height: 33px;
font-size: 19px;
background: #fff;
background: -moz-linear-gradient(top, #ffffff 1%, #eaeaea 100%);
background: -webkit-gradient(linear, left top, left bottom, color-stop(1%,#ffffff), color-stop(100%,#eaeaea));
background: -webkit-linear-gradient(top, #ffffff 1%,#eaeaea 100%);
background: -o-linear-gradient(top, #ffffff 1%,#eaeaea 100%);
background: -ms-linear-gradient(top, #ffffff 1%,#eaeaea 100%);
background: linear-gradient(top, #ffffff 1%,#eaeaea 100%);
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr=’#ffffff’, endColorstr=’#eaeaea’,GradientType=0 );
box-shadow:
0px 0px 0px 1px rgba(155,155,155,0.3),
1px 0px 0px 0px rgba(255,255,255,0.9) inset,
0px 2px 2px rgba(0,0,0,0.1);
}

table{
width:100%;
border-collapse:collapse;
}
table td, table th {
border:1px solid #FA5858;
padding:3px 7px 2px 7px;
}
table th {
text-align:left;
padding-top:5px;
padding-bottom:4px;
background-color:#FA5858;
color:#fff;
}
table tr.alt td {
color:#000;
background-color:#F5A9A9;
}
</style>”
# End the Style.

# HTML Markup
$PageBoxOpener=”<div id=’box1’>”
$ReportClusterStats=”<div id=’boxheader’>ClusterTotal $ClusterName</div>”
$ReportClusterHeader=”<table><tr><th>vCPU Count</th><th>Memory GB Total</th></tr>”
$BoxContentOpener=”<div id=’boxcontent’>”
$PageBoxCloser=”</div>”
$br=”<br>”
$ReportGetVmCluster=”<div id=’boxheader’>VM Details $ClusterName</div>”

Write-Host “Getting Cluster Details for CPU and Memory totals” -foregroundcolor “red”
#Get VMHost info for CPU and Memory totals
$countcpu = 0
$countmem = 0
$MemoryGBtot = 0
$cpu=Get-VM -Location (Get-Cluster -Name $ClusterName) | Select-Object NumCPU
Foreach ($itemcpu in $cpu) { $countcpu += $itemcpu.NumCpu }

$memory=Get-VM -Location (Get-Cluster -Name $ClusterName) | Select-Object @{Name = ‘MemoryGBtot’; Expression = {“{0:N2}” -f ($_.MemoryGB)}}
Foreach ($itemmem in $memory) { $countmem += $itemmem.MemoryGBtot }
# Now we have $countcpu and $countmem for cluster totals
# Memory should be formatted to two decimals

Write-Host “Getting VM information for $ClusterName” -foregroundcolor “red”
#Get VM infos
$GetVmCluster=Get-VM -Location (Get-Cluster -Name $ClusterName) | Select-Object Name,PowerState,NumCPU, MemoryGB | Sort-Object Name | ConvertTo-HTML -Fragment

# Create HTML report
# and export to HTML out file
# Use $fileNameReport = “$OutputPathReportVMDetails-$ClusterName-$(Get-Date -Format o | foreach {$_ -replace “:”, “.”}).html” and | Out-File $fileNameReport when wanting to save
$MyReport = ConvertTo-Html -Title “VM Details Report” -Head “<div id=’title’>VM CPU and Memory Reporting</div>$br<div id=’subtitle’>Report generated on: $(Get-Date)</div>” -Body ” $Css $PageBoxOpener $ReportClusterStats $BoxContentOpener $ReportClusterHeader <tr><td>$countcpu</td> <td>$countmem</td></tr> $PageBoxCloser </table> $br $ReportGetVmCluster $BoxContentOpener $GetVmCluster $PageBoxCloser”

# Disconnect
Write-Host “Closing vCenter connection” -foregroundcolor “red”
Disconnect-VIServer -Confirm:$false

function Send-SMTPmail($to, $from, $subject, $smtpserver, $body) {
$mailer = new-object Net.Mail.SMTPclient($smtpserver)
$msg = new-object Net.Mail.MailMessage($from,$to,$subject,$body)
$msg.IsBodyHTML = $true
$mailer.send($msg)
}

Write-Host “Sending e-mail” -foregroundcolor “red”
# Sending the report
Send-SMTPmail $EmailTo $EmailFrom “$ClusterName Capacity Report $(Get-Date)” $SMTPSRV $MyReport

Notice: at this time the script takes a plaintext password.

Add your environment entries to the settings variables and your good to go.

More

You can add more or specific required cmdlets and information to the report to get what you want. Or you could go on the community and find an already made reporting scripts out there. Maybe not the best way to learn, but you can check in the source what these guys and gals have been up to. A great one for example, vCheck is highly recommended to get an overview report of your environment. This script can be found at: http://www.virtu-al.net/vcheck-pluginsheaders/vcheck/.

– Enjoy!

Sources: Microsoft.com powershell cmdlet library, vmware.com PowerCLI reference, community.vmware.com for examples.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s