Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

Domain Disk space check

by Marza (Vicar)
on Apr 04, 2002 at 02:43 UTC ( #156544=sourcecode: print w/replies, xml ) Need Help??
Category: NT Admin
Author/Contact Info Marza

This script was originally written by an unknown author and was moded and traded a couple times. I rewrote it and streamlined it and got rid of a few cpu intensive approaches.

It will get a domain list of cpus and then list the drive, file system, capacity, used, free, and percent free.

It is simple so feel free to take it and mod it to your needs. If you think something can be done better, please let me know!

You will need AdminMisc PM from Dave Roth.

040402 - Major changes. As to suggestion, I rescoped the vars and got rid of the declare undefs as well as I also added a ping check and an exclusion ability as well as cleaned a couple extranious variables.

040402 - Minor change. Error message was wrong and the computer print needed to be relocated.

use strict;
use warnings;
use Time::Local;
use Net::Ping;
use Win32::AdminMisc;
use Win32::NetAdmin;
use Win32::Lanman;

# Debug anybody?
my $debug = 0;

my (@unixlist, %ignorelist);
my (@computerlist, @drives, @driveinfo);
my $p = Net::Ping->new('icmp',3);

# For now the Samba machines can get excluded by the SV_TYPE_SERVER_UN
+IX option
# of the GetServers command.  But in case that changes....
my @sambasvrs;
# Do we need to exclude a computer for some reason?  Add an entry here
my @exclude; 

# Let's start the report.
my $outfile = "spacecheck.rpt";
open (OUT, ">$outfile")or die ("Could not create $outfile\n");

# Display a header

# Make a workstation list using NetAdmin::GetDomainController for the 
# and NetAdmin::GetServers() for the workstations
my $PDC;
if (Win32::NetAdmin::GetDomainController("","",$PDC)) {
    if ($debug) { print "The PDC is $PDC\n"; }

    my $domain = Win32::DomainName or die "Unable to obtain the domain
+ name\n";
    unless (Win32::NetAdmin::GetServers($PDC, $domain, SV_TYPE_NT, \@c
+omputerlist)) {
        print "Error getting server list: ". Win32::NetAdmin::GetError
+() . "\n";
    # Let's build the ignnore computer list.  This list will hold name
+s for
    # computers that don't act "normal" xerox print station, samba ser
    unless (Win32::NetAdmin::GetServers($PDC, $domain, SV_TYPE_SERVER_
+UNIX, \@unixlist))  {    
        print "Unable to get the unix lists.\n";
    my @buildlist = (@unixlist, @exclude, @sambasvrs );
    foreach (@buildlist) {
        $ignorelist{$_} = 1;

} else {
   print Win32::FormatMessage( Win32::NetAdmin::GetError());
# Let's start checking computers!
foreach my $computer(@computerlist) {
    # Let's see if the computer is up.
    if ($p->ping($computer)) {
        unless (Win32::Lanman::NetServerDiskEnum("\\\\$computer",\@dri
+ves)) {
            # Is this a computer to skip?
            if (exists $ignorelist{$computer}) {
            } else {
                print "\nCan't get disk list for $computer: ". Win32::
+NetAdmin::GetError() . "\n\n";

        # Lets get to work!
        printf("%-16s\n", $computer);
        printf(OUT "%-16s\n", $computer);

        foreach my $drive ( @drives ) {
            if ($debug) { print "Drive says $drive\n"; }
            $drive =~ s/://g;
            my $UNCPath = "\\\\$computer\\$drive\$\\";

            # Let's get the space.  If it is an invalid drive, undef i
+s returned.
            unless ( @driveinfo = Win32::AdminMisc::GetDriveSpace("$UN
+CPath")) {
                if ($debug) { print "Skipping $drive since it is empty
+\n"; }
            if ($debug ) {
                print "Capacity is $driveinfo[0]\n";
                print "Freespace is $driveinfo[1]\n";
            my %volume  = Win32::AdminMisc::GetVolumeInfo("$UNCPath");
            my $capacity = sprintf("%5.2f",($driveinfo[0]/1073741824))
            # We want to skip any removable media.
            next if ($capacity < 0.1);
            my $freespace = sprintf("%5.2f",($driveinfo[1]/1073741824)
            my $used = $capacity - $freespace;
            my $percentfree = ($freespace/$capacity)*100;

            printf("%15s:%6s %8.2f %8.2f %8.2f %6d %%\n", $drive, $vol
+ume{FileSystemName}, $capacity, $used, $freespace, $percentfree);
            printf(OUT "%15s:%6s %8.2f %8.2f %8.2f %6d %%\n", $drive, 
+$volume{FileSystemName}, $capacity, $used, $freespace, $percentfree);
    } else {
        print "\nCan't Ping $computer!\n\n";
        printf OUT "\nCan't Ping $computer!\n\n";
close (OUT);


# Just a simplistic header for both the display and report.
sub print_header {
    print "System/Drives      FS     Total    Used     Free    % Free\
    print "-------------    ------  ------   ------   ------   ------\
    print OUT "                 Drive Space Report (Gigabytes) \n\n";
    print OUT "                   " . scalar localtime;
    print OUT "\n\nSystem/Drives      FS     Total    Used     Free   
+% Free\n";
    print OUT "-------------    ------  ------   ------   ------  ----

Replies are listed 'Best First'.
Re: Domain Disk space check
by Chmrr (Vicar) on Apr 04, 2002 at 03:23 UTC

    Please do not use this It's rather ugly perl4 code in the first place, and you only call it in one place -- and in that case (&ctime(time)) it's equivilent to scalar localtime Except that scalar localtime doesn't have any of the bugs. ;>

    There are only two other things which stick out at me, both of them at least partially stylistic. For one, variables start off being undefined so the = undef part of

    my ($foo, $bar, @baz) = undef
    is repetitive. The only other note is that the code could be made slightly tighter by scoping the variables a little tighter. For instance, both $drive and $computer can be scoped just to the loop they're used in:
    foreach my $computer (@computerlist) { ... # yadda yadda yadda foreach my $drive (@drives) { ... } ... }

    Other than those couple of nitpicks, the code looks to be rather handy.

    perl -pe '"I lo*`+$^X$\"$]!$/"=~m%(.*)%s;$_=$1;y^`+*^e v^#$&V"+@( NO CARRIER'

      Thank you for the suggestions. I kind of debated on where to scope the vars. I changed them as you suggested.

      I removed the ptime script(I was trying things out).

      I also added an exclusion routine and a ping check.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://156544]
Jar. Jar!...

How do I use this? | Other CB clients
Other Users?
Others musing on the Monastery: (4)
As of 2017-06-25 16:52 GMT
Find Nodes?
    Voting Booth?
    How many monitors do you use while coding?

    Results (568 votes). Check out past polls.