Convert JSON or CSV to a PowerShell Class

There’s a new keyword in PowerShell v5.0, it’s for creating classes directly in your PowerShell scripts. Check out Introduction to PowerShell 5 Classes.

Verify Incoming Data

One application of PowerShell classes is the ability to simplify verification of incoming data. For example, you may have comma separated input that looks like this:

Line 3 clearly has bad data. If you use ConvertFrom-Csv, it will happily create PowerShell objects on the fly but both the name and age property will be defined as strings, and 10a is a string. We need a little more safety.

Here is a class Person that strongly types the properties name as string and age as an int.

Putting this together let’s you detect data errors early.

Running the above generates this error.

This is a great way to do pre-flight checks on incoming data to determine if there are issues.

Expand the DataSet

What if the input data has more properties:

Working up a PowerShell class by hand for this can be tedious and error prone. So, let’s automate it with ConvertTo-Class

ConvertTo-Class

ConvertTo-Class is a PowerShell module I published, and it’s on the gallery. It automates creating a PowerShell class from either CSV or JSON text data. ConvertTo-Class determines both the name of the property and the actual data type of the data.

Quick, Easy and accurate!

ConvertTo-Class infers the correct data type for the properties age,zip, and rent.

The class is ready to go. You can save it to a file and dot source it or you can do an Invoke-Expression on it and use it immediately.

Auto Detects JSON Too

The same ConvertTo-Class function atuo detects JSON and produces the same class as it did with the CSV data.

Here is the same class. Notice you can use the -ClassName parameter to override the default class name of RootObject.

Plus, ConvertTo-Class Handles Multiple Classes

Here is sample JSON that has multiple classes. ConvertTo-Class detects and generates each class with it’s properties.

Here’s the code generated PowerShell classes, wired up and with the correct data types.

Generate C# or PowerShell Classes

PowerShell class syntax is the default output. You can also generate classes for use in C# with the -CodeGen CSharp parameter.

In an upcoming post, you’ll see how you can easily specify your own code generation “rules” to create constructs for other languages or purposes.

In Action Video

I’ve also published two PowerShell scripts that let you paste JSON or CSV to classes from the clipboard in either the console, using PSReadline or from ISE via an addon.

image

Grab the PowerShell

You can get ConvertTo-Class from the PowerShell Gallery or on my GitHub repo.

Love the quick one off automation you can do in PowerShell

I use markdown for lots of things. Note taking, blog posts, read me files for my GitHub repos and more.

Typically I launch MarkdownPad, start typing and then do a File|Save, navigate to the directory where I want it and save it.

Too Much Work

That workflow opens itself to lots of missteps. Eye hand coordination problems, fat fingering the directory where I want it saved, etc.

So, let’s whittle that down to 10 characters (less if you use tab completion) plus the name of the file.

New-MDFile blogEntry

The function adds the '.md' extension, then creates it, with the proper encodoing and finally does an Invoke-Item on the file name so it launches MarkdownPad with it ready for editing.

Select-String

On another note, I’ve been working with TypeScript recently. Often, I need to find text across multiple files. The typescript files are organized across directories and in subdirectories.

Rather then repeatably typing ls . -r *.ts and piping it to Select-String with the pattern you’re looking for (too much work). You create a function and combine these operations into one. The search string is optional, fts will return a list of typescript files if it is not specified.

fts showInformationMessage

Question: How would you adapt this to work with PowerShell files? C# files? Other files?

PowerShell ConvertFrom-String: Serious Text wrangling

There’s a new PowerShell cmdlet ConvertFrom-String released with PowerShell v5.0. There are a bunch of write ups on using this cmdlet and I want to show how it makes quick work of HTML source.

HTML Source

Sometimes you’ll get html that looks like the snippet below (remember, it could be hundreds an hundreds of lines of HTML). So editing/transforming it by hand would take quite some time.

The Transform

Let’s say we wanted to go from the HTML above, to this:

I’ve written code (or used a macro recorder in a text editor) to find the first ‘>’, delete the text to the left, find the ‘(‘ grab the text I want, etc.

The challenge is, not all the people I work with know how to do this. Plus, there are many other (mundane) text reformatting tasks that people go through every day.

Enter ConvertFrom-String

The key here is the $template on starting on line 17. I’m using ConvertFrom-String to do example-driven parsing. The template provides the example (hints to ConvertFrom-String on what I want extracted).

I put curly braces around the data I want to extract, and give it a name Item and Count. The * tells ConvertFrom-String this should result in multiple records.

image

image

The data is piped to ConvertFrom-String, parsed an then piped to ForEach which does the final transform.

That, is slick and easy.

Note: I’m providing the data and template in the code. Both the data and template can be in separate external files so script could be run to do transforms over many inputs.

Check Out ConvertFrom-String Buddy

I created a GUI (Using PowerShell and WPF), you can get the script HERE.

It lets you quickly and easily experiment with ConvertFrom-String.

Paste the data you want to transform in the data text box (on the left). Start typing the example template in the template text box (on the right). As you type, you’ll immediately see results in the result text box.

Plus, it generates the PowerShell code as you go. You can copy that to the clipboard and save it as a script for later.