You don't need multiple ForEach-Object loops. For implementing -type f you need to filter for files, though. In PowerShell v3 and newer you'd do that with the parameter -File. In earlier versions you'd have to add a Where-Object {$_.PSIsContainer} to the pipeline.
Something like this should do what you want:
Get-ChildItem -Recurse -File | ForEach-Object {
(Get-Content $_.FullName) -replace 'string1', 'string2' |
Set-Content $_.FullName
$_.FullName
}
or (for short):
ls -r -File | %{(gc $_.FullName) -replace 'string1', 'string2' | sc $_.FullName; $_.FullName}
Note that Set-Content automatically saves the file with ASCII encoding (well, technically it's an ANSI encoding, but let's ignore that since Microsoft has the bad habit of using the two terms synonymous anyway), so you may need to specify a different encoding if you don't want that.
Note also that if you have non-text files you may want to exclude them from processing, since Get-Content and Set-Content do specific things when reading/writing files that are undesirable for binary files (Get-Content without the parameter -Raw or -Encoding Byte splits the input at newlines, Set-Content appends a newline (CR-LF) to the end of each input string before writing them to the output file).