I'm trying to find all files that include some string and are not older than "x" days. Those files have to be sorted and then sent in .txt format.
The code seemed fine to me, but it doesn´t filter files by date. All other cmdlets work as intended, but the part Where-Object {$_.LastWriteTime -ge (Get-Date).AddDays(-$days)} doesn´t seem to be working at all.
Do you have any recommendations how to fix it?
Get-ChildItem -Path $path -Recurse |
Where-Object {$_.LastWriteTime -ge (Get-Date).AddDays(-$days)} |
Select-String -Pattern $searched |
Group-Object -Property Path, Filename |
select Name |
Out-File -Filepath C:\tmp\output.txt
| Sort-Object -Property propertyName -Descending
cmdlet to sort by property value
reference link - https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/sort-object?view=powershell-6
Related
I have a windows network share with over 1000 folders that also have subfolders.
I want to delete the folders that have not been modified since a few years.
When I sort in File Explorer after "date modified", it sorts the parent folders correctly.
But changes in subfolders are not considered.
I try to create a PowerShell script that sorts all folders on the network share considering the last write time in folder or subfolder.
Unfortunately in the current state it lists only the latest modified folder over and over again.
Example:
Get-ChildItem c:\tmp -Directory | ForEach-Object { Get-ChildItem -Directory -Recurse | Sort {$_.LastWriteTime} -Descending | Select {$_.FullName}, {$_.LastWriteTime} -First 1 }
Can someone help?
I think you want "the most recent LastWriteTime of any sub-file/folder", which is
Get-ChildItem -Recurse -Force |
Sort-Object -Property LastWriteTime |
Select-Object -Last 1 -ExpandProperty LastWriteTime
Then you could write the whole thing like:
Get-ChildItem -Path 'c:\test' -Directory |
Select-Object -Property Name, #{Label='LastWriteInside'; Expression={
($_ | Get-ChildItem -Recurse -Force|
Sort-object -property LastWriteTime|
Select-Object -expandproperty lastwritetime -Last 1)
}} |
Sort-Object -Property LastWriteInside
I wrote a script in Powershell that will pull all files in a directory from the past seven years (this is my first time using Powershell).
I am trying to Export my results from the script below into a TXT or CSV document.
get-childitem -Path P:\ -recurse | where-object {$_.LastWriteTime -lt (getdate).Addyears(-7)}
What should I add to the end of this script to get this data written to a file?
First things first, your script is finding files older than 7 years not files from the last 7 years. You need to change your -lt to a -gt.
get-childitem -Path P:\ -recurse| where-object {$_.LastWriteTime -gt (get-date).Addyears(-7)}
As you have written your script it finds the date/time that the file was last written to, for example 3/24/2015 2:45PM. Then it checks if that is less than right now minus 7 years (at the time of writing that is 12/5/2010 3:22PM). Looking at the years alone we can see that 2015 is not less than 2010, so that file would be excluded.
You can output to a text file using the Out-File or (my preference) Set-Content cmdlets.
get-childitem -Path P:\ -recurse| where-object {$_.LastWriteTime -gt (get-date).Addyears(-7)} | Set-Content C:\Path\To\File.txt
Alternatively if you want to capture the data as well, or display it on screen, you can use the Tee-Object cmdlet.
get-childitem -Path P:\ -recurse| where-object {$_.LastWriteTime -gt (get-date).Addyears(-7)} | Tee-Object -FilePath C:\Path\To\File.txt
If you would like a CSV file you use the Export-Csv cmdlet. When using this cmdlet it is very common to use the -NoTypeInformation parameter (shortened to -NoType in my example) to avoid getting a first line that specifies the object types that it output.
get-childitem -Path P:\ -recurse| where-object {$_.LastWriteTime -gt (get-date).Addyears(-7)} | Export-Csv C:\Path\To\File.csv -NoType
get-childitem -path p:\ -recurse | where-object{$_.lastwritetime -lt((get-date).adddyears(-7))} | export-csv c:\temp\test.csv
I am trying to create a CSV file of all jpgs in a directory and its sub-directories that are above 100 KB and have the suffix "_lowRes.jpg".
Want to use Powershell.
Any help please?
This is pretty easy actually!
You'll do this with two separate filters, which PowerShell achieves via the Where-Object cmdlet. This cmdlet accepts comparisons in the format of {$_.PropertyName -eq "Something"} or PropertyName -eq "Something". The later format is only available on PowerShell v3 and up.
First, to filter to only files above 100KB.
Where-Object Length -ge 100KB
The second part, where the filename contains something.
Where-object Name -like "*lowRes.jpg*"
You could join them, but I would just pipe one into the other, like this.
dir *.jpg -Recurse | Where-Object Length -ge 100KB | Where-object Name -like "*lowRes.jpg*"
You might want to put the Name filtering first, because less files will have a certain name than be above or below a certain size. Depends on how your files are laid out.
Finally, pipe all of that into the Export-Csv cmdlet and bam, you're done!
you can do it simply like this :
Get-ChildItem "C:\temp" -Recurse -file -filter "*_lowRes.jpg" |
Where Length -ge 100KB | select fullname, Length |
export-csv "c:\temp\result.csv" -NoType
short version (for no purist) :
gci "C:\temp" -Rec -file -filter "*_lowRes.jpg" | ? L -le 100KB | select fu*, le* | epcsv "c:\temp\result.csv" -Not
I would like to retrieve all (and only) second level directory names of my disk. For example, C:\folder1\folder2 and C:\folder1\folder3, I need to retrieve only folder2 and folder3.
I write this and the PS displays all the directory names:
Get-ChildItem -Recurse | ?{ $_.PSIsContainer} | Select-Object Name
I found this help, and I modify the previous command in this way:
Get-ChildItem -Recurse | `Where-Object {($_.directory -match '^*\\\S*$')} ` | ForEach-Object {?{ $_.PSIsContainer} | Select-Object Name }
but when I use it the PS doesn't display anything.
I can't understand why, someone can help me? Thank you!
Only files appear to have a .directory property, directories do not, so you will never get something which passes your (.directory matches a pattern) filter and also passes your (PSIsContainer) filter.
Except that your PSIsContainer filter doesn't work:
| ForEach-Object {?{ $_.PSIsContainer} | Select-Object Name }
this doesn't make sense; you can only filter the pipeline using ? with cmdlet | ? {}, you cannot filter at the start of a loop scriptblock with no input and get anything useful. This is running where-object {} over and over in a loop, - and that has no output.
Using -Recurse will be very slow, as you go into every single directory all the way to the end, and make [fileinfo] objects for all the files as well.
Apart from Matt's wildcard answer, assuming PS v3 or above, you could list all the directories in the root, and then all the directories inside those, and stop there:
Get-ChildItem c:\ -Directory | Get-ChildItem -Directory | Select -ExpandProperty Name
or
gci c:\ -Dir | ForEach { (gci $_ -Dir).Name }
You should just be able to use some fun wildcards to get what you want here.
Get-ChildItem \*\*\ | Where-Object{$_.PSIsContainer}
Or if you have at least PowerShell 3.0 this would be faster
Get-ChildItem \*\*\ -Directory
Then if you wanted just the names tack on | Select-Object -ExpandProperty Name
Here with full path, network compatible:
(Get-ChildItem "\\folder1\" -Dir).fullname | ForEach {(Get-ChildItem $_ -Dir).name}
Want it stored in an array?
$subfolders = (Get-ChildItem "\\folder1\" -Dir).fullname | ForEach {(Get-ChildItem $_ -Dir).name}
I am using the below code to get the FileDescription of a file:
(dir C:\test.exe).VersionInfo | select-object FileDescription | fl
This is working fine, the next step is: I am looking to search for all files that end with a specific FileDescription, then delete the folders where these files reside. Is this possible? Thanks!
There was an error in my pipe. The file information was lost since we only pipe .VersionInfo
Get-ChildItem C:\test.exe | Where-Object{$_.VersionInfo.FileDescription -like "*endofdescription"} | Remove-Item -WhatIf
It would make more sense if you were to use -Recurse to return more file and keep using Where-Object to filter just the ones you want. This should find the files and return their folder names. Since there could be more than one file in a folder that matches we could pipe the results in Select-Object -Unique to get the individual folders.
Get-ChildItem C:\MyFolder -Recurse | Where-Object{$_.VersionInfo.FileDescription -like "*endofdescription"} | ForEach-Object{Split-Path $_.FullName -Parent} | Select-Object -Unique | ForEach-Object{Remove-Item $_ -WhatIf -Confirm:$false -Force -Recurse}
I leave the -WhatIf as a precaution. Remove if the code suits your needs.
Does this work?
Get-ChildItem C:\MyFolder -Recurse | `
Where-Object{$_.VersionInfo.FileDescription -like "*endofdescription"} |`
%{$_.DirectoryName}|`
sort-object -unique| `
remove-item -recurse -whatif