Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replacing contents of a text file using PowerShell

Tags:

powershell

I've looked all around this site and can't quite seem to find anything that fits my situation. Basically, I am trying to write an addition to the NETLOGON file that will replace text in a text file on all of our users' desktops. The current text is static across the board.

The text I want it changed to will be unique to each user. I want to change the current text (user1) to the users AD username (i.e. johnd, janed, etc.). I am using Windows Server 2008 R2 and all the workstations are Windows 7 Professional SP1 64 bit.

Here's what I have tried so far (with a few variables, which none have worked for one reason or the other):

gc c:\Users\%USERNAME%\desktop\VPN.txt' -replace "user1",$env:username | out-file c:\Users\%USERNAME%\desktop\VPN.txt

I didn't get an error, but it also did not go back to the normal "PS C:>" prompt, just ">>>" and the file did not change as anticipated.

like image 204
Timothy White Avatar asked Jun 23 '15 18:06

Timothy White


2 Answers

If that is how you have the code exactly then I suppose it is because you have an opening single quote without a closing one. You are still going to have two other problems and you have one answer in your code. The >>> is the line continuation characters because the parser knows that the code is not complete and giving you the option to continue with the code. If you were purposely coding a single line on multiple lines you would consider this a feature.

$path = "c:\Users\$($env:username)\desktop\VPN.txt" 
(Get-Content $path) -replace "user1",$env:username | out-file $path 
  • Closed the path in quotes and used a variable since you called the path twice.
  • %name% is used in command prompt. Environment variables in PowerShell use the $env: provider which you did you once in your snippet.
  • -replace is a regex replaced tool that can work against Get-Content but you need to capture the result in a sub expression first.
  • Secondly with -replace is for regex and your string is not regex based you could just use .Replace() as well.
  • Set-Content is generally preferred over Out-File for performance reasons.

All that being said...

you could also try something like this.

$path = "c:\Users\$($env:username)\desktop\VPN.txt"
(Get-Content $path).Replace("user1",$env:username) | Set-Content $path 

Do you want to only replace the first occurrence?

You could use a little regex here with a tweak in how you get the use Get-Content

$path = "c:\Users\$($env:username)\desktop\VPN.txt" 
(Get-Content $path | Out-String) -replace "(.*?)user1(.*)",('$1{0}$2' -f $env:username) | out-file $path 

Regex will match the entire file. There are two groups which it captures.

  1. (.*?) - Up until the first "user1"
  2. (.*) - Everything after that

Then we use the format operator to sandwich the new username in between those capture groups.

like image 153
Matt Avatar answered Sep 28 '22 14:09

Matt


Use:

(Get-Content $fileName) | % {
    if ($_.ReadCount -eq 1) {
        $_ -replace "$original", "$content"
    }
    else {
        $_
    }
} | Set-Content $fileName
like image 22
KP Singh Avatar answered Sep 28 '22 13:09

KP Singh