I have started writing a HTML SQL reporting script based off of Jeffrey Hicks tutorial
Here is my entire script:
###################START SCRIPT#####################################
#requires -version 3.0
#Create a SQL Server report of said SQL environment
[cmdletbinding()]
Param(
[string]$computername=$env:computername,
[string]$path="$env:temp\sqlrpt.htm"
)
#define an empty array to hold all of the HTML fragments
#the fragments will break apart each HTML section in the final output so that you can out whatever information you like
$fragments=@()
#save current location so I can set it back after importing SQL module
$curr = get-location
#import the SQL module
Import-Module SQLPS -DisableNameChecking
#change the location back
set-location $curr
#get uptime
Write-Verbose "Getting SQL Server uptime"
$starttime = Invoke-Sqlcmd -Query 'SELECT sqlserver_start_time AS StartTime FROM sys.dm_os_sys_info' -ServerInstance $computername -database master
$version = Invoke-Sqlcmd "Select @@version AS Version"
#create an object
$uptime = New-Object -TypeName PSObject -Property @{
StartTime = $starttime.Item(0)
Uptime = (Get-Date)-$starttime.Item(0)
Version = $version.Item(0).replace("`n","|")
}
$tmp = $uptime | ConvertTo-HTML -fragment -AS List
#replace "|" place holder with <br>"
$fragments += $tmp.replace("|","<br>")
#SQL Host Information
$smo = new-object ('Microsoft.SqlServer.Management.Smo.Server') $computername
$fragments += "<h3>SQL Host Information Details</h3>"
$fragments += $smo | select ComputerNamePhysicalNetBios,Name, Processors, ProcessorUsage, PhysicalMemory, PhysicalMemoryUsageInKB, MasterDBPath, BackupDirectory | ConvertTo-HTML -Fragment
#Get Status of all SQL related Services
Write-Verbose "Querying services"
$services = Get-Service -DisplayName *SQL* -ComputerName $computername |
Select Name,Displayname,Status
$fragments += "<h3>SQL Services</h3>"
$fragments += $services | ConvertTo-HTML -Fragment
#get databases
#path to databases
Write-Verbose "Querying datases"
$dbpath = "SQLServer:\SQL\Localhost\default\databases"
$fragments += "<h3>Database Utilization</h3>"
$fragments += dir $dbpath | Select Name,Size,DataSpaceUsage,SpaceAvailable,
@{Name="PercentFree";Expression={ [math]::Round((($_.SpaceAvailable/1kb)/$_.size)*100,2) }} |
Sort PercentFree | ConvertTo-HTML -fragment
#get database backup information
# Create an SMO connection to the instance
$smo = new-object ('Microsoft.SqlServer.Management.Smo.Server') $computername
$dbbackups = $smo.Databases
$fragments += "<h3>Last Database Backup Information</h3>"
$fragments += $dbbackups | select Name,LastBackupDate, LastLogBackupDate | ConvertTo-HTML -Fragment
#Login & Service Account Information#SQL Host Information
$smo = new-object ('Microsoft.SqlServer.Management.Smo.Server') $computername
$fragments += "<h3>Login & Service Account Information</h3>"
$fragments += $smo | select ServiceAccount, Logins | ConvertTo-HTML -Fragment
#volume usage
Write-Verbose "Querying system volumes"
$data = Get-CimInstance win32_volume -filter "drivetype=3" -ComputerName $computername
$drives = foreach ($item in $data) {
$prophash = [ordered]@{
Drive = $item.DriveLetter
Volume = $item.DeviceID
Compressed = $item.Compressed
SizeGB = $item.capacity/1GB -as [int]
FreeGB = "{0:N4}" -f ($item.Freespace/1GB )
PercentFree = [math]::Round((($item.Freespace/$item.capacity) * 100),2)
}
#create a new object from the property hash
New-Object PSObject -Property $prophash
}
[xml]$html = $drives | ConvertTo-Html -fragment
#check each row, skipping the TH header row
for ($i=1;$i -le $html.table.tr.count-1;$i++) {
$class = $html.CreateAttribute("class")
#check the value of the last column and assign a class to the row
if (($html.table.tr[$i].td[-1] -as [int]) -le 25) {
$class.value = "danger"
$html.table.tr[$i].Attributes.Append($class) | Out-Null
}
elseif (($html.table.tr[$i].td[-1] -as [int]) -le 35) {
$class.value = "warn"
$html.table.tr[$i].Attributes.Append($class) | Out-Null
}
}
$fragments += "<h3>Volume Utilization</h3>"
$fragments += $html.innerxml
#define the HTML style
Write-Verbose "preparing report"
$imagefile = "c:\scripts\db.png"
$ImageBits = [Convert]::ToBase64String((Get-Content $imagefile -Encoding Byte))
$ImageHTML = "<img src=data:image/png;base64,$($ImageBits) alt='db utilization'/>"
$head = @"
<style>
body { background-color:#FAFAFA;
font-family:Arial;
font-size:12pt; }
td, th { border:1px solid black;
border-collapse:collapse; }
th { color:white;
background-color:black; }
table, tr, td, th { padding: 2px; margin: 0px }
tr:nth-child(odd) {background-color: lightgray}
table { margin-left:50px; }
img
{
float:left;
margin: 0px 25px;
}
.danger {background-color: red}
.warn {background-color: yellow}
</style>
$imagehtml
<br><br><br>
<H2>SQL Server Report: $Computername</H2>
<br>
"@
#create the HTML document
ConvertTo-HTML -Head $head -Body $fragments -PostContent "<i>report generated: $(Get-Date)</i>" |
Out-File -FilePath $path -Encoding ascii
Write-Verbose "Opening report"
Invoke-Item $path
######################END SCRIPT##################################
I have 2 questions for help in regards to the above script:
1) For the Login and Service Account portion I can't get my output to show up properly. Here is the snip from the script:
#Login & Service Account Information#SQL Host Information
$smo = new-object ('Microsoft.SqlServer.Management.Smo.Server') $computername
$fragments += "<h3>Login & Service Account Information</h3>"
$fragments += $smo | select ServiceAccount, Logins | ConvertTo-HTML -Fragment
Here is how the output shows for this portion:
ServiceAccount | Logins |
---|
domain\svcAcct | Microsoft.SqlServer.Management.Smo.LoginCollection |
I would like top have the login information show in the above table of the all the different logins. When I run the script without HTML for that portion and just output to console it shows the login info as I would expect.
2) The 2nd question is, how do I add a variable to the bottom of the script to email the report to said email address. This is probably simple but can't get my head wrapped around this part.
Thanks all in advance!