Powershell length won't show up in output of Get-ChildItem - powershell

I'm trying this command in Windows 10 PowerShell:
Get-ChildItem -Recurse | select FullName,Length,LastAccessTime
The result only contains FullName , while LastAccessTime and Length is missing from output.
PowerShell ScreenShot
What am I doing wrong?

The problem is merely a display problem:
Because the paths among the output objects are long and FullName is the first property selected, the remaining properties (columns) don't print, because they cannot fit on the screen. However, the properties are present, and can be used programmatically.
Note: If the intent is to save to a file for later programmatic processing, you shouldn't use > / Out-File, which result in the same for-display formatting that you see in the console (terminal), because this formatting is meant only for the human observer.
For programmatic processing, use a structured data format such as CSV, as shown in Ashok Prasath's answer
Workarounds:
A quick-and-dirty workaround is to put the FullName property last, as Doug Maurer advises, which will make all properties (columns) show, though the FullName property values will be truncated (symbolized with …), and notably from the start of the paths:
# FullName is placed *last*
# Caveat: Paths will be truncated at the *end*.
Get-ChildItem -Recurse | select Length, LastAccessTime, FullName
If you don't mind switching to a list-based format, where each property value is represented on its own line prefixed by the property name, pipe to Format-List; note that overly long values will line-wrap:
Get-ChildItem -Recurse | select FullName,Length,LastAccessTime | Format-List
If you do want tabular output and don't mind line-wrapping in your output, you can pipe to Out-String with a -Width value large enough to fit all columns (note that Out-File also supports -Width):
Get-ChildItem -Recurse | select FullName,Length,LastAccessTime |
Out-String -Width 300
If you prefer horizontal scrolling to line wrapping, you could save the above to a file and open in it a text editor or, with a text editor such as Visual Studio Code, you can directly pipe the output to it:
# Opens the output directly in a new Visual Studio Code editor tab.
Get-ChildItem -Recurse | select FullName,Length,LastAccessTime |
Out-String -Width 300 | code -
Otherwise - if you do want to see tabular display in the console, in the exact column order specified and without line-wrapping - your only option is to truncate the FullName values so that all columns can fit; note that, for brevity, I am omitting the select (Select-Object) call in favor of direct use of Format-Table:
Get-ChildItem -Recurse |
Format-Table #{ e='FullName'; w=[Console]::WindowWidth-45; a='right'},
Length, LastAccessTime
Note how the column width (w entry, short for width) is based on the console window's with ([Console]::WindowWidth) minus 45 characters, to show as much of the FullName values as possible while still leaving room for the other two columns; also, to ensure that truncation (symbolized with … is applied to the start of the path - so that file/directory name is always displayed - the column is right-aligned (via the a entry, short for alignment); if you prefer truncation of the end of the path, omit the a entry (which then defaults to left).
For more information on this hashtable-based (#{ ... }) way of specifying so-called calculated properties for Format-Table, including a way to truncate from the start while also maintaining left alignment, see this answer.

This will work:
Get-ChildItem -Recurse | select FullName,Length,LastAccessTime | Export-Csv list.csv

Related

Generating hashcodes for specific filetypes only with Powershell

I'm a complete beginner to Powershell and scripting, and have been successfully been using Out-GridView to display some properties of the files I have in my directories using the following:
dir D:\Folder1\$type -Recurse | Select Fullname,Directory,LastWriteTime | out-gridview
where I specifiy the file extension with $type = "*.pdf" for instance.
I would also like to start comparing files using hashcodes so I have tried this command:
ls | Get-Filehash
However, I would like to have the hashcodes in the output window as a seperate column with out-gridview. Is this possible? I've tried
dir D:\Folder1\$type -Recurse | Select Fullname,Directory,LastWriteTime,Filehash | out-gridview
and
dir D:\Folder1\$type -Recurse | Select Fullname,Directory,LastWriteTime | Get-Filehash | out-gridview
Of course neither of these work.
Does anyone have a way of generating hashcodes for a specific file extension only?
Many thanks in advance!
You can do this by using a calculated property with Select-Object:
Get-ChildItem -Path 'D:\Folder1\$type'-Recurse |
Select-Object FullName,Directory,LastWriteTime, #{Label='FileHash'; Expression={(Get-Filehash -Path $_.FullName).Hash}} |
Out-GridView
You should see a new column in the grid view called 'Filehash' that contains the SHA256 hash of the file. You can chage the algorithm (to, say, MD5) using the -Algorithm parameter of Get-FileHash.
If you're wondering what this is doing, the important parts are:
#{...}
signifies a hashtable. e.g. a set of key-value pairs
label
is the key that defines what your property (column name) will be in the grid view
expression defines the code snippet ({...}) that calculates the value of this property
$_
signifies that we are working with the 'current' object (file in this case) passing along the pipeline

Select-String in Powershell only displaying part of the line from a text file, need it to display whole thing

I am trying to write a simple PS script to check large .txt log files for a short string: "SRVE0242I:"
$lines = Select-String -Path $logDir -Pattern "SRVE0242I:" | Select-Object line | Out-String
On output though, it only displays the following:
Line
[28/06/17 13:48:27:839] 00000020 ServletWrappe I SRVE0242I: [User] [User] [com_xxxxxxx_...
And not the full line. Is there a limit to how many characters this pulls? I can't find any info on any restrictions for the Select-String cmdlet. Is there a better way to do this so that I don't a) pull the heading "Line" in my list of lines (Don't really want to create table formatting for such a simple output) and b) get the whole line when I pull the info?
You are seeing it like this because it's displaying the Line property using the default Format-Table view and shortening it to the width of the console.
Do this instead:
$lines = Select-String -Path $logDir -Pattern "SRVE0242I:" | Select-Object -ExpandProperty line
This returns the value of the Line property as a string to the $lines variable. You don't need to use Out-String.
There is! Long story short, Select-Object is doing the truncating here. Here's one way to get the first untruncated line in a Select-String output
$(Select-String -Path $logDir -Pattern "SRVE0242I:")[0].Line
When you run into something like this, you can break down the individual steps to determine what's happening by piping things to Get-Member. Here's what's happening in the code above:
Select-String <# args #> | Get-Member
Select-String gives us a MatchInfo object, which (as you've correctly determined) has a 'Line' property. When run on it's own, Select-String will actually spit out all the information you're looking for, and will not truncate it by default (at least, on v6.0.0-beta). It does give you an array of MatchInfo objects if it finds multiple matches, so you have to index into that array if you just want the first one (like I did above).
Select-String <# args #> | Select-Object Line | Get-Member
Select-Object applies PowerShell's default formatting for objects which, in most cases, will truncate your output for easier viewing. For objects with a bunch of members (like a MatchInfo object), it will try to do one per line by default.
Select-String <# args #> | Select-Object Line | Out-String | Get-Member
Out-String directly translates it's input to a string. That is, rather than trying to cast something to a string or pull a string Property out of an object that's passed to it, it just changes whatever it receives into an object. In this case, it turns the already-formatted MatchInfo output into a string. Nothing happens to the output on the terminal, but Get-Member will reveal a String rather than a MatchInfo object.
It's not directly relevant here, but if you're interested in modifying the default formatting, it's governed by the types.ps1xml file.

Remove Ellipse from Table Output

I am trying to output to a text file the results of the powershell cmdlet Compare-Object The problem is I cannot eliminate the ellipse truncation.
The code below provides a table formatting definition variable which specifies a width of 1000 for the Path column. Yet the output file always truncates the Path column at 122 characters.
The Compare-Object cmdlet is comparing two ArrayLists which are just lists of file path strings from common folder paths between two servers.
What I am attempting to do is put the SideIndicator as the first column and the full path in the second. I do not want truncating of the file path.
$tableFormat = #{Expression={$_.SideIndicator};Label="Side Indicator";width=15}, #{Expression={$_.InputObject};Label="Path";width=1000}
$outputFilename = ($server1 + "_" + $server2 + "_FileCompare" + ".txt");
Compare-Object $Hive1FileArray $Hive2FileArray -IncludeEqual | Format-Table $tableFormat | Out-String | Out-File $outputFilename
I also tried removing Out-String from the pipe makes no difference.
What is going wrong here?
Thanks
Compare-Object $Hive1FileArray $Hive2FileArray -IncludeEqual |`
Format-Table $tableFormat -AutoSize |`
Out-String -Width 1000 |`
Out-File $outputFilename
Read
Get-Help 'Format-Table' -ShowWindow or its Online Version:
-AutoSize
Adjusts the column size and number of columns based on the width of
the data. By default, the column size and number are determined by the
view.
Get-Help 'Out-String' -ShowWindow or its Online Version:
-Width <Int32>
Specifies the number of characters in each line of output. Any
additional characters are truncated, not wrapped. If you omit this
parameter, the width is determined by the characteristics of the host
program. The default value for the Windows PowerShell console is 80
(characters).
Not much more to say not knowing Compare-Object cmdlet input objects…
I know this is a year old but another useful parameter of Format-Table is -wrap.
-Wrap []
Indicates that the cmdlet displays text that exceeds the column width on the next line. By default, text that exceeds the column width is truncated.
Required? false
Position? named
Default value False
Accept pipeline input? False
Accept wildcard characters? false

Whitespace and truncation with ellipsis on Select-Object

I'm trying to figure out why Select-Object
adds a lot of whitespace at the start of its output; and
truncates long properties with ellipsis.
Here's a repro of what I mean. Suppose you run these commands on C:\:
New-Item "MyTest" -Type Directory
cd MyTest
"Some very long lorem ipsum like text going into a certain file, bla bla bla and some more bla." | Out-File test.txt
Get-ChildItem | Select-String "text" | Select-Object LineNumber,Line
This will show output like this:
The ellipsis I can understand, that would be just the way the command ends up getting formatted when the result is written to the console host. However, the whitespace at the start still confuses me in this case.
Things get weirder for me though when I pipe the result to either clip or Out-File output.txt. I get similarly formatted output, with a lot of whitespace at the start and truncated Line properties.
Which command is causing this behavior, and how can I properly solve this? Most importantly: how can I get the full results into a file or onto my clipboard?
The default behavior of outputting the data is to use Format-Table without any modifiers, and the default behavior of Format-Table is to split the viewport into columns of equal width. This makes no assumption on the output width, and is faster in that the cmdlet doesn't need to process any string data from the pipeline prior to output.
To reduce the whitespace, you should use Format-Table -AutoSize as the output method. The -AutoSize switch first measures the widths of data, then outputs with regard to calculated width. If you need to not receive ellipsis and always display the full data set, add -Wrap switch to Format-Table, this way the value will be wrapped into more than a single line, but you can copy it via selecting a square area in Powershell window, just strip newlines off the clipped contents.
Get-ChildItem | Select-String "text" | Select-Object LineNumber,Line | Format-Table -AutoSize -Wrap
I'd say the best way to get the full output into a file would be to export the result as a CSV:
Get-ChildItem |
Select-String "text" |
Select-Object LineNumber,Line |
Export-Csv 'out.csv'
You could also build a string from the selected properties, which might be better for copying the data to the clipboard:
Get-ChildItem |
Select-String "text" |
ForEach-Object { '{0}:{1}' -f $_.LineNumber, $_.Line } |
Tee-Object 'out.txt' | clip
The behavior you observed is caused by the way PowerShell displays output. Basically, it looks at the first object and counts the properties. Objects with less than 5 properties are sent to Format-Table, otherwise to Format-List. The columns of tabular output are spread evenly across the available space. As #Vesper already mentioned you can enforce proportional column width by using the -AutoSize parameter, and wrapping of long lines by using the -Wrap parameter. Format-List wraps long strings by default.
See this blog post from Jeffrey Snover for more information.

how to autofit columns of csv from powershell

I have powershell script which connects to database & exports result in csv file.
However there is one column of date which size needs to be manually increased after opening csv file.
Do we have some command/property which will make columns AutoFit?
export-csv $OutFile -NoTypeInformation
I can't export excel instead CSV, cause I don't have excell installed on my machine.
This is what I have tried latest.
$objTable | Select Store,RegNo,Date,#{L="Amount";E={($_.Amount).PadLeft(50," ")}},TranCount
$objTable | export-csv $OutFile -NoTypeInformation
But even after adding PadLeft() output is same, Date column is short in width (showing ###, need to increase value manually)
When you say you need to increase one of your column sizes all the comments were right about how everything is formatted based on the object content. If you really need the cells to be a certain length you need to change the data before it is exported. Using the string methods .PadLeft() and .PadRight() I think you will get what you need.
Take this example using output from Get-ChildItem which uses a calculated property to pad the "column" so that all the data takes up at least 20 characters.
$path = "C:\temp"
$results = Get-ChildItem $path
$results | Select LastWriteTime,#{L="Name";E={($_.Name).PadLeft(20," ")}} | Export-CSV C:\temp\file.csv -NoTypeInformation
If that was then exported the output file would look like this (Notice the whitespace):
"LastWriteTime","Name"
"2/23/2015 7:33:55 PM"," folder1"
"2/23/2015 7:48:02 PM"," folder2"
"2/23/2015 7:48:02 PM"," Folder3"
"1/8/2015 10:37:45 PM"," logoutput"