Wie erhalte ich die tatsächliche Größe einer Datei auf einer PowerShell-Datei?

8

Ich schreibe ein administratives Skript, und ich muss die Größe der Dateien auf der Festplatte berechnen.

Diese Dateien befinden sich auf einem komprimierten NTFS-Volume.

Ich kann FileInfo.Length nicht verwenden, da dies die Dateigröße und nicht die Größe auf der Festplatte ist. Wenn ich beispielsweise eine 100-MB-Datei habe, aber aufgrund der NTFS-Komprimierung nur 25 MB verwende, muss mein Skript 25 MB zurückgeben.

Gibt es eine Möglichkeit, dies in Powershell zu tun?

(Ich weiß über den GetCompressedFileSize() Win32-Aufruf, aber ich hatte gehofft, dass dies bereits auf einer bestimmten Ebene verpackt ist.)

    
JMarsch 16.02.2009, 18:03
quelle

6 Antworten

9

(bearbeiten)

Ich habe herausgefunden, wie man eine Eigenschaft (eine "Skripteigenschaft") dynamisch zum Dateiobjekt hinzufügt, also kann ich jetzt die Syntax: $ theFileObject.CompressedSize verwenden, um die Größe zu lesen.

(Ende der Bearbeitung)

Lesen Sie die Antwort von Goyuix, und ich dachte "Cool, aber gibt es in Powershell keine Art von Erweiterungsfunktionen?". Also habe ich diesen Scott Hanselman Beitrag gefunden: Ссылка

Und ich habe eine Script-Eigenschaft für das FileInfo-Objekt erstellt: CompressedSize.

Folgendes habe ich getan: (Anmerkung: Ich bin mit Powershell noch recht neu, oder zumindest benutze ich es nicht viel. Das könnte wahrscheinlich viel besser gemacht werden, aber hier ist was ich getan habe:

Zuerst habe ich die Ntfs.ExtendedFileInfo aus Goyuix's Beitrag kompiliert. Ich lege die DLL in mein PowerShell-Profilverzeichnis (Documents \ WindowsPowershell)

Als nächstes habe ich eine Datei in meinem Profilverzeichnis namens My.Types.ps1xml erstellt.

Ich habe folgende XML in die Datei eingefügt:

%Vor%

Dieser Code (sobald er in das Typsystem eingebunden wurde) fügt dynamisch eine Eigenschaft namens CompressedSize zu den FileInfo-Objekten hinzu, die von get-childitem / dir zurückgegeben werden. Aber Powershell weiß noch nichts über den Code und weiß noch nichts über meine DLL. Das erledigen wir im nächsten Schritt:

Bearbeiten Sie Profil.ps1. im selben Verzeichnis. Nun, meine Profildatei hat schon einige Sachen, weil ich die Community Extensions für Powershell installiert habe. Hoffentlich schließe ich alles, was Sie brauchen, in dieses nächste Code-Snippet ein, damit es auch auf einem Rechner funktioniert, der nicht über die Erweiterungen verfügt. Fügen Sie Profile.ps1 den folgenden Code hinzu:

%Vor%

Nun ist die Variable $ ProfileDir, die ich referenziere, früher in meinem Profile.ps1-Skript definiert. Nur für den Fall, dass es nicht in Ihrem ist, hier ist die Definition:

%Vor%

Das ist es. Wenn Sie Powershell das nächste Mal ausführen, können Sie auf die CompressedSize-Eigenschaft des FileInfo-Objekts zugreifen, als ob es sich um eine andere Eigenschaft handelt. Beispiel:

$ myFile = Verzeichnis c: \ temp \ myfile.txt

$ myFile.CompressedSize

Das funktioniert (jedenfalls auf meinem Rechner), aber ich würde gerne hören, ob es zu Best Practices passt. Eine Sache, von der ich weiß, dass ich etwas falsch mache: In der Datei Profile.ps1 gebe ich die Ergebnisse von LoadFile in eine Variable zurück, die ich nicht verwenden werde ($ null = blah blah). Ich habe das gemacht, um die Anzeige des Ergebnisses der Ladedatei auf der Konsole zu unterdrücken. Es gibt wahrscheinlich einen besseren Weg, es zu tun.

    
JMarsch 20.02.2009, 19:50
quelle
8

Laden Sie die verwaltete Windows API ( Ссылка <) / a>) und überprüfen Sie die ExtendedFileInfo-Klasse. Es gibt eine Methode GetPhysicalFileSize () , die die erforderliche Größe einer Datei auf der Festplatte zurückgibt.

%Vor%

Alternativ können Sie eine eigene DLL kompilieren und die Assembly für diese eine Funktion laden:

%Vor%

Dann zu kompilieren:

%Vor%

Und schließlich zum Laden und Ausführen in PowerShell:

%Vor%     
Goyuix 17.02.2009 17:33
quelle
5

Einfach mit V2 Add-Type und Pinvoke.NET zu tun:

%Vor%

Experiment! Genießen! Engage!

Jeffrey Snover [MSFT] Windows Management-Partnerarchitekt Besuchen Sie das Windows PowerShell-Teamblog unter: Ссылка Besuchen Sie das Windows PowerShell-Skriptcenter unter: Ссылка

    
Jeffrey Snover - MSFT 21.02.2009 16:31
quelle
2

Wenn Sie die verwaltete API nicht finden können, die Ihnen gefällt, ist es in PowerShell V2 wesentlich einfacher, eine Win32-API auf P / Invoice zu setzen. Lesen Sie PowerShell P / Invoke Walkthrough für Anweisungen.

    
Jay Bazuzi 18.02.2009 15:15
quelle
1

Beachten Sie, dass dies nicht die "Größe auf der Festplatte" zurückgibt, die der Windows Explorer anzeigt, insbes. für kleine Dateien.

Der (fast) korrekte Weg, um diese Informationen zu erhalten, ist unter Ermitteln der Größe auf Festplatte" für kleine Dateien in Powershell

    
user103035 20.06.2014 08:19
quelle
0

$ s = (kompakt / q C: \ was.dat | where-object {$ _. enthält ('total bytes')}). split ()}; $ s [8] .padleft (20) + $ s [0] .padleft (20)

    
Jan Kooy 03.07.2009 14:46
quelle

Tags und Links