Skip to the main content.

PowerShell Tips

Utilizing external config data in PowerShell (4/4)

Table of contents

Post Featured Image

Tobias & Aleksandar's tip #6:

The two very well-known PowerShell experts have teamed up to share their best and most helpful PowerShell tips.

We will be publishing their scripts over the course of Scriptember in 13 blog posts. Don't miss their insights! Be sure to follow all Scriptember events, listed in our calendar here

 

All four parts of 'utilizing external config data'
from our Scriptember blog series  

 

Utilizing external config data

In the final step of our mini-series, we’ll add robustness and resilience to reading data from *.psd1: The script reading the *.psd1 file applies simple yet powerful type checking. No rogue person (or inexperienced trainee) can add unauthorized keys, typos will immediately raise alerts, and you get type safety: Data meant to be an array (list) will stay an array, even if the *.psd1 file defines just one (or no) value for this key.

Let’s try and improve this. Here is the *.psd1 file again. This time, I removed the prefix "data" from the keys as this prefix is no longer needed when all information is stored in one object, and stored the file as data_new.psd1:


@{
   # paths to important folders
   InPath = 'c:\data1', '\\server2\public\data'
   OutPath = '\\server99\public\results'
   LogPath = 'f:\local\log'

   # AD groups 
   Groups = 'Technicians', 'Testers', 'Auditors'

   # miscellaneaous settings
   TimeoutSeconds = 5400
   LogLevel = 4


Here is how we previously loaded the *.psd1 file and turned its information into an object (make sure both files are stored in the same folder):



# data.psd1 must be located in the same folder
$dataPath = Join-Path -Path $PSScriptRoot -ChildPath data_new.psd1

# convert hash table keys into variables
$hashObject = [PSCustomObject](Import-PowerShellDataFile -Path $dataPath)


That worked great, but there was no strict type declaration that safe-guarded the imported data and made sure it was actually structured in the correct way. 

Thanks to classes (added in Windows PowerShell 5), adding this is very simple: Add a class to your script that defines the order and the data type of the object properties, then cast the object to this class.

Extra tip: For numeric lists like a "LogLevel", either use data type [int], or better yet add an enumeration with friendly names that limits the allowable numeric values to a fixed list (see below):


enum LogLevel
{
   Information = 1
   Verbose = 2
   Debug = 3
   All = 4
}

# define the structure of your input data 
class configDataScript1
{
   # paths:
   [string[]]$InPath
   [string[]]$OutPath
   [string]$LogPath

   # AD groups: 
   [string[]]$Groups

   # miscellaneaous settings
   [int]$TimeoutSeconds
   [LogLevel]$LogLevel
}

# data.psd1 must be located in the same folder
$dataPath = Join-Path -Path $PSScriptRoot -ChildPath data_new.psd1

# safely read psd1 file (caveat: unsafe reads can execute code within psd1 file)
[configDataScript1]$externalData = [PSCustomObject](Import-PowerShellDataFile -Path $dataPath)

$externalData
$externalData.GetType().FullName 


The result is awesome: with a minimum effort, you turned *.psd1 files into a powerful and type-safe way of importing external information into your scripts.

Extra Tip: Casting objects to self-made class definitions works with a multitude of data. You can apply the same technique to imported CSV files, for example. Just make sure the class definition matches exactly the names of your properties, and each property value can in fact be converted to the data type that the class requires.

 

 

Good2know


Scriptember! Stay tuned:

During Scriptember, our calendar provides the best possible overview.  

Scriptember - hier ist die Übersicht

 

  • Follow us on social media, look for and use the hashtags #Scriptember and #PowerShell.
  • Join our live sessions, overview soon here.
  • Participate in challenges and contests. 
  • Share your knowledge.

 

Find all events here!

 

 

Related links 



Related posts

7 min read

Hidden configuration variables in PowerShell

Tobias & Aleksandar's tip #13:

The two very well-known PowerShell experts have teamed up to share their best and most...

4 min read

Hiding confirmations in PowerShell

Tobias & Aleksandar's tip #12:

The two PowerShell experts have teamed up to share their best and most helpful...

4 min read

URL Encoding in PowerShell

Tobias & Aleksandar's tip #11:

The two very well-known PowerShell experts have teamed up to share their best and most...

About the author: