After replace and function no correct output

Hi all,

I have a small problem with the output.

Example - The Output is ok:

cls
$a = "_old1_"
$b = "_old2_"
$test1 = "This is a first command"
$test2 = "This is a second command"

$string_1 = @"
<!doctype html>
<html>
<head>
</head>
<body>
$test1$a $test1$($a)10
$test2$b $test2$($b)20
</body>
</html>
"@

$SearchTxt1="$a"
$ReplaceTxt1="_new1_"
$string_1=$string_1.replace($SearchTxt1, $ReplaceTxt1)

$SearchTxt2="$b"
$ReplaceTxt2="_new2_"
$string_1=$string_1.replace($SearchTxt2, $ReplaceTxt2)

write-host a: $string_1

I can read (with new1 etc…)
This is a first command_new1_ This is a first command_new1_10
This is a second command_new2_ This is a second command_new2_20

With a function option I have a output problem.

cls
$a = "_old1_"
$b = "_old2_"
$test1 = "This is a first command"
$test2 = "This is a second command"

$string_1 = @"
<!doctype html>
<html>
<head>
</head>
<body>
"@

function test
{
# All test are false-...
#$test1$a $test1$($a)10
#$test2$a $test2$($b)20
#"`$test1$($a) `$test1$$($b)10,"
#"`$test2$($a) `$test1$$($b)10,"
#$test1$a $test1$($a)10
#$test2$b $test2$($b)20
#`$test1$($a) `$test1$$($b)10,
#`$test2$($a) `$test1$$($b)10,
#
}
$Output = test | foreach {"$_`r`n"}

$string_2 = @"
</body>
</html>
"@

$SearchTxt1="$a"
$ReplaceTxt1="_new1_"
$Output=$Output.replace($SearchTxt1, $ReplaceTxt1)

$SearchTxt2="$b"
$ReplaceTxt2="_new2_"
$Output=$Output.replace($SearchTxt2, $ReplaceTxt2)

write-host a: $Output

I have a little test with Invoke-Expression - No cance.

No output with:
This is a first command_new1_ This is a first command_new1_10
This is a second command_new2_ This is a second command_new2_20
only example:
$test2_new1_ $test1}(new2)10,

What can I do?
I hope for a little help.
Thanks.

Ps.
Background Info:
I would like to use the html as a template and fill the variables with other values ​​if necessary…

If the output is as expected - what’s your problem?

Hello Olaf
I must have a function and the function make not the output right

Just out of curiosity - why? :wink:

To avoid any problem you could run into with scopes you should not change values from variables outside of a function. Instead you should provide the both - the text you want to use as template and the values you want to have replaced inside the template as input to the function.

Maybe my question is too complicated.
I’ll reformulate again (sorry)
I have two functions:

function test
{
$a = "_old1_"
$b = "_old2_"
$test_ = "ok"
$test_+$($a)+$test_+$($b)+$test_
}
$Output = test

Output:
ok_old1_ok_old2_ok

and this:

function test2
{
	. test
	$SearchText1="$a"
	$ReplaceText1="new1"
	$SearchText2="$b"
	$ReplaceText2="new2"
	$Output=$Output -replace $SearchText1, $ReplaceText1
}
$check = test2

How do I get this output with function test2?
ok_new1_ok_new2_ok

No, it is not. But in my opinion the way you want to achieve your task is wrong. Instead of relying on external variables you should provide all needed items to the function and create the desired output inside the function - without the need of variables from an external scope.

Something like this:

function Out-FilledInTemplate{
    param (
        [string]$SearchText,
        [string]$SearchPattern,
        [string]$ReplaceText
    )
    $EscapedSearchPattern = [regex]::Escape($SearchPattern)
    foreach ($line in $SearchText) {
        $line -replace $EscapedSearchPattern, $ReplaceText
    }
}

Now we can use the samples of your initial question to define our variables:

$Variable1 = "This is a first command"
$Variable2 = "This is a second command"

$string = @"
<!doctype html>
<html>
<head>
</head>
<body>
###Variable1###
###Variable2###
</body>
</html>
"@

And since you have to seperate variables we simply call the function twice. Once with the original search text and once with the intermediate search text provided by the first run of the function:

$Output = Out-FilledInTemplate -SearchText $string -SearchPattern '###Variable1###' -ReplaceText $Variable1
$Output = Out-FilledInTemplate -SearchText $Output -SearchPattern '###Variable2###' -ReplaceText $Variable2

And when we output it …

$Output

… the result would be this:

<!doctype html>
<html>
<head>
</head>
<body>
This is a first command 
This is a second command
</body>
</html>
3 Likes

After about ca. 20 hours of this problem…
Olaf your suggestion is great!

For people and beginners (like me) who read along and need it. The masking of the variables is important these are used!

Example:

$test = "`$test1$($a) `$test1$$($b)10,"
$Variable1 = "$test"

Thanks, thanks again Olaf for your big help!

Have a nice weekend and stay healthy and everyone reading along!

I’m glad it helped. :+1:t4: :slightly_smiling_face:

I still don’t understand what you are actually trying to do, but I would strongly recommend for you to avoid such convoluted constructions if possible. They tend to be error-prone and unreliable.

If you want to use different variables to piece one together you can use a simple string concatenation with variables …

In the end something like this:

"$test1$a $test1$($a)10"

boils down into something like this:

$test1 + $a + ' ' + $test1 + $a + '10'

And in my opinion that’s way easier to read.

Another way of doing something like this is the -f operator.

$a = "_old1_"
$b = "_old2_"
'This is a first command {0} and This is a second command {1} {2}' -f $a, $b, 10

You can read more about here:

https://social.technet.microsoft.com/wiki/contents/articles/7855.powershell-using-the-f-format-operator.aspx

https://ss64.com/ps/syntax-f-operator.html

Thanks again Olaf.
What you write makes sense. 2 questions are still unclear to me.

Take this example:

$Variable1 = "This is a first command"
$Variable2 = "This is a second command"

$string = @"
<!doctype html>
<html>
<head>
</head>
<body>
###Variable1###
###Variable2###
</body>
</html>
"@

###Variable2### will be overwritten with “This is a second command” - OK
I write this:

$Variable2 = "`$xy_0_test1 `$xy_0_test1_10"+','

###Variable2### will be overwritten with: $xy_0_test1 $xy_0_test1_10,
but not edited

If I put direct into the scriptblock:

<body>
###Variable1###
$xy_0_test1 `$xy_0_test1_10"+',
</body>

the output is not $xy_0_test1 `$xy_0_test1_10"+',
the value is edited (processed command) and is also in the html

If I run the command outside of the script block and let it go out on the console, it is exactly as if I had written it in the script block. Only he is not edited.

I read that you can use Invoke-Expression / Invoke-Command for the string to command,
so I tried it like this:

$command =
@"
"`$xy_0_test1 `$xy_0_test1_10"+',"
"@
$Variable1 = [Scriptblock]::Create($command)
Invoke-Command -ScriptBlock $Variable1

but it doesn’t work.
Can it be because the Invoke-Expression is required?

You wrote:

$Output = Out-FilledInTemplate -SearchText $string -SearchPattern '###Variable1###' -ReplaceText $Variable1
$Output = Out-FilledInTemplate -SearchText $Output -SearchPattern '###Variable2###' -ReplaceText $Variable2

How can you actually specify more than 2 variables for overwriting here?

$Output = Out-FilledInTemplate -SearchText $string -SearchPattern '###Variable1###' -ReplaceText $Variable1
$Output = Out-FilledInTemplate -SearchText $string -SearchPattern '###Variable2###' -ReplaceText $Variable2
$Output = Out-FilledInTemplate -SearchText $string -SearchPattern '###Variable3###' -ReplaceText $Variable3
$Output = Out-FilledInTemplate -SearchText $string -SearchPattern '###Variable4###' -ReplaceText $Variable4
$Output = Out-FilledInTemplate -SearchText $Output -SearchPattern '###Variable5###' -ReplaceText $Variable5

Unfortunately that does not work.
It’s a pity that I have to bring this up again, but even after umpteen hours it’s all a big mystery

Hmmm … I feel like it gets more and more confused.

I understood that you have some variables you want to put into a template HTML code snippet, right? Because HTML does not know about PowerShell variables you don’t want to insert the variables itself into the HTML code. Instead you want to insert the content of the variables what is text or strings actually, right?

The HTML template should be prepared to match some certain criterias. At the places where you want to insert the final content you should have some unique strings you can recognize with simple text patterns and are unique enough not to get mistaken. I used ###Variable1### and ###Variable2### for this purpose.

$Output = Out-FilledInTemplate -SearchText $string -SearchPattern '###Variable1###' -ReplaceText $Variable1
$Output = Out-FilledInTemplate -SearchText $Output -SearchPattern '###Variable2###' -ReplaceText $Variable2

In the first line we create a new variable $Output unsing the original HTML template and the strings we want to replace.
In the second line we overwrite this newly created variable unsing itself and the second string as input.

If you want to replace more strings you will have to use the result of the last call of the function as the input for the next call of the function.

If you still struggle to understand you should try to explain what you want to do - not what you think you need to do to get it done. :wink:

You may share an example of the HTML code before and of the expected result.

You classified the matter correctly. My conclusion: I will change a part of the html and then use it as a template. I’ll leave the processing and delivery. That’s my conclusion after countless hours.
greeting