Powershell script to recursively search and find file size differences - powershell

I have code that finds if a file/folder exists or not in a different location, basically compares two folders. I cannot seem to find anything online to also search file size differences. My code is below and I just need help on how to recursively search and find file size differences as well.
$source = Get-ChildItem -Recurse -path "C:\Users\Cl\Desktop\Source"
$compare = Get-ChildItem -Recurse -path "C:\Users\Cl\Desktop\WMIS"
Compare-Object -ReferenceObject $source -DifferenceObject $compare -PassThru

Use measure-object to compare file sizes, then if you want to do something afterwards (like copy the updated one to the destination) store them in a variable and create if statements accordingly. You can use get-member to view the properties you can use. I think this gives you the sizes in bytes so divide the results by "1GB". Try something like this:
$source = gci "c:\users\c1\desktop\source" -recurse | Measure-Object -property length -sum
#$source = ($source.sum / 1GB)
$compare = gci "c:\users\c1\desktop\WMIS" -recurse | Measure-Object -property length -sum
#$compare= ($compare.sum / 1GB)

Related

List all files with size using powershell char limit issue

I have an applications folder that have more than 10 applications in. I want to list all files (including sub-folders) with directory and size info and save it under each application folder.
Here is the script (it is in C:\Users\xxxxxx\Desktop\apps)
$FolderList = Get-ChildItem -Directory
foreach ($folder in $FolderList)
{
$thisPath = Get-Location
Get-ChildItem -File -Filter * -Path $folder -Recurse |
Sort-Object -Property Length -Descending|
Select-Object -Property FullName, Length, #{l='Length (MB)';e={$_.Length/1MB}} |
Format-Table -AutoSize |
Out-File $thisPath\fileList_$folder.txt
}
Output:
FullName - Length - Length (MB)
C:\Users\xxxxxx\Desktop\apps\3\VSCodeUserSetup-x64-1.62.2.exe 79944464 76.2409820556641
C:\Users\xxxxxx\Desktop\apps\3\son.zip 18745870 17.8774547576904
It does what I want but in some of the outputs where the path is too long it didn't write the length or even full path.
FullName
C:\Users\xxxxxx\Desktop\apps\3\xxxxxxxxxxx/xxxxxx/xxxxxxxxxxxxxx/xxxxxxxxxxx/VSCodeUserSetu...
C:\Users\xxxxxx\Desktop\apps\3\son.zip
As I searched I saw that there is a char limit. How can I overcome this issue?
The -Path parameter is defined as a string array, but you are feeding it a DirectoryInfo object.
The second part of your question is about truncation, which happens because you use Format-Table -AutoSize on the data.
Format-* cmdlets are designed to display output on the console window only which has a limited width and all items longer are truncated.
Rule of Thumb: never use Format-* cmdlets when you need to process the data later.
Instead of saving a formatted table to a text file, I would suggest saving the (object) info as structured CSV file which makes working with the data later MUCH easier and without truncation. (you can for instance open it in Excel)
# just get an array of Full pathnames
$FolderList = (Get-ChildItem -Directory).Name #instead of Fullname
foreach ($folder in $FolderList) {
# create the path for the output
$fileOut = Join-Path -Path $folder -ChildPath ('filelist_{0}.csv' -f $folder)
Get-ChildItem -File -Path $folder -Recurse |
Sort-Object -Property Length -Descending |
Select-Object -Property FullName, Length, #{l='Length (MB)';e={$_.Length/1MB}} |
Export-Csv -Path $fileOut -NoTypeInformation -UseCulture
}
I added switch -UseCulture to the Export-Csv cmdlet so you can afterwards simply double-click the csv file to open it in your Excel

Find share sizes across multiple servers -powershell

I have about 1600 old home drives that I need to capture the folder sizes on. They are spread across 12 NAS Appliances and I need to get the size of each folder. I see this asked a lot but they are always asking for all the shares on a single server.
I have used simple one-liners like the the one below which work great.
Get-ChildItem \\Server1\Users\User1 -file -recurse | Measure-Object -Sum Length
How can I feed in a txt or csv from multiple locations?
Like
\\Server1\Users\User1
\\Server2\Users\User1
\\Server3\Users\User1
\\Server4\Users\User1
\\Server5\Users\User1
\\Server6\Users\User1
\\Server7\Users\User1
etc...
Exporting to a csv would be nice as well.
thanks!!
You can use Get-Content to read your text file line-by-line:
Get-Content .\path\to\file.txt
Next up we need to repeat your one-liner for each line:
Get-Content .\path\to\file.txt |ForEach-Object {
Get-ChildItem $_ -File -Recurse | Measure-Object -Sum Length
}
This will give us 1600 individual measurements - but now we won't know which paths they belong to...
To track which measurement belongs to which user directory, let's create a new object containing both all the information instead:
Get-Content .\path\to\file.txt |ForEach-Object {
$Measurement = Get-ChildItem $_ -File -Recurse | Measure-Object -Sum Length
[pscustomobject]#{
Path = $_
FileCount = $Measurement.Count
TotalSize = $Measurement.Sum
}
}
Finally, we can export to CSV using Export-Csv:
Get-Content .\path\to\file.txt |ForEach-Object {
$Measurement = Get-ChildItem $_ -File -Recurse | Measure-Object -Sum Length
[pscustomobject]#{
Path = $_
FileCount = $Measurement.Count
TotalSize = $Measurement.Sum
}
} |Export-Csv .\path\to\output.csv -NoTypeInformation

Find .jpg's in 2 different folders with same name and same LastWriteDate

I have many jpg's on a hardrive which are the same pictures.
Now I'd like to find them. Therefore I need to compare 2 folders and find the pictures which are the same.
I want to find the pictures with the same name AND the same LastWriteTime.
One of the criterias is not enough.
So, I need a Powershell code which could do that.
Here is what I have but it doesnt work well. I got also results which werent't correct.
Thats what I tried:
Get-ChildItem -Path $Pfad1 -Recurse -Filter *jpg |
Where-Object {(Get-ChildItem -Path $Pfad2 -Recurse -Filter *jpg) -match $_.Name -and $_.LastWriteTime} |
ForEach-Object {$_.FullName}
Without recursion you can compare the folders files with Compare-Object
$Folder1 = 'X:\path'
$Folder2 = 'Y:\path'
$Files1 = Get-ChildItem -Path $Folder1 -Filter *.jpg
$Files2 = Get-ChildItem -Path $Folder2 -Filter *.jpg
Compare-Object -Ref $Files1 -Diff $Files2 -Property Name,LastWriteTime `
-IncludeEqual -ExcludeDifferent -PassThru
If recursion is required and the subfolder has to be compared also you'll have to build a calculated property with the relative path to be comparable.

PowerShell Script to Validate/compare Folder and files of Two servers

I am trying to get the number of files inside folders and number of folders along with total size. To a certain extent I have achieved that goal but when I am trying it for checking millions of folders/files and their size may be around 1 TB its getting stuck might be getting into infinite lope.
Also I want to compare the two location size and number of files/folder and get output as bollen value. – true if the size and numbers match, false if they don’t.
Below script is what I tried. Can some one help me with the requirement.
$hostnames = Get-Content C:\server.txt
$directory = "D$\logs"
foreach ($hostname in $hostnames){
$Folderitems = (Get-ChildItem -Path "\\$hostname\$directory" -Directory -Recurse -Force).Count
$FileItems = Get-ChildItem -path "\\$hostname\$directory" -recurse
$Measurement = $FileItems | Measure-Object -property length -sum
$colitems = $FileItems | measure-Object -property length -sum
"$hostname,$directory;{0:N2}" -f ($colitems.sum / 1024MB) + "GB;" + $Measurement.count + " files;" + $items +"Folders;"
}
A performance improvement would be to invoke the Get-ChildItem cmdlet only once and use it to filter the Folders using the Where-Object cmdlet:
$FileItems = Get-ChildItem -path "\\$hostname\$directory" -recurse
$Folderitems = $FileItems | Where-Object PsIsContainer
You also calculate the length twice, remove one of these:
$Measurement = $FileItems | Measure-Object -property length -sum
$colitems = $FileItems | measure-Object -property length -sum
Also i want to compare the two location size and number of
files/folder and get output as bollen value.
Which two locations you want to compare? You are iterating over a list of hostnames and don't store any values...
Edit to your comment:
Regarding the comparison part i want to compare the size and number of
files from server1 to server2 for location d$\website. Its just like
same we do right click on folder and see the files and size.
Currently, you are retrieving the items for D$\logs, not D$\website you probably have to change this?!. To compare the results, you have to store them first. I would recommend an array of PSCustomObjects. The structure looks like this (sample output):
Server Sum Count
------ --- -----
YourServer1 88575206 386
YourServer2 88575206 386
And here the script:
foreach ($hostname in $hostnames){
$FileItems = Get-ChildItem -path "\\$hostname\$directory" -recurse
$Folderitems = $FileItems | Where-Object PsIsContainer
$Measurement = $FileItems | Measure-Object -property length -sum
$serverFileMeasurements += [PSCustomObject]#{
Server = $hostname
Sum = $Measurement.Sum
Count = $Measurement.Count
}
}
# assuming there are only two servers:
if ($serverFileMeasurements[0].Count -eq $serverFileMeasurements[1].Count -and
$serverFileMeasurements[0].Sum -eq $serverFileMeasurements[1].Sum)
{
Write-Host $true
}
else
{
Write-Host $false
}

Comparing 2 folders and saving the paths into a variable?

I've been given the task of comparing 2 folders, FolderA and FolderB and noting any files that exist in A but not in B.
Sorry for not explaining myself fully. Maybe it would help if I explain our situation. A company sales employee has left our company to go to a competitor. He has files in on his work laptop local hard drive. We are trying to establish if there are any files that exist on his computer but not on the shared network folder.
I need to produce a list of any files (along with their paths) that are present on his laptop but not on the share network location. The file structure between the laptop local hard drive and the shared network location are different. What's the best way to go about this?
$folderAcontent = "C:\temp\test1"
$folderBcontent = "C:\temp\test2"
$FolderAContents = Get-ChildItem $folderAcontent -Recurse | where-object {!$_.PSIsContainer}
$FolderBContents = Get-ChildItem $folderBcontent -Recurse | where-object {!$_.PSIsContainer}
$FolderList = Compare-Object -ReferenceObject ($FolderAContents ) -DifferenceObject ($FolderBContents) -Property name
$FolderList | fl *
Use the compare-Object cmdlet :
Compare-Object (gci $folderAcontent) (gci $folderBcontent)
if you want to list the file that are only in $folderAcontent select the results with the <= SideIndicator :
Compare-Object (gci $folderAcontent) (gci $folderBcontent) | where {$_.SideIndicator -eq "<="}
assuming that the filenames in both the directories are same, you can do something like the following :-
$folderAcontent = "C:\temp\test1"
$folderBcontent = "C:\temp\test2"
ForEach($File in Get-ChildItem -Recurse -LiteralPath $FolderA | where {$_.psIsContainer -eq $false} | Select-Object Name)
{
if(!(Test-Path "$folderBcontent\$File"))
{
write-host "Missing File: $folderBcontent\$File"
}
}
The above will only work for files (not subdirectories) present in folder A
Try:
#Set locations
$laptopfolder = "c:\test1"
$serverfolder = "c:\test2"
#Get contents
$laptopcontents = Get-ChildItem $laptopfolder -Recurse | where {!$_.PSIsContainer}
$servercontents = Get-ChildItem $serverfolder -Recurse | where {!$_.PSIsContainer}
#Compare on name and length and find changed files on laptop
$diff = Compare-Object $laptopcontents $servercontents -Property name, length -PassThru | where {$_.sideindicator -eq "<="}
#Output differences
$diff | Select-Object FullName
If you add lastwritetime after length in the compare-object cmdlet it will compare modified date too(if the file was updated but still same size). Just be aware that it only looks for differnt dates, not if it's newer or older. :)