Just one line can not. If you need to do everything with a single Regex.Replace() method, you need to use the callback function as a replacement argument. By passing a match argument to this method, you must convert the date string to a DateTime object in order to correctly calculate the new date. Imagine the file is named 012017.txt , and if you just take 01 and subtract one, you get a zero month, which does not make sense.
Therefore, use the following approach (a slightly modified version of Tomalak ):
Get-ChildItem 'C:\1\*.txt' | Rename-Item -NewName { [Regex]::Replace($_.Name, '([0-9]{6})\.txt$', { try { [DateTime]::ParseExact($args[0].Groups[1].Value, "MMyyyy", $null).AddMonths(-1).ToString("MMyyyy") + ".txt" } catch { $args[0] } }) }
You cannot do without the callback function.
note
$args[0] is an integer match ( Match object)([0-9]{6})\.txt$ is a regular expression that captures 6 digits in the first exciting group, and then the dot and the text txt at the end of the line $ .[DateTime]::ParseExact - [DateTime]::ParseExact contents of the first exciting group ( $args[0].Groups[1].Value ) to the DateTime object in the format "MMyyyy", and .AddMonths(-1) subtracts 1, a .ToString("MMyyyy") converts the date to string again.
Test:
