Trying to display the contents of a folder including the size, date modified, and length - powershell

This script is working so far, but I need the size to be in KB. It works as well, but when I call for a list of files it just outputs the KB size below the list, instead of within the list of itself.
$fileList = Get-ChildItem "E:\"
foreach($file in $fileList) {
ls $file | select -Property fullName, LastWriteTime, length
}
foreach($file in $fileList) {
Write-Host((Get-Item $file).length/1KB) | Sort-Object fullName, LastWriteTime, length
}
I want to see how I can get the KB size to populate the list under length, instead of the default file size being displayed.

You can Select-Object to get only the properties you want:
Get-ChildItem "E:\" | Select-Object fullName,LastWriteTime,Length
FullName LastWriteTime Length
-------- ------------- ------
C:\folder\cluster_totals.xlsx 14/12/2017 15:11:40 9382
C:\folder\IAG.xlsx 23/11/2017 11:05:12 13054
C:\folder\Offline.xml 30/10/2017 16:14:24 21503
And then use Calculated Properties to change the formatting of the Length property into KB.
Get-ChildItem "E:\" | Select-Object fullName,LastWriteTime,#{Name="KB";Expression={"{0:N0}" -f ($_.Length / 1KB)}}
Which will give you something like this:
FullName LastWriteTime KBytes
-------- ------------- ------
C:\folder\cluster_totals.xlsx 14/12/2017 15:11:40 9
C:\folder\IAG.xlsx 23/11/2017 11:05:12 13
C:\folder\Offline.xml 30/10/2017 16:14:24 21

Related

Powershell: How To Extract Binary File Attributes From Directory Listing

In PowerShell, I can get a nice list of files in descending sorted order using a filter:
$tt = gci -Path \\Munis2\musys_read\export_test\* -Include "ARLMA_*.csv" | sort LastWriteTime -Descending
PS H:\WindowsPowerShell\Scripts\ProductionScripts\Munis> $tt
Directory: \\Munis2\musys_read\export_test
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 03/04/2022 3:09 AM 25545520 ARLMA_20220304030027.csv
.
.
.
Then, I can get just the name of the file for the purposes of transferring that file to an FTP site.
PS H:\WindowsPowerShell\Scripts\ProductionScripts\Munis> $tt[0].Name
ARLMA_20220304030027.csv
How can I parse $tt[0].LastWriteTime
PS H:\WindowsPowerShell\Scripts\ProductionScripts\Munis> $tt[0].LastWriteTime
Friday, March 4, 2022 3:09:14 AM
into something that looks like yymmddhhmmss, or is there a way to get the binary time of the file the last time it was accessed?
The ToString() method can be used to format the date into a string. Are you sure that a two digit year is appropriate?
$DateResult = (Get-ChildItem -Path \\Munis2\musys_read\export_test\* -Include "ARLMA_*.csv" |
Sort-Object -Property LastWriteTime -Descending |
Select-Object -First 1).LastWriteTime.ToString('yyMMddHHmmss')

Running Powershell command Out-File in Azure Pipeline cuts lines

As part of a CI pipeline, I need to generate a list of all the files in the repository, including certain properties of them, and to Out-File it into a file. The command I use:
Get-ChildItem $Path -File -Recurse | Select-Object -Property LastWriteTime, #
{
label = "Size(KB)"
expr = { [string]::Format("{0:0.00}", $_.Length/1KB) }
}, FullName, <some_other_property> | Out-File $OutputFile
My problem is, that running this script from the command line gives the desired result.
However, running this during a Azure Pipeline build does 2 bad things:
cuts the lines in the FullName column when they are long:
LastWriteTime Size(KB) Name
------------ ------- ----
<some_date> <some size> ASomeWhatLong...
Doesn't display the rest of the properties such as <some_other_property>
If I turn FullName into Name it all goes OK, but I really need the FullName property.
Because I'm working in a Air-gapped environment I can't copy all the outputs and everything.
I've tried using the -Width flag for Out-File with no success.
I believe what's happening under the hood, ps uses the ToString() method of the object created which outputs it as the Format-Table cmdlet does. You get truncated properties because of the Window's size. To look at it you could use:
(Get-Host).ui.RawUI.WindowSize
Probably this is too small.
What I would suggest is the following:
Pipe the object into Format-Table
Get-ChildItem $Path -File -Recurse | Select-Object -Property LastWriteTime, #
{
label = "Size(KB)"
expr = { [string]::Format("{0:0.00}", $_.Length/1KB) }
}, FullName, <some_other_property> | Format-Table | Out-String | Out-File $OutputFile
This probably won't work as it is, but you could play with the Format-Table's properties like: -Wrap. By default it will allocate enough space for the first properties, and the last one it would try to 'fit' it, which might look as:
LastWriteTime Size(KB) Name
------------ ------- ----
<some_date> <some size> ASomeWhatLong
foobarfoobarfo
foobarfoobarfo
To solve this, you can use the -Property argument, which needs to be as:
$propertWidth = [int]((Get-Host).ui.RawUI.WindowSize.Width / 3)
$property = #(
#{ Expression = 'LastWriteTime'; Width = $propertWidth; },
#{ Expression = 'Size(KB)'; Width = $propertWidth; },
#{ Expression = 'FullName'; Width = $propertWidth; }
)
... | Format-Table -Property $property -Wrap | ...
If you don't mind having a JSON into your file, you could use:
Get-ChildItem $Path -File -Recurse | Select-Object -Property LastWriteTime, #
{
label = "Size(KB)"
expr = { [string]::Format("{0:0.00}", $_.Length/1KB) }
}, FullName, <some_other_property> | ConvertTo-Json | Out-File $OutputFile
But take into account that ConvertTo-Json has a default Depth of 2. This will also truncate your objects if you have nested objects. But as far as property lengths, it will do fine.

Get results of For-Each arrays and display in a table with column headers one line per results

I am trying to get a list of files and a count of the number of rows in each file displayed in a table consisting of two columns, Name and Lines.
I have tried using format table but I don't think the problem is with the format of the table and more to do with my results being separate results. See below
#Get a list of files in the filepath location
$files = Get-ChildItem $filepath
$files | ForEach-Object { $_ ; $_ | Get-Content | Measure-Object -Line} | Format-Table Name,Lines
Expected results
Name Lines
File A
9
File B
89
Actual Results
Name Lines
File A
9
File B
89
Another approach how to make a custom object like this: Using PowerShell's Calculated Properties:
$files | Select-Object -Property #{ N = 'Name' ; E = { $_.Name} },
#{ N = 'Lines'; E = { ($_ | Get-Content | Measure-Object -Line).Lines } }
Name Lines
---- -----
dotNetEnumClass.ps1 232
DotNetVersions.ps1 9
dotNETversionTable.ps1 64
Typically you would make a custom object like this, instead of outputting two different kinds of objects.
$files | ForEach-Object {
$lines = $_ | Get-Content | Measure-Object -Line
[pscustomobject]#{name = $_.name
lines = $lines.lines}
}
name lines
---- -----
rof.ps1 11
rof.ps1~ 7
wai.ps1 2
wai.ps1~ 1

Get all directories in directory that has a numeric name with powershell

I will start off by saying I am new to powershell...
I can get all the directories in a specified directory but I need to only get the directories that their names are numeric. Example:
1 - include
2 - include
3 - include
10 - include
LastFailed - exclude
I also will need to order them in sequential order for later processing.
Here is what I have so far:
$Dirs = Get-ChildItem -Path ..\..\..\builds -Attributes D
foreach($D in $Dirs)
{
Write-Host $D.Name
}
To get a list of just the folders that have numeric names, you can do this:
$Path = '..\..\..\builds'
$Dirs = Get-ChildItem -Path $Path -Attributes D |
Where-Object { $_.Name -match '^\d+$' } |
Sort-Object
$Dirs
This code above uses the Where-Object clause to filter out only the folders that have a numeric-only name.
It does this by using the -match operator and the regular expression ^\d+$ where:
`^` --> start at the beginning of the line
`\d` --> look for numeric values (0-9)
`+` --> there must be 1 or more numeric values present
`$` --> the end of the string
Instead of \d it could also have been written using [0-9]
The code ends with Sort-Object because the OP wants the list of folders sorted.
because we do not tell what property to sort on here, Powershell defaults to the Name.
The above will produce a list like:
Mode LastWriteTime Length Name
---- ------------- ------ ----
d----- 18-8-2018 16:13 1
d----- 18-8-2018 16:13 10
d----- 18-8-2018 16:13 2
d----- 18-8-2018 16:13 5
As you can see, the list is sorted by property Name, but.. the numbers were treated as strings, so '10' follows '1'.
What we most likely want to do here is to have the Sort-Object treat the names as real Numbers, not strings.
To fix that we add the Select-Object cmdlet in order to create our own objects with properties we need.
We can get standard properties of the DirInfo object that is coming through the pipeline, AND it is possible to create a new calculated property.
Here I add the calculated property called SortIndex that is simply the numeric value converted from the Name, which we will then use for the numeric sort:
$Dirs = Get-ChildItem -Path $Path -Attributes D |
Where-Object { $_.Name -match '^\d+$' } |
Select-Object -Property FullName, Name, LastWriteTime, #{Name = 'SortIndex'; Expression = {[int]$_.Name} } |
Sort-Object -Property SortIndex
$Dirs
Now it produces an array of objects that when printed to console looks like this:
FullName Name LastWriteTime SortIndex
-------- ---- ------------- ---------
D:\Temp\1 1 18-8-2018 16:13:22 1
D:\Temp\2 2 18-8-2018 16:13:25 2
D:\Temp\5 5 18-8-2018 16:13:28 5
D:\Temp\10 10 18-8-2018 16:13:31 10
Hope this helps.
You can utilize Where-Object to filter your collection:
$dirs = Get-ChildItem -Path ..\..\..\builds -Directory |
Where-Object -Property Name -Match '\d'
This operation uses regex to match the digit class.
If you meant you only want the directory names that start with a digit, you can use an anchor:
'^\d'
and lastly, you can sort them with Sort-Object:
$dirs = Get-ChildItem -Path ..\..\..\builds -Directory |
Where-Object -Property Name -Match '^\d' |
Sort-Object -Property Name
You can further enhance this sort by being explicit about the starting digit:
-Property {[int]($_.Name -split '[^\d]')[0]}
In this context, we're splitting on the first non-digit character and capturing the first fragment that was split off (which should be the number represented as a string, so we cast to an integer).

How to sort unique most recent file with Powershell

In my folder testtemp, I've got this files
PS C:\scripts\testtemp> Get-ChildItem | select name,lastwritetime
Name LastWriteTime
---- -------------
AABASSI.TMC049913.mapdrives.txt 27/02/2015 11:01:11
AABASSI.TMC049916.mapdrives.txt 02/03/2015 14:29:31
AABASSI.TMC050020.mapdrives.txt 26/11/2014 18:08:48
aabassi.TMS064845.mapdrives.txt 06/03/2015 14:14:50
aaboud.DLECLERCQPC.mapdrives.txt 03/04/2015 09:02:03
aaboud.FHP030221.mapdrives.txt 30/12/2014 15:05:04
aaboud.FHP045846.mapdrives.txt 18/11/2014 10:15:05
Aaccus.FHP047416.mapdrives.txt 25/07/2014 08:16:19
AADRIENVASSE.PHP049659.mapdrives.txt 02/10/2015 14:18:15
AADRIENVASSE.RBXXAMET10.mapdrives.txt 06/08/2015 10:33:33
aagostini.FHP047082.mapdrives.txt 05/03/2015 13:38:07
aagricole.PHP053341.mapdrives.txt 30/03/2015 15:09:03
aagricole.TMS064745.mapdrives.txt 25/03/2015 12:32:06
aaiad.PHP053346.mapdrives.txt 09/06/2015 09:18:58
aaissaoui.FHP029908.mapdrives.txt 28/08/2014 14:41:09
aaissaoui.FHP030685.mapdrives.txt 15/11/2014 18:27:55
aaissaoui.FHP048791.mapdrives.txt 12/09/2014 10:22:19
aaissaoui.FHP048963.mapdrives.txt 06/11/2014 09:55:00
I just want to get only the most recent file for each login (for exemple AABASSi is a login)
If I try sort-object lastwritetime -descending and sort-object -property name -unique, there is a problem because for exemple, AAISSAOUI 28/08/2014 14:41:09 is NOT the most recent file :
Get-ChildItem | select #{l="name";e={($_.name.split(".")[0]).ToUpper()}},lastwritetime | Sort-Object lastwritetime -Descending | Sort-Object -Property name -Unique
name LastWriteTime
---- -------------
AABASSI 26/11/2014 18:08:48
AABOUD 30/12/2014 15:05:04
AACCUS 25/07/2014 08:16:19
AADRIENVASSE 02/10/2015 14:18:15
AAGOSTINI 05/03/2015 13:38:07
AAGRICOLE 25/03/2015 12:32:06
AAIAD 09/06/2015 09:18:58
AAISSAOUI 28/08/2014 14:41:09
Is ther a simple solution for my problem ?
The reason you're having the issue with sorting is that you sort it by the property you actually want, and then you sort it again by a different property (Name). Instead, group the objects by the string before the ".", and select only the newest object from each group. #PetSerAl's method is great:
Get-ChildItem | Group-Object {$_.Name.Split(".")[0]} | % {
$_.Group | Sort-Object LastWriteTime -Descending | Select-Object -First 1
}