1

I'm writing custom Powershell Azure CD Pipeline task(for VM) where my web.config should be replaced with pipeline variables. I have sample config file as with WebService and AuditService defined in my Azure CD pipeline variables.

<client>
      <endpoint address="__WebService__" binding="basicHttpBinding" bindingConfiguration="ServiceSoap" contract="WebServiceClient.ServiceSoap" name="NLSService" />
      <endpoint address="__AuditService__" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_Audit" contract="AuditApiService.Audit" name="AuditService" />
    </client>

I have powershell script as

$zipfileName = "$(System.DefaultWorkingDirectory)\_WebService-CI\drop\Service.zip"
$fileToEdit = "web.config"
$reg = [regex] '__(.*?)__'


[Reflection.Assembly]::LoadWithPartialName("System.IO.Compression.FileSystem");
# Open zip and find the particular file (assumes only one inside the Zip file)
$zip =  [System.IO.Compression.ZipFile]::Open($zipfileName,"Update")
$configFile = $zip.Entries.Where({$_.name -like $fileToEdit})

# Read the contents of the file
$desiredFile = [System.IO.StreamReader]($configFile).Open()
$text = $desiredFile.ReadToEnd()
$desiredFile.Close()
$desiredFile.Dispose()


$text = $text -replace $reg, $(${1}) -join "`r`n"
    #update file with new content
$desiredFile = [System.IO.StreamWriter]($configFile).Open()
$desiredFile.BaseStream.SetLength(0)

# Insert the $text to the file and close
$desiredFile.Write($text)
$desiredFile.Flush()
$desiredFile.Close()

# Write the changes and close the zip file
$zip.Dispose()

So how do I can replace dynamically Regex content within "__" and treat that content as a variable which should look into pipeline variables and replace it in line :

$text = $text -replace $reg, $(${1}) -join "rn"

2
  • Heed the other answer. It very likely is a better approach. If you choose to stay on this one look at stackoverflow.com/questions/30666101/… which you can incorporate with a hashtable of replacements that would work here just fine. Commented Apr 28, 2020 at 3:46
  • Can't you use the Transform web.config Commented Apr 28, 2020 at 4:37

2 Answers 2

1

If you can't use Replace Tokens or Transform Web.config file, here is something :

According to the fact that web.config file contains :

<?xml version="1.0" encoding="utf-8"?>
<!--
  For ...
  -->
<configuration>
..
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="checkVatBinding" />
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="__WebService__" binding="basicHttpBinding" bindingConfiguration="ServiceSoap" contract="WebServiceClient.ServiceSoap" name="NLSService" />
      <endpoint address="__AuditService__" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_Audit" contract="AuditApiService.Audit" name="AuditService" />
    </client>
  </system.serviceModel>
</configuration>

You can try the following :

# Get all the file in a single var in spite of an array    
$data = Get-Content "D:\temp\web.config" -raw
$reg = [Regex]::new( '__(.*?)__', [System.Text.RegularExpressions.RegexOptions]::Singleline)
# Here are the vars with the final values
$WebService = "http://Aurillac.fr"
$AuditService = "http://Cantal.fr"
# Here is how to replace
$reg.replace($data, {param ($p);return (Get-Variable -Name $p.groups[1]).Value})

Explanations :

  • The -raw in Get-Content allows to get all the characters in a single string

  • I use the .NET RegEx class with the option Singleline to allow search accross cariage return line feed (perhaps not necessary)

  • I use the Regex Replace method with a MatchEvaluator Delegate method translated in PowerShell by a Scriptblock to get the variable with the name catched by the RegEx.

It gives :

<?xml version="1.0" encoding="utf-8"?>
<!--
  For ...
  -->
<configuration>
..
  <system.serviceModel>
    <bindings>
      <basicHttpBinding>
        <binding name="checkVatBinding" />
      </basicHttpBinding>
    </bindings>
    <client>
      <endpoint address="http://Aurillac.fr" binding="basicHttpBinding" bindingConfiguration="ServiceSoap" contract="WebServiceClient.ServiceSoap" name="NLSService" />
      <endpoint address="http://Cantal.fr" binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_Audit" contract="AuditApiService.Audit" name="AuditService" />
    </client>
  </system.serviceModel>
</configuration>
Sign up to request clarification or add additional context in comments.

Comments

0

Is there any reason you can't use the Replace Tokens task from the marketplace? This is my go-to for replacing values in config files.

https://marketplace.visualstudio.com/items?itemName=qetza.replacetokens

1 Comment

Replace tokens step(Target files is the SetParameters.xml path) does says, it replaced the tokens but when I deploy with WinRM IIS web app deployment as a next step on Virtual machine, I don't see them transformed.

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.