Quantcast
Channel: PowerShell
Viewing all articles
Browse latest Browse all 1519

Reusing Existing Configuration Scripts in PowerShell Desired State Configuration

$
0
0

You are an expert in PowerShell DSC (or maybe not an expert, just someone playing around with configurations in DSC) and have already written fairly large and complex configurations for configuring your environment/data center. Everything is working well and you are a great fan of DSC. There’s only one problem: your work is complicated. Before long, you have a configuration that is hundreds or thousands of lines long – people from many different teams are editing it. Finding and fixing problems becomes nearly impossible… your configuration is just too unwieldy. Then comes a day when there arises a need to add something more (or maybe delete something) to your configuration. The problem looks trivial to solve right? –Just add one more resource to your (already big) configuration. But you are a forward thinking person and find yourself wondering if there is something clever you can do leverage your existing configuration scripts.


That is why we made configurations composable and reusableJ. Yes, one configuration can call another. How? That is what we are going to cover in this post.

 

The way to make a configuration reusable is by making it what we call a composite resource. Let me walk you through an example to do just that.

 

I have the following parameterized configuration (the parameters of the configuration become the properties of the composite resource) which I will turn into a composite resource:

 

ConfigurationxVirtualMachine

{

param

(

# Name of VMs

[Parameter(Mandatory)]

[ValidateNotNullOrEmpty()]

[String[]]$VMName,

 

# Name of Switch to create

[Parameter(Mandatory)]

[ValidateNotNullOrEmpty()]

[String]$SwitchName,

 

# Type of Switch to create

[Parameter(Mandatory)]

[ValidateNotNullOrEmpty()]

[String]$SwitchType,

 

# Source Path for VHD

[Parameter(Mandatory)]

[ValidateNotNullOrEmpty()]

[String]$VhdParentPath,

 

# Destination path for diff VHD

[Parameter(Mandatory)]

[ValidateNotNullOrEmpty()]

[String]$VHDPath,

 

# Startup Memory for VM

[Parameter(Mandatory)]

[ValidateNotNullOrEmpty()]

[String]$VMStartupMemory,

 

# State of the VM

[Parameter(Mandatory)]

[ValidateNotNullOrEmpty()]

[String]$VMState

)

 

# Import the module that defines custom resources

Import-DscResource-ModulexComputerManagement,xHyper-V

 

# Install the HyperV role

WindowsFeatureHyperV

{

    Ensure="Present"

    Name="Hyper-V"

}

 

# Create the virtual switch

xVMSwitch$switchName

{

    Ensure="Present"

    Name=$switchName

    Type=$SwitchType

    DependsOn="[WindowsFeature]HyperV"

}

 

# Check for Parent VHD file

FileParentVHDFile

{

    Ensure="Present"

    DestinationPath=$VhdParentPath

    Type="File"

    DependsOn="[WindowsFeature]HyperV"

}

 

# Check the destination VHD folder

FileVHDFolder

{

    Ensure="Present"

    DestinationPath=$VHDPath

    Type="Directory"

    DependsOn="[File]ParentVHDFile"

}

 

 # Creae VM specific diff VHD

foreach($Namein$VMName)

{

    xVHD"VhD$Name"

    {

        Ensure="Present"

        Name=$Name

        Path=$VhDPath

        ParentPath=$VhdParentPath

        DependsOn= @("[WindowsFeature]HyperV",

                      "[File]VHDFolder")

    }

}

 

# Create VM using the above VHD

foreach($Namein$VMName)

{

    xVMHyperV"VMachine$Name"

    {

        Ensure="Present"

        Name=$Name

        VhDPath= (Join-Path-Path$VhDPath-ChildPath$Name)

        SwitchName=$SwitchName

        StartupMemory=$VMStartupMemory

        State=$VMState

        MACAddress=$MACAddress

        WaitForIP=$true

        DependsOn= @("[WindowsFeature]HyperV",

                      "[xVHD]Vhd$Name")

    }

}

}

 

The key is to place the configuration in a file with the extension schema.psm1. You can take a look here to find out how to deploy a DSC Resource. Here is how it looks on my machine:

PS C:\Program Files\WindowsPowerShell\Modules\TestCompositeResource\DSCResources\xVirtualMachine> dir

    Directory: C:\Program Files\WindowsPowerShell\Modules\TestCompositeResource\DSCResources\xVirtualMachine

Mode                LastWriteTime     Length Name                                                                         

----                -------------     ------ ----                                                                         

-a---         2/25/2014   8:42 PM       2642 xVirtualMachine.psd1                                                         

-a---         2/25/2014   8:42 PM       2957 xVirtualMachine.schema.psm1   

Note: Take note of the .psd1 file (xVirtualMachine.psd1) inside the DSCResources folder. On my first attempt, I did not put that file in there and wasted some time trying to figure out where I was going wrong (yes, yes, yes a valid PowerShell module must have one out of .psd1, .psm1, .cdxml, .dll extension and it took me some time to figure out the fact that .schema.psm1 does not satisfy that condition).

Inside the .psd1 file, I have this line:

RootModule ='xVirtualMachine.schema.psm1'

 

That is it, you are done!

PS C:\> Get-DscResource -Name xVirtualMachine

ImplementedAs        Name                           Module                                                Properties                                      

-------------              ----                               ------                                                  ----------                                      

Composite               xVirtualMachine           TestCompositeResource                    {VMName, SwitchName, SwitchType, VhdParentPath...}

 

Your configuration shows up as a composite resource.

Let us now see how to use it:

configurationRenameVM

{

Import-DscResource-ModuleTestCompositeResource

 

Node localhost

{

    xVirtualMachine VM

    {

        VMName ="Test"

        SwitchName ="Internal"

        SwitchType ="Internal"

        VhdParentPath ="C:\Demo\Vhd\RTM.vhd"

        VHDPath ="C:\Demo\Vhd"

        VMStartupMemory =1024MB

        VMState ="Running"

    }

    }

   Node "192.168.10.1"

   {  

    xComputerName

    {

        Name="SQL01"

        DomainName="fourthcoffee.com"

    }                                                                                                                                                                                                                                                              

}

}

 

We have used the dynamic keyword Import-DscResource to make our composite resource type available in the configuration. The parameters of the composite resource become its properties. You can discover this in two ways, one way is to use the Get-DscResource cmdlet as above and the other is in ISE. I like the one in ISE since it does not require me to shift my focus to the command window and type in the cmdlet. You can take the cursor to the place where you have the name of the resource, and press CTRL+space. You can discover all the resources by using CTRL+Space after the configuration keyword as well. .You have to do it after Import-DscResource if importing custom resources.

Here is what ISE displays:

 

Untitled

 

Tab completion works on the names of the properties just like any other resource, isn’t that cool?

This way, I have a configuration, where I reused one of my existing configurations and added one more resource to the overall configuration of my machine. This configuration first creates a VM and then uses the xComputerResource to rename it. I can thus build upon my existing configurations as and when the need arises for more complex configurations.

 

 

 

 

Happy configuring!

Abhik Chatterjee

Windows PowerShell Developer

 

 


Viewing all articles
Browse latest Browse all 1519

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>