Beefy Boxes and Bandwidth Generously Provided by pair Networks DiBona
Do you know where your variables are?
 
PerlMonks  

Find A Share size in Win2k

by OzzyOsbourne (Chaplain)
on Oct 10, 2002 at 16:13 UTC ( #204214=perlquestion: print w/ replies, xml ) Need Help??
OzzyOsbourne has asked for the wisdom of the Perl Monks concerning the following question:

Normally, to get the size of a file share on a windows system, I right click on it. for a 42 GB share, this takes under 10 minutes. When scripting, I use a combination of file::Find and stat to recurse the share, pull each individual file size, and add it to a running total.

Problems with this approach:
-I must have permissions to ALL files to be accurate.
-For larger shares it takes a very long time (hours)

Becuase I am dealing with Terrabytes across my network, all the extra time that the script takes adds up fast. Usually, the script will take 8 hours to run.

Solutions:
-DIR /S and parse the output (not really elegant)
-AdminMisc (Will not get share size, only drive size.)
-Wait for the recurse to finish.
-Ask a serious bunch of brains for help.

Any elegant ideas?

-OzzyOsbourne

Comment on Find A Share size in Win2k
Re: Find A Share size in Win2k
by thunders (Priest) on Oct 10, 2002 at 16:20 UTC
    for the record, a call to dir would look something like this:
    #!/usr/bin/perl use strict; my $dir = "//server/share"; #or whatever my ($size)=( (qx{dir /s "$dir"})[-2]=~ /([\d,]+) bytes/ ); print $size;
    Not pretty but probably faster than recursing
    UPDATE: changed directory i'm calling from a local to a share
Re: Find A Share size in Win2k
by jsprat (Curate) on Oct 10, 2002 at 16:36 UTC
    First, a couple of questions:
    • How accurate do you need to be? (this method can give a slightly different number for free space than right-clicking and selecting properties)
    • Can you map a drive to the share before checking, and disconnect after?
    • Is Windows Script Host installed?

    If the answer to these questions are "99% is good enough","yes" and "yes", try this:

    #!perl use warnings; use strict; use Win32::OLE; my $fs = Win32::OLE->CreateObject('Scripting.FileSystemObject'); my $d = $fs->GetDrive('g:'); print $d->{TotalSize}, " total\n"; print $d->{FreeSpace}, " free\n"; print $d->{AvailableSpace}, " available\n"; print $d->{TotalSize} - $d->{FreeSpace}, " used\n"; __END__ Output on my system, with G: mapped to a Samba share: 19447939072 total 16677601280 free 16677601280 available 2770337792 used
    where AvailableSpace is the space available to you and FreeSpace is total free space.

    Note - this code requires you already have the drive mapped before you try it.

    Update: added closing </ul> tag

    Update 2: Please read BrowserUK's caveat below!

Re: Find A Share size in Win2k
by MZSanford (Curate) on Oct 10, 2002 at 19:36 UTC
    just like to point out the blazing speed of jsprat's solution (nearly instant). Were it not for Win32::OLE, i think Perl on Windows would be crippled compared to *gulp* VB.
    from the frivolous to the serious
Re: Find A Share size in Win2k
by BrowserUk (Pope) on Oct 10, 2002 at 20:42 UTC

    This is as much a question as a statement as I don't have access to a network on which to test this properly... Perhaps someone could verify it.

    There seems to be one caveat with jsprat's technique. It works brilliantly provided the share is sharing the root of the remote drive, and not some subset of it. However, if the share represents a subdir on the actual remote drive, the information returned by the GetDrive() call represents the entire drive rather than just the shared portion of it. Or at least it appears to in my tests using local shares.

    There is an alternative FileSystemObject call, GetFolder()->size(), which will return the correct information, but I think that it is doing a recursive descent accumulating filesizes as it goes, and so is possibly not much quicker than using this technique in Perl.

    Anyway, here are the results I got when I shared my perl directory, e:\perl as \\mymachine\perl f:

    #! perl -sw use strict; use Win32::OLE; use Benchmark; my $fs = Win32::OLE->CreateObject('Scripting.FileSystemObject'); my $local = $fs->GetFolder('e:/perl'); print 'e:\perl: ', $local->size(), ' used', $/; my $f = $fs->GetFolder('f:/'); #! e:/perl shared as f: print 'f:\ (e:\perl shared as f:): ', $f->size(), ' used', $/; my $d = $fs->GetDrive('f:'); #! e:/perl shared as f: print 'f: (using GetDrive()): ', $d->{TotalSize} - $d->{FreeSpace}, " +used\n"; __DATA__ c:\test>204222 e:\perl: 52488590 used f:\ (e:\perl shared as f:): 52488590 used f: (using GetDrive()): 2614812672 used c:\test>

    I was intending to try and benchmark the two methods, but it appears to cache the value after the first call and i couldn't see any simple way of clearing the cache without rebooting, so I'll leave that to Ozzy


    Cor! Like yer ring! ... HALO dammit! ... 'Ave it yer way! Hal-lo, Mister la-de-da. ... Like yer ring!
      It works brilliantly provided the share is sharing the root of the remote drive, and not some subset of it. However, if the share represents a subdir on the actual remote drive, the information returned by the GetDrive() call represents the entire drive rather than just the shared portion of it.
      Good catch, BrowserUK. This would've bit Ozzy for sure.

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://204214]
Approved by fireartist
Front-paged by thunders
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others chanting in the Monastery: (5)
As of 2014-04-20 02:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (485 votes), past polls