#50968 - 2000-08-10 07:58 PM
Re: ADSI
|
Shawn
Administrator
   
Registered: 1999-08-13
Posts: 8611
|
Bryce:ADSI is the "pot of gold" at the end the KiX/OLE rainbow ! I've been using scripted ADSI to administer our (pure) NT staging domain for a couple of months now. All that is really required are a few Win2K boxes (or WinNT boxes with the ADSI components installed). Nothing has to be installed or changed on any of the "administered" workstations or servers ! From these (few or many) administration points, one can build KiX scripts to manage just about everything in your NT domain, for example, one can add, change, or assign: 1) USERS 2) GROUPS 3) USERS TO GROUPS 4) SHARES 5) SERVICES 6) PRINTERS 7) MACHINES 8) DOMAINS 9) MACHINES TO DOMAINS The list is endless - and it's all scripted (in the purest sense of the word ). The only caveats here are as follows: 1) Yup - it KiX OLE again. But I think the learning curve here isn't that great and the payoff is tremendous and well worth the investment. 2) It's Active Directory, which at it's heart is very simple, but encompasses so much. Anyway - I'm not in the office today. If anyone's interested, I can post of few of the scripts we use to add users and create shares. My current project is to build a domain user reporting tool (using KiX/ADSI )that will report on SAM records meeting certain criteria (ie. disabled/lockedout accounts). Shawn. [This message has been edited by Shawn (edited 10 August 2000).]
|
|
Top
|
|
|
|
#50970 - 2000-08-11 03:39 PM
Re: ADSI
|
Shawn
Administrator
   
Registered: 1999-08-13
Posts: 8611
|
Bryce:As discussed, here's a KiX/ADSI script to create a file share on a local or remote workstation or server: code:
break on ; This script demonstrates how to use Active Directory Services Interface (ADSI) ; to add shares on local and remote computers.
; use "net share" command to validate results
; Change these properties to suite your environment ...
$server_name = "dn1cov" ; *** change to your hostname *** $share_path = "c:\winnt" ; *** change to valid path *** $share_name = "@userid" $share_maxusercount = 10 $share_description = "This is @userid's share"
$lms = olegetobject ( 0, "WinNT://$server_name/lanmanserver" )
if $lms = 0 ?"Active Data Services Interface (ADSI) not installed on this machine" goto finish endif
$share = val ( "&" + olecallfunc ( $lms, "create", "ss", "fileshare", "$share_name" ) )
$rs = oleputproperty ( $share, "path", "s", "$share_path" ) $rs = oleputproperty ( $share, "maxusercount", "s", "$share_maxusercount" ) $rs = oleputproperty ( $share, "description", "s", "$share_description" )
$rs = olecallproc ( $share, "setinfo" ) if @error ?"Error @error : @serror" goto finish endif
:finish
if $share $rs = olereleaseobject ( $share ) endif
if $lms $rs = olereleaseobject ( $lms ) endif
?
exit
Here's a KiX/ADSI script to add a user to a local or remote workstation or server.
code:
break on; This script demonstrates how to use Active Directory Services Interface (ADSI) ; to add users on local and remote computers. ; Use the "net user" command to validate results
; Change these properties to suite your environment
$server_name = "dn1cov" ; *** Change to your hostname *** $user_name = "kix.rules" $user_password = "kixrules123"
$server = olegetobject ( 0, "WinNT://$server_name" )
if @error ?"Active Directory Interface Services not supported on this machine" goto finish endif
$user = val ( "&" + olecallfunc ( $server, "create", "ss", "user", "$user_name" ))
$rs = olecallfunc ( $user, "setinfo" )
if @error = 0
$rs = olecallfunc ( $user, "setpassword", "s", "$user_password" )
if @error = 0
?"User $user_name successfully added to $server_name"
endif
endif
if @error
?"Error @error : @serror"
endif
:finish
if $user $rs = olereleaseobject ( $user ) endif
if $server $rs = olereleaseobject ( $server ) endif
?
exit
I've had the most success using Win2K as my Administration point - managing WinNT Servers and Workstations. You can also get the WinNT (98?) version of ADSI right off the Microsoft Download site.
Obviously, these examples are just the "tip" of the ADSI "iceberg". They just bearly scratch the surface of Active Directory - but to be honest - once you start using them - you'll get one hell of an itch !!!
Shawn.
|
|
Top
|
|
|
|
#50972 - 2000-08-11 04:02 PM
Re: ADSI
|
Shawn
Administrator
   
Registered: 1999-08-13
Posts: 8611
|
Here's a script that will enumerate all file shares on local or remote servers or workstations.code:
break on ; This script demonstrates how to use Actice Directory Services Interface (ADSI) ; to enumerate all file shares on local and remote computers
; To redirect output to a file, specify $pipe=filename on commandline
$server_name = "dn1cov" ; change to your hostname
if $pipe del "$pipe" $rs = redirectoutput ( "$pipe" ) endif
?"Enumerating shares on $server_name ..."
$lms = olegetobject ( 0, "WinNT://$server_name/lanmanserver" ) if $lms = 0 "Active Data Services Interface (ADSI) not installed on this machine" exit endif
$enum = oleenumobject( $lms )
while @error = 0
$share = oleenumobject( $lms, $enum )
if @error = 0
? ?"Name : " olegetproperty( $share , "name" ) ?"Description: " olegetproperty( $share , "description" ) ?"Path : " olegetproperty( $share , "path" ) ?"Connections: " olegetproperty ( $share, "currentusercount" )
endif
loop
if $enum $rs = olereleaseobject ( $enum ) endif
if $share $rs = olereleaseobject ( $share ) endif
if $lms $rs = olereleaseobject ( $lms ) endif
?
exit
Shawn.
|
|
Top
|
|
|
|
#50975 - 2000-08-11 09:59 PM
Re: ADSI
|
Shawn
Administrator
   
Registered: 1999-08-13
Posts: 8611
|
Things are slow today !I "ripped" this from a WSH script I found on the Internet somewhere (sorry). I like the look & feel of this puppy !
code:
break on $title = "KiXtart/ADSI" $crlf = chr(10) + chr(13)
$message = "GroupInfo.Kix: " + $crlf + $crlf + "Example of getting domain groups using KiX/ADSI" + $crlf + "This may take a moment depending on the size " + $crlf + "and speed of your network."
$rs = messagebox ( "$message", "$title", 0 )
$message = "User:" + $crlf + "@ldomain\@userid" + $crlf + $crlf + "Groups:"
$user = olegetobject ( 0, "WinNT://@ldomain/@userid" ) $groups = val ( "&" + olecallfunc ( $user, "groups" ) )
$enum = oleenumobject ( $groups )
while @error = 0
$group = oleenumobject ( $groups, $enum )
if @error = 0 $message = $message + $crlf + olegetproperty ( $group, "name" )
endif
loop
$rs = messagebox ( "$message", "$title", 0 )
exit
Shawn.
|
|
Top
|
|
|
|
#50976 - 2000-08-11 10:39 PM
Re: ADSI
|
Shawn
Administrator
   
Registered: 1999-08-13
Posts: 8611
|
Here's kinda where I'm at now:The following will list all disabled domain accounts in one's domain. Lot's more work to do here though ! Notice how one can trap objects of the "user" type - other objects are groups and services, etc ! The intent with this one was to great the foundation for a domain user auditing tool. Lot's of other possibilities here me thinks !
code:
break on if $pipe del "$pipe" $rs = redirectoutput ( "$pipe" ) endif
$domain_name = "development"
$domain = olegetobject ( 0, "WinNT://$domain_name" ) if @error ?"Error connecting to WinNT provider for domain $domain_name" ?"Error @error : @serror" goto finish endif
$objects = oleenumobject ( $domain ) if @error ?"Error getting enumeration handle from domain $domain_name" ?"Error @error : @serror" goto finish endif
? ?"Listing of disabled accounts in the $domain_name domain..."
while @error = 0
$object = oleenumobject ( $domain, $objects )
if @error = 0
if olegetproperty ( $object, "class" ) = "user"
if olegetproperty ( $object, "accountdisabled" ) = "-1"
? ? "Username " olegetproperty ( $object, "name" ) ? "Fullname " olegetproperty ( $object, "fullname" ) ? "Comment " olegetproperty ( $object, "description" )
endif
endif
$rs = olereleaseobject ( $object )
endif
loop
:finish
if $object $rs = olereleaseobject ( $object ) endif
if $objects $rs = olereleaseobject ( $objects ) endif
if $domain $rs = olereleaseobject ( $domain ) endif
?
exit
Shawn.
[This message has been edited by Shawn (edited 15 August 2000).]
|
|
Top
|
|
|
|
#50978 - 2000-08-14 04:47 PM
Re: ADSI
|
Shawn
Administrator
   
Registered: 1999-08-13
Posts: 8611
|
Here's the skeleton for a generic domain / server object browser:By testing the class property of domain objects, one can drill-down to just groups, users, computers or services. For example: kix32 enum.kix $domain=mydomain $class=user kix32 enum.kix $domain=mydomain $class=group kix32 enum.kix $domain=mydomain $class=computer kix32 enum.kix $domain=myhost $class=service kix32 enum.kix $domain=myhost $class=group Obviously this won't work: kix32 enum.kix $domain=mydomain $class=service Because services are machine objects, not domain objects code:
break on ; How to use ADSI to enumerate all objects in your domain
; usage: kix32 enum.kix $domain=domain $class=object [$pipe=filename]
; where $domain = your domain or hostname
; where $class = user, group or service
if $domain else $domain = "@ldomain" endif
if $class else $class = "group" endif
$container = olegetobject ( 0, "WinNT://$domain" ) if $container = 0 "Active Data Services Interface (ADSI) not installed on this machine" exit endif
if $pipe del "$pipe" $rs = redirectoutput ( "$pipe" ) endif
?"Enumerating all $class's in $domain ..." ?
$objects = oleenumobject( $container )
$object = oleenumobject ( $container, $objects )
while $object <> 0
if $object and olegetproperty ( $object, "class" ) = "$class"
? ?"Name :" olegetproperty ( $object, "name" ) ?"Remark:" olegetproperty ( $object, "description" )
endif
$rs = olereleaseobject ( $object )
$object = oleenumobject( $container, $objects )
loop
if $objects $rs = olereleaseobject ( $objects ) endif
if $container $rs = olereleaseobject ( $container ) endif
?
exit
Shawn. [This message has been edited by Shawn (edited 14 August 2000).]
|
|
Top
|
|
|
|
#50980 - 2000-08-14 07:31 PM
Re: ADSI
|
Shawn
Administrator
   
Registered: 1999-08-13
Posts: 8611
|
Bryce:Unfortunately, the only answer I can give is our old standby: It all depends ( on the object, that is ) Different objects have different properties, methods and subobjects. For example, WinNT: contains domain objects. WinNT://mydomain contains domain properties, users, groups, computers and a schema object. WinNT/mydomain/myuser contains user properties and groups. Again, in terms of domain enumeration: code:
break on $domainName = "development"
$domain = olegetobject ( 0, "WinNT://$domainName" ) if $domain = 0 "Active Data Services Interface (ADSI) not installed on this machine" exit endif
? ?"Domain Properties:" ? ?"DomainName " olegetproperty ( $domain, "Name" ) ?"IsWorkgroup " olegetproperty ( $domain, "IsWorkgroup" ) ?"MinPasswordLength " olegetproperty ( $domain, "MinPasswordLength" ) ?"MinPasswordAge " olegetproperty ( $domain, "MinPasswordAge" ) ?"MaxPasswordAge " olegetproperty ( $domain, "MaxPasswordAge" ) ?"MaxBadPasswordsAllowed " olegetproperty ( $domain, "MaxBadPasswordsAllowed" ) ?"PasswordHistoryLength " olegetproperty ( $domain, "PasswordHistoryLength" ) ?"PasswordAttributes " olegetproperty ( $domain, "PasswordAttributes" ) ?"AutoUnlockInterval " olegetproperty ( $domain, "AutoUnlockInterval" ) ?"LockoutObservationInterval " olegetproperty ( $domain, "LockoutObservationInterval" ) ?
$objects = oleenumobject ( $domain ) $object = oleenumobject ( $domain, $objects ) $count = 0 $userCount = 0 $groupCount = 0 $computerCount = 0 $schemaCount = 0 $unknownCount = 0 ?"Domain Objects:" ?
while $object <> 0
$class = olegetproperty ( $object, "class" ) $count = $count + 1
select case $class = "user" $userCount = $userCount + 1 case $class = "group" $groupCount = $groupCount + 1 case $class = "computer" $computerCount = $computerCount + 1 case $class = "schema" $schemaCount = $schemaCount + 1 case 1 $unknownCount = $unknownCount + 1 endselect
$rs = olereleaseobject ( $object ) $object = oleenumobject ( $domain, $objects )
loop
?"Users $userCount" ?"Groups $groupCount" ?"Computers $computerCount" ?"Schemas $schemaCount" ?"Unknowns $unknownCount" ?"Total $count"
if $objects $rs = olereleaseobject ( $objects ) endif
if $domain $rs = olereleaseobject ( $domain ) endif
?
exit
This topic is so large that we'd probably need a seperate forum on this BBS to discuss all the permutations and applications of ADSI. As well, I think what would be usefull is some kind of object browser script that would enumerate all the properties, methods and subobjects of any given ADSI object. Then it's just a matter of understanding the KiX OLE syntax and it's off to the races. Shawn.
[This message has been edited by Shawn (edited 14 August 2000).]
|
|
Top
|
|
|
|
#50981 - 2000-08-14 08:50 PM
Re: ADSI
|
Shawn
Administrator
   
Registered: 1999-08-13
Posts: 8611
|
Gang:1) You don't need to be a programmer to use this Automation stuff. If you've written a KiX script, no matter how small, you're a programmer in every sense of the word (any debators ?) 2) These KiX OLE functions might seem daunting and to have a steep learning curve - but stick with it because I promise you - it will be like a lightbulb going on in your head ! After a while, using KiX OLE functions will be no different than using any other KiX function (readvalue(),writevalue(), etc). In fact - they're exactly the same, just called differently !!! Actually, once you get the hang of OLE, the aggravating part will be how to "discover" what properties and methods an object supports. Having said that... 3) I use the ADSI SDK as well, but I find the MSDN to be much more usefull. Set your Active Subject to Visual Basic Documentation and search on ADSI. There are lots of examples of VB code that are much easier to understand and translate into KiX. Ignore all the C++ stuff, the overhead of supporting COM in C++ obscurs the task at hand ! There's is lots of good background info on Automation in the MSDN as well. Required reading ! One has to understand OLE objects and Automation first, then understand the object model of what your Automating !  Shawn.
[This message has been edited by Shawn (edited 15 August 2000).]
|
|
Top
|
|
|
|
#50983 - 2001-10-31 06:50 AM
Re: ADSI
|
Anonymous
Anonymous
Unregistered
|
Shawn, I am very interested in ADSI and have done some preliminary research after reading this thread (thx)...My question is simply this, what method(s) would I use with a script that looks for a folder (home dir) and creates it if it doesn't exist? Any help pointing me in the right direction would be greatly appreciated. Thanks.
|
|
Top
|
|
|
|
Moderator: Glenn Barnas, NTDOC, Arend_, Jochen, Radimus, Allen, ShaneEP, Ruud van Velsen, Mart
|
0 registered
and 595 anonymous users online.
|
|
|