VMware Cloud Community
virtualhobbit
Enthusiast
Enthusiast
Jump to solution

Struggling with substitution

A couple of months back Luc helped me replace the value in a key pair using substitution. I'm now trying to replicate this but it isn't going so well.

I have two lines in a JSON file:

"[{{user `datastore_iso`}}] ISO/myISO.iso",

"[{{user `datastore_iso`}}] ISO/VMware-tools-windows-11.1.0-16036546.iso"

The aim is to substitute the value of myISO.iso with the value of $windowsISO

To isolate the line only containing the Windows ISO, I'm trying something along the lines of:

$windowsISO = "en-gb_windows_10_business_editions_version_1903_x64_dvd_4170a06f.iso"

(Get-Content -Path $packerJSON) -replace '(ISO/en-gb)(.+)',"$('$1')$windowsISO" | Set-Content -Path $packerJSON

But this obviously gives me a mangled:

"[{{user `datastore_iso`}}] ISO/en-gben-gb_windows_10_business_editions_version_1903_x64_dvd_4170a06f.iso

"[{{user `datastore_iso`}}] ISO/VMware-tools-windows-11.1.0-16036546.iso"

Which is also missing the trailing quote and comma.

Can anyone help me with the correct syntax to solve this?

Many thanks,

-Mark

Reply
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Oops, hadn't noticed the removal of the backtick.


The ExpandString eats the backtick (which is in fact a PS escape character).
The easiest solution is to escape the backtick before the ExpendString call (and yes, one uses a backtick to escape the backtick).

This, although not too elegant, should fix the issue.

$windowsISO = "en-gb_windows_10_business_editions_version_1903_x64_dvd_4170a06f.iso"

Get-Content -Path .\test.json |

ForEach-Object -Process {

    $ExecutionContext.InvokeCommand.ExpandString(($_ -replace '(.*)(en-gb.*.iso)(.*)','$1$windowsISO$3').Replace('`','``'))

} | Set-Content -Path .\test2.json


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

Reply
0 Kudos
7 Replies
LucD
Leadership
Leadership
Jump to solution

Can you try like this?

You can't use a variable in the substitute string, hence the ExpandString call after the replace operation.

$windowsISO = "en-gb_windows_10_business_editions_version_1903_x64_dvd_4170a06f.iso"

Get-Content -Path .\test.json |

ForEach-Object -Process {

    $ExecutionContext.InvokeCommand.ExpandString(($_ -replace '(.*)(myISO.iso)(.*)','$1$windowsISO$3'))

} | Set-Content -Path .\test2.json


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

virtualhobbit
Enthusiast
Enthusiast
Jump to solution

Getting there!

Ah, my bad. I forgot to explain the Windows ISO filename changes often. At some point it maybe myISO.iso, others yourISO.iso etc.

So what I need is to try and work out the value of the existing Windows ISO is and then overwrite it. The only thing that is common is that they all start with "en-gb" - that's the only thing I can use to differentiate between the Windows ISO and the VMware Tools one...

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

So that line might be something like

"[{{user `datastore_iso`}}] ISO/en-gb_myISO.iso",

or

"[{{user `datastore_iso`}}] ISO/en-gb_yourISO.iso",

But always with this layout (where the red part is fixed for the lines you target)?

"[{{user `datastore_iso`}}] ISO/en-gb_whatever.iso",


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
virtualhobbit
Enthusiast
Enthusiast
Jump to solution

Yes exactly that.

-Mark

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Ok, then a change in the 2nd capture group in the RegEx expression should do the trick

$windowsISO = "en-gb_windows_10_business_editions_version_1903_x64_dvd_4170a06f.iso"

Get-Content -Path .\test.json |

ForEach-Object -Process {

        $ExecutionContext.InvokeCommand.ExpandString(($_ -replace '(.*)(en-gb.*.iso)(.*)','$1$windowsISO$3'))

} | Set-Content -Path .\test2.json


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
virtualhobbit
Enthusiast
Enthusiast
Jump to solution

That looks bang on! Although, oddly, the output file (test2.json) has all the backquotes removed, so:

"vcenter_server":        "{{user `vcenter_server`}}",
"username":              "{{user `username`}}",
"password":              "{{user `password`}}",

Becomes:

"vcenter_server":        "{{user vcenter_server}}",
"username":              "{{user username}}",
"password":              "{{user password}}",

Which breaks my JSON 😞 Any ideas what might cause that?

-Mark

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Oops, hadn't noticed the removal of the backtick.


The ExpandString eats the backtick (which is in fact a PS escape character).
The easiest solution is to escape the backtick before the ExpendString call (and yes, one uses a backtick to escape the backtick).

This, although not too elegant, should fix the issue.

$windowsISO = "en-gb_windows_10_business_editions_version_1903_x64_dvd_4170a06f.iso"

Get-Content -Path .\test.json |

ForEach-Object -Process {

    $ExecutionContext.InvokeCommand.ExpandString(($_ -replace '(.*)(en-gb.*.iso)(.*)','$1$windowsISO$3').Replace('`','``'))

} | Set-Content -Path .\test2.json


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos