0

I have a script "Deploy.PS1" that I am testing. In it I pass a few parameters:

param(
  [Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $param1,
  [Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $param2,
  [Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $param3,
  [Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $param4,
  [Parameter(Mandatory = $True,valueFromPipeline=$true)][String] $param5
  )

Currently when I run the script I must run the script and pass the parameters ".\Deploy.PS1 p1 p2 p3 p4 p5" and it runs fine. I am trying to create a .xml document that has the parameters already in it. For that, I found a thread that helped me out. Right now that .xml file looks like this:

<Deploy_Params>
<param>
    <param1>p1</param1>
    <param2>p2</param2>
    <param3>p3</param3>
    <param4>p4</param4>
    <param5>p5</param5>
</param>
<param>
    <param1>a1</param1>
    <param2>a2</param2>
    <param3>a3</param3>
    <param4>a4</param4>
    <param5>a5</param5>
</param>
<param>
    <param1>b1</param1>
    <param2>b2</param2>
    <param3>b3</param3>
    <param4>b4</param4>
    <param5>b5</param5>
</param>
</Deploy_Params>

What I need additional help with is passing different parameters depending on which environment I want to deploy to.

For example: I want to run Deploy.PS1 with either parameters "p1 p2 p3 p4 p5", "a1 a2 a3 a4 a5", or "b1 b2 b3 b4 b5". How would I specify in the Deploy.PS1 script or .xml file that I want to pass only the p, a, or b parameters depending on if I want to use either the p, a, or b environment?

(Note: I am new to Stack Overflow and programming in general, I have read several other threads on here that are similar to my question but still cannot seem to resolve my issue. Please bear with me, I can provide additional info or code if needed. Thanks)

1 Answer 1

1

If this were me I would do this a little differently. I would make a hashtable with keys that describe the environment, and values that contain the parameter set for those environments. Something like:

$ParamSets = @{
    'PreProduction' = [PSCustomObject]@{
        'param1' = 'p1'
        'param2' = 'p2'
        'param3' = 'p3'
        'param4' = 'p4'
        'param5' = 'p5'
    }
    'Production' = [PSCustomObject]@{
        'param1' = 'a1'
        'param2' = 'a2'
        'param3' = 'a3'
        'param4' = 'a4'
        'param5' = 'a5'
    }
    'Failover' = [PSCustomObject]@{
        'param1' = 'b1'
        'param2' = 'b2'
        'param3' = 'b3'
        'param4' = 'b4'
        'param5' = 'b5'
    }
}

Then if you want that as an XML file you can use Export-CliXml to save that as an XML file.

$ParamSets | Export-CliXml .\MyParams.xml

Now that you have those defined your Deploy.ps1 script can have its parameters changed just a little bit to accept an object, and change properties to parameters as such:

param(
  [Parameter(Mandatory = $True,valueFromPipelinebyPropertyName=$true)][String] $param1,
  [Parameter(Mandatory = $True,valueFromPipelinebyPropertyName=$true)][String] $param2,
  [Parameter(Mandatory = $True,valueFromPipelinebyPropertyName=$true)][String] $param3,
  [Parameter(Mandatory = $True,valueFromPipelinebyPropertyName=$true)][String] $param4,
  [Parameter(Mandatory = $True,valueFromPipelinebyPropertyName=$true)][String] $param5
  )

Then you can just pass whatever environment you want to the script:

$ParamSets['Failover'] | .\Deploy.ps1

Edit: Since you are having trouble, here's what I did to test. I started by creating the hashtable, and exporting it to a file, exactly as I describe above. Then I imported that file, and saved it as a new variable.

$MyConfig = Import-CliXml .\MyParams.xml

Then I made a simple script for testing:

param(
  [Parameter(Mandatory = $True,valueFromPipelinebyPropertyName=$true)][String] $param1,
  [Parameter(Mandatory = $True,valueFromPipelinebyPropertyName=$true)][String] $param2,
  [Parameter(Mandatory = $True,valueFromPipelinebyPropertyName=$true)][String] $param3,
  [Parameter(Mandatory = $True,valueFromPipelinebyPropertyName=$true)][String] $param4,
  [Parameter(Mandatory = $True,valueFromPipelinebyPropertyName=$true)][String] $param5
  )

"Param1: $param1"
"Param2: $param2"
"Param3: $param3"
"Param4: $param4"
"Param5: $param5"

I saved that to the current folder (C:\Temp, but that shouldn't matter) as test.ps1. I then passed the 'Failover' set to the script as such:

$MyConfig['Failover'] | .\test.ps1

The result was:

Param1: b1
Param2: b2
Param3: b3
Param4: b4
Param5: b5
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for the great response! I believe your answer was exactly what I was looking for. However, I made the changes you suggested and tried to test it out by temporarily deleting the code from Deploy.PS1 to only have the param(...$param1...$param2...etc) and then I wrote Write-Host $param1, Write-Host $param2..etc just to print the variables to check that the script could read the xml file. I'm pretty sure that's not the right way to check because it returned "Cannot index into a null array. At line:1 char:1", when I entered $ParamSets['Failover'] | .\Deploy.ps1. How should I properly test?
I updated the answer to try and explain usage better.
An alternative using parameter splatting. I could write this up as an answer - the comment formatting is poor. $ParamSets = @{ "A" = @{ Object = "AAA" }; "B" = @{ Object = "BBB" }; "C" = @{ Object = "CCC" }; }; $args = $ParamSets["A"]; Write-Host @args; # Write-Host is just an example. Can be your deploy.ps1.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.