Conversion of bytes into MB within a batch file

I am trying to convert the displayed bytes into MB.  I cannot load any external .exe ... it must only be in the batch.  not picky about the code that is used (java, vbs ...).  
I am using the following string to present the data in the command window:

wmic Volume get Name, Capacity, FreeSpace

I get a screen print as follows:
Capacity      FreeSpace    Name
17100320768   2965925888   C:                          
16105062400   14466117632  E:
161059172352  35791892480  E:\DATA\KAPPA
10733957120   10478813184  E:\DATA\SQL\SY0
5362847744    5255077888   E:\DATA\SQL\SD0
5362847744    5322776576   E:\DATA\SQL\SL0
5362847744    4389543936   E:\DATA\SQL\ST0
32210161664   31894343680  E:\DATA\SQL_SUPPORT\SS0

I am trying to get it to look like this:
Capacity      FreeSpace    Name
16308.13672   2828.52734   C:                          
15358.98438   13795.96484  E:
153597.99609  34133.80859  E:\DATA\KAPPA
10236.69922   9993.375  E:\DATA\SQL\SY0
5114.41016    5011.63281   E:\DATA\SQL\SD0
5114.41016    5076.19531   E:\DATA\SQL\SL0
5114.41016    4186.19531   E:\DATA\SQL\ST0
30718.00391   30416.81641  E:\DATA\SQL_SUPPORT\SS0

I understand if the decimal places cannot be presented as above.  I would prefer that all the MB read-outs round UP one (1) MB.  I am sure this is going to be easy for a good coder.  Thank you for your time in advance.
ace350Asked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

zalazarCommented:
I have created the following VBScript which should accomplish this.
Create a vbs file from the code and please execute with "cscript.exe" from a command prompt (cmd.exe).
'*********************************************************************
'* Get Disk Information
'* Zalazar
'*********************************************************************
Dim fso, objWMIService

Set fso = CreateObject("Scripting.FileSystemObject")
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

call GetDiskInfo()

WScript.Quit 0
'--------------------------------------------------------------------
' --------  SUBS  --------
'--------------------------------------------------------------------
Sub GetDiskInfo()
  Dim colVolumes, objDisk
  Dim sCapacity, sFreeSpace, sName

  Wscript.echo "Capacity|FreeSpace|Name"

  ' Get disk information
  Set colVolumes = objWMIService.ExecQuery("Select * from Win32_Volume Where DriveType = 3")
  For Each objDisk In colVolumes
    sCapacity = CDbl(objDisk.Capacity / 1024 / 1024)
    sFreeSpace = CDbl(objDisk.FreeSpace / 1024 / 1024)
    sName = objDisk.Name
    Wscript.echo sCapacity & "|" & sFreeSpace & "|" & sName
  Next
End Sub

Open in new window


VBScript code with RoundUp.
'*********************************************************************
'* Get Disk Information
'* Zalazar
'*********************************************************************
Dim fso, objWMIService

Set fso = CreateObject("Scripting.FileSystemObject")
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

call GetDiskInfo()

WScript.Quit 0
'--------------------------------------------------------------------
' --------  SUBS  --------
'--------------------------------------------------------------------
Sub GetDiskInfo()
  Dim colVolumes, objDisk
  Dim sCapacity, sFreeSpace, sName

  Wscript.echo "Capacity|FreeSpace|Name"

  ' Get disk information
  Set colVolumes = objWMIService.ExecQuery("Select * from Win32_Volume Where DriveType = 3")
  For Each objDisk In colVolumes
    sCapacity = CDbl(objDisk.Capacity / 1024 / 1024)
    If Int(sCapacity) <> sCapacity Then
      sCapacity = Int(sCapacity) + 1
    Else
      sCapacity = Int(sCapacity)
    End If

    sFreeSpace = CDbl(objDisk.FreeSpace / 1024 / 1024)
    If Int(sFreeSpace) <> sFreeSpace Then
      sFreeSpace = Int(sFreeSpace) + 1
    Else
      sFreeSpace = Int(sFreeSpace)
    End If

    sName = objDisk.Name
    Wscript.echo sCapacity & "|" & sFreeSpace & "|" & sName
  Next
End Sub

Open in new window

oBdACommented:
Here's a one-liner in Powershell that will provide the 5 decimal places:
Get-WmiObject -Class Win32_Volume | Select-Object -Property Name, @{n="Capacity"; e={[math]::Round($_.Capacity / 1mb, 5)}}, @{n="FreeSpace"; e={[math]::Round($_.FreeSpace / 1mb, 5)}}

Open in new window

Here's one that always adds 1MB ( it would of course possible to combine the two, but somehow, I don't see the use in having 5 decimal points on the one side, while removing precision by adding on the other side):
Get-WmiObject -Class Win32_Volume | Select-Object -Property Name, @{n="Capacity"; e={[math]::Truncate($_.Capacity / 1mb) + 1}}, @{n="FreeSpace"; e={[math]::Truncate($_.FreeSpace / 1mb) + 1}}

Open in new window

ace350Author Commented:
Thank you for your quick responses

@oBdA - This seems so simple, however, I will need to attempt this on my 2008 and 2012 servers ... right now I have hundreds of 2003 servers to go through, and they don't have Powershell.

@zalazar - How do I insert your code into a batch file?  Sorry for my basic questions, I am trying to learn as fast as possible.  Please be kind ... :D

Here is what I get when I plop the vbs into "Test.cmd" .... I added my original string at the top to compare.

C:\Temp>wmic Volume get Name, Capacity, FreeSpace
Capacity      FreeSpace    Name
17100320768   2963750912   C:\
16105062400   14466052096  E:\
161059172352  35784998912  E:\DATA\KAPPA\
10733957120   10478813184  E:\DATA\SQL\SY0\
5362847744    5255077888   E:\DATA\SQL\SD0\
5362847744    5322776576   E:\DATA\SQL\SL0\
5362847744    4389543936   E:\DATA\SQL\ST0\
32210161664   31894343680  E:\DATA\SQL_SUPPORT\SS0\


C:\Temp>'*********************************************************************
''*********************************************************************' is not recognized as an internal or external command,
operable program or batch file.

C:\Temp>'* Get Disk Information
''*' is not recognized as an internal or external command,
operable program or batch file.

C:\Temp>'* Zalazar
''*' is not recognized as an internal or external command,
operable program or batch file.

C:\Temp>'*********************************************************************
''*********************************************************************' is not recognized as an internal or external command,
operable program or batch file.

C:\Temp>Dim fso, objWMIService
'Dim' is not recognized as an internal or external command,
operable program or batch file.

C:\Temp>Set fso = CreateObject("Scripting.FileSystemObject")

C:\Temp>Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")

C:\Temp>call GetDiskInfo()
'GetDiskInfo' is not recognized as an internal or external command,
operable program or batch file.

C:\Temp>WScript.Quit 0
'WScript.Quit' is not recognized as an internal or external command,
operable program or batch file.

C:\Temp>'--------------------------------------------------------------------
''--------------------------------------------------------------------' is not recognized as an internal or external command,
operable program or batch file.

C:\Temp>' --------  SUBS  --------
''' is not recognized as an internal or external command,
operable program or batch file.

C:\Temp>'--------------------------------------------------------------------
''--------------------------------------------------------------------' is not recognized as an internal or external command,
operable program or batch file.

C:\Temp>Sub GetDiskInfo()
'Sub' is not recognized as an internal or external command,
operable program or batch file.

C:\Temp>Dim colVolumes, objDisk
'Dim' is not recognized as an internal or external command,
operable program or batch file.

C:\Temp>Dim sCapacity, sFreeSpace, sName
'Dim' is not recognized as an internal or external command,
operable program or batch file.

C:\Temp>Wscript.echo "Capacity|FreeSpace|Name"
'Wscript.echo' is not recognized as an internal or external command,
operable program or batch file.

C:\Temp>' Get disk information
''' is not recognized as an internal or external command,
operable program or batch file.

C:\Temp>Set colVolumes = objWMIService.ExecQuery("Select * from Win32_Volume Where DriveType = 3")
Each was unexpected at this time.

C:\Temp>  For Each objDisk In colVolumes
Big Business Goals? Which KPIs Will Help You

The most successful MSPs rely on metrics – known as key performance indicators (KPIs) – for making informed decisions that help their businesses thrive, rather than just survive. This eBook provides an overview of the most important KPIs used by top MSPs.

oBdACommented:
You should be able to run it remotely against the W2k3 servers, since it's just a WMI query; simply add the -ComputerName argument:
Get-WmiObject -Class Win32_Volume -ComputerName SomeServer| Select-Object -Property Name, @{n="Capacity"; e={[math]::Round($_.Capacity / 1mb, 5)}}, @{n="FreeSpace"; e={[math]::Round($_.FreeSpace / 1mb, 5)}}

Open in new window

Or process a text file with the server names (with the PSComputerName property added, so you'll know which result came from which server):
Get-WmiObject -Class Win32_Volume -ComputerName (Get-Content "C:\Temp\servers.txt") | Select-Object -Property PSComputerName, Name, @{n="Capacity"; e={[math]::Round($_.Capacity / 1mb, 5)}}, @{n="FreeSpace"; e={[math]::Round($_.FreeSpace / 1mb, 5)}}

Open in new window

zalazarCommented:
No problem at all.
To be able to use the script please open "Notepad" first.
Copy the VBScript code from above to the clipboard via Control-C.
Then paste the VBScript code into the Notepad window.
Then click "File |Save" and save the file as e.g. "GetDiskInfo.vbs" to a directory, e.g. C:\Scripts
Then open a Command Prompt (cmd.exe) and type:
cscript.exe //nologo "C:\Scripts\GetDiskInfo.vbs"
ace350Author Commented:
@zalazar - this request is part of a larger batch file. Is there a way to incorporate this code into a batch file?
ace350Author Commented:
@oBdA - I am sure that some of the team members will not have rights to run remote scripts. Not too worried about that at this moment but this will become an issue as we start auditing enterprise wide.
oBdACommented:
This would be not a remote script, but remote WMI (like wmic.exe with the "/node" argument). Local administrator permissions on the remote machine are required.
zalazarCommented:
Yes that would be possible.
Please create a file named GetDiskInfo.cmd with the following contents.
@echo off
%SystemRoot%\System32\cscript.exe //nologo "%~dp0GetdiskInfo.vbs"
echo End of GetDiskInfo script
echo\
pause

Open in new window


Create another file named GetDiskInfo.vbs with the following contents.
'*********************************************************************
'* Get Disk Information
'* Version 0.02
'* Zalazar
'*********************************************************************
Dim fso, objWMIService, WshNetwork, strComputerName, strScriptDir, strLogfile
Dim strDate

Set fso = CreateObject("Scripting.FileSystemObject")
Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
Set WshNetwork = CreateObject("WScript.Network")
strComputerName = WshNetwork.ComputerName
strScriptDir = Mid(Wscript.ScriptFullName, 1, InstrRev(Wscript.ScriptFullName, "\") - 1)
strLogfile = strScriptDir & "\Logs\" & strComputerName & "_GetDiskInfo.log"

call GetVariables()
call GetDiskInfo()

WScript.Quit 0
'--------------------------------------------------------------------
' --------  SUBS  --------
'--------------------------------------------------------------------
Sub GetDiskInfo()
  Dim colVolumes, objDisk
  Dim sCapacity, sFreeSpace, sName

  LogMessage strLogfile, strDate & "|" & strComputerName & "|" & "Hostname|Capacity|FreeSpace|Name"

  ' Get disk information
  Wscript.echo ""
  Wscript.echo "Getting disk information..."
  Set colVolumes = objWMIService.ExecQuery("Select * from Win32_Volume Where DriveType = 3")
  For Each objDisk In colVolumes
    sCapacity = CDbl(objDisk.Capacity / 1024 / 1024)
    sFreeSpace = CDbl(objDisk.FreeSpace / 1024 / 1024)
    sName = objDisk.Name
    LogMessage strLogfile, strDate & "|" & strComputerName & "|" & sCapacity & "|" & sFreeSpace & "|" & sName
  Next
End Sub

Sub GetVariables()
  Dim strNow, strDay0, strMonth0, strYear0
  
  strNow = Now
  strDay0 = Day(strNow)
  strMonth0 = Month(strNow)
  strYear0 = Year(strNow)
  If Len(strDay0) = 1 Then strDay0 = "0" & strDay0
  If Len(strMonth0) = 1 Then strMonth0 = "0" & strMonth0
  strDate = strYear0 & strMonth0 & strDay0
End Sub

'------------------------------------------------------------------------
' --------  FUNCTIONS  --------
'------------------------------------------------------------------------
Function LogMessage(sLog, sOutput)
  ' Write information to logfile
  On Error Resume Next
  Dim f

  Set f = fso.OpenTextFile(sLog, 8, True)
  If Err.Number = 0 Then
    f.Write sOutput & vbCrLf
    f.Close
  Else
    Wscript.echo "ERROR while creating or opening logfile|" & sLog & "|" &  CStr(Err.Number) & "|" & Err.Description
    Wscript.Quit 1
  End If

  Set f = Nothing
End Function

Open in new window


I would actually place the scripts on a network share that can be accessed by all team members, e.g. \\servername.domain.com\Scripts$

Within this share create a directory GetDiskInfo and copy the GetDiskInfo.cmd and GetDiskInfo.vbs to this directory.
Then create another directory called Logs inside this GetDiskInfo directory.
Grant at least read permissions to the 2 script files and write permissions to the Logs directory.

Then the instructions would be to go the network share at
\\servername.domain.com\Scripts$
Double click on directory GetDiskInfo and double click on the GetDiskInfo.cmd script.
The logfile will be created in \\servername.domain.com\Scripts$\GetDiskInfo\Logs

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Bill PrewIT / Software Engineering ConsultantCommented:
Can I ask how you are going to use this script?  What will you do with the data, what frequency will it run with, etc?  Might help get some even better answers flowing...

~bp
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Windows Batch

From novice to tech pro — start learning today.