M HYPE SPLASH
// news

Powershell regular expressing to match over multiple lines and replace a small part of what it finds in multiple documents

By Emma Payne

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

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

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