Top-Themen

Aktuelle Themen (A bis Z)

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

Mitglied: killtec

killtec (Level 3) - Jetzt verbinden

12.11.2013, aktualisiert 10:43 Uhr, 10825 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 ..
Ähnliche Inhalte
Windows 7
Offlineordner per Powershell ermitteln?
gelöst Frage von KromifanWindows 74 Kommentare

Hallo, wegen der Umstellung auf ein neues Exchange müssen die Arbeitsplatzrechner einen neuen Benutzer eingerichtet bekommen. Teilweise haben sich ...

Batch & Shell
Powershell - Fenstertitel ermitteln
gelöst Frage von internet2107Batch & Shell2 Kommentare

Hallo und guten Morgen zusammen, kann man, oder wie kann man den Fenstertitel eines offenen Prozesses mit Powershell ermitteln? ...

Batch & Shell
Powershell Treeview Tiefe ermitteln
gelöst Frage von H41mSh1C0RBatch & Shell14 Kommentare

Hi@PS Profis, mir ist der Codeschnipsel von Uwe wieder in die in die Finger gefallen. Jetzt wollte ich parseXML ...

Batch & Shell

PowerShell Ordnergröße Skript ignoriert versteckte Dateien

gelöst Frage von GiffasBatch & Shell3 Kommentare

Guten Tag zusammen, ich habe folgendes Skript im Netz gefunden und würde damit gerne Ordnergrößen auswerten: Jedoch ist mir ...

Neue Wissensbeiträge
Sicherheit

MikroTik-Router patchen, Schwachstelle wird ausgenutzt

Information von kgborn vor 7 StundenSicherheit

Am 23. April 2018 wurde von Mikrotik ein Security Advisory herausgegeben, welches auf eine Schwachstelle im RouterOS hinwies. Mikrotik ...

Windows 10

Microcode-Updates KB4090007, KB4091663, KB4091664, KB4091666 für Windows 10

Information von kgborn vor 14 StundenWindows 101 Kommentar

Kurze Information für Administratoren von Windows 10-Systemen, die mit neueren Intel CPUs laufen. Microsoft hat zum 23. April 2018 ...

iOS
Updates für Iphone und Co
Information von sabines vor 17 StundeniOS

Gestern abend ist iOS 11.3.1 erschienen, ein kleineres Update, dass einige Lücken schließt und "Lahmlegen" nach einem Display Tausch ...

Windows 7

Windows 7 - Server 2008 R2: Exploit für Total Meltdown verfügbar

Information von kgborn vor 2 TagenWindows 7

Kleine Information für Administratoren, die für die Updates von Windows 7 SP1 und Windows Server 2008 R2 SP1 verantwortlich ...

Heiß diskutierte Inhalte
Batch & Shell
Powershell: Im AD nach Rechnern mit bestimmten IP-Adressen suchen
gelöst Frage von Raven42Batch & Shell36 Kommentare

Hallo zusammen, ich suche nach einer Möglichkeit nach Computern im AD zu suchen , deren IP-Adresse mit 10.11.12. beginnt. ...

C und C++
Frage1 C Programmierung-Makefile Frage2 PHP-Programmierung HTTP-Fehler 404
Frage von KatalinaC und C++34 Kommentare

Hallo, ich habe 2 Fragen, die nichts miteinander zu tun haben aber mit denen ich mich gerade beschäftige: 1. ...

LAN, WAN, Wireless
Watchguard T15 VPN Einrichtung
gelöst Frage von thomasjayLAN, WAN, Wireless25 Kommentare

Hallo zusammen, wir möchten gerne über unsere Watchguard T15 einen VPN-Tunnel (Mobile VPN with IPSec) einrichten! Als Client nutzen ...

Windows Server
Alten DC entfernen
Frage von smartinoWindows Server24 Kommentare

Hallo zusammen, ich habe hier eine Umgebung übernommen und erstmal einen DCDIAG gemacht. Dabei fällt auf, daß eine ganze ...