Powershell - How to add File Size to an existing Query - powershell

A user provided me with this query;
Get-ChildItem -Filter '*.*' -recurse -File |
Select-Object FullName, LastWriteTime |
Sort-Object LastWriteTime -Descending |
Export-Csv '!2023.01.24.AllFiles.csv' -NoTypeInformation -UseCulture
How can I add the file size to the last column?
I still need to sort by the LastWriteTime.
FYI: Powershell Noob here...
Looking around it seems that Length is my answer but I keep breaking the applet... :-/
Tried variations of this:
Select-Object -property Length
Select-Object Length
Originally I was hoping to add switches to this command
(gci -filter *.* -recurse).FullName > !!2023.01.24.AllFiles.txt

You're correct that you can get the file size by pulling the length property; e.g.
Get-ChildItem -Filter '*.*' -recurse -File |
Select-Object FullName, LastWriteTime, Length |
Sort-Object LastWriteTime -Descending |
Export-Csv '!2023.01.24.AllFiles.csv' -NoTypeInformation -UseCulture
The Sort-Object doesn't change the content of the records, just their order; so that won't be affected by, and won't affect, the inclusion of the Length property.
If you want the length in KB, MB or GB you can have PowerShell convert it for you; e.g.
Get-ChildItem -Filter '*.*' -recurse -File |
Select-Object FullName, LastWriteTime, #{Name='FileSizeInKb';Expression={$_.Length/1KB}} |
Sort-Object LastWriteTime -Descending |
Export-Csv '!2023.01.24.AllFiles.csv' -NoTypeInformation -UseCulture
Per question in comments, to round the number and include KB in the resulting value:
Get-ChildItem -Filter '*.*' -recurse -File |
Select-Object FullName, LastWriteTime, #{Name='FileSizeInKb';Expression={"$([int]($_.Length/1KB)) KB"}} |
Sort-Object LastWriteTime -Descending |
Export-Csv '!2023.01.24.AllFiles.csv' -NoTypeInformation -UseCulture

Following the documentation example, to get the size in KB:
> $size = #{label="Size(KB)";expression={$_.length/1KB}}
> Get-ChildItem -Filter '*.*' -recurse -File |
Select-Object FullName, LastWriteTime, $size |
Sort-Object LastWriteTime -Descending |
Export-Csv '!2023.01.24.AllFiles.csv' -NoTypeInformation -UseCulture

Related

Get LastAccessTime for each subfolders in a csv folder list

I have a csv ($HomeDir) file like this:
Users,Comments,HomeDir
user1,account1,c:\folder1
user2,account2,c:\folder2
user3,account3,c:\folder3
I get succesfully LastAccessTime for each subfolder in 'HomeDir' column with this code:
$csv = Import-Csv $HomeDir
foreach ($folder in $csv.HomeDir) {
Get-ChildItem $folder -ErrorAction SilentlyContinue |
? {$_.PSIsContainer -eq "True"} |
Select-Object FullName, #{Name='LastAccessTime'; Expression={$_.LastAccessTime.ToString('yyyyMMdd')}} |
Sort-Object -Descending -Property LastAccessTime |
Export-Csv $newcsv -NoTypeInformation -Append
}
The result of $newcsv is:
"FullName","LastAccessTime"
"c:\folder1\Sub1","20201223"
"c:\folder1\Sub1a","20201223"
"c:\folder1\Sub1b","20201223"
"c:\folder2\Sub2","20201218"
"c:\folder2\Sub2a","20201218"
"c:\folder3\Sub3","20201212"
"c:\folder3\Sub3a","20201215"
"c:\folder3\Sub3b","20181215"
"c:\folder3\Sub3c","20201011"
The questions is: is there a way to assign the related User based on corresponding 'Users' column?
It would also be enough for me to get an output like this
"Users","FullName","LastAccessTime"
"user1","c:\felder1\Sub1","20201223"
"user1","c:\folder1\Sub1a","20201223"
"user1","c:\folder1\Sub1b","20201223"
"user2","c:\folder2\Sub2","20201218"
"user2","c:\folder2\Sub2a","20201218"
"user3","c:\folder3\Sub3","20201212"
"user3","c:\folder3\Sub3a","20201215"
"user3","c:\folder3\Sub3b","20181215"
"user3","c:\folder3\Sub3c","20201011"
Thanks in advance
Instead of pulling the HomeDir property out before the loop, just reference it inside the loop and add the Users property to your Fullname and LastAccessTime properties.
$properties = #{Name='User'; Expression={$user}},
'FullName',
#{Name='LastAccessTime'; Expression={$_.LastAccessTime.ToString('yyyyMMdd')}}
Import-Csv $HomeDir | ForEach-Object {
$user = $_.users
Get-ChildItem $_.HomeDir -ErrorAction SilentlyContinue |
Where-Object {$_.PSIsContainer -eq "True"} |
Select-Object $properties |
Sort-Object -Descending -Property LastAccessTime
} | Export-Csv $newcsv -NoTypeInformation
To make it easier to read I put the properties in a variable beforehand. Also, if you are on powershell version 3 or higher you can use -Directory parameter in lieu of $_.PSIsContainer -eq $true. Finally, if you use the Foreach-Object instead of a foreach loop you can pipe to export and not have to use -Append opening and closing the file several times.
$properties = #{Name='User'; Expression={$user}},
'FullName',
#{Name='LastAccessTime'; Expression={$_.LastAccessTime.ToString('yyyyMMdd')}}
Import-Csv $HomeDir | ForEach-Object {
$user = $_.users
Get-ChildItem $_.HomeDir -Directory -ErrorAction SilentlyContinue |
Select-Object $properties | Sort-Object -Descending -Property LastAccessTime
} | Export-Csv $newcsv -NoTypeInformation
I propose my version.
$HomeDir="c:\temp\input.csv"
$newcsv="c:\temp\output.csv"
Import-Csv $HomeDir | %{
#save user name
$User=$_.Users
Get-ChildItem $_.HomeDir -ErrorAction SilentlyContinue -Directory |
Sort LastAccessTime -Descending |
select #{N='Users'; E={$User}}, FullName, #{N='LastAccessTime'; E={$_.LastAccessTime.ToString('yyyyMMdd')}}
} | Export-Csv $newcsv -NoType

Need to put this into a loop

I have a piece of code that works but I not very elegant, it looks at a directory full of backups, deletes all but the last modified.
$path = "C:\Users\test"
Get-ChildItem "$path\*.*" -include *.data* |
Sort-Object -Descending -Property LastWriteTime |
Select-Object -Skip 1 |Remove-Item -Force
Get-ChildItem "$path\*.*" -include *.enroll* |
Sort-Object -Descending -Property LastWriteTime |
Select-Object -Skip 1 |Remove-Item -Force
Get-ChildItem "$path\*.*" -include *.govern* |
Sort-Object -Descending -Property LastWriteTime |
Select-Object -Skip 1 |Remove-Item -Force
I tried this but it does'nt work,
$sites = #("data","govern","enroll")
$path = "C:\Users\test"
for ($i=0; $i -lt $sites.Length; $i++) {
Get-ChildItem "$path\*.*" -include "*.$sites[$i]*" |
Sort-Object -Descending -Property LastWriteTime |
Select-Object -Skip 1 |Remove-Item -Force
}
Just a nice elegant loop is all I'm looking for.

Powershell script deleting files despite -Exclude switch

I have the following script where I'm trying to delete all the SQL .bak files except for the last two. When I run it it wipes out everything in the folder. Does -Exclude not work with array values?
$excludefile=get-childitem D:\TempDB | sort lastwritetime | select-object -Last 2 | select-object -Property Name | select-object -expandproperty Name
foreach ($element in $excludefile)
{
$element
remove-item -Path D:\TempDB -Exclude ($element) -Force
}
Is this what you're looking for?
Get-ChildItem D:\TempDB |
Sort-Object LastWriteTime -Descending |
Select-Object -Skip 2 |
Remove-Item -WhatIf
Of course, you can remove -WhatIf if this is what you need.

Powershell select most recent file containing a specific string

I have written a code in powershell that selects the most recent file in a directory.
$first = Get-ChildItem -Path $dir | Sort-Object CreationTime -Descending | Select-Object -First 1
$first.name
However, I need to select the most recent file containing a specific string in the name. How can I adapt my code in order to do this?
I got it to work using this:
$filterIRP1064="IRP_1064*"
$latest1064 = Get-ChildItem -Path $dir -Filter $filterIRP1064 | Sort-Object LastAccessTime -Descending | Select-Object -First 1
$latest1064.name
#Michael Hoffmann
Like this?
$first = Get-ChildItem -recurse | Select-String -pattern "stringhere" | group path | select name
Get-ChildItem -Path $dir | Sort-Object CreationTime -Descending | Select-Object -First 1
$first.name
Get-ChildItem -recurse | Select-String -pattern "stringhere" | group path | select name
Use this to get all the files containing your string. Select the most recent one afterwards.
Get-ChildItem -path $dir | Select-String -pattern "stringhere" | group path | Sort-Object CreationTime -Descending | Select-Object -First 1 | select name
This should work...

Get List of files Using Powershell - Modified between two dates

I'm using following command to get all the files which were modified before 20 hours and after 20 days past..
Get-ChildItem -Path '\\server\c$\Program Files (x86)\folder' -recurse -Filter *.* -include *.* |? {$_.LastWriteTime -lt (Get-Date).Addhours(-20) }|? {$_.LastWriteTime -gt (Get-Date).AddDays(-20)} | Select Fullname ,LASTWRITETIME | Sort-Object -Property LASTWRITETIME -Descending
It does gives me correct result.
But I'm getting Fullname as:
\\server\c$\Program Files (x86...
How can I get the fullname? Fullname is pretty long.. more than 260 character.
I've tried
Select -Expand Fullname
It works fine but i can't use it with LastWriteTime
Select -Expand Fullname, LastwriteTime
above command gives me error.
You can format output using Format-Table cmdlet like this:
$table_properties = #{Expression={$_.Fullname};Label="Full Name";width=195},
#{Expression={$_.LastWriteTime};Label="Last Write Time";width=35}
Get-ChildItem -Path '\\server\c$\Program Files (x86)\folder' -recurse -Filter *.* -include *.* |
? {$_.LastWriteTime -lt (Get-Date).Addhours(-20) }|
? {$_.LastWriteTime -gt (Get-Date).AddDays(-20)} |
Sort-Object -Property LASTWRITETIME -Descending |
Format-Table $table_properties
Instead of Select Fullname,LASTWRITETIME create custom object $table_properties with formatting parameters and pass it to Format-Table.
If your string is wider than PowerShell host display width than pipe output to Out-String -Width 500, where 500 is enough characters to display all fields.
See Creating custom tables article on TechNet.