Output to HTML issue - powershell

Hello newish to PS and i am having an issue getting the Output data to output.
The HTM file is created but no data, what am I missing here, again im newish!
This is to check TSM backup report and to start service if down.
Here is the script
$serverlist = gc servers.txt
$SvcName = '*tsm*scheduler*'
$filepath = "C:\Scripts\"
$date = "{0:yyy_MM_dd-HH_mm}" -f (get-date)
$file = $filepath + "Results_" + $date + ".htm"
New-Item $filepath -type directory -force -Verbose
$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>
<title>
TSM Report
</title>
"#
ForEach ($server in $serverlist)
{
$Tsm = Get-Service -ComputerName $server| Where {$_.name -Like $SvcName}
If ($Tsm.StartType -ne 'Automatic')
{
Set-Service -InputObject $Tsm -StartupType Automatic
}
If ($Tsm.Status -ne 'Running')
{
$output = "Starting the service."
Start-Service -InputObject $Tsm
}
$Tsm2 = Get-Service -ComputerName $SysName | Where {$_.name -Like $SvcName}
}
$pre= "Here are the results for $date"
$Tsm2 | Select-Object DisplayName, Status, StartupType | ConvertTo-HTML -Head $Header -PreContent $pre | Out-File $file
Invoke-Item $file

Related

Add-member giving output with multiple header

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
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 over Out-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'
}

Output foreach loop to html

So, here's my issue... I have the below PowerShell script that I want to use to do the following:
Pull Each Hyper-V cluster member (currently 29 x Server 2016 nodes)
Run a ForEach loop on each node to get all VMs that have Hyper-V replication enabled.
Combine all 29 outputs into a single .html file with table formatting.
Here is the code:
$Cluster = Get-ClusterNode -Cluster hv-cluster01.contoso.com
$a = "<style>"
$a = $a + "BODY{background-color:peachpuff;}"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$a = $a + "TH{column-width: 200px;border-width: 1px;padding: 8px;border-style: solid;border-color: black;background-color:thistle}"
$a = $a + "TD{column-width: 200px;border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color:PaleGoldenrod;text-align: center}"
$a = $a + "</style>"
ForEach ($Node in $Cluster)
{
Get-VMReplication -ComputerName $Node | Select-Object VMName, State, Health, PrimaryServer | ConvertTo-HTML -head $a -body "<H2>DR Replication Status</H2>" | Out-File C:\Scripts\Test.htm
}
My ultimate goal would be to put this into a scheduled task to run 2-3 times per day, and using Send-MailMessage, send the html content in the body of an eamil, to myself and others on my team.
I appreciate any help I can get.
In your code, you convert and output the object for each $Node in $Cluster. Instead you first have to populate your final object, which contains all information, and then convert and output these information.
You do so, by moving the convert and output part outside the loop. For example:
$Cluster = Get-ClusterNode -Cluster hv-cluster01.contoso.com
$a = "<style>"
$a = $a + "BODY{background-color:peachpuff;}"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$a = $a + "TH{column-width: 200px;border-width: 1px;padding: 8px;border-style: solid;border-color: black;background-color:thistle}"
$a = $a + "TD{column-width: 200px;border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color:PaleGoldenrod;text-align: center}"
$a = $a + "</style>"
$Report = ForEach ($Node in $Cluster) {
Get-VMReplication -ComputerName $Node | Select-Object VMName, State, Health, PrimaryServer
}
$Report | ConvertTo-HTML -head $a -body "<H2>DR Replication Status</H2>" | Out-File C:\Scripts\Test.htm
I've modified the script quite a bit more, to accommodate the rest of what I was trying to do...
I've managed to get the script to pull the content of the HTML file and place it into an email message. My problem is, some of the table style info isn't transferring to the email. Specifically, the column-width part. So all of the table entries are squished together. See below:
Remove-Item C:\Scripts\ReplicationHealth.htm
$Cluster = Get-ClusterNode -Cluster hv-cluster01.contoso.com
$a = "<style>"
$a = $a + "BODY{background-color:LightGrey;}"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$a = $a + "TH{column-width: 200px;border-width: 1px;padding: 8px;border-style: solid;border-color: black;background-color:DodgerBlue}"
$a = $a + "TD{column-width: 200px;border-width: 1px;padding: 3px;border-style: solid;border-color: black;background-color:PapayaWhip;text-align: center}"
$a = $a + "</style>"
$Report = ForEach ($Node in $Cluster) {
Get-VMReplication -ComputerName $Node | Select-Object VMName, State, Health, PrimaryServer
}
$time = Get-Date -Format G
$Report | ConvertTo-HTML -head $a -body "<H2>Hyper-V Replication Status</H2>", $time | Out-File C:\Scripts\ReplicationHealth.htm
$MailBody = Get-Content C:\Scripts\ReplicationHealth.htm -Raw
Send-MailMessage -SmtpServer "SERVERIP" -From "HyperV-Replication#contoso.com" -To "User#contoso.com" -Subject "Hyper-V Replication Status" -Body $MailBody -BodyAsHtml
A tiny bit more help would be awesome!
Thanks in advance!

Formatted HTML Report of win32_Service involving multiple specific services

Im stuck in a Filtering / Formating issue.
Goal:
Provide a customer readable output exported to HTML for easy viewing.
Required:
Filtering multiple services along with their data to be displayed in the report.
Issue:
Gathering/Parsing the data in its needed form using win32_service to query specific services.
#CODE
# First lets create a text file, where we will later save the Service Health info
$ServiceHealthFileName = "ServiceHealth.htm"
$serverlist = "mylistofservers.txt"
$warning = "Stopped"
New-Item -ItemType file $ServiceHealthFileName -Force
# Function to write the HTML Header to the file
Function writeHtmlHeader
{
param($fileName)
$date = ( get-date ).ToString('yyyy/MM/dd')
Add-Content $fileName "<html>"
Add-Content $fileName "<head>"
Add-Content $fileName "<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>"
Add-Content $fileName '<title> Server Health</title>'
add-content $fileName '<STYLE TYPE="text/css">'
add-content $fileName "<!--"
add-content $fileName "td {"
add-content $fileName "font-family: Tahoma;"
add-content $fileName "font-size: 11px;"
add-content $fileName "border-top: 1px solid #999999;"
add-content $fileName "border-right: 1px solid #999999;"
add-content $fileName "border-bottom: 1px solid #999999;"
add-content $fileName "border-left: 1px solid #999999;"
add-content $fileName "padding-top: 0px;"
add-content $fileName "padding-right: 0px;"
add-content $fileName "padding-bottom: 0px;"
add-content $fileName "padding-left: 0px;"
add-content $fileName "}"
add-content $fileName "body {"
add-content $fileName "margin-left: 5px;"
add-content $fileName "margin-top: 5px;"
add-content $fileName "margin-right: 0px;"
add-content $fileName "margin-bottom: 10px;"
add-content $fileName ""
add-content $fileName "table {"
add-content $fileName "border: thin solid #000000;"
add-content $fileName "}"
add-content $fileName "-->"
add-content $fileName "</style>"
Add-Content $fileName "</head>"
Add-Content $fileName "<body>"
add-content $fileName "<table width='100%'>"
add-content $fileName "<tr bgcolor='#CCCCCC'>"
add-content $fileName "<td colspan='7' height='25' align='center'>"
add-content $fileName "<font face='tahoma' color='#003399' size='4'><strong> Server Health - $date</strong></font>"
add-content $fileName "</td>"
add-content $fileName "</tr>"
add-content $fileName "</table>"
}
# Function to write the HTML Header to the file
Function writeTableHeader
{
param($fileName)
Add-Content $fileName "<tr bgcolor=#CCCCCC>"
Add-Content $fileName "<td width='10%' align='center'>Name</td>"
Add-Content $fileName "<td width='50%' align='center'>ProcessId</td>"
Add-Content $fileName "<td width='10%' align='center'>State</td>"
Add-Content $fileName "<td width='10%' align='center'>StartMode</td>"
Add-Content $fileName "<td width='10%' align='center'>ExitCode</td>"
Add-Content $fileName "<td width='10%' align='center'>Status</td>"
Add-Content $fileName "</tr>"
}
Function writeHtmlFooter
{
param($fileName)
Add-Content $fileName "</body>"
Add-Content $fileName "</html>"
}
Function writeServiceInfo
{
param($fileName,$SvcName,$SvcPID,$SvcSM,$SvcExCd,$ServiceState,$SvcStatus)
$SvcName= $Item.Name
$SvcPID= $Item.ProcessId
$SvcSM= $Item.StartMode
$SvcExCd= $Item.ExitCode
$ServiceState= $Item.State
$SvcStatus= $Item.Status
if ($ServiceState -eq $warning)
{
Add-Content $fileName "<tr>"
Add-Content $fileName "<td>$SvcName</td>"
Add-Content $fileName "<td>$SvcPID</td>"
Add-Content $fileName "<td bgcolor='#FBB917' align=center>$ServiceState</td>"
# #FBB917
Add-Content $fileName "<td>$SvcSM</td>"
Add-Content $fileName "<td>$SvcExCd</td>"
Add-Content $fileName "<td>$SvcStatus</td>"
Add-Content $fileName "</tr>"
}
else
{
Add-Content $fileName "<tr>"
Add-Content $fileName "<td>$SvcName</td>"
Add-Content $fileName "<td>$SvcPID</td>"
Add-Content $fileName "<td>$ServiceState</td>"
Add-Content $fileName "<td>$SvcSM</td>"
Add-Content $fileName "<td>$SvcExCd</td>"
Add-Content $fileName "<td>$SvcStatus</td>"
Add-Content $fileName "</tr>"
}
}
#Function sendEmail
#{ param($from,$to,$subject,$smtphost,$htmlFileName)
#$body = Get-Content $htmlFileName
#$smtp= New-Object System.Net.Mail.SmtpClient $smtphost
#$msg = New-Object System.Net.Mail.MailMessage $from, $to, $subject, $body
#$msg.isBodyhtml = $true
#$smtp.send($msg)
writeHtmlHeader $ServiceHealthFileName
foreach ($server in Get-Content $serverlist)
{
Add-Content $ServiceHealthFileName "<table width='100%'><tbody>"
Add-Content $ServiceHealthFileName "<tr bgcolor='#CCCCCC'>"
Add-Content $ServiceHealthFileName "<td width='100%' align='center' colSpan=6><font face='tahoma' color='#003399' size='2'><strong> $server </strong></font></td>"
Add-Content $ServiceHealthFileName "</tr>"
writeTableHeader $ServiceHealthFileName
$store = Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss0'" ;Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss1'";Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss2'";Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss3'";Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss4'";Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss5'";Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss6'";Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss7'"
#The below would not let me create objects in the store it had an error.
#store = Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss0'"
#$store = $store + Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss1'"
#$store = $store + Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss2'"
#$store = $store + Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss3'"
#$store = $store + Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss4'"
#$store = $store + Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss5'"
#$store = $store + Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss6'"
#$store = $store + Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss7'"
foreach ($item in $store)
{
Write-Host $item.Name $item.Name $item.FreeSpace $item.Size
writeServiceInfo $ServiceHealthFileName $item.Name $item.ProcessId $item.State $item.StartMode $Item.ExitCode $Item.Status
}
}
writeHtmlFooter $ServiceHealthFileName
$date = ( get-date ).ToString('yyyy/MM/dd')
My output file is populating correctly but only for the first service.
I get the server name and all the statuses exactly how I want them.
Im not sure what I am missing.
Out of respect this is a chopped version of a diskspace script that I got as an example from a coworker. Kudos to the original writer of whom I do not know.
Your only storing one of your service objects into the $store variable, the rest are just being emitted to the pipeline. make $store an array and then add elements to it.
$store = #()
$store += Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss0'"
$store += Get-WmiObject -Class Win32_Service -ComputerName $name -Filter "Name LIKE 'ss1'"
Also please don't string together multiple lines into one using ; unless you have a really good reason for doing so(which is virtually never in PowerShell), it just makes your code really unclear and doesn't do anything a carriage return doesn't.
The finished code. I added an uptime to the report. Thanks to everyone for the help #MikeGaruccio . Since this was modified from another authors DiskSpace script, Thank you if you see this. In the spirit of the community here is the code for a nice Report of services with a little logic for stopped services.
# First lets create a text file, where we will later save the Service Health info
$ServiceHealthFileName = "ServiceHealth.htm"
$serverlist = "yourserverlist.txt"
$warning = "Stopped"
New-Item -ItemType file $ServiceHealthFileName -Force
# Function to write the HTML Header to the file
Function writeHtmlHeader
{
param($fileName)
$date = ( get-date ).ToString('yyyy/MM/dd')
Add-Content $fileName "<html>"
Add-Content $fileName "<head>"
Add-Content $fileName "<meta http-equiv='Content-Type' content='text/html; charset=iso-8859-1'>"
Add-Content $fileName '<title> Server Health</title>'
add-content $fileName '<STYLE TYPE="text/css">'
add-content $fileName "<!--"
add-content $fileName "td {"
add-content $fileName "font-family: Tahoma;"
add-content $fileName "font-size: 11px;"
add-content $fileName "border-top: 1px solid #999999;"
add-content $fileName "border-right: 1px solid #999999;"
add-content $fileName "border-bottom: 1px solid #999999;"
add-content $fileName "border-left: 1px solid #999999;"
add-content $fileName "padding-top: 0px;"
add-content $fileName "padding-right: 0px;"
add-content $fileName "padding-bottom: 0px;"
add-content $fileName "padding-left: 0px;"
add-content $fileName "}"
add-content $fileName "body {"
add-content $fileName "margin-left: 5px;"
add-content $fileName "margin-top: 5px;"
add-content $fileName "margin-right: 0px;"
add-content $fileName "margin-bottom: 10px;"
add-content $fileName ""
add-content $fileName "table {"
add-content $fileName "border: thin solid #000000;"
add-content $fileName "}"
add-content $fileName "-->"
add-content $fileName "</style>"
Add-Content $fileName "</head>"
Add-Content $fileName "<body>"
add-content $fileName "<table width='100%'>"
add-content $fileName "<tr bgcolor='#CCCCCC'>"
add-content $fileName "<td colspan='7' height='25' align='center'>"
add-content $fileName "<font face='tahoma' color='#003399' size='4'><strong> Server Health - $date</strong></font>"
add-content $fileName "</td>"
add-content $fileName "</tr>"
add-content $fileName "</table>"
}
# Function to write the HTML Header to the file
Function writeTableHeader
{
param($fileName)
Add-Content $fileName "<tr bgcolor=#CCCCCC>"
Add-Content $fileName "<td width='10%' align='center'>Name</td>"
Add-Content $fileName "<td width='50%' align='center'>ProcessId</td>"
Add-Content $fileName "<td width='10%' align='center'>State</td>"
Add-Content $fileName "<td width='10%' align='center'>StartMode</td>"
Add-Content $fileName "<td width='10%' align='center'>ExitCode</td>"
Add-Content $fileName "<td width='10%' align='center'>Status</td>"
Add-Content $fileName "</tr>"
}
Function writeHtmlFooter
{
param($fileName)
Add-Content $fileName "</body>"
Add-Content $fileName "</html>"
}
Function writeServiceInfo
{
param($fileName,$SvcName,$SvcPID,$SvcSM,$SvcExCd,$ServiceState,$SvcStatus)
$SvcName= $Item.Name
$SvcPID= $Item.ProcessId
$SvcSM= $Item.StartMode
$SvcExCd= $Item.ExitCode
$ServiceState= $Item.State
$SvcStatus= $Item.Status
#You can add multiple elseif statements if you wish to display certain events. I have server state of STOPPED in Red.
if ($ServiceState -eq $warning)
{
Add-Content $fileName "<tr>"
Add-Content $fileName "<td>$SvcName</td>"
Add-Content $fileName "<td>$SvcPID</td>"
Add-Content $fileName "<td bgcolor='#FF4C4C' align=center>$ServiceState</td>"
#FF4C4C RED #FBB917 ORANGE
Add-Content $fileName "<td>$SvcSM</td>"
Add-Content $fileName "<td>$SvcExCd</td>"
Add-Content $fileName "<td>$SvcStatus</td>"
Add-Content $fileName "</tr>"
}
else
{
Add-Content $fileName "<tr>"
Add-Content $fileName "<td>$SvcName</td>"
Add-Content $fileName "<td>$SvcPID</td>"
Add-Content $fileName "<td>$ServiceState</td>"
Add-Content $fileName "<td>$SvcSM</td>"
Add-Content $fileName "<td>$SvcExCd</td>"
Add-Content $fileName "<td>$SvcStatus</td>"
Add-Content $fileName "</tr>"
}
}
#The function for the sendemail at the end.
#Function sendEmail
#{ param($from,$to,$subject,$smtphost,$htmlFileName)
#$body = Get-Content $htmlFileName
#$smtp= New-Object System.Net.Mail.SmtpClient $smtphost
#$msg = New-Object System.Net.Mail.MailMessage $from, $to, $subject, $body
#$msg.isBodyhtml = $true
#$smtp.send($msg)
writeHtmlHeader $ServiceHealthFileName
foreach ($server in Get-Content $serverlist)
{
#This adds the Uptime for the server you will need $Display in your add-content.
$hostname = get-wmiobject win32_computersystem -computername $server | fl model
$os = Get-WmiObject win32_operatingsystem -ComputerName $server
$uptime = (Get-Date) - ($os.ConvertToDateTime($os.lastbootuptime))
$Display = "Uptime: " + $Uptime.Days + " days, " + $Uptime.Hours + " hours, " + $Uptime.Minutes + " minutes"
#This builds the header for each server and include the name and uptime.
Add-Content $ServiceHealthFileName "<table width='100%'><tbody>"
Add-Content $ServiceHealthFileName "<tr bgcolor='#CCCCCC'>"
Add-Content $ServiceHealthFileName "<td width='100%' align='center' colSpan=6><font face='tahoma' color='#003399' size='2'><strong> $server $Display </strong></font></td>"
Add-Content $ServiceHealthFileName "</tr>"
#This writes the header and builds the body of each server health
writeTableHeader $ServiceHealthFileName
$store = #()
$store += Get-WmiObject -Class Win32_Service -ComputerName $server -Filter "Name LIKE 'yourservice'"
$store += Get-WmiObject -Class Win32_Service -ComputerName $server -Filter "Name LIKE 'yourservice'"
$store += Get-WmiObject -Class Win32_Service -ComputerName $server -Filter "Name LIKE 'yourservice'"
$store += Get-WmiObject -Class Win32_Service -ComputerName $server -Filter "Name LIKE 'yourservice'"
$store += Get-WmiObject -Class Win32_Service -ComputerName $server -Filter "Name LIKE 'yourservice'"
$store += Get-WmiObject -Class Win32_Service -ComputerName $server -Filter "Name LIKE 'yourservice'"
$store += Get-WmiObject -Class Win32_Service -ComputerName $server -Filter "Name LIKE 'yourservice'"
$store += Get-WmiObject -Class Win32_Service -ComputerName $server -Filter "Name LIKE 'yourservice'"
#This write the body of each header in the order you defined
foreach ($item in $store)
{
#If you dont want on screen read out as the script progresses; comment out the write-host line.
#Write-Host $server $item.Name $item.ProcessId $item.State
writeServiceInfo $ServiceHealthFileName $item.Name $item.ProcessId $item.State $item.StartMode $Item.ExitCode $Item.Status
}
}
#This writes the footer
writeHtmlFooter $ServiceHealthFileName
$date = ( get-date ).ToString('yyyy/MM/dd')
#Use the below line to setup an email of the report,
#sendEmail emailaddress emailaddress "Server Status Report - $Date" EmailServer $ServiceHealthFileName
WMI Output All Services
If you don't mind using the built-in WMI output format, then this one-liner will accomplish exporting a listing of all services in table-format to HTML. If you needed this to run on multiple remote machines that can be accomplished with the /node: switch.
wmic /OUTPUT:%userprofile%\Desktop\%computername%_svc.html SERVICE list full /format:htable

Trying to match strings when importing a CSV with Powershell

I am trying to create a report showing older operating systems out of a CSV file. The program displays the output beautifully, but doesn't actually parse anything. I'm trying to separate out Windows 2000, 2003, XP, and yes, windows NT machines. The sample data is below:
Finding Title,IP Address / FQDN,Port,Service,OS,FQDN,Default Username,Default Password,Remediation Notes,Misc Notes,Misc Notes 2,Contact,Remediation
Default Password (yada) for 'yadayada' Account on Windows,fakefake,445,cifs,Microsoft Windows Server 2003 Service Pack 2,fakefake,yadayada,yadayada,Change the password.,,,,
Default Password (yadayada) for 'yadayada' Account on Windows,fakefake1,445,cifs,Microsoft Windows Server 2003 Service Pack 2,fakefake1,yadayada,yadayada,Change the password.,,,,
Default Password (yadayada) for 'yadayada' Account on Windows,fakefake2,445,cifs,Microsoft Windows Server 2003 Service Pack 1,fakefake2,yadayada,yadayada,Change the password.,,,,
Default Password (yadayada) for 'yadayada' Account on Windows,fakefake3,445,cifs,Microsoft Windows Server 2008 R2 Standard,fakefake3,yadayada,yadayada,Change the password.
The program I have so far is here:
$name = Read-Host 'CSV File?'
$csvs = import-csv $name
$object = $csvs.os
ForEach ( $object in $csvs ) {
if ($object -like '*2003*') { out-file -inputobject $object -append $name}
elseif ($object -like '*2000*') { out-file -inputobject $object -append $name}
elseif ($objects -clike '*NT*') { out-file -inputobject $object -append $name}
elseif ($object -clike '*XP*') { out-file -inputobject $object -append $name}
write-output $outfile
}
$a = "<style>"
$a = $a + "BODY{background-color:white;}"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color: black;border-collapse: collapse;}"
$a = $a + "TH{border-width: 1px;padding: 2px;border-style: solid;border-color: black;background-color:thistle}"
$a = $a + "TD{border-width: 1px;padding: 2px;border-style: solid;border-color: black;background-color:white}"
$a = $a + "TD:Nth-Child(Odd) {Background-Color: #dddddd;}"
$a = $a + "</style>"
import-csv $name | ConvertTo-HTML -head $a| Out-File C:\Users\myuser\Downloads\scripts\Test.htm
I think you have a bug in there, you have 2 variables named object that you are using for different purposes:
$object = $csvs.os
ForEach ( $object in $csvs ) # object above getting overwritten
I would just get rid of the first object assignment and write the loop like this:
ForEach ( $object in $csvs ) {
if ($object.os -like '*2003*') { out-file -inputobject $object -append $name}
elseif ($object.os -like '*2000*') { out-file -inputobject $object -append $name}
elseif ($object.os -clike '*NT*') { out-file -inputobject $object -append $name}
elseif ($object.os -clike '*XP*') { out-file -inputobject $object -append $name}
}
Though you can avoid the repetition like this:
$csvs | where-object{ $_.os -like '*2003*' -or $_.os -like '*2000*' -or $_.os -clike '*NT*' -or $_.os -clike '*XP*'} | out-file -append $name

PowerShell outtput to HTML

Using the following and would like to know how to output the results to HTML file
$Start = (Get-Date).AddMinutes(-5)
$Computername = gc C:\Temp\List.txt
$Events = gc C:\Temp\ErrorCodes.txt
Get-EventLog -AsString -ComputerName $Computername |
ForEach-Object {
# write status info
Write-Progress -Activity "Checking Eventlogs on \\$ComputerName" -Status $_
# get event entries and add the name of the log this came from
Get-EventLog -LogName $_ -EntryType Error, Warning -After $Start -ComputerName $ComputerName -ErrorAction SilentlyContinue |
Add-Member NoteProperty EventLog $_ -PassThru | Where-Object {$Events -contains $_.eventid}
} |
# select the properties for the report
Select-Object EventLog, EventID, TimeGenerated, EntryType, Source, Message
This will get it to print with pretty colors. You can tinker around with it and change whatever you want.
$a = "<style>"
$a = $a + "BODY{background-color:peachpuff;}"
$a = $a + "TABLE{border-width: 1px;border-style: solid;border-color:black;border-collapse: collapse;}"
$a = $a + "TH{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:thistle}"
$a = $a + "TD{border-width: 1px;padding: 0px;border-style: solid;border-color: black;background-color:palegoldenrod}"
$a = $a + "</style>"
$Variable = get-what_I_want
$Variable2 = get-what_I_want
$VariableHTML = $Variable | ConvertTo-HTML -head $a -body "<H2>Title I want</H2>"
$Variable2HTML = $Variable2 | ConvertTo-HTML -head $a -body "<H1>Header One</H1> <H2>Header Two</H2> <H3>Header Three</H3> <p>Paragraph<p/>"
$VariableHTML > C:\PoSH\My_Exported_HTML.html
I added a second variable. As you can see, you can add different levels of headers and a Paragraph. I found this helpful for single line items or if you want a better description.
If I would say: ConvertTo-Html is what you need, than probably that would be enough to add a comment.
Instead I will say: before asking questions outside PowerShell, ask them inside PowerShell first.
Get-Help *html*