I am having a code which is giving me output like below
ESXi Datastore ReadIOPS WriteIOPS ReadLatency[ms] WriteLatency[ms] ReadRate[KBps] WriteRate[KBps]
---- --------- -------- --------- --------------- ---------------- -------------- ---------------
999_TEST8AP EV_8190 0 1 0 3 0 13
ESXi Datastore ReadIOPS WriteIOPS ReadLatency[ms] WriteLatency[ms] ReadRate[KBps] WriteRate[KBps]
---- --------- -------- --------- --------------- ---------------- -------------- ---------------
999_TANS2AP DEV_8190 0 2 0 1 0 14
I need to write this output in html. please let me know how to display only one header instead of multiple header for each server.
Also please help me with writing this to html. going forward there will be multiple datastore and VM's on which I need to execute this code
This is the code
[CmdletBinding()]
param(
[String]$vcenter=""
)
Begin {
#Ignore invalid certificate
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false -Verbose
try {
#Connect to VCSA
Connect-VIServer -Server $vcenter
}
catch {
Write-Host "Incorrect vCenter creds!"
$PSCmdlet.ThrowTerminatingError($PSItem)
}
#Collect list of datastore names
if (-not (test-path -path C:\datastore_list.txt)) {
Disconnect-VIServer $vcenter -Confirm:$false
Write-Error 'The file datastore_list.txt does not exist!' -ErrorAction Stop
}
else {
$list1 = Get-Content C:\datastore_list.txt
}
#Collect list of ESXi servers
if (-not (test-path -path C:\esxi_list.txt)) {
Disconnect-VIServer $vcenter -Confirm:$false
Write-Error 'The file esxi_list.txt does not exist!' -ErrorAction Stop
}
else {
$list2 = Get-Content C:\esxi_list.txt
}
}
Process {
#Function to collect datastore performance stats
Function datastore_perf ($host_name) {
$stat_array =@()
For ($i = 0; $i -lt $list1.count; $i ){
$datastore_name = $list1
if($datastore_name) {
$instance_id = (Get-Datastore $datastore_name).ExtensionData.Info.Vmfs.Uuid
$t1 = Get-Stat -Entity $host_name -Stat datastore.numberReadAveraged.average -MaxSamples 1 -Realtime -Instance $instance_id
$t2 = Get-Stat -Entity $host_name -Stat datastore.numberWriteAveraged.average -MaxSamples 1 -Realtime -Instance $instance_id
$t3 = Get-Stat -Entity $host_name -Stat datastore.totalReadLatency.average -MaxSamples 1 -Realtime -Instance $instance_id
$t4 = Get-Stat -Entity $host_name -Stat datastore.totalWriteLatency.average -MaxSamples 1 -Realtime -Instance $instance_id
$t6 = Get-Stat -Entity $host_name -Stat datastore.read.average -MaxSamples 1 -Realtime -Instance $instance_id
$t7 = Get-Stat -Entity $host_name -Stat datastore.write.average -MaxSamples 1 -Realtime -Instance $instance_id
$stat_object = New-Object System.Object
$read_iops = $t1[0].Value
$write_iops = $t2[0].Value
$read_latency = $t3[0].Value
$write_latency = $t4[0].Value
$read_avg = $t6[0].Value
$write_avg = $t7[0].Value
$stat_object | Add-Member -Type NoteProperty -Name ESXi -Value "$host_name"
$stat_object | Add-Member -Type NoteProperty -Name Datastore -Value "$datastore_name"
$stat_object | Add-Member -Type NoteProperty -Name ReadIOPS -Value "$read_iops"
$stat_object | Add-Member -Type NoteProperty -Name WriteIOPS -Value "$write_iops"
$stat_object | Add-Member -Type NoteProperty -Name ReadLatency[ms] -Value "$read_latency"
$stat_object | Add-Member -Type NoteProperty -Name WriteLatency[ms] -Value "$write_latency"
$stat_object | Add-Member -Type NoteProperty -Name ReadRate[KBps] -Value "$read_avg"
$stat_object | Add-Member -Type NoteProperty -Name WriteRate[KBps] -Value "$write_avg"
$stat_array = $stat_object
}
}
cls
$Header = @"
<style>
TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #6495ED;}
TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
</style>
"@
$stat_array | ConvertTo-Html -head $Header | Out-File -FilePath C:\stat_report.html -Append
}
}
}
End {
$result = $list2 | ForEach-Object { datastore_perf -host_name $PSItem }
}
html sample
CodePudding user response:
A few things I would change in your code:
$datastore_name = $list1
-->$datastore_name = $list1[$i]
- do not use
=
to add to an array because this is time and memory costly (on each iteration the entire array needs to be built that way). Instead, have your function simply output a PsCustomObject and gather all in variable$result
- join the string array from
ConvertTo-Html
with newlines and do not use-Append
to write the output HTML file - Prefer
Set-Content
overOut-File
, because in PowerShell up to and including version 5.1, the encoding for Out-File is Unicode (UTF16-LE) which is probably not what you want.
Try
[CmdletBinding()]
param(
[String]$vcenter=""
)
Begin {
#Ignore invalid certificate
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false -Verbose
try {
#Connect to VCSA
Connect-VIServer -Server $vcenter
}
catch {
Write-Host "Incorrect vCenter creds!"
$PSCmdlet.ThrowTerminatingError($PSItem)
}
#Collect list of datastore names
if (-not (test-path -Path 'C:\datastore_list.txt')) {
Disconnect-VIServer $vcenter -Confirm:$false
Write-Error 'The file datastore_list.txt does not exist!'
}
else {
$list1 = Get-Content -Path 'C:\datastore_list.txt'
}
#Collect list of ESXi servers
if (-not (test-path -path C:\esxi_list.txt)) {
Disconnect-VIServer $vcenter -Confirm:$false
Write-Error 'The file esxi_list.txt does not exist!'
}
else {
$list2 = Get-Content 'C:\esxi_list.txt'
}
}
Process {
#Function to collect datastore performance stats
function datastore_perf ($host_name) {
for ($i = 0; $i -lt $list1.count; $i ){
$datastore_name = $list1[$i]
if($datastore_name) {
$instance_id = (Get-Datastore $datastore_name).ExtensionData.Info.Vmfs.Uuid
$t1 = Get-Stat -Entity $host_name -Stat datastore.numberReadAveraged.average -MaxSamples 1 -Realtime -Instance $instance_id
$t2 = Get-Stat -Entity $host_name -Stat datastore.numberWriteAveraged.average -MaxSamples 1 -Realtime -Instance $instance_id
$t3 = Get-Stat -Entity $host_name -Stat datastore.totalReadLatency.average -MaxSamples 1 -Realtime -Instance $instance_id
$t4 = Get-Stat -Entity $host_name -Stat datastore.totalWriteLatency.average -MaxSamples 1 -Realtime -Instance $instance_id
$t6 = Get-Stat -Entity $host_name -Stat datastore.read.average -MaxSamples 1 -Realtime -Instance $instance_id
$t7 = Get-Stat -Entity $host_name -Stat datastore.write.average -MaxSamples 1 -Realtime -Instance $instance_id
# simply output an object with the properties you need
# this output will be collected below in variable $result
[PsCustomObject]@{
'ESXi' = $host_name
'Datastore' = $datastore_name
'ReadIOPS' = $t1[0].Value
'WriteIOPS' = $t2[0].Value
'ReadLatency[ms]' = $t3[0].Value
'WriteLatency[ms]' = $t4[0].Value
'ReadRate[KBps]' = $t6[0].Value
'WriteRate[KBps]' = $t7[0].Value
}
}
}
}
$result = $list2 | ForEach-Object { datastore_perf -host_name $_ }
$Header = @"
<style>
TABLE {border-width: 1px; border-style: solid; border-color: black; border-collapse: collapse;}
TH {border-width: 1px; padding: 3px; border-style: solid; border-color: black; background-color: #6495ED;}
TD {border-width: 1px; padding: 3px; border-style: solid; border-color: black;}
</style>
"@
# write the HTML file
($result | ConvertTo-Html -Head $Header) -join [environment]::NewLine | Set-Content -Path 'C:\stat_report.html'
}