INI editing with PowerShell - powershell

My problem is I want to change paths in INI Files wich are saved in a folder and its subfolders.
The path of the folder is C:\New\Path\.
Example INI file:
notAIniText = C:\A\Path\notAIniText
maybeAIniText = C:\A\Path\maybeAIniText
AIniText = C:\A\Path\AIniText
I read some other questions about PSini but I don't want to just id because I want to use the script on multiple PC and I don't want to install every time PSIni.
I tried:
$mabyIni = "C:\New\Path"
$AiniFile = Get-ChildItem - Path "C:\New\Path\*" -Include *.ini -Recurse
foreach ($file in $AiniFile) {
Select-String -Path $file -AllMatches "C:\A\Path\" | ForEach-Opject {
$file -replace [regex]:Escape('C:\A\Path'), ('$mabyIni')
} | Set-Content $mabyIni -Include *.ini
But this doesn't work. I tried it with Get-Content too, but that also doesn't work.
Is there any way whitout PSini?

The code in your comment is close, but just has a few syntax issues. It starts out strong:
$mabyIni = "C:\New\Path"
$AiniFile = Get-ChildItem - Path "C:\New\Path*" -include *.ini -recurse
ForEach($file in $AiniFile) {
So far, so good. You define the new path, and you get a list of .ini files in the old path, then you start to loop through those files. This is all good code so far. Then things start to go astray.
I see that you are trying to get the contents of each .ini file, replace the string in question, and then output that file to the new path with this:
(Get-Content $AiniFile.PSPath) | ForEach-Object {
$file -replace [regex]:Escape('C:\A\Path'),('$mabyIni')
}| Set-Content $mabyIni -include *.ini
Unfortunately you're using the wrong variables, and adding in an extra ForEach loop in there as well. Let's start with the Get-Content line. At this point in the script you are looping through files, with each current file being represented by $file. So what you really want to get the contents of is $file, and not $AiniFile.PSPath.
(Get-Content $file)
Ok, that got us the contents of that file as an array of strings. Now, I'm guessing you weren't aware, but the -Replace operator works on arrays of strings. Perfect, we just so happen to have gotten an array of strings! Since the Get-Content command is wrapped in parenthesis it completes first, we can actually just tack on the -Replace command right after it.
(Get-Content $file) -replace [regex]:Escape('C:\A\Path'),$mabyIni
Your -replace command that you had was super close! In fact, I have to give you props for using [regex]::escape() in there. That's totally a pro move, well done! The only issue with it is the replacement string didn't need to be in parenthesis, and it was single quoted, so it would not have expanded the string and your .ini files would have all had a line like:
AIniText = $mabyIni\AIniText
Not exactly what you wanted I'm guessing, so I removed the parenthesis (they weren't hurting anything, but weren't helping either, so for cleanliness and simplicity I got rid of them), and I got rid of the single quotes ' as well since we really just want the string that's stored in that variable.
So now we're looping through files, reading the contents, replacing the old path with the new path, all that's left is to output the new .ini file. It looks like they're already in place, so we just use the existing path for the file, and set the content to the updated data.
(Get-Content $file) -replace [regex]:Escape('C:\A\Path'),$mabyIni | Set-Content -Path $File.FullName
Ok, done! You just have to close the ForEach loop, and run it.
$mabyIni = "C:\New\Path"
$AiniFile = Get-ChildItem - Path "C:\New\Path*" -include *.ini -recurse
ForEach($file in $AiniFile) {
(Get-Content $file) -replace [regex]:Escape('C:\A\Path'),$mabyIni | Set-Content -Path $File.FullName
}

Related

Powershell Help, Need to search for pattern/string and copy to new destination

I need Help to search a Network Share for 30+ Keywords and then to copy them to a new location...
I need to search for all type of docs... txt, doc, docx, pdfs, xls, xlsx, etc...
I have a CSV file of Keywords... the header is called Words
FYI - In the CSV file I have each word is not in quotes and some lines does have two words (do they need quotes? a few have a wildcard hous* (for houses, house, housing, etc..) does that need quotes?
example
street
1234 Elm St
Hous*
Do they need to be in Quotes?
It will wont search sub directories
This is what I have...
$CSV = Import-Csv -Path "C:\Users\Username\Documents\book1.csv"
foreach ($Words in $CSV)
{
Get-ChildItem \\Server\Groups$\HR-Dept -Recurse | Select-String -Pattern '$Words' -CaseSensitive -SimpleMatch | Copy-Item -Destination "C:\Users\Username\Desktop\Testing"
}
If you're intending to search by file name rather than content, -filter does the job quite efficiently.
$CSV = Import-Csv -Path "C:\Users\Username\Documents\book1.csv"
foreach ($Words in $CSV) {
# remove any extra "*" to avoid duplication later
$words = $words -replace "*"
# use -File to exclude directories from match. NB: PS version-dependent
Get-ChildItem \\Server\Groups$\HR-Dept -filter *$words* -Recurse -File | Copy-Item -Destination "C:\Users\Username\Desktop\Testing"
}
Spaces in your $words should be fine if your file names will have the same words and spaces.
I recommend trying the gci part first to see if you get the appropriate list of files before pipelining it to the Copy-Item. I haven't tested with a file path that includes a $, so that might be a consideration.

How to change a character in multiple .txt-files and save/ overwrite the existing file in Powershell

i'm really new to Powershell (2 days) and i am not good yet. :(
My Question ist:
How to change a character in multiple .txt-files and save/ overwrite the existing file in Powershell
My goal is to Copy multiple RAW-Files in a new folder, change the file-name from .tsv to .txt and at least change one character in these files from % to percent.
What i've got so far:
The first two steps are working, but i'm losing my mind with the third step (the replacement).
Copy-Item -Path "C:\Users\user\Desktop\RAW\*.tsv" -Destination "C:\Users\user\Desktop\TXT" -Recurse
Set-Location "C:\Users\User\Desktop\TXT"
Get-ChildItem *.tsv | Rename-Item -NewName { $_.Name -replace '.tsv','.txt' }
This works fine for me and now i am not able to get further ...
I am able to replace the "%" in one specific file, and save it in a new file, but this doesn't work for a batch processing with changing file-names.
$file = "A.txt"
Get-Content $file | Foreach {$_ -replace "%", "percent"} | Set-Content A_1.txt
It would be perfect, if "$file = "A.txt"" would be "all the files in this path with .txt" and
"Set-Content A_1.txt" would be "overwrite the existing file".
I hope someone will help me, thank you! <3 <3 <3
You already have some of the solution in your first code snippet, you need to iterate over the files again to perform the replace and save.
$txtFiles = Get-ChildItem -Name *.txt
ForEach ($file in $txtFiles) {
(Get-Content $file) | ForEach-Object {
$_ -replace '%','percent'
} | Set-Content $file
}
The first line adds all the text files to an array, the foreach loop iterates over the files of the array and grabs the content of the file and unloads it - that's the reason for the parenthesis, the Foreach-Object then iterates over the content of the file and saves it to the same file name as before.
If you skip the parentheses around Get-Content $file the file would still be loaded into memory and you would get an error message about not being able to save the file.

One Line PowerShell Batch Rename based on File Contents

I have a list of EDI text files with specific text in them. Currently in order for our custom scripting to convert them into an SQL table, we need to be able to see the X12 file type in the filename. Because we are using SQL script to get the files into tables this solution needs to be a one line solution. We have a definition table of client files which specify which field terminator and file types to look for so we will be later substitute those values into the one line solution to be executed individually. I am currently looking at Powershell (v.3) to do this for maximum present and future compatibility. Also, I am totally new to Powershell, and have based my script generation on posts in this forum.
Files example
t.text.oxf.20170815123456.out
t.text.oxf.20170815234567.out
t.text.oxf.20170815345678.out
t.text.oxf.20170815456789.out
Search strings to find within files: (To find EDI X12 file type uniquely, which may be duplicated within the same file n times)
ST*867
ST*846
ST~867
ST~846
ST|867
ST|846
Here is what I have so far which does not show itself doing anything with the whatif parameter:
(Get-ChildItem .\ -recurse | Select-String -pattern 'ST~867' -SimpleMatch).Path | Foreach -Begin {$i=1} -Process {Rename-Item -LiteralPath $_ -NewName ($_ -replace 'out$','867.out' -f $i++) -whatif}
The fist part:
(Get-ChildItem .\ -recurse | Select-String -pattern 'ST~867' -SimpleMatch).Path
Simply gets a list of paths that we need to input to be renamed
The second part after the | pipe:
Foreach -Begin {$i=1} -Process {Rename-Item -LiteralPath $_ -NewName ($_ -replace '\.out','.867.out' -f $i++) -whatif}
will supposedly loop through that list and rename the files adding the EDI type to the end of the file. I have tried 'out$','867.out' with no change.
Current Errors:
The first part shows duplicated path elements probably because there are multiple Transaction Set Headers in the files, is there any way to force it to be unique?
The command does not show any Errors (red text) but with the whatif parameter shows that it does not rename any files (tried running it without as well).
1) remove duplicates using -List switch in Select-String
2) you need to really pipe the objects into the for loop
Try this?
Select-String -Path .\*.out -pattern 'ST~867' -SimpleMatch -List | Select-Object Path | ForEach-Object { Rename-Item $_.path ($_.path -replace 'out$','867.out') }

PowerShell Script for updating a visual studio .vsxproj file

I have a small problem. I want to search a directory ,lets say D:\ . I want to find the files with the extention .vsxproj. Then I can do 2 things.
1. Access a node called project properties and change a single word amongst a string.
2. Or, just replace the word from the entire file without searching specific node. This is easier and would serve my purpose.
Now for the actual code. I have tried the following.
(Get-Content D:\data123.xml) |
Foreach-Object {$_ -replace "Wow32", "Wow3232" } |
Set-Content D:\data123.xml
This works for a single file if I know the name. But i have more than a hundred file.So I try something like this.I go to my D drive and do this:
$configFiles = Get-ChildItem . *.vsxproj -rec
foreach ($file in $configFiles)
{
(Get-Content $file.PSPath) |
Foreach-Object {$_ -replace "Wow32", "Wow3232" } |
Set-Content $file.PSPath
}
Please let me know how can I recurse over several file and change this one word. I have searched and looked at quite a few answers.None of them actually solves my problem. Please help.

Powershell replace special characters string in all files in directory path

I'm trying to create a 'find and replace' script for the website our company just acquired. Right now, I just want to use it to replace their address and phone number with
ours, but I'll likely need to customize it in the future to replace or update other stuffs.
So far, what I got is:
(Get-Content C:\Scripts\Test.txt) |
Foreach-Object {$_ -replace "\*", "#"} |
Set-Content C:\Scripts\Test.txt
which I got from The Scripting Guy :P
However, I need help customizing it. What I need it to do is:
Do it for all files in a directory and all sub-directories, not just one file. The website as far as I can tell is a collection of *.php files
Handle special characters that appear in some addresses, like copyrights (©) pipes (|) commas (,) and periods (.)
Here's the exact string I'm trying to replace (as it appears in the .php's):
<p>©Copyright 2012 GSS | 48009 Fremont Blvd., Fremont, CA 94538 USA</p>
Since this could be the first tool in my powershell toolbox, any explaining of what you're adding or changing would greatly help me understand what's going on.
Bonus points:
Any way to log which files were 'find-and-replace'ed?
My suggestion would be to use a ForEach loop. I don't see the need for a function in this case, just have the code in your ForEach loop. I would define a string to search for, and a string to replace with. When you perform the replace make sure that it is escaped. Something along these lines:
$TxtToFind = "<p>©Copyright 2012 GSS | 48009 Fremont Blvd., Fremont, CA 94538 USA</p>"
$UpdatedTxt = "<p>©Copyright 2014 | 1234 Somenew St., Houston, TX 77045 USA</p>"
$Logfile = "C:\Temp\FileUpdate.log"
ForEach($File in (GCI C:\WebRoot\ -Recurse)){
If($File|Select-String $TxtToFind -SimpleMatch -Quiet){
"Updating lines in $($File.FullName)" |Out-File $Logfile -append
$File|Select-String $TxtToFind -SimpleMatch -AllMatches|Select -ExpandProperty LineNumber -Unique|Out-File $Logfile -append
(GC $File.FullName) | %{$_ -replace [RegEx]::Escape($TxtToFind),$UpdatedTxt} | Set-Content $File.Fullname
}
}
You can leverage regular expression to find/replace the string you desire and the following script will iterate over all the php files within the provided folder recursively.
function ParseFile($file){
#Add logic to parse the file
Write-Host $file.FullName
}
$files = Get-ChildItem -recurse C:\Path -Filter *.php
foreach ($file in $files) {
ParseFile $file
}