Converting Text to HTML Revised

A few years ago I published a PowerShell function to convert text files into HTML listings. I thought it would be handy to convert scripts to HTML documents with line numbering and some formatting. Turns out someone actually used it! He had some questions about the function which led me to revisit it and realize there were some improvements to be made.

Part of the challenge with this project is that the function takes an existing text file and creates a much larger text file. On one hand this is to be expected because we are adding HTML to it.  But I wanted to find ways to keep the size down.

After some HTML style tweaking, I found a better way to preserve the  formatting without dramatically increasing the file size. I also added an option so that you can specify an alternate CSS file. If you don’t use one, then the function will insert a default style into the head section. I also gave you the option to specify your own document title.

The revised script, which includes defining an alias, is now a gist on GitHub.

The function behaves much like ConvertTo-HTML in that it doesn’t create an actual file. You still need to pipe the output to Out-File.  And you should use Out-File instead of the console redirection character (>) as that created a much larger version of the file.

Here’s an example of a converted file using the default style sheet.

convertto-htmllisting2

If you want to create your own style sheet, be sure to use the setting white-space:pre; as this should retain document formatting. At least the best it can.

I hope you’ll find this helpful. Enjoy.

SQL Database Report Revised

Last year I wrote an article that explained how to use the SQLSERVER PSDrive to create an HTML report highlighting some server and database information. If you want a refresher you can find that article here. In short, you can install the SQL Server PowerShell module on your client desktop and use it to manage remote servers.
During a PowerShell class I was teaching this week, I included some content on the SQL cmdlets and had an opportunity to revisit the original script. Even though the original version was intended to work with remote servers, I had a few bugs that prevented that from happening. I also decided to include some additional information as well as incorporate more conditional formatting. For example, depending on how much free space is left, the report might format the value in yellow, to indicate a warning or in red to indicate something more critical.

In the SQLSERVER PSdrive, the Databases directory doesn’t show any system databasese by default unless you use -Force.
sqldatabases
So I updated the script to allow you to include those databases if you want.

Here is the revised script:

My script includes a graphic file to make it pretty. You can download my graphic file db.png. Put the graphic in the same directory as the script. Or modify the script to use your own graphics. You can then run a command like this to generate the HTML report.

This script lacks a provision for alternate credentials and assumes the account you are running under has the necessary SQL permissions. When finished you can get a report like this.

I hope you’ll let me know what you think and if you find this useful.

Friday Fun: 50 Shades of PowerShell HTML Reports

happyreport I’ve been working on a project for a client that includes creating an HTML report, generated by PowerShell. I originally thought I would include a certain feature but decided against it. However, this is so cool I thought I’d share it with you as a Friday Fun article. I’ve done alot this year with some advanced HTML scripting techniques and this one might come in handy.

I’m always looking for ways to add visual reinforcement to my HTML reports. And since keeping track of disk space is a common IT Pro task, I figured it would be nice to have a visual representation on disk utilization. So I created a short proof of concept script that generates an HTML report like this:

gradientdemo

What do you think? Here’s how I did it.

The key element here is the addition of a gradient. In the script you can see that I’ve defined a here string for the gradient. The string includes code to support just about any browser, that’s why you see all the background-image lines. The here string also has place holders, {0} and {1} for the starting and ending percentages. I’ll explain how that works in a moment.

Using Get-CIMInstance, the script gets fixed logical disks. Now, instead of simply creating an HTML fragment, I create the fragment as an XML document. This allows me to add a caption to the table, using the computer name. Then I iterate through the table node, skipping the first row which is the table header. I create an attribute called Style.

Next, I get the value of the last cell, which is the PercentFree value. That’s one of the reasons I used an ordered hashtable so I could guarantee that the last cell would always be the PercentFree property. I grab the value and make sure it is an integer.

I can use this value and plug it in to my gradient here string using the -f operator.

I append the style attribute to each node. This allows me to set different values for each drive.

After going through the table rows, all that remains is to add the modified HTML, which is the InnerXML property to my array of fragments and create the final report.

The gradient isn’t absolute but it gives you a rough visual approximation of how much free space is on each drive. By the way, you can also use the gradient in the body element of a style sheet if you want to jazz up the background of your report.

I included plenty of comments in my code which I hope helps. If not, please leave a comment. Enjoy!

PowerShell Morning Report with Credentials

I had an email about trying to use my Morning Report script to connect to machines that required alternate credentials. For example, you might have non-domain systems in a DMZ. Fair enough. Since most of the report script uses WMI, it wasn’t too hard to add a Credential parameter and modify the WMI code to use it. I tweaked the code a bit to use hashtables to splat parameters.


#region define a parameter hashtable
[email protected]{
Classname="Win32_OperatingSystem"
Computername=$Computername
ErrorAction="Stop"
}

if ($credential) {
$paramhash.Add("Credential",$Credential)
}
If ($OK) {

Try {
#get Operating system information from WMI
$os = Get-WmiObject @paramhash
...

I’m a little mixed on using splatting in the script. On one hand it makes it easier to wrap up parameters but the actual command might be a little confusing. Hopefully the comments make it clear.

So that handled all the WMI parts. The event log section is using Get-Eventlog which doesn’t have a -Credential parameter. I could have tried to rewrite the section using WMI, but that seemed like a lot of work. So I made the assumption that the computers you are querying are running PowerShell 2 or later with remoting enabled. That means I can use Invoke-Command to run Get-Eventlog ON the remote computer. As an additional benefit this seems to run a little faster, at least in my testing.

The tricky part was passing all the parameter values to Get-EventLog and Invoke-Command. I ended up with some complicated nesting but it works.


#Event log errors and warnings in the last $Hours hours
$last=(Get-Date).AddHours(-$Hours)
#define a hash table of parameters to splat to Get-Eventlog
$GetEventLogParam = @{
LogName="System"
EntryType="Error","Warning"
After=$last}

#System Log
Write-Host "...System Event Log Error/Warning since $last" -ForegroundColor Cyan
#hashtable of optional parameters for Invoke-Command
$InvokeCommandParam = @{
Computername=$Computername
ArgumentList=$GetEventLogParam
ScriptBlock = {Param ($params) Get-EventLog @params }
}

if ($Credential) { $InvokeCommandParam.Add("Credential",$Credential) }

$syslog = Invoke-Command @InvokeCommandParam

$syslogdata = $syslog | Select TimeGenerated,EventID,Source,Message

#Application Log
Write-Host "...Application Event Log Error/Warning since $last" -ForegroundColor Cyan
#update the hashtable
$GetEventLogParam.LogName="Application"

#update invoke-command parameters
$InvokeCommandParam.ArgumentList = $GetEventLogParam

$applog = Invoke-Command @InvokeCommandParam
$applogdata = $applog | Select TimeGenerated,EventID,Source,Message

Now you can run the script using -Credential, specifying either a saved credential object or the user name which will give you the Get-Credential prompt. I also made some slight tweaks to the embedded style and layout.

morning report

If you missed the original and related posts, you might want to read:
http://jdhitsolutions.com/blog/2012/01/the-powershell-morning-report/
http://jdhitsolutions.com/blog/2012/02/morning-report-revised/
http://jdhitsolutions.com/blog/2012/08/event-log-morning-report/

Download the latest version of the MorningReport.

Event Log Morning Report

The Morning Report script I published earlier this yeas was quite popular. One of the changes I made in it was to skip getting event log entries to speed up the overall process. But I received an inquiry today about how to create the report with only event log information. The only way really is to revise the script.

So I did.

Well, actually I wrote a new script based on the last version. This script, EventlogMorningReport.ps1 works basically the same as the regular morning report except it only gets event log information. Although I added a section to also get audit failures from the Security event log. You run it the same way. You might even want to use a background job.


PS E:\> start-job {get-content computers.txt | c:\scripts\EventLogMorningReport.ps1 -verbose -html | out-file E:\temp\evtlog.htm}

I suppose the better approach would have been to modify the Morning Report script and make each of the different sections optional. And perhaps I’ll address that at some point. But time was tight this morning and it was quicker to simply strip out the bits I didn’t need.

The underlying code hasn’t really changed much so I won’t post it. Feel free to download EventLogMorningReport and give it a spin.