Leo Torres
asked on
Powershell search and replace
I have a directory that has 699 dtsx packages..
I need to iterate thru the files search for a string if it exists replace it..
The code below is what has made the most sense to me but it errors and does nothing
here is the error from code below
Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:12 char:16
+ (Get-Content <<<< $file.FullName) | Foreach-Object {$_ -replace $SearchString , $Replacement } | Set-Content $file.FullName
+ CategoryInfo : InvalidData: (:) [Get-Content], ParameterBindingValidation Exception
+ FullyQualifiedErrorId : ParameterArgumentValidatio nErrorNull NotAllowed ,Microsoft .PowerShel l.Commands .GetConten tCommand
I need to iterate thru the files search for a string if it exists replace it..
The code below is what has made the most sense to me but it errors and does nothing
here is the error from code below
Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:12 char:16
+ (Get-Content <<<< $file.FullName) | Foreach-Object {$_ -replace $SearchString , $Replacement } | Set-Content $file.FullName
+ CategoryInfo : InvalidData: (:) [Get-Content], ParameterBindingValidation
+ FullyQualifiedErrorId : ParameterArgumentValidatio
$RootString = "\\ServerHome\mydocs\ltorres\My Documents\SSIS_Packages\"
$SearchString = "192.168.0.249"
$Replacement = "ServerName"
$table = get-childitem $RootString -recurse -Filter *.dtsx | Select-String -pattern $SearchString
foreach($file in $table){
# $file.Name
$file.FullName
(Get-Content $file.FullName) | Foreach-Object {$_ -replace $SearchString , $Replacement } | Set-Content $file.FullName
}
ASKER
OK may take a few.. made change now running..
ASKER
Same error
Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:11 char:16
+ (Get-Content <<<< $file.FullName) | Foreach-Object {$_ -replace $SearchString , $Replacement } | Set-Content $file.FullName
+ CategoryInfo : InvalidData: (:) [Get-Content], ParameterBindingValidation Exception
+ FullyQualifiedErrorId : ParameterArgumentValidatio nErrorNull NotAllowed ,Microsoft .PowerShel l.Commands .GetConten tCommand
Get-Content : Cannot bind argument to parameter 'Path' because it is null.
At line:11 char:16
+ (Get-Content <<<< $file.FullName) | Foreach-Object {$_ -replace $SearchString , $Replacement } | Set-Content $file.FullName
+ CategoryInfo : InvalidData: (:) [Get-Content], ParameterBindingValidation
+ FullyQualifiedErrorId : ParameterArgumentValidatio
here:
cls
$RootString = "\\ServerHome\mydocs\ltorres\My Documents\SSIS_Packages\"
$SearchString = "192.168.0.249"
$Replacement = "ServerName"
if(test-path $RootString){
gci -Path $RootString -Recurse -Filter *.dtsx |
Where {$_ -IS [IO.FileInfo]} |
% {
sc $_.FullName ((gc $_.FullName) -replace $SearchString ,$Replacement )
}
}}
ASKER
I know whats going ong just dont know how to fix.
Follow along....
This Code returns results
$RootString = "\\pcna-02\mydocs\ltorres\ My Documents\SSIS_Packages\PC SQ-02_test \"
$SearchString = "192.168.0.249"
$Replacement = "PCSQ-02"
$table = gci -path $RootString -recurse -Filter *.dtsx
foreach($file in $table){
# $file.Name
$file.FullName
# (Get-Content $file.FullName) | Foreach-Object {$_ -replace $SearchString , $Replacement } | Set-Content $file.FullName
}
This code does not
$RootString = "\\pcna-02\mydocs\ltorres\ My Documents\SSIS_Packages\PC SQ-02_test \"
$SearchString = "192.168.0.249"
$Replacement = "PCSQ-02"
$table = gci -path $RootString -recurse -Filter *.dtsx | Select-String -pattern $SearchString
foreach($file in $table){
# $file.Name
$file.FullName
# (Get-Content $file.FullName) | Foreach-Object {$_ -replace $SearchString , $Replacement } | Set-Content $file.FullName
}
The Select-String -pattern $SearchString returns null thats why its says its a null path..
I know those values are in there
I used the code below to identify the occurrences.. So they do exists in somefiles
As for your code In think it worked let me check
Follow along....
This Code returns results
$RootString = "\\pcna-02\mydocs\ltorres\
$SearchString = "192.168.0.249"
$Replacement = "PCSQ-02"
$table = gci -path $RootString -recurse -Filter *.dtsx
foreach($file in $table){
# $file.Name
$file.FullName
# (Get-Content $file.FullName) | Foreach-Object {$_ -replace $SearchString , $Replacement } | Set-Content $file.FullName
}
This code does not
$RootString = "\\pcna-02\mydocs\ltorres\
$SearchString = "192.168.0.249"
$Replacement = "PCSQ-02"
$table = gci -path $RootString -recurse -Filter *.dtsx | Select-String -pattern $SearchString
foreach($file in $table){
# $file.Name
$file.FullName
# (Get-Content $file.FullName) | Foreach-Object {$_ -replace $SearchString , $Replacement } | Set-Content $file.FullName
}
The Select-String -pattern $SearchString returns null thats why its says its a null path..
I know those values are in there
I used the code below to identify the occurrences.. So they do exists in somefiles
$RootString = "\\Server\mydocs\ltorres\My Documents\SSIS_Packages\"
$SearchString = "192.168.0.249"
$FileName = Get-ChildItem $RootString -recurse | Select-String -pattern $SearchString | group path | select name
#$FileName | Out-GridView
$FileName | Out-file -width 300 -filepath "C:\Users\ltorres\Desktop\pshellOutPut.txt"
As for your code In think it worked let me check
ASKER
OK your code works, but I would still like to tweak it a little bit.
Looks like your code rewrites every single file.. I would only like to re-write files that have the string..
Here is what I mean if I did not make myself clear..
Once you change the file the date modified changes to now... but it will also change the date of files that did not have the string...
I would only like to change date Modified to files that actually had a replacement done that way it is easier for me to validate that the right files got modified..
Looks like your code rewrites every single file.. I would only like to re-write files that have the string..
Here is what I mean if I did not make myself clear..
Once you change the file the date modified changes to now... but it will also change the date of files that did not have the string...
I would only like to change date Modified to files that actually had a replacement done that way it is easier for me to validate that the right files got modified..
select-string indeed returns null if not found, so u need to check before pipeline the results to next one, thats why i didn't use this method.
using -replace is simpler since it replaces the string if found, if not moves to next file.
using -replace is simpler since it replaces the string if found, if not moves to next file.
ASKER
But isnt it looping thru all files it should return path if file has string.. Shouldn't it?
ASKER CERTIFIED SOLUTION
membership
Create a free account to see this answer
Signing up is free and takes 30 seconds. No credit card required.
ASKER
Wholee molee! it works!
Thank you I am going to close this question now
I will open new question can you help me now write the script to import the entire directory to a SQL Server?
I have already downloaded SQLPSX
Thank you I am going to close this question now
I will open new question can you help me now write the script to import the entire directory to a SQL Server?
I have already downloaded SQLPSX
sure mate, once u close this one add the url to your new question and ill help u through.
-sedgwick
-sedgwick
btw u dont need sqlpx, u can use .net sql classes to do whatever u need with sql db.
Doing Databases with PowerShell
Doing Databases with PowerShell
ASKER
On this here can I out put the paths that a replace done to a flat file?
ASKER
Oh I thought you did? I went to a conference and the the presenter was showing it off.. SO I figured it was the best thing to do.. but ok Cool.
do u mean importing ssis pavckage to sql or working with sql databases?
check this link:
http://sev17.com/2011/02/02/importing-and-exporting-ssis-packages-using-powershell/
check this link:
http://sev17.com/2011/02/02/importing-and-exporting-ssis-packages-using-powershell/
ASKER
HAHA funny thats was the page I read it from
ASKER
Excellent.. very fast had my solution less than 20 mins.. when I spent more than 4 hours last night tring to figure it out.. Man I really wished I had just posted it would have saved time!
Need help with similar one as well please help
https://www.experts-exchange.com/questions/28034193/Import-SSIS-packages-with-Powershell.html
Need help with similar one as well please help
https://www.experts-exchange.com/questions/28034193/Import-SSIS-packages-with-Powershell.html
select-string does not return $null at all.
select-string returns MatchInfo objects, not FileInfo ones. Hence you will have to use .Path instead of .FullName inside the loop. Your slightly improved code then is:
Also you should take care: Get-Content ... | Set-Content for the same file will often replace the file with an empty one. That is because in a pipeline, initialisation of Set-Content includes creating the file, and that is done at the very start of the pipeline. Either Get-Content retrieves the first line only, or Set-Content errors out as the file is still in use.
First retrieving the complete content, and then setting the file content, works.
select-string returns MatchInfo objects, not FileInfo ones. Hence you will have to use .Path instead of .FullName inside the loop. Your slightly improved code then is:
$RootString = "\\ServerHome\mydocs\ltorres\My Documents\SSIS_Packages\"
$SearchString = "192.168.0.249"
$Replacement = "ServerName"
$table = get-childitem $RootString -recurse -Filter *.dtsx | Select-String -pattern $SearchString -List
foreach ($file in $table)
{
$file.Path
Set-Content $file.Path ((Get-Content $file.Path) -replace $SearchString , $Replacement)
}
Note the change in the Select-String line, so we only get a single match per file instead of all matches, as we only need the filenames later, this is much better.Also you should take care: Get-Content ... | Set-Content for the same file will often replace the file with an empty one. That is because in a pipeline, initialisation of Set-Content includes creating the file, and that is done at the very start of the pipeline. Either Get-Content retrieves the first line only, or Set-Content errors out as the file is still in use.
First retrieving the complete content, and then setting the file content, works.
so great, its got pretty much everything u need to get u started, if u have specific question im here for you
$table = gci -path $RootString -recurse -Filter *.dtsx | Select-String -pattern $SearchString