1

I have one config.xml file for configuration and another (steps.xml) that acts as a guide and contains steps that generate scripts for execution.

config.xml:

<CFG>
    <Server>sql-server.com</Server>
    <Database>mySQLDB</Database>
</CFG>

steps.xml:

<Steps>
    <Step no="1">
        <script>
          USE [<v>$configs.CFG.Database</v>]
          UPDATE server_name SET name = '<v>$configs.CFG.Server</v>'
        </script>
    </Step>
</Steps>

I use <v></v> to tell my script where the variables are. I don't know if that is a good way to go about.

Then I run this script to parse the files:

$configFile = 'd:\ps\config.xml'
$stepsfile = 'd:\ps\steps.xml'
[xml]$steps = Get-Content -Path $stepsfile 
[xml]$configs = Get-Content -Path $configFile

$t = $Steps.Steps.Step[0].script.v

foreach ($var in $t){
    $exec = Invoke-Expression $var
    # use $exec to form a working script
}

I can resolve the actual information from configuration file but I am stuck at putting it back together. I know I can use this to get full script text:

$Steps.Steps.Step[0].script."#text"

But I am lost how can I pinpoint the location of variables to put resolved names back into it and form a usable script.

The output I'm trying to achieve should be:

USE [mySQLDB]
UPDATE server_name SET name = 'sql-server.com'
6
  • Are the configuration files your own design and you can change, or is that something you have to live with? My first impression, they are really tedious to parse and potentially insecure. Commented Feb 22, 2019 at 6:55
  • I can change the design of configurations as i go, any suggestions that would make this easier and safer to implement are more than welcome :) Commented Feb 22, 2019 at 7:05
  • 1
    Invoke-Expression leads to arbitrary code execution. When the data that you are parsing is going to be SQL, Invoke-Sql is, let's say, only a threat to your database instead the whole system. A good topic to study would be: parametrized sql queries. Commented Feb 22, 2019 at 7:20
  • I am just generating the queries, I will not execute them from this script. Commented Feb 22, 2019 at 7:31
  • Here's a malicious example: <Steps><Step no=1><script>Restart-Computer</script></Step></Steps>. To avoid that from happening, you should do string manipulation without evaluating it as code. Commented Feb 22, 2019 at 7:36

1 Answer 1

1

Invoke-Expression is considered harmful. Do not use it.

Instead of using nested XML nodes in the script body you could use any kind of placeholder that normally wouldn't appear in the SQL code (e.g. the names of the nodes from $configs in curly brackets: {Server} and {Database}) and then insert the values via string replacements.

foreach ($step in $steps.SelectNodes('//script')) {
    foreach ($cfg in $configs.SelectNodes('/CFG/*')) {
        $step.'#text' = $step.'#text'.Replace("{$($cfg.Name)}", $cfg.'#text')
    }
}
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.