PowerShell output to file - powershell

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)

Related

Searching Logs for Filename From List in a Directory w/ Powershell

I'm trying to search text file content in a log directory for matching file names that exist in another directory.
I know I can do a Get-ChildItem $Path -file -name and get a list returned. I also know how to perform a Get-Content ... | Select-String -Pattern
However, I don't know how to feed the file list to the -Pattern.
What I've tried without success:
# Delete all Files in C:\Data\Uploads older than 90 day(s)
$Path = "C:\the_path"
$LogPath = "C:\logs"
Get-Content $LogPath + "\*.log" | Select-String -Pattern (Get-ChildItem $Path -name)
But I know this is just a blind attempt because Get-ChildItem is returning an iterative and not a usable pattern.
How can I do what I'm attempting to do and that is take a list of file names and recursively search for them in a directory of log files? #wishingitwasgrep
Select-String essentially is PowerShell's implementation of grep. Except it can't recurse by itself. That's where Get-ChildItem comes into play.
Get-ChildItem -Path "$LogPath\*.log" -Recurse |
Select-String -Pattern (Get-ChildItem $Path -Name) -SimpleMatch
You can make the statement a little less verbose by using aliases as well as positional instead of named parameters (not recommended for use in scripts, though).
ls "$LogPath\*.log" -r | sls (ls $Path -n) -s
If you want a regular expression match instead of a simple string match remove the -SimpleMatch switch.
You're close, but here's something that should work:
#(Get-Content -Path C:\logs\*.log) |
Where-Object { $_ -in #(Get-ChildItem -Path C:\the_path -Name) }
Now you have a list of files.
How can I do what I'm attempting to do and that is take a list of file names and recursively search for them in a directory of log files?
$List = Get-Content -Path 'C:\LogList.txt'
$LogList = #(Get-ChildItem -Path 'C:\Logs' -Recurse |
Where-Object { $_.Name -in $List })
This assumes your LogList.txt has a newline separated list of log file names with an extension (such as MyLog.txt). $LogList will then have an array of System.IO.FileInfo objects which you can utilize to do whatever you want with these files. For example:
$LogList | Remove-Item

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

Searching for strings within file names using PowerShell

I've just started a new job, and we write reports for clients that are helpful for me to read to learn the ropes. I was trying to use PowerShell to pipe the titles into a text file, but unfortunately the company only standardised titles recently. This means that reports can be named anything, but having a look through the .docs, a lot of them have the word "report" in the title. Is there anyway that I could adapt my current commands to search more liberally for the word "report"?
Get-ChildItem -recurse -include *.doc | Out-File P:\report.txt
Most efficient version should be
Get-ChildItem -Path "your path here" -recurse -Filter *report*.doc | Out-File P:\report.txt
or if you only want the path in your file:
Get-ChildItem -Path "your path here" -recurse -Filter *report*.doc | Select -ExpandProperty Fullname | Out-File P:\report.txt
Try this:
Get-ChildItem -Path "your path here" -recurse -include *.doc | select-String "report" | out-file P:\report.txt

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.

Using PowerShell, read multiple known file names, append text of all files, create and write to one output file

I have five .sql files and know the name of each file. For this example, call them one.sql, two.sql, three.sql, four.sql and five.sql. I want to append the text of all files and create one file called master.sql. How do I do this in PowerShell? Feel free to post multiple answers to this problem because I am sure there are several ways to do this.
My attempt does not work and creates a file with several hundred thousand lines.
PS C:\sql> get-content '.\one.sql' | get-content '.\two.sql' | get-content '.\three.sql' | get-content '.\four.sql' | get-content '.\five.sql' | out-file -encoding UNICODE master.sql
Get-Content one.sql,two.sql,three.sql,four.sql,five.sql > master.sql
Note that > is equivalent to Out-File -Encoding Unicode. I only tend to use Out-File when I need to specify a different encoding.
There are some good answers here but if you have a whole lot of files and maybe you don't know all of the names this is what I came up with:
$vara = get-childitem -name "path"
$varb = foreach ($a in $vara) {gc "path\$a"}
example
$vara = get-childitem -name "c:\users\test"
$varb = foreach ($a in $vara) {gc "c:\users\test\$a"}
You can obviously pipe this directly into | add-content or whatever but I like to capture in variables so I can manipulate later on.
See if this works better
get-childitem "one.sql","two.sql","three.sql","four.sql","five.sql" | get-content | out-file -encoding UNICODE master.sql
I needed something similar, Chris Berry's post helped, but I think this is more efficient:
gci -name "*PathToFiles*" | gc > master.sql
The first part gci -name "*PathToFiles*" gets you your file list. This can be done with wildcards to just get your .sql files i.e. gci -name "\\share\folder\*.sql"
Then pipes to Get-Content and redirects the output to your master.sql file. As noted by Kieth Hill, you can use Out-File in place of > to better control your output if needed.
I think logical way of solving this is to use Add-Content
$files = Get-ChildItem '.\one.sql', '.\two.sql', '.\three.sql', '.\four.sql', '.\five.sql'
$files | foreach { Get-Content $_ | Add-Content '.\master.sql' -encoding UNICODE }
hovewer Get-Content is usually very slow when reading multiple very large files. If its your case this article could help: http://keithhill.spaces.live.com/blog/cns!5A8D2641E0963A97!756.entry
What about:
Get-Content .\one.sql,.\two.sql,.\three.sql,.\four.sql,.\five.sql | Set-Content .\master.sql
Here is how I do concatenate sql files from the Sql folder:
# Set the current location of the script to use relative path
Set-Location $PSScriptRoot
# Concatenate all the sql files
$concatSql = Get-Content -Path .\Sql\*.sql
# Write/overwrite sql to single file
Add-Content -Path concatFile.sql -Value $concatSql