使用 REGEX 内容替换动态变量作为 Azure CD 管道 Powershell 任务中的变量

Replacing dynamic variables using REGEX content as variable in Azure CD Pipeline Powershell Task

我正在编写自定义 Powershell Azure CD 管道任务(用于 VM),其中我的 web.config 应该替换为管道变量。我的 Azure CD 管道变量中定义了 WebServiceAuditService 示例配置文件。

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

我有 powershell 脚本

$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, $() -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()

那么我如何才能动态替换“__”中的 Regex 内容并将该内容视为一个变量,该变量应该查看管道变量并在行中替换它:

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

您有什么理由不能使用市场中的替换代币任务吗?这是我替换配置文件中的值的首选。

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

如果您不能使用 Replace TokensTransform Web.config file,这里有一些东西:

根据 web.config 文件包含的事实:

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

您可以尝试以下方法:

# 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})

解释:

  • Get-Content中的-raw允许获取单个字符串中的所有字符

  • 我将 .NET RegEx class 与选项 Singleline 一起使用,以允许跨马车搜索 return 换行(可能没有必要)

  • 我将 Regex Replace 方法与 Scriptblock 在 PowerShell 中翻译的 MatchEvaluator Delegate 方法结合使用,以获取名称由 RegEx 捕获的变量。

它给出:

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