I would like help making a batch script to test if there is a certain amount of storage available in a drive in Winodws 7, thanks in advance.
fsutil volume diskfree C: | find /i "avail free"
I had this squirreled away from a previous request.
#echo off
set "low="
for /f "tokens=3" %%a in ('dir c:\ /-p 2^>nul') do set "size=%%a"
for /f "tokens=1-4 delims=," %%a in ("%size%") do (
if "%%d"=="" set low=1
set gb=%%a
set mb=%%b
)
if %gb%%mb% LEQ 2000 set low=1
If defined low (
echo email here with %size%
echo WARNING: Drive C: has %size% free
) else (
echo Drive C: has %gb%.%mb% free GB
)
pause
Related
This code returns the disk size and space in GB. The problem is, it's only using C and i have to hard-code it.
What i'm trying is, it should iterate over all of the disks and i shouldn't have to write the disk part myself. All of my experiments were failure, i couldn't solve.
for /f "tokens=1-3" %%n in ('"WMIC LOGICALDISK GET Name,Size,FreeSpace | find /i "C:""') do set free=%%n& set total=%%p
set free=%free:~0,-3%
set /a free=%free%/1049
set total=%total:~0,-3%
set /a total=%total%/1049
set /a free=%free%/1024
echo C: Space Free- %free% GB
set /a total=%total%/1024
echo C: Space total- %total% GB
Something like this? It is a little sloppy but I think it does what you are asking for using the batch you (mostly) wrote.
I am using a batch function to get the variables out of the for /f loop. You could have also used delayed expansion. I find the whole !syntax! annoying but it seems that most people prefer it to batch functions.
#echo off
for /f "tokens=1-3" %%n in ('"WMIC LOGICALDISK GET Name,Size,FreeSpace"') do call :calculate "%%n" "%%o" "%%p"
goto :EOF
:calculate
set free=%~1
set drive=%~2
set total=%~3
if "%drive%"=="" goto :EOF
if not "%drive:~1%"==":" goto :EOF
echo ---- information for drive %drive% ----
set free=%free:~0,-3%
set /a free=%free%/1049
set total=%total:~0,-3%
set /a total=%total%/1049
set /a free=%free%/1024
echo Free- %free% GB
set /a total=%total%/1024
echo Total- %total% GB
goto :EOF
Below is part of a script i've previously written to grab drive information that is echoed to screen, written to a text file and also into a CSV.
#echo off
set "pathBackup=C:\backup"
set "infoFileName=%computername%_DriveSize.txt"
set "csvFile=All_DriveSizes.csv"
::Fix for CSV format output error on some systems
if exist "%WINDIR%\System32\wbem\en-us\csv.xsl" (
set csvformat="%WINDIR%\System32\wbem\en-us\csv"
) else (
set csvformat=csv
)
:: Get Drive Partition information
echo. - Looking for Drive sizes
setlocal EnableDelayedExpansion
for /f "skip=2 tokens=2-5 delims=," %%a in ('wmic logicaldisk where (DriveType^="3"^) get DeviceID^,FreeSpace^,Size^,VolumeName /format:%csvformat%') do (
set "diskID=%%a"
set "diskSpace=%%b"
set "diskSize=%%c"
set "diskName=%%d"
set /a diskSize1=!diskSize:~0,-4! / 107374
if "0"=="!diskSize1!" (
set /a diskSize1=!diskSize! / 1048576
set diskSize1=0.!diskSize1:~0,-2!
)
set /a diskSpace1=!diskSpace:~0,-4! / 107374
if "0"=="!diskSpace1!" (
set /a diskSpace1=!diskSpace! / 1048576
set diskSpace1=0.!diskSpace1:~0,-2!
)
set driveSizes=!driveSizes!"[%%a] %%d (!diskSize1!:!diskSpace1!)",
)
endlocal&if "_%~2"=="_" (set driveSizes=%driveSizes:~0,-1%)
:: Create non CSV variable for use in CSV file creation
set driveSizescsv=%driveSizes:"=%
set driveSizescsv="%driveSizescsv%"
The bit that echos to screen and writes to text file...
echo PC Drives : [Drive] Label (Size GB:Free GB)>>"%pathBackup%\%infoFileName%"
echo PC Drives : [Drive] Label (Size GB:Free GB)
:: Write individual drives one at a time
setlocal EnableDelayedExpansion
for %%i in (%driveSizes:,= %) do (
set driveSizes1=%%i
echo. !driveSizes1:"=!
set driveSizes2=!driveSizes1:"=!
echo. !driveSizes2!>>"%pathBackup%\%infoFileName%"
)
endlocal
The bit that writes to a csv
echo %computername%,%driveSizescsv% >>"%pathBackup%\%csvfile%"
Output example..
PC Drives : [Drive] Label (Size GB:Free GB)
[C:] Windows (79:42)
[D:] Database Volume (599:90)
[E:] Log File (39:31)
As the wmic command can take a while, and arithmetic can be particularly tricky in pure batch, here are a couple of additional options for you, which leverage other built-in scripting languages:
This complete batch-file uses powershell:
#"%__AppDir__%WindowsPowerShell\v1.0\powershell.exe" -NoP^
"[System.IO.DriveInfo]::GetDrives()|?{$_.IsReady -Eq $True}|"^
"Select #{N='Drive';E={$_.Name.TrimEnd('\')}},"^
"#{N='Size (GiB)';E={[Double]('{0:N2}' -F ($_.TotalSize/1GB))}},"^
"#{N='Free (GiB)';E={[Double]('{0:N2}' -F ($_.AvailableFreeSpace/1GB))}}|FL
#"%__AppDir__%timeout.exe" /T 5 /NoBreak>NUL
And this even quicker batch-file uses the vbscript engine of wsh:
<!-- :
#"%__AppDir__%cscript.exe" //NoLogo "%~f0?.wsf"
#"%__AppDir__%timeout.exe" /T 5 /NoBreak>NUL
#Exit /B
-->
<Job><Script Language="VBScript">
Set o=CreateObject("Scripting.FileSystemObject")
For Each Drv In o.Drives:If Drv.IsReady=True Then
WScript.Echo "Drive="&Drv.DriveLetter&":"&VBCrLf&_
"Size="&Round(Drv.TotalSize/1073741824,2)&" GiB"&VBCrLf&_
"Free="&Round(Drv.FreeSpace/1073741824,2)&" GiB"
End If:Next
</Script></Job>
I am trying to figure out how many sub-folders contain a folder called "img", so I want to implement a recursive count of all subfolders called "img", if this is possible.
Also, how can I do a count that is one level deep? i.e it will look only one folder deep for all folders called "img"?
So, if my folder structure was :
>folder1
>img
>folder2
>subfolder
>img
>folder3
>subfolder
>subsubfolder
>img
>folder4
>img
The first part would return 4, and the second script would return 2.
Is this possible to do either from CMD or with some Windows tool?
I've had a look around and the closest I could find was a CLI script to print all folders and sub-folders to a file :
dir /directory:n /ad > f.txt
from here.
Which I could then copy paste into Notepad++ and do some manual messing around with...but I was hoping there was a cleaner/faster solution than this in case I ever come across this in the future. What would I need to write for this?
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
SET /a onelevelcount=0
FOR /f "delims=" %%a IN (
'dir /b /ad "%sourcedir%" 2^>nul'
) DO (
IF EXIST "%sourcedir%\%%a\img\." SET /a onelevelcount+=1
)
ECHO one level down=%onelevelcount%
SET /a grandtotal=0
FOR /f %%c IN ('dir /s /ad "%sourcedir%" 2^>nul^|findstr /i /e /r "\\img"') DO SET /a grandtotal+=1
ECHO grand total=%grandtotal%
GOTO :EOF
You would need to change the setting of sourcedir to suit your circumstances.
As for how you'd figure it out - practice makes perfect. Lots of examples on SO.
type the folowing code on notepad and save it as .dll
#ECHO OFF
SETLOCAL
SET "sourcedir=U:\sourcedir\t w o"
SET /a onelevelcount=0
FOR /f "delims=" %%a IN (
'dir /b /ad "%sourcedir%" 2^>nul'
) DO (
IF EXIST "%sourcedir%\%%a\img\." SET /a onelevelcount+=1
)
ECHO one level down=%onelevelcount%
SET /a grandtotal=0
FOR /f %%c IN ('dir /s /ad "%sourcedir%" 2^>nul^|findstr /i /e /r "\\img"') DO SET /a grandtotal+=1
ECHO grand total=%grandtotal%
GOTO :EOF`enter code here`
I need to include page size information of many single-paged pdf's into their filenames. E.g. "150x250mm.pdf". I found no renamer apps able to do it. I suspect this could be done using a batch file and pdfinfo.exe (from xpdf suite), but I have no idea how to make use of it.. Could you give me some hints?
Yes, you can convert from postscript points to MM. In this case, the script is in the top level folder containing the PDF's to be renamed. It does go into subfolders. If you don't want or need that, remove the /s from the dir command on the 5th line. Change the paths as needed.
#echo off
setlocal enabledelayedexpansion
set "pdfi=U:\Scripts\Utilities\xpdf\pdfinfo.exe"
for /f "delims=" %%a in ('dir /b /s *.pdf') do (
for /f "tokens=3,5 delims= " %%b in (
'%pdfi% -meta "%%a"^|find /i "Page size:"') do (
set pts=%%b %%c
for %%d in (!pts!) do (
call :Eval %%d*.352777778 mm
set "mm1=!mm1!x!mm!"
)
ren "%%~dpfnxa" "!mm1:~1!.pdf"
set mm1=
)
)
exit /b
:Eval <in> <out>
setlocal
if exist eval.vbs del eval.vbs
>eval.vbs echo wsh.echo formatnumber(eval("%1"),0)
for /f "delims=" %%a in (
'cscript //nologo eval.vbs'
) do endlocal & set %~2=%%a
del eval.vbs
:LOOP
:: Finds Removable Disk Letter
for /f "tokens=1-3" %%a in ('wmic logicaldisk get caption^, description') do if "%%b %%c"=="Removable Disk" set drive=%%a&goto COPY
:COPY
xcopy %drive% D:\Backup
goto :LOOP
I have no such experience in batch and I want to know, how can I do following? :
if removable disk not exist, do not go to COPY and go to LOOP ?
Just let wmic do the filtering for you:
:LOOP
for /f %%d in (
'wmic logicaldisk where description^="Removable Disk" get caption ^| find ":"'
) do (
xcopy %%d D:\Backup
)
goto LOOP
:LOOP
:: Finds Removable Disk Letter
for /f "tokens=1-3" %%a in ('wmic logicaldisk get caption^, description') do (
if "%%b %%c"=="Removable Disk" set drive=%%a
if not exist "%%a" goto :LOOP
)
:COPY
xcopy %drive% D:\Backup
goto :LOOP
Basically, if the drive doesn't exist it will go back to :LOOP, if it does it will automatically fall through to :COPY.
Can you recommend a way to list files on a WinXP disk that have a total file name (drive+folder+subfolder+filename+ext) greater than some value or MAX_PATH? Ideally this would be in batch or VB script. Thanks in advance.
#echo off
setlocal
if "%~1%~2"=="%~2%~1" (
echo Usage: drive maxlength
echo Example: %0 d: 200
goto :EOF
)
for /F %%A in ('dir /S/B/A:-D "%~d1\*" 2^>nul') do call :chkpath "%%~A" %2
goto :EOF
:chkpath
set #=%~1%
set len=0
:longer
if defined # (set "#=%#:~1%"&set /A len += 1&goto longer)
if %len% GTR %2 echo.%~1
goto :EOF
I would imagine that windows scripting host is faster...