F:\Dev\CPP\AdMod>admod -csv? AdMod V01.07.00cpp_BETA1 Joe Richards (joe@joeware.net) September 2006 -help Basic help. -? Basic help. -?? Advanced help. -???? Shortcut help. -sc? Shortcut help. -csv? CSV / ADCSV help. Usage: AdMod [switches] [attr-action] Switches: (designated by - or /) AdMod CSV Options ================= -csv Enable CSV input from STDIN. Must pipe DNs into ADMOD. -csvdelim x Delimiter to use for separating attributes in CSV input, default (,). -csvmvdelim x Delimiter to use for separating multiple values in input, default (;). -csvq x Character used for quoting attributes, default ("). -countstart x Integer value to start in counter enumerator. -bmod x Add op only. Base modification expansion string. -autobase x:y Add op only. Autobase generation. x is count of DNs to create and y is base value to expand for DN. -import Import mode, suck in all attributes in CSV. -importexclattr x Attributes to exclude in import, semicolon delimited. -expand Variable expansion mode. Automatically enabled when ADCSV detected. See below for expansion details. This CAN be used in non-CSV modes however, you can't expand values from the CSV fields because there aren't any. :) The CSV option supports renames, adds, and modifications. The documentation is intentionally light as it would take a long time to fully document every aspect and I will save that for a book or something that pays to spend all that time on it and move onto something else I need done. I expect most of it can be worked out by others by simple trial and eror (get it?) or looking at the examples. Something to keep in mind when importing CSV files is that AdMod will not figure out and handle ordering for you. For instance, if you have group1 that has a member of group2 and you are importing groups, the import will fail unless group2 is created before group1. If you have group1 as a member of group2 and group2 is a member of group1 (i.e. recursive nesting) then you need to create the groups in one pass and then in a second pass populate the membership. The -importexclattr excludes several attributes by default even if you do not specify any other attributes: createTimeStamp distinguishedName dSCorePropagationData lastLogonTimestamp modifyTimeStamp msDS-Cached-Membership msDS-Cached-Membership-Time-Stamp objectCategory objectGUID objectSid replUpToDateVector repsFrom repsTo sIDHistory subRefs uSNChanged uSNCreated whenChanged whenCreated Currently there is no check for the size of update/add request. This means that if you try to import a group with some large number of members it is possible and even likely that it will fail if the update exceeds the LDAP packet size maximum. The number of members will be limited based on the size of the DNs of the members. Correction of this issue will occur in some future version of AdMod. ADCSV ===== There is also a special ADCSV submode which is automatically invoked when AdMod detects the ADCSV header on info piped in from AdFind. You can invoke this mode by specifying -ADCSV in the AdFind command line. The ADCSV mode sends some additional information over from switches from AdFind including: o CSV Delimiter o CSV Multivalue Delimiter o CSV Quote Character o Host o Port The obvious benefit here is that if you use something other than the default values you won't have to specify that to AdMod, it can figure it out on its own. Also the Host and Port specified means you hit the same server and port you pulled the information from. However, if for some reason you want to, you can override the values with switches directly applied to the AdMod command line. EXPANSION ========= AdMod supports 'expansion' of strings with 'variables' to generate values on the fly. This is quite unlike any CSV capability you have probably seen, definitely unlike anything I have personally seen. :) There is both base DN and attribute level expansion that can occur. The variables available for use are composed both of attributes available in the CSV input and some additional special values offered up by AdMod. This is EXTREMELY POWERFUL and EXTREMELY COOL capability in my mind and really opens up some interesting possibilities for folks who may normally have to script certain types of updates. Expansion Strings ----------------- AdMod has a relatively flexible expansion string format. It isn't perfect however it is far more powerful than most everything else that is available. Once it is out in the wild for a while a review will be made on how folks are using it and determinations on how to expand its capability/flexibility. An expansion string is simply a string that has 'operations' embedded in it that require expansion. These operations are designated by a start/end markers and can be intermixed in the string with other operations or plain text. The start of operation marker is '{{' and the end of operation marker is '}}'. Within the markers you can specify values. These values can be various opcodes or field names from the CSV input. Any CSV fields specified *must* be in the CSV data stream or AdMod will immediately terminate. On top of the values, you have the option to specify modifiers to 'tweak' the values with modifiers. Modifiers are specified by a colon (:) character or in a couple of special specifically documented cases a double colon (::) following the value. All values can have either the _lc (lowercase)or _uc (uppercase) modifier applied. Some opcode values have additional modifiers that can be specified. So an operation will look something like {{value[:modifier]}} The brackets around the modifier indicate that it is optional. OpCodes are differentiated from attributes by having a leading and trailing asterisk in the name. So while you may have an attribute named parent, to use the parent OpCode you would use *parent*. That way you could use both the parent attribute and the parent OpCode in a single Expansion string without confusion. Available OpCodes ................. o *cnt* - This is an enumerator. The value is incremented for every DN processed. The counter starts at 0 by default, but this can be modified with the -counterstart switch. Usage: {{*cnt*}} o *rnd* - This is a random character generator. The value is randomly generated individually every time it is encountered. There are three optional modifiers available for this opcode: minimum length, maximum length, and character set specified as :min:max:char_set. The default values for the modifiers are: * min 15 * max 25 * char_set 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJK LMNOPQRSTUVWXYZ!@#$%*_-=+:;{}[],.?|~ Usage: {{*rnd*}} {{*rnd*:5:10}} {{*rnd*:5:10:0123456789ABCDEF}} o *dn* - DN of current object. Usage: {{*dn*}} o *rdn* - RDN of current object. Usage: {{*rdn*}} o *parent* - Parent DN of current object. Usage: {{*parent*}} o *domain* - Domain DN of current object. Usage: {{*dn*}} o *ndc* - Non-Domain portion of DN of current object. Usage: {{*ndc*}} o *name* - Name of current object. Usage: {{*name*}} o *now* - Current local time in format YYYY/MM/DD-HH:MM:SS TZ String Usage: {{*now*}} o *now_utc* - Like *now* but UTC TZ Usage: {{*now_utc*}} o *now_int8* - Like *now* but in int8 integer format. There are three optional modifiers available for this opcode: modify type, delta value integer. The modify types are: * +d Add delta days * -d Subtract delta days * +h Add delta hours * -h Subtract delta hours * +m Add delta minutes * -m Subtract delta minutes Usage: {{*now_int8*}} {{*now_int8*:+h:6}} o *enclocal_int8* - Encode time/date string into int8. There is a mandatory modifier for this opcode which specifies the date/time to encode. The format of the time to encode is YYYY/MM/DD[-HH:MM:SS]. The date aspect of the modifier is required, the time is optional. After the mandatory modifier you can add the same optional modifiers mentioned for *now_int8* above. NOTE: There is a deviation from the standard modifier notation to add this additional modifier. Instead of using a single colon (:), you need to specify a double colon (::) to avoid collision with the colons. Usage: {{*enclocal_int8*:2006/11/07-08:00:00}} {{*enclocal_int8*:2006/11/07-08:00:00::+d:10}} o *encutc_int8* - Like *enclocal_int8* but UTC TZ. Usage: {{*encutc_int8*:2006/11/07-08:00:00}} {{*encutc_int8*:2006/11/07-08:00:00::+d:10}} CSV Field Modifiers ................... o enclocal_int8 - Encode time/date string into int8. This CSV Field modifier does not have the mandatory modifier of the date/time value from the opcode of the same name as it is passed in the CSV Field. It does, however have the same optional modifiers as the opcode with the same modifier specifier deviation. I.E. The double colon (::). Usage: {{somecsvfield:enclocal_int8}} {{somecsvfield:enclocal_int8::+d:10}} o encutc_int8 - Like enclocal_int8 but UTC TZ. Usage: {{somecsvfield:encutc_int8}} {{somecsvfield:encutc_int8::+d:10}} o int8+d - Takes int8 CSV field and adds days to it. It has one required modifier, the integer value for number of days. Usage: {{somecsvfield:int8+d:5}} o int8-d - Takes int8 CSV field and subtracts days from it. It has one required modifier, the integer value for number of days. Usage: {{somecsvfield:int8-d:5}} o int8+h - Takes int8 CSV field and adds hours to it. It has one required modifier, the integer value for number of hours. Usage: {{somecsvfield:int8+h:5}} o int8-h - Takes int8 CSV field and subtracts hours from it. It has one required modifier, the integer value for number of hours. Usage: {{somecsvfield:int8-h:5}} o int8+m - Takes int8 CSV field and adds minutes to it. It has one required modifier, the integer value for number of minutes. Usage: {{somecsvfield:int8+m:5}} o int8-m - Takes int8 CSV field and subtracts minutes from it. It has one required modifier, the integer value for number of minutes. Usage: {{somecsvfield:int8-m:5}} o Various logical/mathematical operators - This is a catch-all for several math functions available. They all follow the same format: somecsvfield:operator:intvalue The intvalue field can be specified in three formats * Binary - bnnnn where nnnn is a binary string. * Hex - 0xnnnn where nnnn is a hex string. * Decimal - nnnn where nnnn is a decimal string. The list of logical/mathematical operators * CLR - Clear bits specified by intvalue. * SET - Set bits specified by intvalue. * AND - Logical AND (value&=intvalue) * OR - Logical OR (value|=intvalue) * XOR - Logical XOR (value^=intvalue) * + - Addition (value+=intvalue) * - - Subtraction (value-=intvalue) * * - Multiplication (value*=intvalue) * / - Division (value/=intvalue) Usage: {{somecsvfield:SET:0x02}} {{somecsvfield:CLR:2}} {{somecsvfield:+:500}} o r - This is the replace modifier. It has two values that you need to specify, string to find and the string to replace it with. It will replace the first occurrence of the string found. Usage: {{somecsvfield:r:somestring1:somestring2}} o r_ci - Same as r, but case-insensitive. Usage: {{somecsvfield:r_ci:somestring1:somestring2}} o rall - This is the replace all modifier. It has two values that you need to specify, string to find and the string to replace it with. It will replace every instance of the string found. Usage: {{somecsvfield:r:somestring1:somestring2}} o rall_ci - Same as rall, but case-insensitive. Usage: {{somecsvfield:rall_ci:somestring1:somestring2}} Examples: Ex1: Creating 1000 enabled users w/ random passwords via template. (all one line) admod -add -autobase 1000:cn=myuser,cn=users,dc=test,dc=loc -bmod {{*RDN*}}_{{*cnt*}},{{*parent*}} objectclass::user -kerbenc unicodepwd::{{*rnd*:6:8}} samaccountname::{{*RDN*}}_{{*cnt*}} useraccountcontrol::512 -exterr Ex2: Copy OU structure from AD to ADAM (all one line) adfind -default -f objectcategory=organizationalunit -adcsv objectclass description | admod -h adamsrv -add -replacedn "dc=test,dc=loc:ou=mytestou" -import -unsafe -exterr Ex3: Copy the first 25 users from AD into ADAM as userProxies (all one line) adfind -default -f samaccounttype=805306368 -maxe 25 objectsid displayname -adcsv | admod -h adamsrv -add -bmod {{*RDN*}},ou=userproxies,ou=import,ou=mytestou objectclass::userproxy displayname::{{displayname}} objectsid::{{objectsid}} -unsafe -exterr Ex4: Rename user accounts to lastname,firstname (all one line) adfind -default -f samaccounttype=805306368 sn givenname -adcsv | admod -rename {{sn}}\,{{givenname}} Ex5: Export group from AD and then reimport group into AD in two passes. Export Group adfind -b CN=g1,OU=tmptestou,DC=test,DC=loc displayname objectclass grouptype member -csv >group.csv Import Group w/o members admod -csv -add -import -importexclattr member -exterr < group.csv Import Group members admod -csv -expand member:++:{{member}} -exterr < group.csv This software is Freeware. Use it as you wish at your own risk. I do not warrant this software to be fit for any purpose or use and I do not guarantee that it will not damage or destroy your system. See full Warranty documentation on www.joeware.net. If you have improvement ideas, bugs, or just wish to say Hi, I receive email 24x7 and read it in a semi-regular timeframe. You can usually find me at joe@joeware.net