Powershell Regular Expressing to Match over Multiple Lines and Replace a Small Part of What It Finds in Multiple Documents

I'm using powershell to get lots of different documents, find a pattern in them and replace that pattern with something else. I have this working, however I'm trying to expand one of the regular expressions to go over multiple lines to be more accurate now and I can't figure it out.

I'm trying to find a DOMAIN\UserName that's with in a certain element and replace it with NewDomain keeping the UserName after it what it originally was. E.g.

      <gMSA> <!--gManagedServiceAccount, can only be 15 Characters and needs to end with a '$'(Runs AppPool and Broker Services)-->
          DomainName\UserName
      </gMSA>

in Notepad++ this works:

Find:

(\<gMSA>.*?\t)D.*?(\\.*?\</gMSA>)

Replace:

$1NewDomain$2

However that doesn't work in powershell. This is what I'm tying to use to replace the text:

#Set Install set path
$ProfilePath = 'D:\Customers\Live'

#Update deployparameters in InstallSet Profiles
$DeployParam = Get-ChildItem $ProfilePath deployparameters.xml -rec
foreach ($file in $DeployParam)
{
    (Get-Content $file.PSPath) |
    Foreach-Object { $_ -replace '(<gMSA\>.*\t)D.*?(\\.*?</gMSA>)', '$1NewDomain$2' } |
    Set-Content $file.PSPath
}

I've tried a few things like \s after the * to make it go over multiple lines but I have no Joy.

Many thanks in advance.

3

2 Answers

Hummmm, interesting...

Continuing from my comment.

If you are certain that, the pattern is only in the passed string(s)

$MyString = @"
      <gMSA> <!--gManagedServiceAccount, can only be 15 Characters and needs to end with a '$'(Runs AppPool and Broker Services)-->
          DomainName\UserName
      </gMSA> 
      <gMSA> <!--gManagedServiceAccount, can only be 15 Characters and needs to end with a '$'(Runs AppPool and Broker Services)-->
          DomainName\UserName
      </gMSA>
      <gMSA> <!--gManagedServiceAccount, can only be 15 Characters and needs to end with a '$'(Runs AppPool and Broker Services)-->
          DomainName\UserName
      </gMSA>
"@ 

Then why not just ask for that.

[regex]::Matches($MyString, '(\w.*\\.*)')
# Results
<#
Groups   : {0, 1}
Success  : True
Name     : 0
Captures : {0}
Index    : 143
Length   : 20
Value    : DomainName\UserName

...
#>

[regex]::Matches($MyString, '(\w.*\\.*)').Value
# Results
<#
DomainName\UserName
DomainName\UserName
DomainName\UserName
#>

@TessellatingHeckler had the answer I needed. This is my working solution, simply adding both -Raw and (?s)

#Set Install set path
$ProfilePath = 'D:\Customers\Live'

#Update deployparameters in InstallSet Profiles
$DeployParam = Get-ChildItem $ProfilePath deployparameters.xml -rec
foreach ($file in $DeployParam)
{
    (Get-Content -Raw $file.PSPath) |
    Foreach-Object { $_ -replace '(?s)(<gMSA\>.*\t)D.*?(\\.*?</gMSA>)', '$1NewDomain$2' } |
    Set-Content $file.PSPath
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

James H. Sterling

James H. Sterling

Environmental Science & Climate Journalist

James Sterling reports on renewable energy developments, climate policy, ecological conservation, and green tech innovations around the globe.

Share this article
Twitter Facebook Pinterest