Using the pipeline is (potentially) memory-efficient, but slow.
To speed up processing:
avoid the pipeline, but that is only an option if your data fits into memory as a whole - which shouldn't be a problem with 20 MB files.
separately, use .NET framework types and their methods directly, which is usually faster than using cmdlets.
Applying these insights to your scenario (PSv3+ syntax):
[regex]::Matches(
[IO.File]::ReadAllText($PWD.ProviderPath + '/Test.log'),
'M\d{10}'
).Value | Select-Object -Unique
Note that for convenience the pipeline is still used, with Select-Object -Unique
, in order to get the unique occurrences, but the assumption is that the bulk of the processing - extracting the regex matches - is in the optimized part of the statement.