Select-Object omitting output from Select-String powershell - 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

Related

Find lines with specific characters recursively

I am searching for all lines with '.png' and '.jpg' strings in them across multiple folders of TXT files.
Tried:
(Get-ChildItem K:\FILES -Recurse -Include '*.txt') | ForEach-Object {
(Get-Content $_) -match '\.png','\.jpg' | out-file K:\Output.txt
}
but it does not output anything. No error either. I did something similar recently and it was working. I am scratching my head wondering what am I doing wrong here...
By placing your Out-File call inside the ForEach-Object script block, you're rewriting your output file in full for every input file, so that the last input file's results - which may be none - end up as the sole content of the file.
The immediate fix is to move the Out-File call to its own pipeline segment, so that it receives all output, across all files:
Get-ChildItem K:\FILES -Recurse -Include '*.txt' |
ForEach-Object {
#(Get-Content $_) -match '\.png', '\.jpg'
} |
Out-File K:\Output.txt
Note: Technically, adding -Append to your Out-File call inside the ForEach-Object could have worked too, but this approach should be avoided:
Every Out-File call must open and close the output file, which makes the operation much slower.
You need to ensure that there is no preexisting output file beforehand - otherwise you'll end up appending to that file's existing content.
However, consider speeding up your command with the help of Select-String:
Get-ChildItem K:\FILES -Recurse -Include '*.txt' |
Select-String -Pattern '\.png', '\.jpg' |
ForEach-Object Line |
Out-File K:\Output.txt
Note:
In PowerShell (Core) 7+, you can use the -Raw switch with Select-String, which directly outputs only the text of all matching lines, in which case ForEach-Object Line isn't needed.
If you want to prefix each matching line with the source file path:
Get-ChildItem K:\FILES -Recurse -Include '*.txt' |
Select-String -Pattern '\.png', '\.jpg' |
ForEach-Object { '{0}: {1}' -f $_.Path, $_.Line } |
Out-File K:\Output.txt
Note: If you pipe Select-String output directly (without -Raw or ForEach-Object Line) to Out-File (or if you use >), you'll get similar output (even including a character position), but with limitations:
You'll get a blank line at the top and the bottom of the file.
Long line texts may be truncated.
The reason is that Out-File and its virtual alias > send the for-display representations of the input objects to the output file, which aren't meant for programmatic processing and can incur truncation of the data based on the line length (number of columns) of the current console window.

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.

PowerShell output to file

I want to save the results from my PowerShell script to a text file. How can I do that?
GET-CHILDITEM -recurse C:\Enlistment\DAX\* | SELECT-STRING -pattern "BatchIL.start()"
Quite easily: :-)
Get-ChildItem C:\Enlistment\DAX -r | Select-String "BatchIL.start()" > results.txt
If you don't like the default Unicode encoding of results.txt you can also do it this way:
Get-ChildItem C:\Enlistment\DAX -r | Select-String "BatchIL.start()" |
Out-File results.txt -Encoding Ascii
Another way would be to use the "Add-Content" commandlet:
add-content <fileLocation> (CHILDITEM -recurse C:\Enlistment\DAX\* | SELECT-STRING -pattern "BatchIL.start()")
You can also use Join-Path in brackets () in the file location for something like this:
add-content (Join-Path $env:UserProfile "OutputFile.txt") (CHILDITEM -recurse C:\Enlistment\DAX\* | SELECT-STRING -pattern "BatchIL.start()")
That would make it a bit more portable if you need to run it on other machines and want to avoid hard coding. The above example will put the whole output of you command into "OutputFile.txt" into the root of the User's profile (for example C:\Users\Username in Windows Vista & 7)

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.

Listing full address path with Windows 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