Creating Custom PowerShell Objects

Creating Custom PowerShell Objects

  • Comments 2
  • Likes

Summary: Use Windows PowerShell to create custom objects prior to data export.

Microsoft Scripting Guy, Ed Wilson, is here. It is nice and cool this morning so I decided to walk over to the neighborhood coffee and tea shop to have a cup of tea. I can sit outside and enjoy the day. There is free wireless Internet, so I brought my Surface Pro 3 to check my email sent to scripter@microsoft.com, hang out on Facebook and Twitter, and generally do all the things I do in my day-to-day life as the Scripting Guy.

Today, I want to look at creating custom objects from Windows PowerShell as a way of outputting the data that I groomed nicely throughout the week. Because I planned on getting to this point in my script from the very outset, it will be pretty easy to put the pieces together to groom my data. I transformed the date, addresses, and names (see Use PowerShell to Normalize Names Before Data Import), so I expect there to be three sections for these. However, in the end, transforming the date was so easy (see Use PowerShell to Fix Date from CSV File) that I decided to code it directly in the portion of the script that creates the custom object.

Also, because I knew I would be putting everything together, I used the same sorts of variables. So the first portion of the script, which reads the CSV file and walks through the collection is the same:

$datain = import-csv C:\DataIn\DataDump.csv

Foreach ($d in $datain)

    {

Now, I define a region for the name. To do this, I use the #region and #endregion tags. Now, I copy the script that I created earlier to normalize names, and I assign it to a region. This is shown here:

#region Name

 If($d.name -match  ',')

        {

          $name = (Get-Culture).textinfo.ToTitleCase($d.name).Split(',').trim()

          $ln = $name[0]

          $fn = $name[1]

          }

        ELSE {

         $name = $d.Name.Split().trim()

         $fn = $name[0]

         $ln = $name[1]

           }

#endregion

Now I add the region for the address. Once again, I copy the essential transforming code from the script I wrote earlier (see Use PowerShell to Fix Address Issues Prior to Export).

I also create an address region so it makes the script easier to read and troubleshoot. The command is shown here:

#region Address

     $a = $d.address.split(',')

     $str = $a[0] -replace '(Street|street)','ST'

     $city = If($a[1] -match 'dwpt') {"Dewpoint"} ELSE {$a[1]}

     $state = if($a[2] -match 'South Carolina') {"SC"} ELSE {$a[2]}

     $zip = If($a[3].trim().Length -gt 5) {"Error for $a"} ELSE {$a[3]}

#endregion

To create and output the custom object, I use the [PSCustomObject] type accelerator, and I assign a hash table to the [PSCustomObject]. Each element in the hash table is in the form of "property name equals value." Almost every value I need is assigned via a variable. The exception is the date. I decided to do this as a single line of code, as shown here:

Date = [datetime]("{0}/{1}/{2}" -f $d.month, $d.day, $d.year)

I also call the ToUpper method on the strings that are stored in the Street and City properties of the object:

Street = $str.ToUpper()

City = $city.ToUpper()

The last thing I do is clean up the state property. I trim it to remove any leading or trailing spaces. I choose only two letters (beginning at the first position), and I make them capital letters. Here is that command:

State = $state.Trim().Substring(0,2).ToUpper()

And that is it. Here is the complete CreateCustomObjectsFromData.ps1 script:

$datain = import-csv C:\DataIn\DataDump.csv

Foreach ($d in $datain)

    {

#region Name

 If($d.name -match  ',')

        {

          $name = (Get-Culture).textinfo.ToTitleCase($d.name).Split(',').trim()

          $ln = $name[0]

          $fn = $name[1]

          }

        ELSE {

         $name = $d.Name.Split().trim()

         $fn = $name[0]

         $ln = $name[1]

           }

#endregion

 

 #region Address

     $a = $d.address.split(',')

     $str = $a[0] -replace '(Street|street)','ST'

     $city = If($a[1] -match 'dwpt') {"Dewpoint"} ELSE {$a[1]}

     $state = if($a[2] -match 'South Carolina') {"SC"} ELSE {$a[2]}

     $zip = If($a[3].trim().Length -gt 5) {"Error for $a"} ELSE {$a[3]}

#endregion

 

#region Create Custom Object

     [PSCustomObject]@{

       Lname = $ln

       Fname = $fn

       Date = [datetime]("{0}/{1}/{2}" -f $d.month, $d.day, $d.year)

       Street = $str.ToUpper()

       City = $city.ToUpper()

       State = $state.Trim().Substring(0,2).ToUpper()

       Zip = $zip }

#endregion

    } 

And here is the output from the script:

Image of command output

That's it for Data Manipulation Week. I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy 

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment