Powershell: Build Configuration Objects - part 2 of 3

theinfradev

TheInfraDev

Posted on February 16, 2019

Powershell: Build Configuration Objects - part 2 of 3

PowerShell Functions and Classes Pt 2 - Build Configuration Objects

Note: This is part two of a three part series on PowerShell Classes and Functions.

In part one we looked at how we can create a class to hold our configuration object. We then created a constructor to create some automation in our config. In the second part I want to look into how we can use methods to generate our objects. For example, lets take our last example of a TV Gaming PC.


Class PCSystem
{
        [string]$CPU
        [string]$Mainboard   = 'MSI B450M Mortar Titanium'
        [string]$Case        = 'Thermaltake Level 20 VT Chassis'
        [string]$PowerSupply = 'SeaSonic FocusPlus Gold 650W'
        [string]$RAM         = 'Team Delta RGB - 16 GB DDR3000'
        [string]$Storage     = 'Samsung 970 EVO 500 GB'
        [string]$GPU
}
We have deliberately left the CPU and GPU options available to be tweaked as these are the main configuration changes we can make to our performance. I would like to be able to configure it with the following options:
  • 1 : CPU = 'AMD Ryzen 5 2400G' | GPU = 'No GPU'
  • 2 : CPU = 'AMD Ryzen 3 2200G' | GPU = 'EVGA - GeForce GTX 2070'
  • 3 : CPU = 'AMD Ryzen 5 2400G' | GPU = 'EVGA - GeForce GTX 2070'
  • How do we do this? Well we could just instantiate the object and add these configurations in the body of the script. This is certainly common, but i think it makes the script hard to read. It is always preferable to make the script read like a narrative. Alternatively, we can create a constructor that takes an argument, say an integer like "1", "2" or "3".

    This seems cleaner to me and allows us to clean up our later code, while also creating discrete configurations that can be later appended or added to easily, because we are housing all our configs in one spot.

    Lets create our class to build specific types of computers.

    Good to see you are finally adding a GPU to this crappy build.

    In my previous article I took the CPU name as the input to our constructor, this time all we are going to do is take a single integer. (i.e. 1,2 or 3)


    So lets see how this is done.

    
    Class PCSystem
    {
        $CPU; $Mainboard; $Case; $PowerSupply; $RAM; $Storage; $GPU
    
      First you can see we created our class with the declarations of what properties our class is going to house.
    
        PCSystem([int32]$Option)
        {
            [string]$this.Mainboard     = 'MSI B450M Mortar Titanium'
            [string]$this.Case          = 'Thermaltake Level 20 VT Chassis'
            [string]$this.PowerSupply   = 'SeaSonic FocusPlus Gold 650W'
            [string]$this.RAM           = 'Team Delta RGB - 16 GB DDR3000'
            [string]$this.Storage       = 'Samsung 970 EVO 500 GB'
    
      Now we create our constructor. You can see we are taking the parameter '$Option' as our input to tell the constructor what to do. Now while we want to be able to change the CPU/GPU the rest don't change so rather than repeatedly declare the rest of the properties for each configuration - we are going to set the other properties now.
    
            switch($Option)
            {
                1{
                    [string]$this.CPU  = 'AMD Ryzen 5 2400G'
                    [string]$this.GPU  = ''
                 }
                2{
                    [string]$this.CPU  = 'AMD Ryzen 3 2400G'
                    [string]$this.GPU  = 'EVGA - GeForce GTX 2070'  
                 }
                3{
                    [string]$this.CPU  = 'AMD Ryzen 5 2400G'
                    [string]$this.GPU  = 'EVGA - GeForce GTX 2070'
                 }
    Default 
             {
                    [string]$this.CPU  = 'Invalid configuration'
                    [string]$this.GPU  = ''
                 }
            }
        }
    }
    
      Lastly, we have done the most interesting bit, and using a switch statement we set the CPU/GPU properties based on which option the constructor is provided. (a bad input to $option will return the 'default' of "invalid configuration").

    And there it is, we now have a way of creating this complex object in our script by simply calling it with an integer. Just to see what that looks like we might as well call option 3:

    
    >_ [PCSystem]::new(3)
    
    CPU          : AMD Ryzen 5 2400G
    Mainboard    : MSI B450M Mortar Titanium
    Case         : Thermaltake Level 20 VT Chassis
    PowerSupply  : SeaSonic FocusPlus Gold 650W
    RAM          : Team Delta RGB - 16 GB DDR3000
    Storage      : Samsung 970 EVO 500 GB
    GPU          : EVGA - GeForce GTX 2070
    

    Can you think of other configurations this could apply too?

    Why don’t you, I am tired from reading the millions of words


    This configuration builder approach is a great way of dealing with building PowerShell objects. Importantly it also takes this configuration step out of your main logic, "separating the concern". For many dev's this is a pretty standard approach but for the System Engineer this may be a brand-new way of thinking about things. If you asking yourself, why should I do this, maybe hang in there for the next post when i wrap this up, but just offhand I have found this is great for structuring your scripts into discrete sections, it cleans up your configuration while putting it all in one place which any engineer could find. We have now a clear understanding of what each object needs, because the totality of it is defined at the start of the class and if we want to add a configuration we are using composition to include new configurations in the constructor which will then filter down through the whole script. Just some of the objects for which I have used this configuration class include: Virtual Machines, Network Adapter, and AD User/Computer configurations.


    In the final part of this 3 part series, I will look at how to use this configuration object in a Function providing a full implementation and, you know - actually doing something with this class object that I have spent so long demonstrating.


    If you can think of another type of configuration you could use this for, leave it in the comments below because I am always looking for new ideas.


    Cheers,


    The Infra Dev


    To get updates on my new articles, follow me on Twitter @theinfradev

    Photo by Philipp Katzenberger on Unsplash

    💖 💪 🙅 🚩
    theinfradev
    TheInfraDev

    Posted on February 16, 2019

    Join Our Newsletter. No Spam, Only the good stuff.

    Sign up to receive the latest update from our blog.

    Related