Home > Software design >  Find file using partial name then string replace powershell
Find file using partial name then string replace powershell

Time:10-05

This feels like it should be straightforward, however, I am coming a bit undone. I want to replace text in a file so that people's VPN configs point to a new address. As each config file is the user's name I first go to the uniform VPN path in windows, then find the VPN config file. From here it should just be a case of getting that content and then replacing it. So my thinking was to get a path variable which will go to the OpenVPN config folder. From there find where the .ovpn file is kept and get the name of that file. String replace the text in that file and overwrite said file. I have managed to successfully do this with manually entering my own file / config paths, I just want to automate it for the staff we have otherwise that's a lot of manual edits I need to do.

I'm aware that this will also need to be ran as admin.

This is what I have currently got.

$path="C:\Program Files\OpenVPN\config\"
$ConfigFile = Get-ChildItem -Path $path -Recurse -Filter "*.ovpn" | select name
(Get-Content $ConfigFile) -replace 'x.x.x.x', 'y.y.y.y' | Set-Content $ConfigFile

CodePudding user response:

select name gives you an object with a single name property that contains only the file name without folder path. Use select -expand fullname instead to get the value of the full file path.

Also there might be multiple .ovpn files, so you have to write a loop to process them all. In this case it will be easier to use property access using . operator instead of select -expand though. ;-)

Get-ChildItem -Path $path -Recurse -File -Filter '*.ovpn' | ForEach-Object {
    (Get-Content $_.Fullname) -replace 'x\.x\.x\.x', 'y.y.y.y' | Set-Content $_.Fullname
}
  • As we expect Get-ChildItem to only return files, I've added the -File switch. Although it may look like the filter *.ovpn is enough, there could be folders named like *.ovpn (admittedly unlikely, but better safe than sorry).
  • As Theo noted, -replace uses RegEx and the dot has special meaning in a RegEx pattern. To specify a dot literally, it has to be backslash-escaped. This isn't necessary in the replacement pattern (it does have other special characters like $, which isn't relevant here).
  • Related