Kleine und große Linux AHAs
MailMig Teil 3: Datengrundlage erstellen
Die nötigen Daten zu diesem Projekt befinden sich zu einem großen Teil im Exchange Server. Nur wie kommt man an diese Daten, um vernünftig mit ihnen arbeiten zu können? Ich habe einen Weg gefunden, der mir recht gut gefällt.
Zuerst ein Export! Aber wie?
Die Daten aus dem Exchange Server zu exportieren mag man sich einfacher vorstellen, als es möglich ist. Also meine erste Vermutung war: Im Verzeichnisbaum mit der rechten Maustaste klicken, exportieren, alles, speichern unter – fertig. Naja, das wäre zu einfach gewesen. Es gibt zwar diesen Menüeintrag, allerdings lässt sich damit nur die aktuelle Listenansicht exportieren. In dieser sind jedoch nicht alle Informationen enthalten.
Nach einiger Suche hatte ich einen neuen Freund gefunden: csvde.exe. Soll wohl sowas bedeuten wie “CSV Direcory Export”. Nutzt man diesen Befehl ohne Eingrenzung und unter einem Account mit den nötigen Privilegien, bekommt man eine .csv Datei mit “allen” Inhalten des Directories. Das sind mal gerade >300 Spalten
Ich habe den Befehl so ausgeführt:
csvde -u -f listing.csv
In listing.csv sind damit alle Informationen enthalten.
Wie nun damit arbeiten?
Diese Datei ist extrem unübersichtlich und auch mit Skripten in der Form nicht gut zu nutzen. Darum habe ich mir diese Datei in eine MySQL Datenbank eingelesen (macht bei einer größeren Anzahl Mailboxen wirklich Sinn). Sind die Daten in der Datenbank kann man recht einfach mit Perl andocken, Views bauen oder auch mit Grafischen Frontends Abfragen erstellen.
Damit die Datenbank ohne größeren Aufwand während der Migrationsphase aktualisiert werden kann, habe ich mir ein Script erstellt welches die .csv Datei in die Datenbank einliest, Views erstellt und über ein Perl Programm auch schon beispielsweise eine Tabelle mit den aktuellen Verteilerlisten erstellt (verteiler eMailadresse/Zieladressen). Das ganze sieht dann so aus:
#!/bin/bash
#
# Script zur Erstellung der Datenbanktabellen und Import der Daten aus einem
# Exchange Directory Dump.
#
# Ronny Becker, 08.2010
#
#
# Prerequisites:
# - Datenbank gal muss vorhanden sein
# - der Benutzer gal (pw: gal) muss Vollzugriff auf die Datenbank haben
#
# Tabelle anlegen
echo "drop table if exists pure_import; create table pure_import (
DN LONGTEXT,objectClass LONGTEXT,distinguishedName LONGTEXT,
instanceType LONGTEXT,whenCreated LONGTEXT,whenChanged LONGTEXT,
subRefs LONGTEXT,uSNCreated LONGTEXT,dSASignature LONGTEXT,
repsTo LONGTEXT,repsFrom LONGTEXT,uSNChanged LONGTEXT,
name LONGTEXT,objectGUID LONGTEXT,replUpToDateVector LONGTEXT,
creationTime LONGTEXT,forceLogoff LONGTEXT,lockoutDuration LONGTEXT,
lockOutObservationWindow LONGTEXT,lockoutThreshold LONGTEXT,maxPwdAge LONGTEXT,
minPwdAge LONGTEXT,minPwdLength LONGTEXT,modifiedCountAtLastProm LONGTEXT,
nextRid LONGTEXT,pwdProperties LONGTEXT,pwdHistoryLength LONGTEXT,
objectSid LONGTEXT,serverState LONGTEXT,uASCompat LONGTEXT,
modifiedCount LONGTEXT,auditingPolicy LONGTEXT,nTMixedDomain LONGTEXT,
rIDManagerReference LONGTEXT,fSMORoleOwner LONGTEXT,systemFlags LONGTEXT,
wellKnownObjects LONGTEXT,objectCategory LONGTEXT,isCriticalSystemObject LONGTEXT,
gPLink LONGTEXT,gPOptions LONGTEXT,masteredBy LONGTEXT,
msDSMachineAccountQuota LONGTEXT,msDSBehaviorVersion LONGTEXT,
msDSPerUserTrustQuota LONGTEXT,msDSAllUsersTrustQuota LONGTEXT,
msDSPerUserTrustTombstonesQuota LONGTEXT,msDsmasteredBy LONGTEXT,
msDSIsDomainFor LONGTEXT,dc LONGTEXT,ou LONGTEXT,description LONGTEXT,
showInAdvancedViewOnly LONGTEXT,dSCorePropagationData LONGTEXT,cn LONGTEXT,
memberOf LONGTEXT,userAccountControl LONGTEXT,badPwdCount LONGTEXT,codePage LONGTEXT,
countryCode LONGTEXT,badPasswordTime LONGTEXT,lastLogoff LONGTEXT,lastLogon LONGTEXT,
localPolicyFlags LONGTEXT,pwdLastSet LONGTEXT,primaryGroupID LONGTEXT,accountExpires LONGTEXT,
logonCount LONGTEXT,sAMAccountName LONGTEXT,sAMAccountType LONGTEXT,operatingSystem LONGTEXT,
operatingSystemVersion LONGTEXT,operatingSystemServicePack LONGTEXT,dNSHostName LONGTEXT,
rIDSetReferences LONGTEXT,servicePrincipalName LONGTEXT,userCertificate LONGTEXT,
displayName LONGTEXT,serverReferenceBL LONGTEXT,frsComputerReferenceBL LONGTEXT,
rIDAvailablePool LONGTEXT,msDSTombstoneQuotaFactor LONGTEXT,flags LONGTEXT,
versionNumber LONGTEXT,gPCFunctionalityVersion LONGTEXT,gPCFileSysPath LONGTEXT,
gPCMachineExtensionNames LONGTEXT,gPCUserExtensionNames LONGTEXT,ipsecName LONGTEXT,
ipsecID LONGTEXT,ipsecDataType LONGTEXT,ipsecData LONGTEXT,ipsecISAKMPReference LONGTEXT,
ipsecNFAReference LONGTEXT,ipsecOwnersReference LONGTEXT,ipsecNegotiationPolicyReference LONGTEXT,
ipsecFilterReference LONGTEXT,iPSECNegotiationPolicyType LONGTEXT,iPSECNegotiationPolicyAction LONGTEXT,
userParameters LONGTEXT,adminCount LONGTEXT,lockoutTime LONGTEXT,msNPAllowDialin LONGTEXT,
members LONGTEXT,groupType LONGTEXT,revision LONGTEXT,logonHours LONGTEXT,comments LONGTEXT,
lastSetTime LONGTEXT,priorSetTime LONGTEXT,fRSReplicaSetType LONGTEXT,fRSVersionGUID LONGTEXT,
fRSFileFilter LONGTEXT,fRSReplicaSetGUID LONGTEXT,serverReference LONGTEXT,frsComputerReference LONGTEXT,
fRSMemberReferenceBL LONGTEXT,fRSWorkingPath LONGTEXT,fRSRootPath LONGTEXT,fRSStagingPath LONGTEXT,
fRSMemberReference LONGTEXT,rIDAllocationPool LONGTEXT,rIDPreviousAllocationPool LONGTEXT,
rIDUsedPool LONGTEXT,rIDNextRID LONGTEXT,dNSProperty LONGTEXT,sn LONGTEXT,givenName LONGTEXT,
homeMTA LONGTEXT,proxyAddresses LONGTEXT,homeMDB LONGTEXT,mDBUseDefaults LONGTEXT,
mailNickname LONGTEXT,legacyExchangeDN LONGTEXT,userPrincipalName LONGTEXT,textEncodedORAddress LONGTEXT,
mail LONGTEXT,msExchHomeServerName LONGTEXT,msExchALObjectVersion LONGTEXT,msExchHideFromAddressLists LONGTEXT,
msExchMailboxSecurityDescriptor LONGTEXT,msExchUserAccountControl LONGTEXT,msExchMailboxGuid LONGTEXT,
msExchPoliciesIncluded LONGTEXT,showInAddressBook LONGTEXT,mSMQSignCertificates LONGTEXT,
mSMQDigests LONGTEXT,objectVersion LONGTEXT,sIDHistory LONGTEXT,managedBy LONGTEXT,
reportToOriginator LONGTEXT,deletedItemFlags LONGTEXT,garbageCollPeriod LONGTEXT,replicatedObjectVersion LONGTEXT,
replicationSignature LONGTEXT,msExchADCGlobalNames LONGTEXT,msExchMasterAccountSid LONGTEXT,dLMemDefault LONGTEXT,
msExchPoliciesExcluded LONGTEXT,reportToOwner LONGTEXT,hideDLMembership LONGTEXT,oOFReplyToOriginator LONGTEXT,
l LONGTEXT,telephoneNumber LONGTEXT,department LONGTEXT,mAPIRecipient LONGTEXT,employeeNumber LONGTEXT,
employeeID LONGTEXT,uid LONGTEXT,manager LONGTEXT,BsiSysteme LONGTEXT,uidNumber LONGTEXT,gidNumber LONGTEXT,
unixHomeDirectory LONGTEXT,loginShell LONGTEXT,assistant LONGTEXT,securityProtocol LONGTEXT,
deliverAndRedirect LONGTEXT,autoReplyMessage LONGTEXT,extensionAttribute10 LONGTEXT,protocolSettings LONGTEXT,
physicalDeliveryOfficeName LONGTEXT,targetAddress LONGTEXT,internetEncoding LONGTEXT,title LONGTEXT,
msExchPreviousAccountSid LONGTEXT,altRecipient LONGTEXT,info LONGTEXT,facsimileTelephoneNumber LONGTEXT,
publicDelegates LONGTEXT,altRecipientBL LONGTEXT,profilePath LONGTEXT,publicDelegatesBL LONGTEXT,
displayNamePrintable LONGTEXT,msExchExpansionServerName LONGTEXT,msExchUnmergedAttsPt LONGTEXT,
deliveryMechanism LONGTEXT,msExchPFTreeType LONGTEXT,delivContLength LONGTEXT,msExchRequireAuthToSendTo LONGTEXT,
securityIdentifier LONGTEXT,trustDirection LONGTEXT,trustPartner LONGTEXT,trustPosixOffset LONGTEXT,
trustType LONGTEXT,trustAttributes LONGTEXT,flatName LONGTEXT,scriptPath LONGTEXT,roomNumber LONGTEXT,
homeDirectory LONGTEXT,homeDrive LONGTEXT,msRADIUSCallbackNumber LONGTEXT,msRADIUSServiceType LONGTEXT,
userWorkstations LONGTEXT,directReports LONGTEXT,msRASSavedCallbackNumber LONGTEXT,company LONGTEXT,
submissionContLength LONGTEXT,managedObjects LONGTEXT,operatorCount LONGTEXT,lastKnownParent LONGTEXT,
mDBOverHardQuotaLimit LONGTEXT,pager LONGTEXT,otherFacsimileTelephoneNumber LONGTEXT,location LONGTEXT,
gPCWQLFilter LONGTEXT,mSDSCreatorSID LONGTEXT,msRRASAttribute LONGTEXT,unixUserPassword LONGTEXT,
initials LONGTEXT,adminDisplayName LONGTEXT,keywords LONGTEXT,serviceClassName LONGTEXT,serviceBindingInformation LONGTEXT,
serviceDNSName LONGTEXT,serviceDNSNameType LONGTEXT,categoryId LONGTEXT,localizedDescription LONGTEXT,extensionName LONGTEXT,
lastUpdateSequence LONGTEXT,appSchemaVersion LONGTEXT,msiScriptPath LONGTEXT,cOMClassID LONGTEXT,localeID LONGTEXT,
machineArchitecture LONGTEXT,packageType LONGTEXT,packageName LONGTEXT,packageFlags LONGTEXT,versionNumberHi LONGTEXT,
versionNumberLo LONGTEXT,msiFileList LONGTEXT,upgradeProductCode LONGTEXT,productCode LONGTEXT,msiScriptName LONGTEXT,
installUiLevel LONGTEXT,canUpgradeScript LONGTEXT,mSMQSites LONGTEXT,mSMQServiceType LONGTEXT,mSMQOSType LONGTEXT,
mSMQEncryptKey LONGTEXT,mSMQSignKey LONGTEXT,mSMQDependentClientServices LONGTEXT,mSMQRoutingServices LONGTEXT,
mSMQDsServices LONGTEXT,url LONGTEXT,fileExtPriority LONGTEXT,postalCode LONGTEXT,streetAddress LONGTEXT,
msDSSupportedEncryptionTypes LONGTEXT,gecos LONGTEXT,dnsRecord LONGTEXT,uNCName LONGTEXT,serverName LONGTEXT,
portName LONGTEXT,driverName LONGTEXT,priority LONGTEXT,printStartTime LONGTEXT,printEndTime LONGTEXT,printBinNames LONGTEXT,
printMaxResolutionSupported LONGTEXT,printOrientationsSupported LONGTEXT,printCollate LONGTEXT,printColor LONGTEXT,
printShareName LONGTEXT,printSpooling LONGTEXT,printKeepPrintedJobs LONGTEXT,driverVersion LONGTEXT,printMaxXExtent LONGTEXT,
printMaxYExtent LONGTEXT,printMinXExtent LONGTEXT,printMinYExtent LONGTEXT,printStaplingSupported LONGTEXT,printMediaReady LONGTEXT,
printNumberUp LONGTEXT,printMediaSupported LONGTEXT,printerName LONGTEXT,shortServerName LONGTEXT,printDuplexSupported LONGTEXT,
printMemory LONGTEXT,printRateUnit LONGTEXT,printLanguage LONGTEXT,printRate LONGTEXT,printPagesPerMinute LONGTEXT,
adminDescription LONGTEXT,schemaVersion LONGTEXT,msSFU30KeyAttributes LONGTEXT,msSFU30FieldSeparator LONGTEXT,
msSFU30IntraFieldSeparator LONGTEXT,msSFU30SearchAttributes LONGTEXT,msSFU30ResultAttributes LONGTEXT,msSFU30MapFilter LONGTEXT,
msSFU30MasterServerName LONGTEXT,msSFU30OrderNumber LONGTEXT,msSFU30Domains LONGTEXT);" | mysql -u gal -pgal gal
# Daten einlesen
echo "LOAD DATA INFILE 'listing.csv' INTO TABLE pure_import FIELDS TERMINATED BY ',' ENCLOSED BY '\"' IGNORE 1 LINES;" | mysql -u gal -pgal gal
# views einrichten
echo "CREATE VIEW `gal`.`aliases_with_mail` AS SELECT DN,members,mail FROM `gal`.`pure_import` where mail <> '' and members <> '' and members LIKE 'CN%';" | mysql -u gal -pgal gal
echo "CREATE VIEW `gal`.`AddBook` AS select `gal`.`pure_import`.`sn` AS `sn`,`gal`.`pure_import`.`givenName` AS `givenName`,`gal`.`pure_import`.`mail` AS `mail`,`gal`.`pure_import`.`l` AS `l`,`gal`.`pure_import`.`telephoneNumber` AS `telephoneNumber`,`gal`.`pure_import`.`department` AS `department`,`gal`.`pure_import`.`description` AS `description`,`gal`.`pure_import`.`showInAddressBook` AS `showInAddressBook` from `gal`.`pure_import` where (`gal`.`pure_import`.`showInAddressBook` like '%Globale Adressliste%')" | mysql -u gal -pgal gal
# tabelle mit verteilerlisten anlegen
echo "drop table if exists lists; create table lists (mail TEXT,recipient LONGTEXT);" | mysql -u gal -pgal gal
# Tabelle mit Verteilerlisten fuellen
./gal_create_table_sub.pl
Hier nun noch das sub-Script:
#!/usr/bin/perl
# Listing
@MAILADDS=`echo "select mail,members from aliases_with_mail" | mysql -N -u gal -pgal gal`;
$count_all=$#MAILADDS + 1;
$counter=1;
foreach $line (@MAILADDS) {
chomp($line);
$all_rec="";
($mail,$members)=split("\t",$line);
@each_member=split(";",$members);
foreach $member (@each_member) {
$tmp_add=`echo "select mail from tabelle1 where DN='$member';" | mysql -N -u gal -pgal gal`;
chomp($tmp_add);
if ( length($tmp_add) != 0 ) {
$all_rec=$all_rec.",".$tmp_add;
}
}
$all_rec =~ s/^,//;
`echo "insert into lists(mail,recipient) values('$mail','$all_rec');" | mysql -N -u gal -pgal gal`;
print "$counter / $count_all\n";
$counter++;
}
| Artikel drucken | Dieser Beitrag wurde von Ronny am 27. August 2010 um 08:32 veröffentlicht und unter bash, MailMig, ScriptHints, ubuntuusers.de abgelegt. Du kannst allen Antworten zu diesem Beitrag durch RSS 2.0 folgen. Du kannst direkt zum Ende gehen und einen Kommentar hinterlassen. Pings ist momentan nicht möglich. |









vor 1 Jahr
Das Perlscript wäre doch wesentlich schöner, wenn du einfach DBI verwenden würdest, statt dieses üblen mysql-systemcalls.
Um die Anzahl der Elemente eine arrays zu bekommen, reicht es übrigens, den array in scalarem Kontext zu behandeln, also:
$count_all = @MAILADDS # reicht schon!
statt des kryptischen
$count_all=$#MAILADDS + 1;
vor 1 Jahr
Deswegen hab ich ja geschrieben, dass das alles recht “dreckig” ist. Ich werde das Script lediglich während der Migrationsphase benutzen und daher habe ich da nicht viel Hirnschmalz reingesteckt
vor 1 Jahr
Finde es immer interessant Erfahrungsberichte zu lesen. Freue mich schon auf den nächsten Artikel.
Die Nutzerdaten willst du dann auch in Zukunft in der MySQL-DB vorhalten? Für Domänen-Geschichten wäre eine LDAP-Lösung auch nicht verkehrt.
lg
phil
vor 1 Jahr
Hi,
vielen Dank.
Die Datenbank ist nur temporär – damit man einfacher mit den Daten arbeiten kann.
Gruß
Ronny