# profileRpt script lists all NT domain login profiles and the number # of users each is assigned to. # Written 29-sep-2000 by fgb; adapted from loginRpt.pl. # Mod 29-jan-02, fgb: ignore path in comparison. # # *** NB: "last" command can't be used in while(($sName,$nCount) = each(%hScript)) # *** since it doesn't reset the each iteration! # # Of interest: CaseInsensitive sort subroutine; AdminMisc stuff. require "ctime.pl"; use Win32; use Win32::AdminMisc; $bDebug = 0; INIT: $sAppName = "profileRpt"; $sDate = &ctime(time); $bFound = 0; @aMatchingUsers; $bNoProfile = 0; my $sPDC = "\\\\sfd_srv1"; ### hardcoded PDC server name %hProfile = (); @hProfile{"ops.man","ops2.man","ops2k.man"} = (0,0,0); $sProfile = ""; $sRptFile = ""; $bSingleProfile = 0; $sTempFile = "t.t"; $sToday = substr($sDate,4); $nTotal = 0; $sUser = ""; $bUseRptFile = 1; @aUsers; $sVersion = "1.0"; MAIN: print "$sAppName $sVersion\n"; &ParseCmdArgs(); print "Getting domain users from server $sDC...\n"; Win32::AdminMisc::GetUsers($sPDC,'', \@aUsers); $n = 0; $nUsers = @aUsers; if ($bNoProfile) { $sProfile = "[no script]"; } if ($bSingleProfile) { print "Checking $nUsers users for $sProfile..."; } foreach $sUser (@aUsers) { $_ = $sUser; if (/\$$/) { next; } # skip names ending in '$' if (not $sUser =~ /\$+/) { # skip machine accounts if ($bDebug) { print "\ndbg> checking user $sUser\n"; } Win32::AdminMisc::UserGetMiscAttributes('',$_,\%hash); $sUsrProf = $hash{USER_PROFILE}; if ($bSingleProfile) { if ($sUsrProf eq $sProfile) { push @aMatchingUsers,$sUser; } else { if ($bNoProfile && ($sUsrProf eq "")) { push @aMatchingUsers,$sUser; } if ($sUsrProf =~ /\\/) { # if path included, strip & retest $n = strrchr($sUsrProf,'\\'); $sBare = substr($sUsrProf,$n+1); if ($sBare eq $sProfile) { push @aMatchingUsers,$sUser; } } } } else { if ($sUsrProf eq "") { $sUsrProf = "[none]"; } $bFound = 0; while(($sName,$nCount) = each(%hProfile)) { if ($sName eq $sUsrProf) { $bFound = 1; ++$hProfile{$sName}; # inc count for match in hash ### last; } } if ($bFound == 0) { $hProfile{$sUsrProf} = 1; } } } # end else (collect all profile stats) ++$n; if (!($n % 10)) { print "."; } # print '.' for every 10 users } print "\n"; if ($sRptFile) { $sOut = ">$sRptFile"; open(RPTFIL,$sOut) || die "Can't open file $sRptFile: $!"; print RPTFIL "$sAppName report generated on $sToday\n"; } if (! $bSingleProfile) { @sortedList = reverse sort byCount keys(%hProfile); foreach (@sortedList) { print "$_: $hProfile{$_}\n"; if ($sRptFile) { print RPTFIL "$_: $hProfile{$_}\n"; } } } else { $nMatches = @aMatchingUsers; print "\nFound $nMatches users with profile $sProfile:\n"; if ($sRptFile) { print RPTFIL "Found $nMatches users with profile $sProfile:\n"; } @sortedList = sort CaseInsensitive @aMatchingUsers; foreach (@sortedList) { print "$_\n"; if ($sRptFile) { print RPTFIL "$_\n"; } } if (!$sRptFile) { print "\nComplete.\n"; } } if ($sRptFile) { close RPTFIL; print "\nCreated report file $sRptFile\n"; } ### subroutines: ### sub byCount { return $hProfile{$a} <=> $hProfile{$b}; } sub CaseInsensitive { lc($a) cmp lc($b); } sub Help { print "\n$sAppName version $sVersion\n"; print "\nusage: $sAppName [[profilename] | [/noprofile]] [/output=filespec]\n"; print "\n 'noprofile' option lists accounts with no assigned profile\n"; } sub ParseCmdArgs { while (@ARGV) { $_ = shift @ARGV; if ($bDebug) { print "dbg: parsing $_\n"; } if (/^[\/\-]/) { # is arg a switch? $arg = substr($_,1,3); # parse 1st 3 chars: if (($arg eq "hel") || (substr($arg,0,1) eq "?")) { &Help(); exit; } if ($arg eq "out") { $i = index($_,"="); $i++; $sRptFile = sprintf("%s",substr($_,$i)); } if ($arg eq "nop") { # 'noprofile' $bSingleProfile = $bNoProfile = 1; } } else { # not a switch $sProfile = $_; $bSingleProfile = 1; } } if ($bDebug) { print "dbg: sRptFile = $sRptFile\n"; } } sub strrchr { local $nLen = length($_[0]); if ($nLen == 0) { print "strrchr error: zero-length string\n"; return -1; } local $sRevStr = reverse($_[0]); local $n = index($sRevStr,$_[1]); if ($n == -1) { return -1; } return ($nLen - $n) - 1; } __END__