Recursively looking for count of file extension using PowerShell - powershell

Looking to get a PowerShell snippet that will list all file extensions recursively in a folder along with the count.
/abc/(1).cfc
/abc/john/(265).cfm, (1).html
/abc/john/js/(25).js
/abc/john/css/(6).css
This is what I've tried so far, but I'm not sure how to add the path for each:
Get-Childitem "C:\projects\newfolder\edit" -Recurse |
where { -not $_.PSIsContainer } |
group Extension -NoElement |
sort count -Desc

The answer posted by #AnsgarWiechers is OK if you want the list of matching files as well as the count; if you only want the directory name and the count,
(Powershell v2:)
Get-ChildItem 'C:\projects\newfolder\edit' -Recurse |
Where-Object { -not $_.PSIsContainer } |
Group-Object DirectoryName, Extension |
Select-Object Name, Count
(PowerShell v3+:)
Get-ChildItem 'C:\projects\newfolder\edit' -Recurse -File |
Group-Object DirectoryName, Extension |
Select-Object Name, Count

You can group by multiple criteria:
Get-ChildItem 'C:\projects\newfolder\edit' -Recurse |
Where-Object { -not $_.PSIsContainer } |
Group-Object DirectoryName, Extension
On PowerShell v3 and newer the filtering can be done directly with Get-ChildItem:
Get-ChildItem 'C:\projects\newfolder\edit' -Recurse -File |
Group-Object DirectoryName, Extension

You can use the following script to achieve the expected output:
Get-ChildItem "C:\TempFiles" -Recurse -File | Group-Object DirectoryName |
ForEach-Object {
"{0}\{1}" -f $_.Name,
(($_.Group | Group-Object Extension |
ForEach-Object { ("({0}){1}" -f $_.Count, $_.Name) }) -join ",")
}
Output
C:\TempFiles\Root\(1).json,(2).html,(2).txt
C:\TempFiles\Root\Folder1\(4).json,(2).html,(2).txt,(2).png
C:\TempFiles\Root\Folder1\Folder1-1\(2).json,(2).html
C:\TempFiles\Root\Folder2\(2).txt

Related

PowerShell cmdlet to get a name of recently zipped folder?

I have tried
$latest1 = gci $path -Include *.zip| ? { $_.PSIsContainer } | sort CreationTime -desc | select -f 1
but $latest1 is giving blank output.
The -Include switch will only work if the path ends in \* or when used together with the -Recurse switch.
Since in your case, you are only looking for zip files, I would use the -Filter parameter.
$latest1 = Get-ChildItem $path -Filter '*.zip' -File |
Sort-Object CreationTime -Descending | Select-Object -First 1
For PowerShell version below 3.0 use
$latest1 = Get-ChildItem $path -Filter '*.zip' | Where-Object { !$_.PSIsContainer } |
Sort-Object CreationTime -Descending | Select-Object -First 1
If a zip file was found in the path, $latest should now be a FileInfo object with properties like FullName, BaseName etc.
Try changing your where-object filter or removing it
$latest1 = gci $path -Include *.zip| ? { $_.PSIsContainer -eq $false } | sort CreationTime -desc | select -f 1
$latest1 = gci $path -Include *.zip| | sort CreationTime -desc | select -f 1

Find the last modified files with different file names in PowerShell

I have a folder full of SQL backups from different DBs. I need to isolate the last modified from each DB and delete the rest.
I can find the last modified of them all and delete the rest but that would delete the last backup from the other 2 DBs.
$files = Get-ChildItem -Path $path -Recurse |
Where-Object {-not $_.PsIsContainer}
$keep = 1
if ($files.Count -gt $keep) {
$files | Sort-Object CreationTime |
Select-Object -First ($files.Count - $keep) |
Remove-Item -Force
}
This will just Keep the newest and remove the rest.
So if I have
db1.bak
db1.bak
db1.bak
db2.bak
db2.bak
db2.bak
db3.bak
db3.bak
db3.bak
how do I keep the last modified of each then delete the rest?
Group the files by name, skip the most recent file from each group, and remove the rest.
Get-ChildItem -Path $path -Recurse |
Where-Object {-not $_.PsIsContainer}
Group-Object Name |
ForEach-Object {
$_.Group |
Sort-Object LastWriteTime -Desc |
Select-Object -Skip 1 |
Remove-Item -Force
}

Finding Files in a directory equal to 0 Powershell

I was wondering how I can display a list of empty files in a directory
$test = gci "C:\Users\Freedom\Documents" -Recurse
$test | Where-Object {$_.PsISContainer} | Select-Object FullName | Where-Object {$_.GetFiles() -eq 0}
I Don't understand because when I do get-childitem | get-member I get a list of properties and methods I can use and in the list is getfiles() why can't I use this method why's it giving me an error message?
Method invocation failed because [System.IO.FileInfo] does not contain a method named 'GetFiles'.
I think you want this:
Get-ChildItem | Where-Object { (-not $_.PSIsContainer) -and ($_.Length -eq 0) }
If you have PowerShell 3.0 or later you can use this:
Get-ChildItem -File | Where-Object { $_.Length -eq 0 }
Of course you can add whatever other parameters for Get-ChildItem that you want (-Recurse, etc.).
Wow I had what I wanted mixed up! And I had to add the .count to the getfiles() method
$test | Where-Object {$_.PsISContainer} | Where-Object {$_.GetFiles().Count -eq 0} | Select-Object FullName
try this
Get-ChildItem "c:\temp" -File -Recurse | where Length -eq 0
Use Get-ChildItem and the File flag, -Recurse is needed to get every file in the folder and in the folder below. Then get all the files were Get-Content returns null.
Get-ChildItem $YourPath -Recurse -File | Where-Object {!(Get-Content $_.Fullname)}

Adding File Properties such as the Creator or Author

As of now I have a script that will pull and export all files that are older than 7 years:
get-childitem -Path C:\ -recurse|
where-object {$_.LastWriteTime -lt (get-date).Addyears(-7)} |
Select-Object FullName, LastWriteTime, #{N='Owner';E={$_.GetAccessControl().Owner}}, #{N='Author';E={$_.GetAccessControl().Author}}|
Export-Csv C:\file.csv
Now, I need help adding the Creator or Author from the file properties. The #{N='Author';E={$_.GetAccessControl().Author}} doesn't work.
Adjusted so that you're retrieving ACLs properly. I don't think it's possible to grab the original author, however.
Get-ChildItem -Path C:\ -Recurse |
Where-Object {$_.LastWriteTime -lt (Get-Date).AddYears(-7)} |
Select-Object #( 'FullName'
'LastWriteTime'
#{ N = 'Owner'
E = { (Get-Acl -Path $_.FullName).Owner }
}
) |
Export-Csv -Path C:\file.csv

PowerShell Filter on multiple parameters

I was wondering if is possible to specify multiple search filters as once. For example, I have this line of code that finds all files that have the "&" symbol.
get-childitem ./ -Recurse -Filter "*&*" |
? { $_.PSIsContainer } |
Select-Object -Property FullName
I'd like to extend this so that I can search one time and find files with other symbols like %,$,#, etc. I want to find files that have any of these symbols, not neccesarly files that have all of them so I assume there needs to be an OR somewhere. I tried the below code but it didn't seem to work for me:
get-childitem ./ -Recurse -Filter "*&*" -Filter "%" |
? { $_.PSIsContainer } |
Select-Object -Property FullName
You can use the -match operator and a regex for this:
Get-ChildItem -Recurse |
Where { !$_.PSIsContainer -and ($_.name -match '&|%|\$|#')} |
Select-Object -Property FullName
If you are on PowerShell v3 or higher you can simplify this a bit:
Get-ChildItem -Recurse -File |
Where Name -match '&|%|\$|#' |
Select-Object -Property FullName
If you have V3 or better, you can leverage the "globbing" wildcard feature:
get-childitem './*[&%$#]*' -Recurse | where {$_.PSIsContainer}
If you've got V4, you can dispense with the $_.PSIsContainer filter and use the -Directory switch:
get-childitem './*[&%$#]*' -Recurse -Directory