I've got a Question. I have a Script which gets everybodys Usernames and there sums der pst Files and puts out a Table with all Users and the Size of all ther pst Files in GB.
$Gesamt = Get-ChildItem $Verzeichniss |Select-Object Name,#{Name='TotalSizeInGB';Expression={ (Get-ChildItem -Path $Verzeichniss$($_.Name)\ , $Verzeichniss$($_.Name)\Archiv\ , $Verzeichniss$($_.Name)\Outlook\ -Filter *$($FileType) | Measure Length -Sum).Sum /1.GB}} | Sort-Object -Property TotalSizeInGB -Descending | Select-Object -Property Name,TotalSizeInGB -First 30
My Problem now is that the size of the pst files is about 10 digits long after the ".". But I don't know how i maybe can make it only 2 digits long after the ".". Do you guys have a idea?
try using round, like so
$a = 111.2226
[math]::Round($a,2)
will give you: 111.22 and
[math]::Round($a)
will give you: 111
Solution:
$Gesamt = Get-ChildItem $Verzeichniss |Select-Object Name,#{Name='TotalSizeInGB';Expression={ [math]::Round(((Get-ChildItem -Path $Verzeichniss$($_.Name)\ , $Verzeichniss$($_.Name)\Archiv\ , $Verzeichniss$($_.Name)\Outlook\ -Filter *$($FileType) | Measure Length -Sum).Sum /1.GB),2)}} | Sort-Object -Property TotalSizeInGB -Descending | Select-Object -Property Name,TotalSizeInGB -First 30
Modify the query accordingly.
ref: https://devblogs.microsoft.com/scripting/powertip-use-powershell-to-round-to-specific-decimal-place/
If this is a display problem, then you can use string formatting to get you there
$Gesamt = Get-ChildItem $Verzeichniss |Select-Object Name,#{Name='TotalSizeInGB';Expression={ (Get-ChildItem -Path $Verzeichniss$($_.Name)\ , $Verzeichniss$($_.Name)\Archiv\ , $Verzeichniss$($_.Name)\Outlook\ -Filter *$($FileType) | Measure Length -Sum).Sum /1.GB}} | Sort-Object -Property TotalSizeInGB -Descending | Select-Object -Property Name,TotalSizeInGB -First 30
Output results using format string specifying digits
$Gesamt | ForEach-Object { Write-Output ( 'Name: {0}; Total Size(GB): {1:F2}' -f $_.Name, $_.TotalSizeInGB ) }
Related
I am trying to import multiple csv files and output a total score, i don't want to create another csv for the output, below is how the csv is stored. below is csv 1
and this is csv 2
i want to group by Name and total the wins, please see code below that i have tried
get-item -Path "File Path" |
ForEach-Object {
import-csv $_|
Group-Object Name
Select-Object Name, #{ n='Wins'; e={ ($_.Group | Measure-Object Wins -Sum).Sum } }
}
i was hoping for an outcome like below
any help would be awesome
for some reason the current code is showing the below
Its looking better but still not grouping on Name
This will give you the output you are expecting, with the names and total wins for each player.
$csv1 = import-csv "File path of CSV 1"
$csv2 = import-csv "File path of CSV 2"
$allRecords = $csv1 + $csv2
$allRecords | Group-Object Name | Select-Object Name, #{ n='Wins'; e={ ($_.Group | Measure-Object Wins -Sum).Sum } }
the ouptut
Update
With multiple Csv Files
$allRecords = #()
$directory = "Path of the directory containing the CSV files"
$filePaths = Get-ChildItem -Path $directory -Filter "*.csv"
foreach ($filePath in $filePaths) {
$csv = import-csv $filePath
$allRecords += $csv
}
$allRecords | Group-Object Name | Select-Object Name, #{ n='Wins'; e={ ($_.Group | Measure-Object Wins -Sum).Sum } }
If you have a very high number of csv files, you'll find something like this much faster:
$CombinedRecords = Get-ChildItem -Filter *.csv -Path C:\temp | Select-Object -ExpandProperty FullName | Import-Csv
$CombinedRecords | Group-Object Name | Select-Object Name, #{ n='Wins'; e={ ($_.Group | Measure-Object Wins -Sum).Sum } }
It can even be a one-liner:
Get-ChildItem -Filter *.csv -Path C:\temp | Select-Object -ExpandProperty FullName | Import-Csv | Group-Object Name | Select-Object Name, #{ n='Wins'; e={ ($_.Group | Measure-Object Wins -Sum).Sum } }
There is such a shell command in the chapter "transformational programming" of "The Pragmatic Programmer".
Its function is to list the five files with the most lines in the current directory.
$ find . -type f | xargs wc -l | sort -n | tail -6 | head -5
470 ./debug.pml
470 ./test_to_build.pml
487 ./dbc.pml
719 ./domain_languages.pml
727 ./dry.pml
I'm trying to do the same thing with PowerShell,But it seems too wordy
(Get-ChildItem .\ | ForEach-Object {$_ | Select-Object -Property 'Name', #{label = 'Lines'; expression = {($_ | Get-Content).Length}}} |Sort-Object -Property 'Lines')|Select-Object -Last 5
I believe there will be a simpler way, but I can't think of it.
How to get files with most lines in the current directory by simplest way using PowerShell?
Of course, you don't need to use custom aliases and abbreviations to shorten the length. Although it looks more concise, it loses readability.
Get-Content * | Group-Object PSChildName | Select-Object Count, Name |
Sort-Object Count | Select-Object -Last 5
I finally found my own satisfactory answer!
Used 3 pipeline operators, shell used 5!
What's more, what we get is the object, which can be used for more extensible operations.
I feel better than shell of linux.
dir -file | sort {($_ | gc).Length} | select -l 5
Try either File.ReadLines with Linq or File.ReadAllLines with Count property.
File.ReadLines
Get-ChildItem .\ -File |
Select-Object -Property Name, #{n='Lines'; e= {
[System.Linq.Enumerable]::Count([System.IO.File]::ReadLines($_.FullName))
}
} | Sort-Object -Property 'Lines' -Descending | Select-Object -First 5
File.ReadAllLines
Get-ChildItem .\ -File |
Select-Object -Property Name, #{n='Lines'; e= {
[System.IO.File]::ReadAllLines($_.FullName).Count
}
} | Sort-Object -Property 'Lines' -Descending | Select-Object -First 5
A fast approach would be to use switch -File:
$files = (Get-ChildItem -File ).FullName
$result = foreach ($file in $files) {
$lineCount = 0
switch -File $file {
default { $lineCount++ }
}
[PsCustomObject]#{
File = $file
Lines = $lineCount
}
}
$result | Sort-Object Lines | Select-Object -Last 5
I was writing a power shell script to get a size of directory
(get-childitem <path> -recurse | measure-object -property length -sum).sum/1MB
now I want both "size" and "size on the disk" of a folder to be displayed as output
Try this:
GCI <Path> -Recurse |
Group-Object -Property Directory | % {
New-Object psobject -Property #{
Name = $_.Name
Size = ($_.Group | ? {!($_.PSIsContainer)} | Measure-Object Length -Sum).Sum
}
} |
Sort-Object -Property Size -Descending
Here is what I am trying to do:
Search my computer for files ending with a .doc, .docx, .xls, or .xlsx
Output the filenames and sizes (in groups by file extension) to a text file named “File_Summary.txt”.
I also want the total of the number of files and total file size for each file extension listed in the output.
I can't even get past the check folder part:
$Folder_To_Check = C:\AIU
$Report_File_Location = "File_Summary.txt"
$files= Get-Childitem -Path $Folder_To_Check-Include *doc, *docx, *xls, *xlsx $Report_File_Location
$totalfiles = ($files | Measure-Object).Count
$totalsize = ($files | Measure-Object -Sum Length).Sum
Update. Here is my code again with some changes I made from the suggestions, but I'm still coming up empty.
$Report_File_Location = "File_Summary.txt"
$files= Get-Childitem C:\AIU -include "*doc", "*docx", "*xls", "*xlsx"-recurse | Sort-Object | Get-Unique -asString
$files | Out-File $Report_File_Location
$totalfiles = ($files | Measure-Object).Count
$totalsize = ($files | Measure-Object -Sum Length).Sum
write-host "totalfiles: $totalfiles"
write-host "totalsize: $totalsize"
The more I was looking about this I think I shouldn't use the Sort-Object but to use Group Extension -NoElement | Sort Count -Descending that would give me the total number of files for each type?
UPDATE
Thanks to help of people here I got my code to work. But I had an issue where it was saying that my file didn't exist. The problem? I needed to list the entire folder path and use SINGLE quotes.
This code works:
$Folder_To_Check = 'C:\Users\Sarah\Documents\AIU'
$Report_File_Location = "File_Summary.txt"
$results = Get-ChildItem $Folder_To_Check -Include *.doc,*.docx,*.xls,*.xlsx -Recurse
$results | Group-Object extension | ForEach-Object {
[PSCustomObject]#{
Results = $_.Name
Count = $_.Count
Size = [Math]::Round(($_.Group | Measure-Object -Sum Length | Select-Object - ExpandProperty Sum) / 1MB,2)
}
} | Out-File $Report_File_Location -Append
BIG props to Matt for helping me organize my results so nice. Thank you for helping me learn.
$Folder_To_Check = C:\AIU
$Report_File_Location = "File_Summary.txt"
$results = Get-ChildItem $Folder_To_Check -Include *.doc,*.docx,*.xls,*.xlsx -Recurse
$results | Group-Object extension | ForEach-Object {
[PSCustomObject]#{
Extension = $_.Name
Count = $_.Count
Size = [Math]::Round(($_.Group | Measure-Object -Sum Length | Select-Object -ExpandProperty Sum) / 1MB,2)
}
} | Out-File $Report_File_Location -Append
Get all of the files you are looking for with Get-ChildItem much like you were. Vasja mentioned it as well that you might want to use -Recurse to get results from sub directories as well. Use Group-Object to collect the files by extension. For each collection output a custom object of the extension and file count, which both come Group-Object, and the size of all the files of that particular extension converted to MB and rounded to 2 decimal places.
Update for 2.0
In case you only have 2.0 installed I wanted to provide and answer that works for that.
$results | Group-Object extension | ForEach-Object {
$properties = #{
Extension = $_.Name
Count = $_.Count
Size = [Math]::Round(($_.Group | Measure-Object -Sum Length | Select-Object -ExpandProperty Sum) / 1MB,2)
}
New-Object -TypeName PSObject -Property $properties
}
Added some quotes.
Also you probably want -Recurse on Get-Childitem
$Folder_To_Check = "C:\AIU"
$Report_File_Location = "E:\tmp\File_Summary.txt"
$files = Get-Childitem -Path $Folder_To_Check -Include *doc, *docx, *xls, *xlsx -Recurse
$files | Out-File $Report_File_Location
$totalfiles = ($files | Measure-Object).Count
$totalsize = ($files | Measure-Object -Sum Length).Sum
write-host "totalfiles: $totalfiles"
write-host "totalsize: $totalsize"
Yep, you need a collection of strings for the -Include argument. So, what you tried is one string, that being:
"*doc, *docx, *xls, *xlsx"
While the commas do need to seperate the extensions when you include it within the quotes it thinks that's a part of the one thing to include, so it's seriously looking for files that have anything (as per the asterisk) then "doc," then anything then "docx," then anything then... you see where I'm going. It thinks it has to include all of that. Instead you need a collection of strings like:
-Include "*doc","*docx","*xls","xlsx"
I hope that helps. Here's your line modified to what should work:
$files= Get-Childitem -Path $Folder_To_Check-Include "*doc", "*docx", "*xls", "*xlsx"
I got the following string from Output sub-folder with the latest write access
Get-ChildItem $FilePath | Sort {$_.LastWriteTime} -Descending | where {$_.PsIsContainer} |Select {$_.Name} -First 1
But the output is :
$_.Name
Username
The output I am trying to get is :
Username
I tried formatting the output by :
(Get-ChildItem $FilePath | Sort {$_.LastWriteTime} -Descending | where {$_.PsIsContainer} |Select {$_.Name} -First 1).name
But I'm not sure why it's not working.
Thank you
try this:
Get-ChildItem $filepath | ? { $_.PsIsContainer} | Sort LastWriteTime -Descending | Select -expa Name -First 1
I've anticipaded the where-object, aka '?' , for better performance.
With select-object the {} are needed only for calculated properties and to avoid the coloumn name use the -expand parameter.