Mit Batch den freien Laufwerkspeicher in GB auslesen

biohazard261

Cadet 4th Year
Registriert
Aug. 2011
Beiträge
81
Hallo Zusammen,

ich bin total neu im batch scripting und soll ein Möglichkeit finden mittels Batch Skript den freien Speicher eines Netzlaufwerks auszulesen und z.B. mit Datum und Zeit in einer csv zu speichern. Der Speicher soll dabei in GB ausgelesen werden.

Ich habe schon einige Zeit im Netz nach einer Lösung gesucht, die gefundenen funktionierten aber nicht. Bis auf eine:

REM Keine Ausgaben

@ECHO OFF


REM Variable verz setzen (mit dem Pfad des zu messendem Ordners)

REM Variable groesse auf 0 setzen.

SET verz=I:\TEMP

SET groesse=0



REM Von jeder Datei in dem Ordner (und dem Unterordner) die Dateigröße

REM auslesen und addieren. groesse=Summe aller Dateigrößen

FOR /F "tokens=" %%a IN ('DIR /S /A-D /B %verz%\.*') DO (

SET /A groesse+=%%~za

)


REM Wenn groesse = (GTR) größer als 1073741824 dann

REM handelt es sich um Gigabyte. Nachkomma errechnen

IF /I %groesse% GTR 1073741824 (

SET /A nachkomma=%groesse% %% 1073741824

SET /A groesse/= 1073741824

SET unit=GB

)

REM Wenn groesse größer 1048576 dann handelt es sich um MegaByte

ELSE (

IF /I %groesse% GTR 1048576 (

SET /A nachkomma=%groesse% %% 1048576

SET /A groesse/= 1048576

SET unit=MB

) ELSE (

IF /I %groesse% GTR 1024 (

SET /A nachkomma=%groesse% %% 1024

SET /A groesse/=1024

SET unit=kB

) ELSE (

SET /A nachkomma=0

SET unit=B

)

)

)


REM Ausgabe von Date und Time und groesse in Datei umleiten

echo %DATE% >> H:\csvdatei.txt

echo %TIME% >> H:\csvdatei.txt

ECHO Groesse: %groesse%,%nachkomma:~0,2%%unit% >> C:\csvdatei.txt

Die ausgegebene Größe ist aber falsch. es sollten ca 7,5 GB oder bei einem anderen Laufwerk 45 GB ausgegeben werden, aber es kommt ein Wert heraus, der weder der freie, noch belegte, noch Gesamtspeicher ist. Und zusaätzlich sind Datum, Zeit und Größe in der csv nicht durch ein semicolon getrennt.

hoffe mir kann da jemadn helfen.
danke schonmal
 
Auseinander basteln musst du selbst
Code:
@echo off & setlocal ENABLEDELAYEDEXPANSION
SET "volume=C:"
FOR /f "tokens=1*delims=:" %%i IN ('fsutil volume diskfree %volume%') DO (
    SET "diskfree=!disktotal!"
SET "disktotal=!diskavail!"
SET "diskavail=%%j"
)
FOR /f "tokens=1,2" %%i IN ("%disktotal% %diskavail%") DO SET "disktotal=%%i"& SET "diskavail=%%j"
ECHO(total  %disktotal:~0,-9% GB
ECHO(avail. %diskavail:~0,-9% GB
 
Alternative mit Powershell:

PowerShell:
Get-WMIObject Win32_Logicaldisk | where {$_.DriveType -eq 4} | select DeviceID,@{Name = 'FreeGB'; Expression = {[Math]::Round($_.FreeSpace/[Math]::Pow(1024,3),2)}}

DriveType für Netzlaufwerke ist 4, so kannst du gleich alle anderen Sachen rausfiltern.
 
Oder mit "Get-PSDrive"
1588841691171.png


E: Get-PsDrive wurde ja schon genannt...
 
  • Gefällt mir
Reaktionen: Mar1u5
als Alternative

wmic logicaldisk where (caption='C:') get freespace
 
Noch eine, schon im RL gesehene, Lösung
Auf einem Rechner mit Linux minütlich eine Textdatei mit dem freiem Speicher in die Freigabe schreiben lassen und die dann aufm Windowsrechner per Batch einlesen.
 
biohazard261 schrieb:
ch bin total neu im batch scripting und soll ein Möglichkeit finden mittels Batch Skript
Warum gibt man denn dir die Aufgabe, wenn du kein Batch kannst? In Zukunft wirst du dann wohl oefters Batch Skripte erstellen?
Warum muss es immer Batch sein?
 
xammu schrieb:
Auseinander basteln musst du selbst
Code:
@echo off & setlocal ENABLEDELAYEDEXPANSION
SET "volume=C:"
FOR /f "tokens=1*delims=:" %%i IN ('fsutil volume diskfree %volume%') DO (
    SET "diskfree=!disktotal!"
SET "disktotal=!diskavail!"
SET "diskavail=%%j"
)
FOR /f "tokens=1,2" %%i IN ("%disktotal% %diskavail%") DO SET "disktotal=%%i"& SET "diskavail=%%j"
ECHO(total  %disktotal:~0,-9% GB
ECHO(avail. %diskavail:~0,-9% GB

Danke, hab das jetzt so zu sammengesetzt:
@echo off & setlocal ENABLEDELAYEDEXPANSION
SET "volume=I:"
FOR /f "tokens=1*delims=:" %%i IN ('fsutil volume diskfree %volume%') DO (
SET "diskfree=!disktotal!"
SET "disktotal=!diskavail!"
SET "diskavail=%%j"
)
FOR /f "tokens=1,2" %%i IN ("%disktotal% %diskavail%") DO SET "disktotal=%%i"& SET "diskavail=%%j"
ECHO(total %disktotal:~0,-9% GB
ECHO(avail. %diskavail:~0,-9% GB

echo %DATE%; >> H:\Speicherbelegung2.txt
echo %TIME%; >> H:\Speicherbelegung2.txt
echo ?????? GB >> H:\Speicherbelegung2.txt

Was muss ich bei ?????? einsetzen damit er mir den Wert des freien Speichers in GB ausspuckt? Und bei der Zeit gibt er mir jetzt 14:56:45,80 aus. Am besten wäre zb 14:56


abcddcba schrieb:
Warum gibt man denn dir die Aufgabe, wenn du kein Batch kannst? In Zukunft wirst du dann wohl oefters Batch Skripte erstellen?
Warum muss es immer Batch sein?
Zum Lernen damit umzugehen und weil dieses Problem gerade ansteht. SPäter soll die Batchdatei mit windowsstart starten und den freien Speicher protokollieren.
 
Wie wärs mit dem Teil %diskavail... ? Ein wenig mitdenken kann man doch wohl
 
xammu schrieb:
Wie wärs mit dem Teil %diskavail... ? Ein wenig mitdenken kann man doch wohl
Ja, das habe ich gestern auch versucht, aber dann wurde: (450 ausgespuckt.

Edit: Habe es nun noch paar mal ausprobiert, dann kommt unter anderem einfach nur "v" oder "Echo ist ausgeschaltet (OFF)".
 
Zuletzt bearbeitet:
Die Syntax von "xammu" ist fehlerhaft, zumindest bei Win10:
  1. Der Befehl "fsutil volume diskfree %volume%" funktioniert nicht mit Netzlaufwerken.
  2. Die Werte werden bei der 2. FOR-Schleife falsch ausgelesen.
  3. In den letzten 2 Zeilen werden von den Byte-Zahlen (wenn die 2. FOR-Schleife korrekt wäre) einfach die letzten 9 Stellen entfernt. So werden die GByte wie bei HDD-Herstellern angezeigt (1 GB = 1.000.000.000 Bytes).
----------------------------------------------------

Dein Script aus deinem Start-Post hat auch einige Fehler. Vor allem zeigt es den belegten Speicher und nicht den freien Speicher an.

Einige haben ja schon eine Alternative mit Powershell gepostet.
Aber wenn du unbedingt eine Batch haben möchtest, hier ist mein Code. Einfach als Batch-Datei abspeichern. Funktioniert in einem deutschen Win10 mit deutschen MS-Excel (auslesen der CSV-Datei) ohne Probleme. Bei anderen Windows-Sprachversionen oder einem anderen Programm als Excel muss man den Code anpassen.

Unklar ist noch, was du genau in der CSV-Datei haben möchtest? Das Script trägt jetzt das Datum, die Uhrzeit und den freien Speicher mit 3 Nachkommastellen ein.

Code:
@ECHO OFF

REM Variable "Laufwerk" mit Laufwerksbuchstabe vom Netzlaufwerk setzen
SET Laufwerk=Z:

REM Den "Bytes frei"-Wert vom DIR-Befehl auslesen
FOR /F "tokens=3" %%i IN ('DIR %Laufwerk%^|FIND /I "Bytes frei"') DO SET Freier_Speicher_in_Byte=%%i

REM Vom "Bytes frei"-Wert die Punkte für die Zifferngruppierung löschen
SET Freier_Speicher_in_Byte=%Freier_Speicher_in_Byte:.=%

REM VBScript-Datei erstellen
REM Grund: Das "SET /A" in Batches kann nicht mit Werten über 2.147.483.647 arbeiten.
ECHO Set objArg = WScript.Arguments > Byte_to_GiB.vbs
ECHO Wert_in_Byte = objArg(0) >> Byte_to_GiB.vbs
ECHO Wert_in_GiB = Wert_in_Byte / 1073741824 >> Byte_to_GiB.vbs
ECHO Wert_in_GiB = FormatNumber(Wert_in_GiB, 3)   ' 3 = Anzahl der Nachkommastellen >> Byte_to_GiB.vbs
ECHO WScript.Echo Wert_in_GiB >> Byte_to_GiB.vbs
ECHO WScript.Quit >> Byte_to_GiB.vbs

REM VBScript-Datei ausführen und den Rückgabe-Wert aufnehmen
FOR /F %%i IN ('cscript Byte_to_GiB.vbs %Freier_Speicher_in_Byte% //Nologo') DO SET Freier_Speicher_in_GiB=%%i

REM VBScript-Datei löschen
DEL Byte_to_GiB.vbs

REM Uhrzeit ohne Millisekunden erstellen
FOR /F "delims=:, tokens=1,2,3" %%i IN ("%TIME%") DO SET Zeit=%%i:%%j:%%k

REM Leerzeichen bei einstelliger Stundenzahl löschen
SET Zeit=%Zeit: =%

REM Daten in eine Datei schreiben.
ECHO %DATE%;%Zeit%;"%Freier_Speicher_in_GiB%">> E:\CSVDatei.csv
 
Zuletzt bearbeitet: (Code optimiert.)
Darkman.X schrieb:
Die Syntax von "xammu" ist fehlerhaft, zumindest bei Win10:
  1. Der Befehl "fsutil volume diskfree %volume%" funktioniert nicht mit Netzlaufwerken.
  2. Die Werte werden bei der 2. FOR-Schleife falsch ausgelesen.
  3. In den letzten 2 Zeilen werden von den Byte-Zahlen (wenn die 2. FOR-Schleife korrekt wäre) einfach die letzten 9 Stellen entfernt. So werden die GByte wie bei HDD-Herstellern angezeigt (1 GB = 1.000.000.000 Bytes).
----------------------------------------------------

Dein Script aus deinem Start-Post hat auch einige Fehler. Vor allem zeigt es den belegten Speicher und nicht den freien Speicher an.

Einige haben ja schon eine Alternative mit Powershell gepostet.
Aber wenn du unbedingt eine Batch haben möchtest, hier ist mein Code. Einfach als Batch-Datei abspeichern. Funktioniert in einem deutschen Win10 mit deutschen MS-Excel (auslesen der CSV-Datei) ohne Probleme. Bei anderen Windows-Sprachversionen oder einem anderen Programm als Excel muss man den Code anpassen.

Unklar ist noch, was du genau in der CSV-Datei haben möchtest? Das Script trägt jetzt das Datum, die Uhrzeit und den freien Speicher mit 3 Nachkommastellen ein.

Code:
@ECHO OFF

REM Variable "Laufwerk" mit Laufwerksbuchstabe vom Netzlaufwerk setzen
SET Laufwerk=Z:

REM Den "Bytes frei"-Wert vom DIR-Befehl auslesen
FOR /F "tokens=3" %%i IN ('DIR %Laufwerk%^|FIND /I "Bytes frei"') DO SET Freier_Speicher_in_Byte=%%i

REM Vom "Bytes frei"-Wert die Punkte für die Zifferngruppierung löschen
SET Freier_Speicher_in_Byte=%Freier_Speicher_in_Byte:.=%

REM VBScript-Datei erstellen
REM Grund: Das "SET /A" in Batches kann nicht mit Werten über 2.147.483.647 arbeiten.
ECHO Set objArg = WScript.Arguments > Byte_to_GiB.vbs
ECHO Wert_in_Byte = objArg(0) >> Byte_to_GiB.vbs
ECHO Wert_in_GiB = Wert_in_Byte / 1073741824 >> Byte_to_GiB.vbs
ECHO Wert_in_GiB = FormatNumber(Wert_in_GiB, 3)   ' 3 = Anzahl der Nachkommastellen >> Byte_to_GiB.vbs
ECHO WScript.Echo Wert_in_GiB >> Byte_to_GiB.vbs
ECHO WScript.Quit >> Byte_to_GiB.vbs

REM VBScript-Datei ausführen und den Rückgabe-Wert aufnehmen
FOR /F %%i IN ('cscript Byte_to_GiB.vbs %Freier_Speicher_in_Byte% //Nologo') DO SET Freier_Speicher_in_GiB=%%i

REM VBScript-Datei löschen
DEL Byte_to_GiB.vbs

REM Uhrzeit ohne Millisekunden erstellen
FOR /F "delims=:, tokens=1,2,3" %%i IN ("%TIME%") DO SET Zeit=%%i:%%j:%%k

REM Leerzeichen bei einstelliger Stundenzahl löschen
SET Zeit=%Zeit: =%

REM Daten in eine Datei schreiben.
ECHO %DATE%;%Zeit%;"%Freier_Speicher_in_GiB%">> E:\CSVDatei.csv

Perfekt, danke , es funktioniert. Und danke für deine Erklärungen, die sind extrem hilfreich zum Verständnis.
Ich werde morgen mal schauen, wie genau die Daten weiterverarbeitet werden sollen. Aktuell werden sie einmal täglich händisch in eine Excel-Tabelle eingetragen und die Differenz zum Vortag berechnet. Als nächstes soll das Batchskript dann optimalerweise beim windows start ausgeführt werden, dann ist quasi kein handschlag mehr nötig.
 
Nachdem ich mir den Code nochmal angeschaut habe, konnte ich den sogar noch wesentlich vereinfachen, mit Hilfe vom Text vom User "kartoffelpü".

Zeile 4 von der vorherigen Version wurde verändert (Doppelpunkt entfernt)
Zeilen 6-25 von der vorherigen Version wurden zu einem PowerShell-Befehl zusammengeschrumpft.
Zeile 28 von der vorherigen Version (die Erstellung der Variable "Zeit") wurde vereinfacht.

(Bei mir durchläuft Code immer einer Evolution. Erstmal muss er funktionieren, dann wird optimiert. Vermutlich ein schlechter Stil.)

Code:
@ECHO OFF

REM Variable "Laufwerk" mit Laufwerksbuchstabe vom Netzlaufwerk setzen
SET Laufwerk=Z

REM Den freien Speicher über ein Powershell-Befehl auslesen
FOR /F %%i IN ('powershell ^(Get-PSDrive -Name %Laufwerk%^).Free/1GB') DO SET Freier_Speicher_in_GiB=%%i

REM Uhrzeit ohne Millisekunden erstellen
FOR /F "delims=, tokens=1" %%i IN ("%TIME%") DO SET Zeit=%%i

REM Leerzeichen bei einstelliger Stundenzahl löschen
SET Zeit=%Zeit: =%

REM Daten in eine Datei schreiben.
ECHO %DATE%;%Zeit%;"%Freier_Speicher_in_GiB%">> E:\CSVDatei.csv
 
Wenn es denn irgendwann später doch mal PowerShell sein soll, was zu empfehlen ist, hier noch eine Möglichkeit:

PowerShell:
Add-Type -Name Window -Namespace Console -MemberDefinition @"
[DllImport("Kernel32.dll")]
public static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, Int32 nCmdShow);
"@

[Void][Console.Window]::ShowWindow([Console.Window]::GetConsoleWindow(),0)

<#
-------------------------------------------------------------
Zeile 33.......: Where {$_.Name -Match 'Laufwerksbuchstabe'}   
Zeile 36, 37...: (1gb) -> in Gigabyte
                 (1mb) -> in Megabyte
                 (1kb) -> in Kilobyte
Zeile 38, 39...: {0:N2} -> zwei Stellen hinter dem Komma
                 {0:N3} -> drei Stellen hinter dem Komma usw.
Zeile 49.......: Desktop aktueller Benutzer: $Home\Desktop\
                 alternativ:
                 Desktop alle Benutzer: $Env:PUBLIC\Desktop\
Zeile 50.......: Textdatei kann direkt nach dem Speichern
                 aufgerufen werden (Zeichen # entfernen)
-------------------------------------------------------------
#>

Function GetFreeSpace {

    $Culture = New-Object System.Globalization.CultureInfo("de-DE")
    $Date = Get-Date
    $DTdayt = $Date.ToString("dddd, dd. MMMM yyyy",$Culture)
    $DTtime = $Date.ToString("HH:mm:ss",$Culture) + " Uhr"

    $Drive0 = [System.IO.DriveInfo]::GetDrives() | Where {$_.Name -Match 'C'} | `
    Select Name,AvailableFreeSpace,TotalSize
    $Disk0LW = ($Drive0.Name).Split(":\")[0]
    $Disk0AvFrSpace = ($Drive0.AvailableFreeSpace) / (1gb)
    $Disk0TotalSize = ($Drive0.TotalSize) / (1gb)
    $Disk0AV = "{0:N2} GB" -F $Disk0AvFrSpace
    $Disk0TS = "{0:N2} GB" -F $Disk0TotalSize
    $Disk0MathDivis = ($Disk0AvFrSpace/$Disk0TotalSize)
    $Disk0PR = "{0:P2}" -F $Disk0MathDivis
    $Disk0AP = "($Disk0PR)"

    [String]$DskD0 = "Datum....................: $DTdayt`r`n" `
    + "Systemzeit...............: $DTtime`r`n`r`n" `
    + "Laufwerk.................: $Disk0LW`r`n" `
    + "Kapazität................: $Disk0TS`r`n" `
    + "Frei.....................: $Disk0AV $Disk0AP`r`n"
    $DskD0 | Out-File "$Home\Desktop\GetFreeSpace.txt" -Encoding UTF8 -Force
    #Invoke-Item "$Home\Desktop\GetFreeSpace.txt"
}
GetFreeSpace

Sauber formatiert und in einer Textdatei abgespeichert, so sollte es sein.
Den Code einfach in einen Texteditor kopieren und die Datei dann mit dem Dateiformat .ps1 abspeichern.
 
TOP, ich danke euch. Jetzt wurde ja öfter erwähnt, das powershell eher zu empfehlen ist, warum genau? ist batch einfach zu veraltet?
 
Darkman.X schrieb:
Nachdem ich mir den Code nochmal angeschaut habe, konnte ich den sogar noch wesentlich vereinfachen, mit Hilfe vom Text vom User "kartoffelpü".

Zeile 4 von der vorherigen Version wurde verändert (Doppelpunkt entfernt)
Zeilen 6-25 von der vorherigen Version wurden zu einem PowerShell-Befehl zusammengeschrumpft.
Zeile 28 von der vorherigen Version (die Erstellung der Variable "Zeit") wurde vereinfacht.

(Bei mir durchläuft Code immer einer Evolution. Erstmal muss er funktionieren, dann wird optimiert. Vermutlich ein schlechter Stil.)

Code:
@ECHO OFF

REM Variable "Laufwerk" mit Laufwerksbuchstabe vom Netzlaufwerk setzen
SET Laufwerk=Z

REM Den freien Speicher über ein Powershell-Befehl auslesen
FOR /F %%i IN ('powershell ^(Get-PSDrive -Name %Laufwerk%^).Free/1GB') DO SET Freier_Speicher_in_GiB=%%i

REM Uhrzeit ohne Millisekunden erstellen
FOR /F "delims=, tokens=1" %%i IN ("%TIME%") DO SET Zeit=%%i

REM Leerzeichen bei einstelliger Stundenzahl löschen
SET Zeit=%Zeit: =%

REM Daten in eine Datei schreiben.
ECHO %DATE%;%Zeit%;"%Freier_Speicher_in_GiB%">> E:\CSVDatei.csv
Gibt es auch eine so einfachen Befehl um die Gesamtspeicherkapazität auszulesen, suche schon aber finde nichts. Mit get PSdrive bekomme ich belegten und freien speicher ausgegeben, muss ich das dann über einen befehl addieren?
 
Pwershell ist für Microsoft die Zukunft, die normale Eingabeaufforderung wird immer mehr versteckt. Und Powershell ist auch wesentlich mächtiger, basiert auf .NET.

Zu deiner Gesamtkapazität: Ob es einen einzelnen Befehl gibt, weiß ich nicht, ich bin in Powershell nicht drin. Aber die Idee, den belegten Speicher und freien Speicher zu addieren, ist gut:

((Get-PSDrive -Name Z).Used/1GB) + ((Get-PSDrive -Name Z).Free/1GB)

Funktioniert sogar :)
 
Zurück
Oben