http://qs321.pair.com?node_id=573693
Category: NT Admin
Author/Contact Info /msg davis
Description:

Here's a script to extract telephone entries from a Windows AD via Net::LDAP (thanks g0n!) and output them to a LaTeX file to be process with pdflatex. The results aren't too terrible.

You'll probably need to customize it; we, for example, store "Mobile speed dial" numbers in the "Pager" field. We also deliberately separate based on the physical building — YMMV.

I'd recommend separating the template into a separate file, I included here inline because it's easier to download.


#!/usr/bin/perl

use warnings;
use strict;
use Data::Dumper;
use Net::LDAP;
use Net::LDAPS;
use Template;

my $template_input = '\documentclass[10pt,a4paper]{article}
\usepackage{times}
\usepackage{xtab}
\usepackage{colortbl}

\setlength\textheight{290mm}
\setlength{\voffset}{-15mm} 
\begin{document}
\begin{center}
\begin{xtabular}{lllll}
\textbf{Name} & \textbf{Title} & \textbf{Ext.} & \textbf{Mobile} & \te
+xtbf{SPD} \\\\
\hline

[% FOREACH buildings %]
\hline
\multicolumn{5}{c}{[% buildingname %]}\\\\
\hline

[% FOREACH staff %]
[%- IF loop.index % 2 -%]\rowcolor[gray]{0.91}[%- END -%][%name%] & \\
+tiny{[%title%]} & [%extension%] & [%mobile%]  & [%mobile_speed_dial%]
+\\\\
[% END %]
[% END %]
\end{xtabular}
\end{center}
\end{document}';


##There'll be some customization necessary here
my $ldap = Net::LDAPS->new("domain.controller") or die "$@";

my $message
    = $ldap->bind( "cn=Some User,ou=Service Accounts,dc=company,dc=com
+",
    password => 'Secret' );

$message = $ldap->search(
    base   => "ou=Employees,dc=company,dc=com",
    filter => "(& (cn=*) (objectClass=user))",
);

$message->code && die $message->error;

my @skip_names = (

    #A list of names to be skipped (service/admin accounts etc)
);

my %staff;

foreach my $employee ( $message->all_entries ) {

    my $name = $employee->get_value("cn");
    next if ( grep /^\Q$name\E$/, @skip_names );
    
    my $title             = $employee->get_value("title")           ||
+ "";
    my $extension         = $employee->get_value("telephoneNumber") ||
+ "";
    my $mobile            = $employee->get_value("mobile")          ||
+ "";
    my $mobile_speed_dial = $employee->get_value("pager")           ||
+ "";
    
    my $building = $employee->get_value("physicalDeliveryOfficeName") 
+|| "";
    my $useraccount_control = $employee->get_value("userAccountControl
+")
        || "";

    next if ( account_disabled($useraccount_control) );    # Skip disa
+bled accounts

    push @{ $staff{$building} },
        {
        name              => $name,
        title             => $title,
        extension         => $extension,
        mobile            => $mobile,
        mobile_speed_dial => $mobile_speed_dial
        };
}

my @buildings;
foreach my $building ( sort keys(%staff) ) {
    my @staff = sort { $a->{name} cmp $b->{name} } @{ $staff{$building
+} };
    push @buildings, { buildingname => $building, staff => \@staff };
}
my $template = Template->new();
my $output;
$template->process( \$template_input, { buildings => \@buildings }, \$
+output )
    or die $template->e->error(), "\n";
open( my $fh, ">", "phone_list.tex" )
    or die "Couldn't open phone_list.tex for writing: $!\n";
print $fh $output;
close($fh);

sub account_disabled {
    my $flags = shift;
    my %check = calculate_flags($flags);
    return 1 if ( $check{ACCOUNTDISABLE} );
    return 0;
}

sub calculate_flags {
    my $flags_to_check = shift;
    my %table          = (
        SCRIPT                         => 0x0001,
        ACCOUNTDISABLE                 => 0x0002,
        HOMEDIR_REQUIRED               => 0x0008,
        LOCKOUT                        => 0x0010,
        PASSWD_NOTREQD                 => 0x0020,
        PASSWD_CANT_CHANGE             => 0x0040,
        ENCRYPTED_TEXT_PWD_ALLOWED     => 0x0080,
        TEMP_DUPLICATE_ACCOUNT         => 0x0100,
        NORMAL_ACCOUNT                 => 0x0200,
        INTERDOMAIN_TRUST_ACCOUNT      => 0x0800,
        WORKSTATION_TRUST_ACCOUNT      => 0x1000,
        SERVER_TRUST_ACCOUNT           => 0x2000,
        DONT_EXPIRE_PASSWORD           => 0x10000,
        MNS_LOGON_ACCOUNT              => 0x20000,
        SMARTCARD_REQUIRED             => 0x40000,
        TRUSTED_FOR_DELEGATION         => 0x80000,
        NOT_DELEGATED                  => 0x100000,
        USE_DES_KEY_ONLY               => 0x200000,
        DONT_REQ_PREAUTH               => 0x400000,
        PASSWORD_EXPIRED               => 0x800000,
        TRUSTED_TO_AUTH_FOR_DELEGATION => 0x1000000,
    );
    my %results;
    foreach my $flag ( keys %table ) {

        $results{$flag} = 1 if ( $flags_to_check & $table{$flag} );

    }
    return %results;
}