http://qs321.pair.com?node_id=74683
Category: NT Admin
Author/Contact Info idnopheq
Description: useradd adds a user to a NT host a la the Solaris useradd utility.

TODO:

  • Modify for Win2K, domains
  • POD
  • Testing Testing Testing

This script is very BETA, hense the use diagnostics. But, I posted this for the logonhours part (works like net user syntax) and for folks who want to reuse solaris useradmin scripts on NT.

#!/usr/local/bin/perl -w
#-*-perl-*-
# ------ Create a new user

use strict;
use Win32;
use Win32::NetAdmin;
use Win32API::Net;
use Getopt::Std;
use diagnostics;

use vars qw( %Option %args %Account %Share @opts %Day %Daynames @logon
+hours $Error );

my ($VERSION) = '$Revision: 2.0 $' =~ /([.\d]+)/;

my $warnings = 0;

# Print a usuage message on a unknown option.

$SIG {__WARN__} = sub {
    if (substr ($_ [0], 0, 14) eq "Unknown option") {die "Usage"};
    require File::Basename;
    $0 = File::Basename::basename ($0);
    $warnings = 1;
    warn "$0: @_";
};

$SIG {__DIE__} = sub {
    require File::Basename;
    $0 = File::Basename::basename ($0);
    if (substr ($_ [0], 0,  5) eq "Usage") {
        die <<EOF;
$0 (NT Perl bin utils) $VERSION
$0 [ -c comment ][ -f fullname ][ -h home dir ][ -m ][ -e expire ]
        [ -l logon script ][ -g group ][ -t logonhours] username
EOF
    }
    die "$0: @_";
};

# Get the options.

getopts ( 
     'c:f:h::e:l:G:g:t:m',
      \%Option 
    );                    # 

die "Usage" unless @ARGV;

# don't waste time if the user exists

my $Server     = "";
Existance();

# set default values unless defined

$Option{'h'} ||= "$ENV{SystemRoot}\\Profiles\\$ARGV[0]";
$Option{'c'} ||= "Normal User";
$Option{'f'} ||= "";
$Option{'e'} ||= "30";
$Option{'l'} ||= "";
$Option{'g'} ||= "Users";
$Option{'t'} ||= "0";
$Option{'E'} ||= "0";

# set up the account hash

my $Level = "3";
%Account = (
        'acctExpires'     => "-1", # 30 days,
        'authFlags'       => "",
        'badPWCount'      => "",
        'codePage'        => "",
        'comment'         => $Option{'c'},
        'countryCode'     => "",
        'flags'           => "513",
        'fullName'        => $Option{'f'},
        'homeDir'         => $Option{'h'},
        'homeDirDrive'    => "",
        'lastLogon'       => "",
        'lastLogoff'      => "",
        'logonHours'      => $Option{'t'},
        'logonServer'     => "",
        'maxStorage'      => "-1",
        'name'            => $ARGV[0],
        'numLogons'       => "",
        'parms'           => "",
        'password'        => 'testpassword', 
        'passwordAge'     => "",
        'passwordExpired' => $Option{'E'},
        'primaryGroupId'  => "0x201",
        'priv'            => "1",
        'profile'         => "",
        'scriptPath'      => $Option{'l'},
        'unitsPerWeek'    => "168",
        'userId'          => "",
        'usrComment'      => "$Option{'f'} - $Option{'c'}",
        'workstations'    => "",
       );

$Account{acctExpires} = time + ( $Option{'e'} * 8640 ) if exists $Opti
+on{'e'};
# $Account{name} = $ARGV[0];

AddUser();
# AddUser2Group();
exit 1;

sub Existance {
  if ( Win32::NetAdmin::UsersExist ( 
                    $Server,
                    $ARGV[0] 
                   ) ) {
    print "$ARGV[0] exists on $Server ... nothing to do\n";
    exit 1;
  } else {
    print "$ARGV[0] does not exist ... building ... ";
  }
}

sub AddUser {
  if (
      ! Win32API::Net::UserAdd( 
                   $Server,
                   $Level,
                   \%Account,
                   $Error
                  ) ) {
    print "Sorry, something went wrong; error: $^E\n";
    exit 1; 
  } else {
    print "$Account{name} built ... \n";
  }
}

sub AddUser2Group {
  if (!Win32::NetAdmin::LocalGroupAddUsers( 
                       $Server, 
                       $Option{'g'}, 
                       $Account{name}
                      ) ) { 
    print "Sorry, something went wrong: error: $^E\n"; 
    exit 1; 
  }
  print "added $Account{name} to group ... \n";
}


sub MakeHome {
  %Share = (
        'path'          => "c:\\home\\$Account{name}",
        'netname'       => "$Account{name}",
        'maxusers'      => -1,
        'remark'        => "$Account{full_name}",
        'passwd'        => "",
        'current-users' => 0,
        'permissions'   => 0,
        'type'          => 0,
       );

  mkdir ("\\\\$Server\\c\$\\home\\$Account{name}",
     0777) || print "Error creating home dir: $!\n";
  if ( Win32::NetResource::NetShareAdd( \%Share, 
                    my $Param, 
                    "\\\\$Server" ) ) {
    print "Successfully shared $Share{path} as $Share{netname}.\n";
  } else {
    print "Failed to share $Share{path} as $Share{netname}.\n";
    #     Win32::NetResource::GetError( $Error2 );
    #     if( my $Error == ERROR_EXTENDED_ERROR )
    #     {
    #         Win32::NetResource::WNetGetLastError( $Error, 
    #                           my $Text, 
    #                           my $Provider );
    #         $Text .= " ($Provider)";
    #     }else{
    #         $Text = Win32::FormatMessage( $Error );
    #     }
    #     print "Error $Error: $Text";
  }
}

sub LogonHours {

  @logonhours = ("000000000000000000000000",
         "000000000000000000000000",
         "000000000000000000000000",
         "000000000000000000000000",
         "000000000000000000000000",
         "000000000000000000000000",
         "000000000000000000000000");

  %Day        = ( 
         "Su" => "0",
         "M"  => "1",
         "T"  => "2",
         "W"  => "3",
         "Th" => "4",
         "F"  => "5",
         "Sa" => "6",
        );

  %Daynames   = (
         "Sunday"    => "Su",
         "Monday"    => "M",
         "Tuesday"   => "T",
         "Wednesday" => "W",
         "Thursday"  => "Th",
         "Friday"    => "F",
         "Saturday"  => "Sa",
        );

  if (!@_) {
    die "Syntax!\n";
  }

  @opts = split (/,/, $_[0]);

  if ($opts[0] =~ /all/i) {
    for (@logonhours) {
      s/0/1/g;
    }
  } else {
    while (@opts) {
      my ($first,
      $last);
      if ($opts[0] =~ /^[MTWF||Th||Sa||Su].*/i) {
    my $dow = ucfirst $opts[0];
    if ($dow =~ /-/) {
      ($first,
       $last) = split (/-/, $dow);
      $last = ucfirst $last;
      if (exists $Daynames{$first}) {
        $first = $Daynames{$first};
      } else {
        if (!exists $Day{$first}) {
          die "Invalid day syntax $first!\n";
        }
      }
      if (exists $Daynames{$last}) {
        $last = $Daynames{$last};
      } else { 
        if (!exists $Day{$first}) {
          die "Invalid day syntax $last!\n";
        }
      }
      if ($Day{$last} - $Day{$first} < 0) {
        push @opts, "Su-$last";
        push @opts, $opts[1];
        $last = "Sa";
      }
    } else {
      if (exists($Daynames{$dow})) {
        $dow = $Daynames{$dow};
      } elsif (!exists($Day{$dow})) {
        die "Invalid day syntax $last!\n";
      }
      $first = $last = $dow;
    }
    shift @opts;
      }
      if ($opts[0] =~ /^[0-9]/) {
    if ($opts[0] =~ /-/) {
      my $time = $opts[0];
      my ($begin,
          $end) = split (/-/, $time);
      if ($begin =~ s/pm//i) {
        if ($begin <= 12) {
          $begin = $begin + 12;
        }
      } elsif ($begin =~ s/am//i) {
        if ($begin == 12) {
          $begin = "0";
        }
      }
      if ($end =~ s/pm//i) {
        if ($end < 12) {
          $end = $end + 12;
        }
      } elsif ($end =~ s/am//i) {
        if ($end == 12) {
          $end = "23";
        }
      }
      if ($end - $begin < 0) {
        die "Invalid time syntax in $time\n";
      }
      for (my $q = $Day{$first}; $q <= $Day{$last}; $q++) {
        my $bitstr = "0";
        if ($begin == "0") {
          $bitstr = "1";
        }
        for (my $i = 1; $i <= 23; $i++) {
          if ($i < $begin || $i > $end) {
        $bitstr = $bitstr . "0";
          } else {
        $bitstr = $bitstr . "1";
          }
        }
        $logonhours[$q] = $bitstr;
      }
      shift @opts;
    } else {
      die "Invalid time syntax: $opts[0]\n";
    }
      } else {
    die "Invalid time syntax: $opts[0]\n";
      }
    }
  }

  # foreach (@logonhours) {
  #   print $_ . "\n";
  # }
  my $LogonHours = pack("b168",
            join ('',
                  @logonhours));
  return $LogonHours;
  # print $LogonHours ."\n";

}