TLDR; The idea of this article is to show how to build a web report. I will show the usage of several commands that you can connect that does all the heavy lifting for you
Ok, here you are, you are looking to read data from one place and present that as a web report. The data is remote, you need to fetch it somehow, you also probably need to think about how to convert the incoming data and lastly create that web report. If you are a developer, you probably think that oh ok, this is probably a few moving parts, 10-20 lines of code. But you've heard of PowerShell, it's supposed to be powerful, do a lot of heavy lifting, so why not give it a spin.
To achieve our task, we need to plan it out. Carry it out sequentially, and who knows, maybe this is something we can reuse? So what steps:
We have a game plan. Now let's see if we can find the commands we need. A good starting point is the Microsoft.PowerShell.Utility section. In this section, there are tons of commands that does a lot of heavy lifting for you.
First things first, we need to grab some data remotely, so what's our options?
PowerShell formats the response based to the data type. For an RSS or ATOM feed, PowerShell returns the Item or Entry XML nodes. For JavaScript Object Notation (JSON) or XML, PowerShell converts, or deserializes, the content into [PSCustomObject] objects.
It takes a JSON response and turns that into a PSCustomObject, nice. Well let's see with our other commands before we make a decision.
This is the last thing we need to do but we need to understand if there's a command that helps us with report creation and most importantly, what input it takes. I think we found it:
Yea, that reminds us of something, Invoke-RestMethod
. Why? Cause Invoke-RestMethod
produces custom objects, i.e .NET objects.
How do we save the report to a file though, so we can store that somewhere and let it be hosted by a web server? Oh, here's an example, pipe it to Out-File
, like so ConvertTo-Html | Out-File aliases.htm
So we have a theory on how to do this:
Invoke-RestMethod
.ConvertTo-Html
.Out-File
.Seems almost too easy. Ah well, let's give it whirl. First things first, lets choose a data source, SWAPI, the Star Wars API, cause use the -Force
, am I right? :)
pwsh
in the console. Invoke-RestMethod -URI https://swapi.dev/api/people/1/ |
ConvertTo-Html |
Out-File report.htm
./web-report.ps1
(or .\web-report.ps1
for Windows folks)It created a report.htm file for us. Ok, let's have a look:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>HTML TABLE</title>
</head><body>
<table>
<colgroup><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/></colgroup>
<tr><th>name</th><th>height</th><th>mass</th><th>hair_color</th><th>skin_color</th><th>eye_color</th><th>birth_year</th><th>gender</th><th>homeworld</th><th>films</th><th>species</th><th>vehicles</th><th>starships</th><th>created</th><th>edited</th><th>url</th></tr>
<tr><td>Luke Skywalker</td><td>172</td><td>77</td><td>blond</td><td>fair</td><td>blue</td><td>19BBY</td><td>male</td><td>https://swapi.dev/api/planets/1/</td><td>System.Object[]</td><td>System.Object[]</td><td>System.Object[]</td><td>System.Object[]</td><td>09/12/2014 13:50:51</td><td>20/12/2014 21:17:56</td><td>https://swapi.dev/api/people/1/</td></tr>
</table>
</body></html>
Invoke_Item
: Invoke-Item ./report.htm
This should start up a browser and you should see something like:
Ok, you could be done here, or we can make it more flexible. We don't like hardcoded values, right? RIGHT?
I thought so, now, let's add some parameters for, URL, and report name.
Param(
[String] $URL = "https://swapi.dev/api/people/1/",
[String] $Report = "report.htm"
)
./web-report.ps1 -URL https://swapi.dev/api/people/2/
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>HTML TABLE</title>
</head><body>
<table>
<colgroup><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/><col/></colgroup>
<tr><th>name</th><th>height</th><th>mass</th><th>hair_color</th><th>skin_color</th><th>eye_color</th><th>birth_year</th><th>gender</th><th>homeworld</th><th>films</th><th>species</th><th>vehicles</th><th>starships</th><th>created</th><th>edited</th><th>url</th></tr>
<tr><td>C-3PO</td><td>167</td><td>75</td><td>n/a</td><td>gold</td><td>yellow</td><td>112BBY</td><td>n/a</td><td>https://swapi.dev/api/planets/1/</td><td>System.Object[]</td><td>System.Object[]</td><td>System.Object[]</td><td>System.Object[]</td><td>10/12/2014 15:10:51</td><td>20/12/2014 21:17:50</td><td>https://swapi.dev/api/people/2/</td></tr>
</table>
</body></html>
This time we have C-3PO
, yup, definitely not Luke, it seems to be working :)
So, so far we had a ton of columns coming back, maybe we just need a few fields from the response, like name
, planet
and height
. Yea let's do that, and justt pick what we need from the response:
Select-Object
like so: Select-Object name, age, planet |
with the full code looking like so:
Param(
[String] $URL = "https://swapi.dev/api/people/1/",
[String] $Report = "report.htm"
)
Invoke-RestMethod -URI $URL |
ConvertTo-Html -Property name, height, homeworld |
Out-File $Report
./web-report.ps1 -URL https://swapi.dev/api/people/1/
and our report now looks like:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>HTML TABLE</title>
</head><body>
<table>
<colgroup><col/><col/><col/></colgroup>
<tr><th>name</th><th>height</th><th>homeworld</th></tr>
<tr><td>Luke Skywalker</td><td>172</td><td>https://swapi.dev/api/planets/1/</td></tr>
</table>
</body></html>
Much better :) In fact, reading up a bit, we can just use -Property on ConvertTo-Html
, so we get:
Invoke-RestMethod -URI $URL |
ConvertTo-Html -Property name, height, homeworld |
Out-File $Report
In all honesty, this report is bad, no colors, no nothing. Surely, we must be able to pass a CSS file to ConvertTo-Html
?
Ah yes, looking through the docs there's the parameter -CssUri
that takes a file path. Let's create a CSS file then.
report.css
and add the following CSS table {
border: solid 1px black;
padding: 10px;
border-collapse: collapse;
}
tr:nth-child(even) {background: #CCC}
tr:nth-child(odd) {background: #FFF}
-CssUri report.css
on ConvertTo-Html
In summary, we learned that we could use just a few commands, Invoke-RestMethod
, ConvertTo-Html
and Out-File
and boom, we've created ourselves a report.
Full code:
Param(
[String] $URL = "https://swapi.dev/api/people/1/",
[String] $Report = "report.htm"
)
Invoke-RestMethod -URI $URL |
ConvertTo-Html -CssUri report.css -Title "Web report" -Property name, height, homeworld |
Out-File $Report
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.