Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

lastlogin for NT/2K

by idnopheq (Chaplain)
on Apr 23, 2001 at 13:53 UTC ( #74669=sourcecode: print w/ replies, xml ) Need Help??

Category: NT Admin
Author/Contact Info idnopheq
Description: lastlogin -- show the last date on which each person logged in.

lastlogin displayes the last logon date for each user in the local host's user database.

UPDATE: Got rid of the exists test on scalars, per Re: lastlogin for NT/2K. THX frag! What ~was~ I thinking?

#!/usr/local/bin/perl -w

use strict;
use Win32API::Net;
use vars qw ( %UserInfo @WhoList );
use Win32::NetAdmin;

my ($VERSION) = '$Revision: 1.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 [ userid ] [ -h ]
    die "$0: @_";

die "Usage" if ( $ARGV[0] && $ARGV[0] eq "-h" );

my $Server = "";              # localhost only
my $Level  = "11";            # make UserGetInfo() return lastLogon
my $Filter = "0";             # I do not know what this does and why
                              # it must be numeric.

Win32::NetAdmin::GetUsers (
  or die "$^E\n"
  unless $ARGV[0];

if ( exists $ARGV[0] ) {
    $WhoList[0] = $ARGV[0] 
      if Win32::NetAdmin::UsersExist (
      or exit;

foreach my $UserName ( @WhoList ) {
    my (
       ) = UserGetInfo( $UserName );

    printf "%s %$ {NameLength}s: %s\n", $UserName, "Last login", $Last

sub UserGetInfo {
    my $userid = shift ( @_ );
    my $length = 25 - length $userid;
    my $last;
    if ( Win32API::Net::UserGetInfo (
        ) ) {

 if ( $UserInfo{lastLogon} == 0 ) {
     $last = "never";
 else {
     $last = localtime ( $UserInfo{lastLogon} );
    else {
     $last = "unknown";
    return ( $last, $length );


=head1 NAME

B<lastlogin> -- show the last date on which each person logged in.


B<lastlogin> [ I<userid> ] [ -h ]


B<lastlogin> displayes the last logon date for each user in the local 
+host's user database.

=head2 OPTIONS

The following options are supported:

=over 4

=item userid

List the lastlogon information for a single user.

=item -h

Display syntax.


=head1 EXAMPLE

Below are exampls of B<lastlogin>:

C:\> lastlogin Guest
Guest           Last login: never

C:\> lastlogin
Administrator   Last login: Thu Jun 22 09:39:28 2000
Guest           Last login: never
IUSR_IKIRU      Last login: Mon Jun 19 08:16:13 2000
IWAM_IKIRU      Last login: never
sfuuser         Last login: never


The working of B<lastlogin> is not influenced by any environment varia

=head1 BUGS

B<lastlogin> isn't as nice as I would like, but Win32 isn't Unix, now 
+is it?  This I<really> doesn't like Samba domain controllers, which i
+s why I added the 'unknown' entry in the output.

Samba causes problems, which is why an entry might return "unknown".


It does not make sense to talk about standards in a B<lastlogin> manua
+l page.


    Revision 1.0  2000/06/22 12:13:22  idnopheq
    Initial revision

=head1 AUTHOR

The Perl implementation of B<lastlogin> was written by Dexter Coffin, 


This program is copyright by Dexter Coffin 2000.

This program is free and open software. You may use, copy, modify, dis
and sell this program (and any modified variants) in any way you wish,
provided you do not restrict others from doing the same.

=head1 SEE ALSO



Comment on lastlogin for NT/2K
Download Code
Replies are listed 'Best First'.
Re: lastlogin for NT/2K
by frag (Hermit) on Apr 24, 2001 at 03:24 UTC
    In a few spots, you apply "exists" to test an array element. exists() is only meant for testing hash entries, and for me, this generates a compile-time error. You should replace
    ( exists $ARGV[0] )
    with plain old
    ( $ARGV[0] )

    Also, personally I'd take

    Win32::NetAdmin::GetUsers ... or die unless exists $ARGV[0]; if ( exists $ARGV[0] ) { ... }
    and turn it into an unless-else:
    unless ($ARGV[0]) { Win32::NetAdmin::GetUsers ... } else { ... }

    Style issues aside, as a Linux-user adjusting to Win32, these tools you've posted are good things to have; thanks for posting them.

    -- Frag.

Back to Code Catacombs

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: sourcecode [id://74669]
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others about the Monastery: (7)
As of 2015-10-14 00:27 GMT
Find Nodes?
    Voting Booth?

    Does Humor Belong in Programming?

    Results (319 votes), past polls