I have created a script in Perl to connect to LDAP, retrieve values and post them to a CSV file. The values I am retrieving via a query are d”distinguished name, userAccountControl & pwdLastSet. I can pull and parse the first two results correctly and post them to the CSV file, but the pwdLastSet is returning WIN32::OLE=HASH(0x…….). I have tired sprintf, hex(), and the results are either the WIN32 value or 0. I am expecting something 18 digits in length. Thanks for the help.
#!/usr/bin/perl
use xSV;
use Win32;
use Win32::OLE;
# use strict;
.
.
.
.
while ($line = <GROUPS>) {
chomp($line);
if ($line =~ m/^ user .*/) {
$line =~ s/^ user.\s//;
my ($objRootDSE, $strDomain, $strUsername, $objConnection, $objCommand, $objRecordSet, $strDN, $arrSplitResponse, $strLName, $strFName, $strUserType);
use constant ADS_SCOPE_SUBTREE => 2;
# Get domain components
$objRootDSE = Win32::OLE->GetObject('LDAP://RootDSE');
$strDomain = $objRootDSE->Get('DefaultNamingContext');
# Get username to search for
$strUsername = $line;
# Set ADO connection
$objConnection = Win32::OLE->new('ADODB.Connection');
$objConnection->{Provider} = 'ADsDSOObject';
$objConnection->Open('Active Directory Provider');
# Set ADO command
$objCommand = Win32::OLE->new('ADODB.Command');
$objCommand->{ActiveConnection} = $objConnection;
$objCommand->SetProperty("Properties", 'Searchscope', ADS_SCOPE_SUBTREE);
$objCommand->{CommandText} = 'SELECT distinguishedName, userAccountControl, pwdLastSet FROM \'LDAP://' . $strDomain . '\' WHERE objectCategory=\'user\' AND samAccountName = \'' . $strUsername . '\'';
# Set recordset to hold the query result
$objRecordSet = $objCommand->Execute;
# If a user was found - Retrieve the distinguishedName
if (!$objRecordSet->EOF) {
$strDN = $objRecordSet->Fields('distinguishedName')->Value;
$strAcctControl = $objRecordSet->Fields('userAccountControl')->Value;
$strpwdLS = sprintf($objRecordSet->Fields('pwdLastSet')->Value);
@arrSplitResponse = split(/,/, $strDN);
$strLName = substr($arrSplitResponse[0],3);
if ($strLName =~ m/\\$/) {
$strLName = substr($strLName,0,-1);
}
$strFName = $arrSplitResponse[1];
if ($strFName =~ m/OU=/) {
$strUserType = $strFName;
$strFName = "";
$strUserType = substr($strUserType,3);
} else {
$strUserType = substr($arrSplitResponse[2],3);
}
if ($strAcctControl == 512) {
$strAcctControl = "Active";
} else {
$strAcctControl = "Disabled";
}
} else {
print "No user found";
}
&debug("Match!: $line in $group\n");
$csv->print_data(
AccountName => $line,
LastName => $strLName,
FirstName => $strFName,
SYSGenericAcct => $strUserType,
AccessLevel => $group,
AccessCapability => "User",
Description => $desc,
Status => $strAcctControl,
LastPwdChange => $strpwdLS
);
} else {
$group = $line;
chomp($desc = <GROUPS>);
chomp($group2 = <GROUPS>);
&debug("$group\n$desc\n$group\n");
}
}
Use Net::Ldap to search AD server. It is fast and it is portable. It is possible to search AD server from other hosts, even from linux. It is a fast and mature module.
You could also do some debug, using Data::Dumper.
use Data::Dumper;
…
print Dumper($strpwdLS);
I found this thread: http://code.activestate.com/lists/pdk/3876/