Powershell, look through all drives - powershell

I'm new to Powershell and I've tried finding a solution to my problem online but I can't seem to find one. Basically I need to write something that will let powershell look through all drives and directories to find the following:
total number of files (exclude folders), largest file size, average file size, total file size
Here's what I've written so far:
$source = "get-psdrive"
#attempt at looking through all drives/directories which didn't work
foreach($a in $source) {
#counts files in given directory
Get-ChildItem -Recurse -File -ErrorAction SilentlyContinue -Force |
Measure-Object |
ForEach-Object { $_.Count }
#select largest file in given directory
Get-ChildItem -Recurse -File -ErrorAction SilentlyContinue -Force |
Sort-Object Length -Descending |
Select-Object -First 1
#get average file size in a given directory
Get-ChildItem -Recurse -File -ErrorAction SilentlyContinue -Force |
Measure-Object -Property Length -Average
#sum of file sizes in given directory
(Get-ChildItem -Recurse -File -ErrorAction SilentlyContinue -Force |
Measure-Object -Sum Length).Sum
}
The issue is that it only looks in the C drive. I don't know if there's a way to look through my computer instead of specific drives but I couldn't seem to find a way. Any help is appreciated.

With "..." you define a string, so in your example you try to loop over a string.
Try it like this:
$Drives = Get-PSDrive -PSProvider 'FileSystem'
foreach($Drive in $drives) {
#counts files in given directory
Get-ChildItem -Path $Drive.Root -Recurse -File -ErrorAction SilentlyContinue -Force |
Measure-Object |
ForEach-Object { $_.Count }
#select largest file in given directory
Get-ChildItem -Path $Drive.Root -Recurse -File -ErrorAction SilentlyContinue -Force |
Sort-Object Length -Descending |
Select-Object -First 1
#get average file size in a given directory
Get-ChildItem -Path $Drive.Root -Recurse -File -ErrorAction SilentlyContinue -Force |
Measure-Object -Property Length -Average
#sum of file sizes in given directory
(Get-ChildItem -Path $Drive.Root -Recurse -File -ErrorAction SilentlyContinue -Force |
Measure-Object -Sum Length).Sum
}
Note! I didn't chang your Get-ChildItem code (except the path where it will search). I only wrote the foreach loop.

Could make it a bit faster by feeding the results into a variable, instead of running GCI it 4 times each loop. Something like this:
#specify preferred measures
$average_size = "MB"
$individual_size = "GB"
$total_size = "TB"
Get-PSDrive -PSProvider FileSystem |ForEach-Object {
"`n$($_.Root)" |Write-Host -ForegroundColor Cyan
$details=$null
$details = Get-ChildItem -Path $_.Root -Recurse -File -ErrorAction SilentlyContinue -Force
"`nFile Count: $('{0:N0}' -f $details.count)"
"Average size: "+"$([math]::round(($details |
Measure-Object -Property Length -Average |select -Property average).average /"1$($average_size)", 2))"+" $($average_size)"
"Total size: "+"$([math]::round(($details |
Measure-Object -Property Length -sum |select -Property sum).sum /"1$($total_size)", 2))"+" $($total_size)"
$details |
Sort-Object Length -Descending |
Select-Object -First 5 -Property #{L='Path';E ={$_.fullname}},#{L="Size $($individual_size)";E={[math]::round(($_.length) /"1$($individual_size)", 3)}} |ft
}
Couldn't stretch it to assign sizes dynamically, but where do you draw the line...

Related

PowerShell ISE .jpg and .png summary size (Windows and its subdirectories)

I am looking for a solution to this problem: Find the summary size of .jpg and .bmp files in Windows and its subdirectories.
I use the following commands:
Get-ChildItem -Force -Depth 2 -Path C:\Windows\ | Where-Object -Property Extension -Match "\.(bmp|jpg)$" | Measure-Object -Property Length -Sum | Select-Object -Property Sum
How do I count the actual summary size without getting an access error:
The output is:
Get-ChildItem : Access to the path 'C:\Windows\CSC\v2.0.6' is denied.
At line:1 char:1
+ Get-ChildItem -Force -Depth 2 -Path C:\Windows\ | Where-Object -Prope ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : PermissionDenied: (C:\Windows\CSC\v2.0.6:String) [Get-ChildItem], UnauthorizedAccessException
+ FullyQualifiedErrorId : DirUnauthorizedAccessError,Microsoft.PowerShell.Commands.GetChildItemCommand
Sum
---
35241685
Thank You.
To get all *.bmp and *.jpg files and to sum their length you can do:
$measure = Get-ChildItem -path $env:SystemRoot* -Include #('*.bmp','*.jpg') -ErrorAction:SilentlyContinue -Recurse | Measure-Object -Property length -sum
But this is quite slow. By using the parameter "-Filter" this runs much much faster, but you have to do 2 calls as the parameter "-Filter" only accepts a string and not a array:
#Get files
$files = #(
get-childitem -path $env:SystemRoot -Filter '*.jpg' -Recurse -ErrorAction:SilentlyContinue
get-childitem -path $env:SystemRoot -Filter '*.bmp' -Recurse -ErrorAction:SilentlyContinue
)
#Get count and sum
$measure = $files | Measure-Object -Property length -sum
Finally to avoid the "path too long" issue:
#Get files
$files = #(
get-childitem -pspath "\\?\C:\Windows" -Filter '*.jpg' -Recurse -ErrorAction:SilentlyContinue
get-childitem -pspath "\\?\C:\Windows" -Filter '*.bmp' -Recurse -ErrorAction:SilentlyContinue
)
#Get count and sum
$measure = $files | Measure-Object -Property length -sum
See: https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry

Now what is the correct variable that the inhlat greater than 5GB deletes all this data in the folder

$sum = (Get-ChildItem -Path C:\test501 -Force -Recurse -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum).Sum
gci Downloads -Dir -r | %{$_.FullName; ((gci -File $_.FullName | measure Length -Sum).Sum) /1GB }

How do I get list of all the files on a computer using Powershell [duplicate]

I'm new to Powershell and I've tried finding a solution to my problem online but I can't seem to find one. Basically I need to write something that will let powershell look through all drives and directories to find the following:
total number of files (exclude folders), largest file size, average file size, total file size
Here's what I've written so far:
$source = "get-psdrive"
#attempt at looking through all drives/directories which didn't work
foreach($a in $source) {
#counts files in given directory
Get-ChildItem -Recurse -File -ErrorAction SilentlyContinue -Force |
Measure-Object |
ForEach-Object { $_.Count }
#select largest file in given directory
Get-ChildItem -Recurse -File -ErrorAction SilentlyContinue -Force |
Sort-Object Length -Descending |
Select-Object -First 1
#get average file size in a given directory
Get-ChildItem -Recurse -File -ErrorAction SilentlyContinue -Force |
Measure-Object -Property Length -Average
#sum of file sizes in given directory
(Get-ChildItem -Recurse -File -ErrorAction SilentlyContinue -Force |
Measure-Object -Sum Length).Sum
}
The issue is that it only looks in the C drive. I don't know if there's a way to look through my computer instead of specific drives but I couldn't seem to find a way. Any help is appreciated.
With "..." you define a string, so in your example you try to loop over a string.
Try it like this:
$Drives = Get-PSDrive -PSProvider 'FileSystem'
foreach($Drive in $drives) {
#counts files in given directory
Get-ChildItem -Path $Drive.Root -Recurse -File -ErrorAction SilentlyContinue -Force |
Measure-Object |
ForEach-Object { $_.Count }
#select largest file in given directory
Get-ChildItem -Path $Drive.Root -Recurse -File -ErrorAction SilentlyContinue -Force |
Sort-Object Length -Descending |
Select-Object -First 1
#get average file size in a given directory
Get-ChildItem -Path $Drive.Root -Recurse -File -ErrorAction SilentlyContinue -Force |
Measure-Object -Property Length -Average
#sum of file sizes in given directory
(Get-ChildItem -Path $Drive.Root -Recurse -File -ErrorAction SilentlyContinue -Force |
Measure-Object -Sum Length).Sum
}
Note! I didn't chang your Get-ChildItem code (except the path where it will search). I only wrote the foreach loop.
Could make it a bit faster by feeding the results into a variable, instead of running GCI it 4 times each loop. Something like this:
#specify preferred measures
$average_size = "MB"
$individual_size = "GB"
$total_size = "TB"
Get-PSDrive -PSProvider FileSystem |ForEach-Object {
"`n$($_.Root)" |Write-Host -ForegroundColor Cyan
$details=$null
$details = Get-ChildItem -Path $_.Root -Recurse -File -ErrorAction SilentlyContinue -Force
"`nFile Count: $('{0:N0}' -f $details.count)"
"Average size: "+"$([math]::round(($details |
Measure-Object -Property Length -Average |select -Property average).average /"1$($average_size)", 2))"+" $($average_size)"
"Total size: "+"$([math]::round(($details |
Measure-Object -Property Length -sum |select -Property sum).sum /"1$($total_size)", 2))"+" $($total_size)"
$details |
Sort-Object Length -Descending |
Select-Object -First 5 -Property #{L='Path';E ={$_.fullname}},#{L="Size $($individual_size)";E={[math]::round(($_.length) /"1$($individual_size)", 3)}} |ft
}
Couldn't stretch it to assign sizes dynamically, but where do you draw the line...

How to improve performance of 3 successive GCI -Recurse calls?

Powershell noob here.
In order to create a list of potential duplicate dirs, I have a loop that runs the following 3 GCI commands on all directories to get the total size, number of files and number of directories below the currently examins dir:
$folderSize = Get-Childitem -Path $fullPath -Recurse -Force -ErrorAction SilentlyContinue | Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue
$folderDirs = Get-ChildItem -Path $fullPath -Recurse -Force -ErrorAction SilentlyContinue -Directory | Measure-Object -ErrorAction SilentlyContinue
$folderFiles = Get-ChildItem -Path $fullPath -Recurse -Force -ErrorAction SilentlyContinue -File | Measure-Object -ErrorAction SilentlyContinue
The code is working fine but it seems really dumb to run 3 times a GCI with the recurse parameter on the same path. What would be a more efficient way to get those 3 informations for a given directory?
Store the results of the where first query in a variable, use the .Where({}) extension method to split them into categories based on the PSIsContainer property - at which point you can reference the automagical Count property of each (rather than invoking Measure-Object for the simple act of counting the items):
$allFileSystemItems = Get-Childitem -Path $fullPath -Recurse -Force -ErrorAction SilentlyContinue
$size = $allFileSystemItems |Measure-Object Length -Sum
# split collections into "directories" and "files"
$dirs,$files = $allFileSystemItems.Where({$_.PsIscontainer}, 'Split')
$dirCount = $dirs.Count
$fileCount = $files.Count

With PowerShell's Get-ChildItem, how to I list matching files AND count them at the same time

How do I show AND count matching files using a single Get-ChildItem command in PowerShell? Currently I am using two Get-ChildItem commands, the first to count, the second to display the files - works fine but it is not very effective when scanning an entire disk ...
Command to count the matches:
$count = Get-ChildItem -Path $searchLocation -Filter $filename -Recurse -ErrorAction SilentlyContinue | Measure-Object | %{$_.Count}
Command to display the files:
Get-ChildItem -Path $searchLocation -Filter $filename -Recurse -ErrorAction SilentlyContinue | %{$_.FullName}
As Get-ChildItem is returning an array, its size is stored in .Length member and explicit measurement is not needed. Thus, store the file names in the same collection and then print length for number of entries and iterate the collection for file names. Swapping the variable name as $files to reflect this like so,
$files = Get-ChildItem -Path $searchLocation -Filter $filename `
-Recurse -ErrorAction SilentlyContinue
# ` can used to divide command into multiple lines (and work-around for markup stupidness)
# prints the number of items
$files.Length
# prints the full names
$files | %{$_.FullName}
An alternative method is to add a file number to each file as it processes.
$i = 1
$Files = Get-ChildItem -Path $searchLocation -Filter $filename -Recurse -ErrorAction SilentlyContinue
Foreach($Item in $Files) {
$Item | Add-Member -MemberType NoteProperty -Name FileNo -Value $i
$i++
}
$Files | Select-Object FileNo, Fullname
You can then see the order the files were processed, get the last file number by doing $File[-1].FileNo. And it will maintain all the additional file metadata suck as CreationTime, DirectoryName, VersionInfo etc.
Simply like this :
$AllFile=Get-ChildItem $searchLocation -File -Filter $filename -Recurse | select FullName
$AllFile.Count
$AllFile.FullName
Or you can ad a rank into your loop like this :
$Rang=0
Get-ChildItem "c:\temp" -File -Filter "*.txt" -Recurse | %{
$Rang++
Add-Member -InputObject $_ -Name "Rang" -MemberType NoteProperty -Value $rang
$_
} | select Rang, FullName