Listing full address path with Windows PowerShell - powershell

I have a small script that searches through all files in a directory using something like this;
Get-ChildItem $location -recurse | select-string -pattern $pattern | select-object Path, FileName, LineNumber > C:\test.txt
The problem I have is that the Path gets enshortened, like this;
C:\program files\new folder\new f...
How can I get it to display the full path?

Just so it's clear why you saw the truncating behavior, the default formatter picked is Format-Table which divies up the current host width into three equally sized columns and if the data is wider than that it gets truncated. Another way of doing this:
gci $location -r | select-string $pattern |
Format-Table Path, FileName, LineNumber -Auto |
Out-File C:\test.txt -width 512

Export-Csv
made it possible, thanks to BartekB and denty on freenode's #powershell

Related

Why is all the Powershell output not written to txt file

I have the following Powershell script that I am running in Powershell Core:
PS C:\> Get-ChildItem -Recurse -File -Filter *.pbix |
Sort-Object -Property LastAccessTime |
Select-object -Property Name, FullName, LastAccessTime, LastWriteTime -Last 10
>> files.txt
Opening the file files.txt there are no columns for LastAccessTime, LastWriteTime - why is this and how do I amend the script so they are included in the text file?
Two asides:
>> is a (virtual) alias for Out-File -Append; if the intent is not to append (to a preexisting file) but to only capture the current command's (entire) output, use just > / Out-File without -Append.
Out-File and therefore also > / >> capture the for-display representation of the input objects in a file, which is not suitable for subsequent programmatic processing. For the latter, use a cmdlet that produces structured output, such as Export-Csv.
That said, it's reasonable to expect Out-File to capture all for-display data, given that a file rather than the display is the target.
Regrettably, as of PowerShell [Core] v7.0, Out-File / > / >> are (still) sensitive to the console (terminal) window's width and capture only as much as would currently fit on the screen.
You can use Out-File with the -Width parameter to work around that:
Get-ChildItem -Recurse -File -Filter *.pbix |
Sort-Object -Property LastAccessTime |
Select-object -Property Name, FullName, LastAccessTime, LastWriteTime -Last 10 |
Out-File -Width ([int]::MaxValue-1) files.txt # Add -Append, if needed.
Note: As of v7.0, [int]::MaxValue-1 is seemingly the highest value accepted; [int]::MaxValue is quietly ignored. Also, be sure not to use such a high value in Windows PowerShell, where each output line is unconditionally right-space-padded to that length, which would result in excessively large files.

Select-Object omitting output from Select-String powershell

I wrote a Powershell script that looks for a string (such as ERROR) in log files and grabs those lines and outputs those lines to a file, for simpler reading and such (the industry I'm in has VERY large log files), but I'm having an issue. Before, when the (relevant) part of the code looked like this:
Select-String -Path "$file" -Pattern "$string" -CaseSensitive | Out-File -filepath $filepath
It would output the file path, the line number, and then the actual line, making for a very cluttered file. Well I only needed the line and the line number, so I did this:
Select-String -Path "$file" -Pattern "$string" -CaseSensitive | Select-Object -Property LineNumber,Line | Out-File -filepath $filepath
Which would return lines looking like this:
978 2017-07-10 10:46:11,288 ERROR [Music...
That is the line number then the line, with the line only totaling 35 characters.
Before I piped Select-String to Select-Object, the script would output the whole line, but now with Select-Object it omits some output. I tried adding -verbose parameters to both Select-String and Select-Object, but that did nothing.
Can you try this :
Select-String -Path "test.xml" -Pattern "ERROR" -CaseSensitive | ft -Property LineNumber,Line -Wrap | Out-File -FilePath c:\out.txt
The reason for your problem is screen buffer length(increasing powershell screen buffer width) ,you can change it as well but the above snippet is simpler and effective

Powershell Create CSV of files with "_lowRes.jpg" of a certain file size

I am trying to create a CSV file of all jpgs in a directory and its sub-directories that are above 100 KB and have the suffix "_lowRes.jpg".
Want to use Powershell.
Any help please?
This is pretty easy actually!
You'll do this with two separate filters, which PowerShell achieves via the Where-Object cmdlet. This cmdlet accepts comparisons in the format of {$_.PropertyName -eq "Something"} or PropertyName -eq "Something". The later format is only available on PowerShell v3 and up.
First, to filter to only files above 100KB.
Where-Object Length -ge 100KB
The second part, where the filename contains something.
Where-object Name -like "*lowRes.jpg*"
You could join them, but I would just pipe one into the other, like this.
dir *.jpg -Recurse | Where-Object Length -ge 100KB | Where-object Name -like "*lowRes.jpg*"
You might want to put the Name filtering first, because less files will have a certain name than be above or below a certain size. Depends on how your files are laid out.
Finally, pipe all of that into the Export-Csv cmdlet and bam, you're done!
you can do it simply like this :
Get-ChildItem "C:\temp" -Recurse -file -filter "*_lowRes.jpg" |
Where Length -ge 100KB | select fullname, Length |
export-csv "c:\temp\result.csv" -NoType
short version (for no purist) :
gci "C:\temp" -Rec -file -filter "*_lowRes.jpg" | ? L -le 100KB | select fu*, le* | epcsv "c:\temp\result.csv" -Not

Delete files containing string

How can I delete all files in a directory that contain a string using powershell?
I've tried something like
$list = get-childitem *.milk | select-string -pattern "fRating=2" | Format-Table Path
$list | foreach { rm $_.Path }
And that worked for some files but did not remove everything. I've tried other various things but nothing is working.
I can easily get the list of file names and can create an array with the path's only using
$lista = #(); foreach ($f in $list) { $lista += $f.Path; }
but can't seem to get any command (del, rm, or Remove-Item) to do anything. Just returns immediately without deleting the files or giving errors.
Thanks
First we can simplify your code as:
Get-ChildItem "*.milk" | Select-String -Pattern "fRating=2" | Select-Object -ExcludeProperty path | Remove-Item -Force -Confirm
The lack of action and errors might be addressable by one of two things. The Force parameter which:
Allows the cmdlet to remove items that cannot otherwise be changed,
such as hidden or read-only files or read-only aliases or variables.
I would aslo suggest that you run this script as administrator. Depending where these files are located you might not have permissions. If this is not the case or does not work please include the error you are getting.
Im going to guess the error is:
remove-item : Cannot remove item C:\temp\somefile.txt: The process cannot access the file 'C:\temp\somefile.txt'
because it is being used by another process.
Update
In testing, I was also getting a similar error. Upon research it looks like the Select-String cmd-let was holding onto the file preventing its deletion. Assumption based on i have never seen Get-ChildItem do this before. The solution in that case would be encase the first part of this in parentheses as a sub expression so it would process all the files before going through the pipe.
(Get-ChildItem | Select-String -Pattern "tes" | Select-Object -ExpandProperty path) | Remove-Item -Force -Confirm
Remove -Confirm if deemed required. It exists as a precaution so that you don't open up a new powershell in c:\windows\system32 and copy paste a remove-item cmdlet in there.
Another Update
[ and ] are wildcard searches in powershell in order to escape those in some cmdlets you use -Literalpath. Also Select-String can return multiple hits in files so we should use -Unique
(Get-ChildItem *.milk | Select-String -Pattern "fRating=2" | Select-Object -ExpandProperty path -Unique) | ForEach-Object{Remove-Item -Force -LiteralPath $_}
Why do you use select-string -pattern "fRating=2"? You would like to select all files with this name?
I think the Format-Table Path don't work. The command Get-ChildItem don't have a property called "Path".
Work this snipped for you?
$list = get-childitem *.milk | Where-Object -FilterScript {$_.Name -match "fRating=2"}
$list | foreach { rm $_.FullName }
The following code gets all files of type *.milk and puts them in $listA, then uses that list to get all the files that contain the string fRating=[01] and stores them in $listB. The files in $listB are deleted and then the number of files deleted versus the number of files that contained the match is displayed(they should be equal).
sv -name listA -value (Get-ChildItem *.milk); sv -name listB -value ($listA | Select-String -Pattern "fRating=[01]"); (($listB | Select-Object -ExpandProperty path) | ForEach-Object {Remove-Item -Force -LiteralPath $_}); (sv -name FCount -value ((Get-ChildItem *.milk).Count)); Write-Host -NoNewline Files Deleted ($listA.Count - $FCount)/($listB.Count)`n;
No need to complicate things:
1. $sourcePath = "\\path\to\the\file\"
2. Remove-Item "$sourcePath*whatever*"
I tried the answer, unfortunately, errors seems to always come up, however, I managed to create a solution to get this done:
Without using Get-ChilItem; You can use select-string directly to search for files matching a certain string, yes, this will return the filename:count:content ... etc, but, internally these have names that you can chose or omit, the one you need is the "filename" to do this pipe this into "select-object" choosing the "FileName" from the output.
So, to select all *.MSG files that has the pattern of "Subject: Webservices restarted", you can do the following:
Select-String -Path .*.MSG -Pattern 'Subject: WebServices Restarted'
-List | select-object Filename
Also, to remove these files on the fly, you could pip into a ForEach statement with the RM command as follows:
Select-String -Path .*.MSG -Pattern 'Subject: WebServices Restarted'
-List | select-object Filename | foreach { rm $_.FileName }
I tried this myself, works 100%.
I hope this helps

How do I remove carriage returns from text file using Powershell?

I'm outputting the contents of a directory to a txt file using the following command:
$SearchPath="c:\searchpath"
$Outpath="c:\outpath"
Get-ChildItem "$SearchPath" -Recurse | where {!$_.psiscontainer} | Format-Wide -Column 1'
| Out-File "$OutPath\Contents.txt" -Encoding ASCII -Width 200
What I end up with when I do this is a txt file with the information I need, but it adds numerous carriage returns I don't need, making the output harder to read.
This is what it looks like:
c:\searchpath\directory
name of file.txt
name of another file.txt
c:\searchpath\another directory
name of some file.txt
That makes a txt file that requires a lot of scrolling, but the actual information isn't that much, usually a lot less than a hundred lines.
I would like for it to look like:
c:\searchpath\directory
nameoffile.txt
c:\searchpath\another directory
another file.txt
This is what I've tried so far, not working
$configFiles=get-childitem "c:\outpath\*.txt" -rec
foreach ($file in $configFiles)
{
(Get-Content $file.PSPath) |
Foreach-Object {$_ -replace "'n", ""} |
Set-Content $file.PSPath
}
I've also tried 'r but both options leave the file unchanged.
Another attempt:
Select-String -Pattern "\w" -Path 'c:\outpath\contents.txt' | foreach {$_.line}'
| Set-Content -Path c:\outpath\contents2.txt
When I run that string without the Set-content at the end, it appears exactly as I need it in the ISE, but as soon as I add the Set-Content at the end, it once agains carriage returns where I don't need them.
Here's something interesting, if I create a text file with a few carriage returns and a few tabs, then if I use the same -replace script I've been using, but uset to replace the tabs, it works perfect. Butr and n do not work. It's almost as though it doesn't recognize them as escape characters. But if I addr and `n in the txt file then run the script, it still doesn't replace anything. Doesn't seem to know what to do with it.
Set-Content adds newlines by default. Replacing Set-Content by Out-File in your last attempt in your question will give you the file you want:
Select-String -Pattern "\w" -Path 'c:\outpath\contents.txt' | foreach {$_.line} |
Out-File -FilePath c:\outpath\contents2.txt
It's not 'r (apostrophe), it's a back tick: `r. That's the key above the tab key on the US keyboard layout. :)
You can simply avoid all those empty lines by using Select-Object -ExpandProperty Name:
Get-ChildItem "$SearchPath" -Recurse |
Where { !$_.PSIsContainer } |
Select-Object -ExpandProperty Name |
Out-File "$OutPath\Contents.txt" -Encoding ASCII -Width 200
... if you don't need the folder names.