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$2However 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.
32 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
}