Top-Themen

AppleEntwicklungHardwareInternetLinuxMicrosoftMultimediaNetzwerkeOff TopicSicherheitSonstige SystemeVirtualisierungWeiterbildungZusammenarbeit

Aktuelle Themen

Administrator.de FeedbackApache ServerAppleAssemblerAudioAusbildungAuslandBackupBasicBatch & ShellBenchmarksBibliotheken & ToolkitsBlogsCloud-DiensteClusterCMSCPU, RAM, MainboardsCSSC und C++DatenbankenDatenschutzDebianDigitiales FernsehenDNSDrucker und ScannerDSL, VDSLE-BooksE-BusinessE-MailEntwicklungErkennung und -AbwehrExchange ServerFestplatten, SSD, RaidFirewallFlatratesGoogle AndroidGrafikGrafikkarten & MonitoreGroupwareHardwareHosting & HousingHTMLHumor (lol)Hyper-VIconsIDE & EditorenInformationsdiensteInstallationInstant MessagingInternetInternet DomäneniOSISDN & AnaloganschlüsseiTunesJavaJavaScriptKiXtartKVMLAN, WAN, WirelessLinuxLinux DesktopLinux NetzwerkLinux ToolsLinux UserverwaltungLizenzierungMac OS XMicrosoftMicrosoft OfficeMikroTik RouterOSMonitoringMultimediaMultimedia & ZubehörNetzwerkeNetzwerkgrundlagenNetzwerkmanagementNetzwerkprotokolleNotebook & ZubehörNovell NetwareOff TopicOpenOffice, LibreOfficeOutlook & MailPapierkorbPascal und DelphiPeripheriegerätePerlPHPPythonRechtliche FragenRedHat, CentOS, FedoraRouter & RoutingSambaSAN, NAS, DASSchriftartenSchulung & TrainingSEOServerServer-HardwareSicherheitSicherheits-ToolsSicherheitsgrundlagenSolarisSonstige SystemeSoziale NetzwerkeSpeicherkartenStudentenjobs & PraktikumSuche ProjektpartnerSuseSwitche und HubsTipps & TricksTK-Netze & GeräteUbuntuUMTS, EDGE & GPRSUtilitiesVB for ApplicationsVerschlüsselung & ZertifikateVideo & StreamingViren und TrojanerVirtualisierungVisual StudioVmwareVoice over IPWebbrowserWebentwicklungWeiterbildungWindows 7Windows 8Windows 10Windows InstallationWindows MobileWindows NetzwerkWindows ServerWindows SystemdateienWindows ToolsWindows UpdateWindows UserverwaltungWindows VistaWindows XPXenserverXMLZusammenarbeit

Ordnergrößen mittels Powershell ermitteln

Frage Entwicklung Batch & Shell

Mitglied: killtec

killtec (Level 3) - Jetzt verbinden

12.11.2013, aktualisiert 10:43 Uhr, 7918 Aufrufe, 10 Kommentare, 1 Danke

Hallo zusammen,
ich würde gerne folgendes mit Hilfe der Powershell lösen.
Ich habe auf einem Server einen Ordner, nennen wir ihn "basisordner" und diesem sind mehrere unterordner mit wiederum unterordnern.
Ich möchte nun mittels Powershell alle Unterordner unter Basisordner auflisten und deren Größe ermitteln.

Bsp.:
Basisordner
\Unterordner 1
-\Unterordner 11
\Unterordner 2
\Unterordner 3
-\Unterordner 31
-\Unterordner 32

Als Ergebnis soll rauskommen:
Unterordner 1 1GB
Unterordner 2 500 MB
Unterordner 3 3GB

Ich denke mal dass das vorgehen so wäre, erst alle Ordner aufzulisten und dann die Dateigrößen aller Ordner (bzw. unterordner) zu summieren.
Die Ausgabe als TXT / CSV wäre ideal.

Gruß

Edit: Habe da etwas gefunden: http://technet.microsoft.com/en-us/library/ff730945
als txt kann ich das mittels Scriptaufruf und Ausgabeumleitung machen. Lässt sich dies denn noch eleganter lösen?

Edit2: Ich bekomme oft die Meldung, dass der Dateipfad zu lang ist
Mitglied: colinardo
12.11.2013, aktualisiert um 15:39 Uhr
Hallo killtec,
Edit2: Ich bekomme oft die Meldung, dass der Dateipfad zu lang ist face-sad
das mit den überlangen Pfaden größer 248 Zeichen ist schon Lange ein Problem von .Net:
http://social.technet.microsoft.com/Forums/scriptcenter/en-US/dedfd9e2- ...

Grüße Uwe
Bitte warten ..
Mitglied: colinardo
12.11.2013, aktualisiert 14.11.2013
Ohne jetzt das Problem mit den überlangen Pfaden zu beachten(experimentiere noch an einer Lösung) kannst du die Größen der Ordner nach Größe sortiert folgendermaßen in eine CSV-Datei exportieren:
01.
function parseFolders($sFolder){ 
02.
    $allFolders = get-childitem $sFolder -ErrorAction SilentlyContinue |?{$_.PSIsContainer}     
03.
    foreach ($f in $allFolders){ 
04.
        $size = (get-childitem $f.FullName -ErrorAction SilentlyContinue | ?{!($_.PSIsContainer)} | Measure-Object -Property Length -Sum -ErrorAction SilentlyContinue).Sum 
05.
        $folderSum += $size 
06.
        parseFolders $f.FullName 
07.
        if ($f.Parent.FullName -eq $global:startFolder){ 
08.
            echo "$($f.FullName) hat eine Größe von $([MATH]::Round($folderSum / (1024*1024),2)) MB" 
09.
            $global:folderList += New-Object PSObject -Property @{"Ordner"=$f.FullName;"Größe"="$([MATH]::Round($folderSum / (1024*1024),2)) MB"} 
10.
            $folderSum = 0     
11.
12.
13.
 
14.
15.
 
16.
$global:startFolder = "C:\temp\source" 
17.
$csvDatei = "C:\temp\test.csv" 
18.
$global:folderList = @() 
19.
parseFolders $startFolder 
20.
$global:folderList | select Ordner,Größe | Sort-Object -Property Größe -Descending | Export-Csv -Path $csvDatei -Delimiter ";" -NoTypeInformation -Encoding UTF8
Zeile 16 und 17 anpassen.

Grüße Uwe
Bitte warten ..
Mitglied: killtec
14.11.2013 um 08:12 Uhr
Hi Uwe,
irgendwie mag das Script nicht so recht. Die csv ist 1KB groß und leer
Habe lange Dateipfade da zwischen und auch Sonderzeichen (deutsche Sonderzeichen). Ist das evtl. ein Problem?

Gruß
Bitte warten ..
Mitglied: colinardo
14.11.2013, aktualisiert um 09:05 Uhr
Dann eliminiere zuerst die langen Pfade.
Um zu ermitteln welche Pfade mehr wie 248 Zeichen haben, kannst du folgende Funktion nutzen:
(Den Startpfad gibst du in der letzten Zeile des Scripts ein)
01.
Function Get-LongPaths { 
02.
 
03.
param( 
04.
    [CmdletBinding()] 
05.
    [Parameter( 
06.
    Position=0,  
07.
    Mandatory=$true,  
08.
    ValueFromPipeline=$true, 
09.
    ValueFromPipelineByPropertyName=$true)] 
10.
    [string[]] 
11.
        $FolderPath, 
12.
    [ValidateRange(10,248)] 
13.
	[int] 
14.
		$MaxChars=248 
15.
16.
 
17.
    begin { 
18.
        if (!(Test-Path -Path $(Join-Path $env:SystemRoot 'System32\robocopy.exe'))) { 
19.
            write-warning "Robocopy wurde nicht gefunden, bitte installieren Sie Robocopy um diese Funktion nutzen zu können!" 
20.
            return 
21.
22.
23.
 
24.
    process { 
25.
        $regex = [Regex] "\t" 
26.
        foreach ($Path in $FolderPath) { 
27.
            $RoboOutput = robocopy.exe $Path c:\temp /l /e /b /np /fp /njh /njs /r:0 /w:0 
28.
  
29.
            $RoboOutput | Where-Object {$_} | 
30.
            ForEach-Object { 
31.
                $CurrentPath =  $regex.Split($_)[2] 
32.
                if ($CurrentPath.Length -gt $MaxChars) { 
33.
                    New-Object -TypeName PSCustomObject -Property @{ 
34.
                        FullName = $CurrentPath 
35.
                        PfadLänge = $CurrentPath.Length 
36.
                        Type = if ($CurrentPath.SubString($CurrentPath.Length-1,1) -eq '\') { 
37.
                                   'Ordner' 
38.
                               } else { 
39.
                                   'Datei' 
40.
41.
42.
43.
44.
45.
46.
47.
 
48.
Get-LongPaths -FolderPath 'C:\Startpfad'
Die Funktion entstammt im Ursprung von hier, wurde aber von mir verbessert. Sie benötigt als Voraussetzung das 'robocopy' installiert ist.

Es ist ein Witz das MS den Umstand mit den langen Pfaden noch nicht mal mit PS4.0 bzw. Net 4.5 behoben hat...

Grüße Uwe
Bitte warten ..
Mitglied: killtec
15.11.2013 um 10:20 Uhr
Hi Uwe,
sorry, hat etwas gedauert mit dem testen,
ist es richtig, dass die Asugabe leer bleibt? In Zeile 27 hast du noch das Verzeichnis c:\temp stehen. das wäre dann das Zeil korrekt?
Wird dies nur als temporär genutzt, bzw. nur dazu, dass ein Verzeichnis da steht? Das Verzeichnis gibt es bei mir z.b. nicht.

Gruß
Bitte warten ..
Mitglied: colinardo
15.11.2013 um 10:26 Uhr
Zitat von killtec:
ist es richtig, dass die Asugabe leer bleibt? In Zeile 27 hast du noch das Verzeichnis c:\temp stehen. das wäre dann das Zeil
korrekt?
Wird dies nur als temporär genutzt, bzw. nur dazu, dass ein Verzeichnis da steht? Das Verzeichnis gibt es bei mir z.b.
nicht.
Das Verzeichnis C:\temp ist nur ein Dummy für Robocopy es wird nicht erstellt bzw. muss nicht existieren.
Wenn die Ausgabe leer ist, sind in dem Ordner und Unterordnern keine überlangen Ordnernamen.
Hier geht diese Überprüfung einwandfrei (PS3.0 Win7x64).
Bitte warten ..
Mitglied: killtec
15.11.2013 um 11:03 Uhr
Ok,
habe das jetzt mal direkt auf meinem PC laufen lassen (also das Script mit den Ordnergrößen).
Ich bkomme folgende Meldung:
01.
PS C:\> .\foldersize_script.ps1 
02.
Skriptfehler aufgrund eines Überlaufs der Aufruftiefe. Die Aufruftiefe hat 1001 
03.
 erreicht. Der Höchstwert lautet 1000. 
04.
    + CategoryInfo          : InvalidOperation: (1001:Int32) [], ParentContain 
05.
   sErrorRecordException 
06.
    + FullyQualifiedErrorId : CallDepthOverflow
Diese Meldung sagt mir nicht so wirklich etwas. Außer, dass evtl. zu vile Aufrufe gemacht wurden?

Gruß
Bitte warten ..
Mitglied: Tsunami87
17.02.2014, aktualisiert um 15:52 Uhr
Hallo,

ich setz mal hier an.
Da die obigen Powershell-Befehle auf Fehler laufen.(Die Aufruftiefe hat 1001erreicht. Der Höchstwert lautet 1000.)

Sind diese an den Start gekommen:
01.
$Content = Get-Content 'c:\Schreiben\Content2.txt' 
02.
foreach($Content in $content) 
03.
{$colItems = (Get-ChildItem $content -recurse | Measure-Object -property length -sum) 
04.
"$content" + " " + "{0:N2}" -f ($colItems.sum / 1MB) +  " MB"  
05.
}
In Content2.txt stehen ca.100 Einträge.
Dauer ca. 25min.

Gibt es paar Kniffe die Abfrage zu beschleunigen?


Über Tips und Vorschläge wäre ich sehr dankbar.

Grüße
René
Bitte warten ..
Mitglied: colinardo
17.02.2014, aktualisiert um 17:24 Uhr
tach auch,
du verwendest zwei gleich lautende Variablen in deinem ForEach() Konstrukt: $Content und $content das solltest du unbedingt vermeiden und eine separate Variable verwenden:
01.
$Content = Get-Content 'c:\Schreiben\Content2.txt' 
02.
foreach($line in $content){ 
03.
  $colItems = (Get-ChildItem $line -recurse | Measure-Object -property length -sum) 
04.
  "$line" + " " + "{0:N2}" -f ($colItems.sum / 1MB) +  " MB"  
05.
}
ansonsten nutze mal testweise u.s. Code. Denke zwar das es nicht viel schneller sein wird, aber das ist nun mal in Windows so, dass dies seine Zeit dauert. In der Win32 API gibt es auch keine schnellere Methode. Selbst der Windows Explorer benötigt hier eben solange wenn man die Eigenschaften für einen Ordner aufruft der zig tausende Files und Unterordner beinhaltet.
01.
function initCode() { 
02.
    [String]$SourceCode = @" 
03.
Namespace colinardo 
04.
    Public Class MyFunctions 
05.
        Public Shared Function GetDirectorySize(ByVal sPath As String) As Long 
06.
            Dim lngSize As Long = 0 
07.
            Try 
08.
                Dim diDir As New System.io.DirectoryInfo(sPath) 
09.
                Dim file As System.io.FileInfo 
10.
                For Each file In diDir.GetFiles() 
11.
                    lngSize += file.Length 
12.
                Next 
13.
                Dim subDirInfo As System.io.DirectoryInfo 
14.
                For Each subDirInfo In diDir.GetDirectories() 
15.
                    lngSize += GetDirectorySize(subDirInfo.FullName) 
16.
                Next 
17.
            Catch ex as System.Exception 
18.
            End Try 
19.
            Return lngSize 
20.
        End Function 
21.
    End Class 
22.
End Namespace 
23.
"@ 
24.
 add-type -TypeDefinition $SourceCode -Language VisualBasic 
25.
26.
initCode 
27.
 
28.
$Content = Get-Content 'c:\Schreiben\Content2.txt' 
29.
foreach($line in $content){ 
30.
  "$line" + " " + "{0:N2}" -f ([colinardo.MyFunctions]::GetDirectorySize($line) / 1MB) + " MB" 
31.
}
Grüße Uwe
Bitte warten ..
Mitglied: Tsunami87
18.02.2014 um 06:52 Uhr
Morgen Uwe,

Danke für den Tipp!

Dein Vorschlag läuft Lokal schneller.
Verwende ich eine Netzwerkresource ist die Geschwindigkeit, gefühlt, gleich.


Grüße
René
Bitte warten ..
Neuester Wissensbeitrag
Festplatten, SSD, Raid

12TB written pro SSD in 2 Jahren mit RAID5 auf Hyper-VServer

Erfahrungsbericht von Lochkartenstanzer zum Thema Festplatten, SSD, Raid ...

Ähnliche Inhalte
Batch & Shell
gelöst PowerShell Script Move-Item nach x Tagen (5)

Frage von lupolo zum Thema Batch & Shell ...

Batch & Shell
gelöst Powershell - In Textdatei suchen und ersetzen (5)

Frage von Raaja89 zum Thema Batch & Shell ...

Batch & Shell
gelöst PowerShell Domain Join (2)

Frage von Patrick-IT zum Thema Batch & Shell ...

Heiß diskutierte Inhalte
Windows Userverwaltung
Ausgeschiedene Mitarbeiter im Unternehmen - was tun mit den AD Konten? (34)

Frage von patz223 zum Thema Windows Userverwaltung ...

LAN, WAN, Wireless
gelöst Server erkennt Client nicht wenn er ausserhalb des DHCP Pools liegt (28)

Frage von Mar-west zum Thema LAN, WAN, Wireless ...

LAN, WAN, Wireless
FritzBox, zwei Server, verschiedene Netze (21)

Frage von DavidGl zum Thema LAN, WAN, Wireless ...

Viren und Trojaner
Aufgepasst: Neue Ransomware Goldeneye verbreitet sich rasant (20)

Link von Penny.Cilin zum Thema Viren und Trojaner ...