Showing NTFS timestamp with 100 nsec granularity - vbscript

I understand that the FAT file system stores its time stamps for files (modify date, etc.) with a 2 second granularity, and NTFS stores them with a 100 nsec granularity.
I'm using VBScript with FileSystemObject to show file details. The function file.DateLastModified shows me the date with a 1 second precision (on NTFS).
Is there a way to show the time stamps with a precision according to the internal storage granularity of NTFS. I'm imagining something like 8/9/2010 14:40:30,1234567
And if not with VBScript / FileSystemObject, would there be any other way?

File timestamps are held as FILETIME in NTFS but the millisecond portion is not passed to the Variant DateTime so VBS doesn't see it. The WMI object can support this though.
Sub PrintTimestamp(sFilename)
Set oWMI = GetObject("winmgmts:!\\.\root\cimv2")
Set oFiles = oWMI.ExecQuery("Select * from CIM_DataFile where Name = '" & sFilename & "'")
Set oDateTime = CreateObject("WbemScripting.SWbemDateTime")
For Each oFile in oFiles
oDateTime.Value = oFile.LastAccessed
WScript.Echo oFile.Name & " " & oDateTime.GetVarDate & " " & oDateTime.Microseconds
Next
End Sub
PrintTimestamp("c:\\temp\\demo.vbs")

Full-precision file times are easily accessible via the native Windows API. This MSDN article explains how to do it: File Times.
I do not know of any way to read the 64-bit FILETIME from VBS, especially since VBS does not handle 64-bit numbers natively. Once you have a FILETIME you can parse it with SWbemDateTime, though. Here is an example.

Related

WMI to get current printer job (including number of copies) [duplicate]

This question already has an answer here:
Real number of TotalPages of a PrintJob (Win32_PrintJob)
(1 answer)
Closed last month.
I tried to follow the example of WMI scripting (VBScript) to obtain several info from the current Windows OS, including the print job. Both are working successfully.
' My SampleCapturingPrinter.vbs
' ———————————————–‘
Option Explicit
Dim objWMIService, objItem, colItems, strComputer
' On Error Resume Next
strComputer = "."
While True
Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_Printer")
For Each objItem in colItems
Wscript.Echo "- " & objItem.DefaultCopies
Next
Wscript.Echo "====================="
WScript.Sleep 1000
Wend
WSCript.Quit
' End of My SampleCapturingPrinter.vbs
' ———————————————–
But from the official documentation , there is no info about -current number of copies- ? So my question is... where is the counter located / stored exactly?
If let say the user click Print through out any app and set the copies to let say '3 copies' and pressed (Print). The printer job tracked nicely, but I don't know where the 'number of copies' stored.
CMIIW, is it possible through out WMI to obtain the current details?
As I've said in other answers, WMI has problems with printing, and it doesn't provide copies.
The question itself is problematic, similar to N-Up. Early printers didn't have any concept of copies, so the Windows printing APIs support the concept weakly with an optional copies entry in the DEVMODE. To complicate things, some apps (notably some versions of MS Office) handle copies internally, while some drivers don't use the DEVMODE entries.

When using GetDrive, FreeSpace is reporting incorrect in VBSCript

I have the code below which will get drive p(a network drive) and throw up a message box with its total & free space. Total is reporting fine but for some reason free is throwing up a completely incorrect value.
Set filesystemObject = CreateObject("Scripting.FileSystemObject")
Set drive = filesystemObject.GetDrive("P:")
total = round(drive.TotalSize/1024/1024/1024)
free = round(drive.FreeSpace/1024/1024/1024)
MsgBox(total & " " & free) // throws up 400gb total and 34gb free
Free should be 1.7gb, which I have verified as being accurate on the actual server. I also checked the total free space across all drives and this total came to 25gb(across 4 drives) so I cannot see that being an impacting factor.
Does anyone know what could potentially be throwing this value off?
Edit:
Bonds answer below is marked correct as its a secondary method of proving the code above is accurate. If you come across this problem there are several features which may impact the values that you are returned.
1) Quotas being enabled.
2) Your admins rigging free space to not be accurate. In my case the admins had been rigging the share to display a much lower free space than there actually was in an effort to make users think about what they are storing.
I've had trouble trusting the FSO's numbers in the past, too. Have you tried using WMI?
Const strDrive = "P:"
intFactor = 1024 ^ 3
Set objWMIService = GetObject("winmgmts:\\.\root\CIMV2")
Set colItems = objWMIService.ExecQuery("select * from Win32_LogicalDisk where DeviceID='" & strDrive & "'")
For Each objItem in colItems
MsgBox "Size: " & FormatNumber(objItem.Size / intFactor)
MsgBox "Free: " & FormatNumber(objItem.FreeSpace / intFactor)
MsgBox "Used: " & FormatNumber((objItem.Size - objItem.FreeSpace) / intFactor)
Next

Having windows read out what time it is

I am using this format to make my computer speak every hour:
Dim speaks, speech
speaks = “It is ” & hour(time) & ” O’clock”
Set speech = CreateObject(“sapi.spvoice”)
speech.Speak speaks
The problem is it reads it in 24hr and not 12hr format, does anybody happen to know how to fix that? I have my system clock set to 12hr format, but for some reason when its read by Microsoft Hazel, she reads it in 24hr format.
As documented, Hour() returns a number between 0 and 23 representing the current hour. You need to divide the hour modulo 12 to get what you want:
speaks = "It is " & Hour(Time) Mod 12 & " o'clock"

How to fetch the NATIVE resolution of attached monitor from EDID file through VB6.0?

I am developing a VB application in which i need to know the native resolution of the monitor and not the one set by the user(current resolution). So i need to read the EDID (extended display identification data) directly from the monitor.
I did try to find the resolution of monitor through some programs...but all it returns is the current resolution. Any help to read the info directly from EDID of monitor is appriciable.
Thanks in advance
After a lot of research i was able to fix my problem..
Thanks for the the valuable info Yahia.
First, we need to find the EDID data . The physical display information is in fact available to the OS, via Extended Display Identification Data(EDID). A copy of the EDID block is kept in the windows registry. But the problem was to obtain the correct EDID, as the registry has information stored about all the monitors which have been, at any point of time, attached to the system. So, first we use a WMI class “Win32_DesktopMonitor”, and through a simple SQL query grab the PNP device id to find a monitor that is available (not offline). We can then dig into the registry to find the data.
`'for monitor in wmiquery('Select * from Win32_DesktopMonitor'):
regkey = ('HKLM\SYSTEM\CurrentControlSet\Enum\' +
monitor.PNPDeviceID + '\Device Parameters\EDID')
edid = get_regval(regkey)'`
Second, it is necessary to parse the data. The base EDID information of a display is conveyed within a 128-byte data structure that contains pertinent manufacturer and operation-related data. Most of this information is uninteresting to us.
To know the NATIVE resolution we need to start looking in the DTD ( Detailed timing descriptor ) which starts at byte = 54.
Following is the logic for finding the maximum resolution from the EDID
`dtd = 54 # start byte of detailed timing desc.
horizontalRes = ((edid[dtd+4] >> 4) << 8) | edid[dtd+2]
verticalRes = ((edid[dtd+7] >> 4) << 8) | edid[dtd+5]
res=(horizontalRes,verticalRes)`
The values obtained are Hex values which can be converted to Decimal to find the NATIVE RESOLUTION in pixels.
Thanks
Hope it helps
Sachin
For some source code (although C/C++) to read the EDID block see Point 5 at this link. The only official means to retrieve this information through Windows Setup API.
For an EDID format description see for example here.
'Here is a complete solution for everything except for actually setting the resolution. This will read out the native resolution settings from the EDID of the active monitor.
Set WshShell = WScript.CreateObject("WScript.Shell")
Const HKEY_LOCAL_MACHINE = &H80000002
Const DTD_INDEX = 54
strComputer = "."
Set objWMIService = GetObject("winmgmts:\" & strComputer & "\root\cimv2")
Set oReg=GetObject("winmgmts:{impersonationLevel=impersonate}!\" & strComputer & "\root\default:StdRegProv")
Set colItems = objWMIService.ExecQuery("Select * from Win32_DesktopMonitor",,48)
For Each objItem in colItems 'Gets active monitor EDID registry path
strKeyPath = "SYSTEM\CurrentControlSet\Enum\" & objItem.PNPDeviceID & "\Device Parameters"
Next
oReg.GetBinaryValue HKEY_LOCAL_MACHINE,strKeyPath,"EDID",arrRawEDID
hor_resolution = arrRawEDID(DTD_INDEX + 2) + (arrRawEDID(DTD_INDEX + 4) And 240) * 16
vert_resolution = arrRawEDID(DTD_INDEX + 5) + (arrRawEDID(DTD_INDEX + 7) And 240) * 16
WshShell.Run "res.exe " & hor_resolution & " " & vert_resolution

When accessing a logical drive's space status, the total drive results are correct, but the free space results are not

The problem appears to be with the The Win32_LogicalDisk class' free space property as it is showing only what the currently logged in user has rights to, not what free space actually exists.
Example code, though not entirely necc:
Set objLogicalDisk = objWMIService.Get("Win32_LogicalDisk.DeviceID='Z:'")
' server share, total disk size, total disk free, percent free
tmpStatus = tmpStatus & arrShares(i) & "," & FormatNumber((objLogicalDisk.size / GBCONVERSION),,-1) & "," & _
FormatNumber((objLogicalDisk.FreeSpace / GBCONVERSION),,-1) & "," & _
((objLogicalDisk.FreeSpace / GBCONVERSION) / (objLogicalDisk.size / GBCONVERSION) * 100) & "#"
NOTE: This is for a virtual server network share, so the drive type is 4
Is there a better way? Again, the total drive space is correct, but the free space is not since from what I've found on MSDN it uses the current user's rights to determine free space. There must be another/better way.
Ok so the trick seems to be to use the file system object disk properties instead of the w32_logicaldisk properties. Using FSO, all of the numbers are accurate.

Resources