1

I am working on writing a PowerShell script to auto-upgrade the installed components. The config details of the file are stored in an XML file. Since there is interdependence in the variables the variables are defined as below.

<root>
    <variable name="APP_NAME", value="My App" />
    <variable name="INSTALL_PATH", value="some folder/${APP_NAME}" />
    <variable name="PRODUCT_HOME" value="${INSTALL_PATH}\productinfo\${APP_NAME}" />
<root>

When I read the XML file I want to get the value of $INSTALL_PATH as some folder/My App instead of some Folder/${APP-NAME}. And the value of APP_NAME changes after few steps and I have to re-parse the XML file again.

What would be the best way to do it?

I thought of reading the XML file and creating PowerShell variables for every variable in the XML file and when I have to re parse the XML file I will change the values of variables.

Is there any better way of achieving this?

4
  • You're effectively writing your own little domain language in XML. If you don't restrict this in any way (that is, it's legal for definitions to appear in any order) you have to go the full hog and construct a DAG and topologically sort it. I strongly recommend not doing that and allowing definitions in order only -- in which case, you can get away with parsing the file line by line and maintaining a hash of definitions that are substituted on every line. Commented Jul 10, 2017 at 10:39
  • 1
    An even lazier but possibly effective alternative is to request that the configuration be a PowerShell object, that you get from dot-sourcing a script somewhere. The benefit is that it allows people full flexibility in constructing the configuration. The drawback is that it allows people full flexibility in constructing the configuration -- it's code that needs to be maintained and understood and could possibly have security implications. Commented Jul 10, 2017 at 10:41
  • Last but not least (OK, I'm guessing I should have been spending my time writing an answer) ensure you're not reinventing the wheel in some way. There's (semi-)native support in PowerShell for maintaining components in the form of Desired State Configuration. It may be overkill for your purposes, or it may be a future-proof solution that beats rolling your own. Commented Jul 10, 2017 at 10:44
  • @JeroenMostert thanks for your inputs. Have checked Powershell DSC. It's overkill for my requirement. I am going with you second approach by combining below answer from Ansgar. Commented Jul 12, 2017 at 15:21

1 Answer 1

2

If the <variable> nodes are "in-order", i.e. each node uses only variables that were already defined in previous nodes, you could do something like this:

$xml.SelectNodes('//variable') | ForEach-Object {
  New-Variable -Name $_.name -Value $ExecutionContext.InvokeCommand.ExpandString($_.value)
}

Otherwise you'll have to define the variables first, and expand the nested variables in a second step:

$nodes = $xml.SelectNodes('//variable')

$nodes | ForEach-Object {
  New-Variable -Name $_.name -Value $_.value
}

$nodes | Select-Object -Expand name | ForEach-Object {
  $var = Get-Variable -Name $_
  $var.Value = $ExecutionContext.InvokeCommand.ExpandString($var.Value)
}

Note that using a hashtable instead of individual variables tends to make the handling much easier.

Sign up to request clarification or add additional context in comments.

Comments

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.