7 Replies Latest reply on Jul 2, 2020 2:39 AM by LucD

    Struggling with substitution

    Mark Brookfield Enthusiast
    vExpert

      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

        • 1. Re: Struggling with substitution
          LucD Guru
          vExpertUser ModeratorsCommunity Warriors

          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: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
          1 person found this helpful
          • 2. Re: Struggling with substitution
            Mark Brookfield Enthusiast
            vExpert

            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...

            • 3. Re: Struggling with substitution
              LucD Guru
              vExpertCommunity WarriorsUser Moderators

              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: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
              • 4. Re: Struggling with substitution
                Mark Brookfield Enthusiast
                vExpert

                Yes exactly that.

                 

                 

                -Mark

                • 5. Re: Struggling with substitution
                  LucD Guru
                  User ModeratorsCommunity WarriorsvExpert

                  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: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz
                  • 6. Re: Struggling with substitution
                    Mark Brookfield Enthusiast
                    vExpert

                    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

                    • 7. Re: Struggling with substitution
                      LucD Guru
                      Community WarriorsvExpertUser Moderators

                      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: http://lucd.info | Twitter: @LucD22 | PowerCLI Reference co-author: http://tinyurl.com/hkn4glz