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, 13309 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
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: Restspeicherplatz von C: und D: ermitteln

gelöst Frage von HeuristikerBatch & Shell7 Kommentare

Hallo Leute, nutze ein Powershell-Skript, dessen Kernbefehl den restlichen Plattenplatz ermittelt und in eine CSV-Datei exportiert: gwmi Win32_LogicalDisk -ComputerName ...

Batch & Shell

Windows RDP - Client Computername via Powershell ermitteln

gelöst Frage von adm2015Batch & Shell5 Kommentare

Hallo zusammen, ich hoffe mir kann hier jemand helfen. Ich bin auf der Suche nach einem Powershell Befehl welcher ...

Batch & Shell

Powershell Datum der zuletzt eingespielten Patche bei remote Servern ermitteln

gelöst Frage von bensonhedgesBatch & Shell18 Kommentare

Hallo, ich möchte gerne anhand einer Serverliste (bsp. computers.txt) via PS ermitteln, wann derjeweilige Server zuletzt gepatcht wurde (Liste ...

Neue Wissensbeiträge
Humor (lol)
Preisvertipper
Information von Dilbert-MD vor 2 TagenHumor (lol)7 Kommentare

Moin! weil heute Freitag ist, zeige ich Euch den Preisvertipper der Woche: vergesst den Acer Predator 21x, der ist ...

Windows Update
Sicherheitsupdate für SQL Server 2014 SP3
Information von sabines vor 3 TagenWindows Update2 Kommentare

Für den SQL Server 2014 existiert ein Sicherheitsupdate. Laut KB Artikel wird es als CU3 angezeigt: Server 2014 SP3 ...

Backup

Veeam Agent für MS Windows - neue Version verfügbar (bedingt jedoch offenbar .NET Framework 4.6)

Information von VGem-e vor 4 TagenBackup1 Kommentar

Moin Kollegen, einer unserer Server zeigte grad an, dass für o.g. Software ein Update verfügbar ist. Ob ein evtl. ...

Python

Sie meinen es ja nur gut - Microsoft hilft python-Entwicklern auf unnachahmliche Weise

Information von DerWoWusste vor 6 TagenPython2 Kommentare

Stellt Euch vor, Ihr nutzt python unter Windows 10 und skriptet damit regelmäßig Dinge. Nach dem Update auf Windows ...

Heiß diskutierte Inhalte
Cloud-Dienste
MS Sharepoint generelle Frage zur Einrichtung
Frage von ralf86Cloud-Dienste15 Kommentare

Hallo, ich will den Sharepoint als FileServer nutzen. Hier sollen mehrere Freigabeordner mit unterschiedlichen Berechtigungen erstellt werden z.B. Geschäftsführung ...

Router & Routing
FritzBox und SynologyNAS VPN
Frage von ndeedyRouter & Routing10 Kommentare

Moin moin. Irgendwie habe ich entweder ein bescheuertes Setup, oder mir bereits komplett die Birne mit Versuchen durchgebraten. Bin ...

Vmware
VMware Update 5.1 zu 6.7U4
gelöst Frage von patrickebertVmware8 Kommentare

Hallo alle zusammen, ich den nächsten Monaten steht für mich die Umstellung zwei neuer physikalischer Server an und ich ...

Outlook & Mail
Outlook 2016: Schrift der Ordnerspalte verkleinern
Frage von usercrashOutlook & Mail7 Kommentare

Hallo, wie/wo kann man in MS Outlook 2016 im Ordnerbereich am linken Bildrand die Schriften, die Überschriften und den ...