0

I would like to have a PowerShell script loop through all .xml files in a directory and delete a matching .xml node. I also want to save a copy of the original .xml file.

I have this line of code which is able to change one file at a time. However, I would like to have a script that does this for all .xml files in a folder.

Get-Content \\network\path\file1.xml | Where-Object {$_ -notmatch '<NUGLET key="000000000000025"/>'} | Set-Content \\network\path\file1.new.xml

I've been working on this script but I'm at a point where it seems to be looking in my documents directory instead of in the network path.

Get-ChildItem \\network\path\ *.xml | 
ForEach-Object {
# Load the file's contents, delete string
(Get-Content $_) | Where-Object {$_ -notmatch '<NUGLET key="000000000000025"/>'} 
}

So why am I getting the following error?

Get-Content : Cannot find path 'C:\Users\username\Documents\file1.xml' because it does not exist.
At C:\Users\username\Local\Temp\4a8c4fc2-9af6-4c35-ab40-99d88cf67a86.ps1:5 char:14
+     (Get-Content <<<<  $_) | Where-Object {$_ -notmatch '<NUGLET key="000000000000025"/>'} 
+ CategoryInfo          : ObjectNotFound: (C:\Users\userna...-file1.xml:String) [Get-Content], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

And how can I modify the script to make a copy of the original xml file for backup purposes.

EDIT:

So with Nate's suggestion I am now using the following:

Get-ChildItem \\network\path\ *.xml | 
ForEach-Object {
# Load the file's contents, delete string
(Get-Content $_.fullname) | Where-Object {$_ -notmatch '<NUGLET key="000000000000025"/>' | Set-Content $_.fullname} 
}
0

1 Answer 1

2

The $_ in Get-Content $_ is only passing the file's name to Get-Content, not the full path, causing Get-Content to look for it in the current directory.

Try Get-Content $_.FullName instead.


The full script, including copying the file, would be something like:

Get-ChildItem \\network\path\ *.xml |
ForEach-Object {
    Copy-Item $_.FullName ((Join-Path $_.Directory $_.BaseName) + ".orig" + $_.Extension )
    (Get-Content $_.fullname) | Where-Object {$_ -notmatch '<NUGLET key="000000000000025"/>' | Set-Content $_.fullname} 
}
Sign up to request clarification or add additional context in comments.

3 Comments

That works. Thanks Nate! So now my only issue is that I would like to create a backup of all the files before they're replaced. Is there a way to integrate that into the pipeline... or perhaps maybe it is better to just write a new pipeline to create the backups before modifying them.
Your foreach-object can do a copy-item before doing the get-content.
I like saving backup files with the right extension if possible so programs still know how to open them. Change your copy line to this if you want that Copy-Item $_.FullName ((Join-Path $_.Directory $_.BaseName) + ".orig" + $_.Extension )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.