#92156 - 2003-06-12 04:20 PM
KiXforms - Active Directory Browser
|
Chris S.
MM club member
Registered: 2002-03-18
Posts: 2368
Loc: Earth
|
I wrote this script because, having just implemented AD, I couldn't figure out how to navigate the ADsPath for scripting purposes. You can use this to browse your Active Directory and find out what the fully-qualified ADsPath of an object is.
I hope you find it useful when you're writing ADSI scripts and can't remember the right path to the container or OU that you're trying to get to.
(P.S. It also shows off the new tabcontrols.)
Code:
Break On
; === Main Form ========================================================
$frmMain = CreateObject("Kixtart.Form")
$frmMain.ClientSize = 640,480
$frmMain.FormBorderStyle = 4
$frmMain.Icon = "shell32.dll;42"
$imgList = $frmMain.Controls.ImageList
$imgList.ColorDepth = 16
For $i = 0 To $frmMain.SmallImageList.Images.Count
$imgList.Images.Add($frmMain.SmallImageList.Images($i))
Next
If Exist("%WINDIR%\System32\dsuiext.dll")
$c=$imgList.Images.Add("dsuiext.dll;1")
$g=$imgList.Images.Add("dsuiext.dll;7")
$u=$imgList.Images.Add("dsuiext.dll;12")
$o=$imgList.Images.Add("dsuiext.dll;13")
$ux=$imgList.Images.Add("dsuiext.dll;27")
$ul=$imgList.Images.Add(".\user_locked_16.ico")
$f=$imgList.Images.Add("dsquery.dll;0")
$frmMain.Icon = $imgList.Images($f)
Else
$c=53 $g=35 $u=34 $o=50
EndIf
$imgLarge = $frmMain.Controls.ImageList
$imgLarge.ImageSize = 32,32
For $i = 0 To $imgList.Images.Count
$imgLarge.Images.Add($imgList.Images($i))
Next
$MsgBox = $frmMain.Dialogs.MessageBox
$MsgBox.Title = "Information..."
$MsgBox.Style = 68
$txtCopy = $frmMain.Controls.TextBox("",0,0,0,0)
$txtCopy.Hide
; ======================================================================
; === ToolBar ==========================================================
$grpToolBar = $frmMain.GroupBox("",0,0,$frmMain.ClientWidth,30)
$grpToolBar.Anchor = 7
$btnBack = $grpToolBar.ToolButton("Back",2,2,60,26)
$btnBack.FlatStyle = 1
$btnBack.Icon = 18
$btnBack.OnClick = "fnOnBack()"
$btnBack.ToolTipText = "Back"
$btnRefresh = $grpToolBar.ToolButton("",$btnBack.Right,2,26,26)
$btnRefresh.FlatStyle = 1
$btnRefresh.Icon = 36
$btnRefresh.OnClick = "fnRefresh()"
$btnRefresh.ToolTipText = "Refresh"
$btnCopy = $grpToolBar.ToolButton("",$btnRefresh.Right,2,26,26)
$btnCopy.FlatStyle = 1
$btnCopy.Icon = 7
$btnCopy.OnClick = "fnCopy()"
$btnCopy.ToolTipText = "Copy current container to clipboard"
$btnView = $grpToolBar.ToolButton("",$btnCopy.Right,2,26,26)
$btnView.FlatStyle = 1
$btnView.Icon = 41
$btnView.OnClick = "fnView()"
$btnView.ToolTipText = "Cycle view options"
$btnCancel = $grpToolBar.ToolButton("Cancel",$grpToolBar.ClientWidth-62,2,60,26)
$btnCancel.Anchor = 4
$btnCancel.FlatStyle = 1
$btnCancel.Icon = 37
$btnCancel.OnClick = "$$btnCancel.Tag = 1"
$btnCancel.ToolTipText = "Cancel Enumeration"
; ======================================================================
; === Container Tabs ===================================================
$tabMain = $frmMain.Controls.TabControl("",0,$grpToolBar.Bottom+1,$frmMain.ClientWidth,
$frmMain.ClientHeight-30)
$tabMain.Anchor = 15
$tabMain.OnSelectedIndexChanged = "fnOnTabChange()"
$frmMain.Text = "LDAP://"+GetObject("LDAP://rootDSE").Get("defaultNamingContext")
$objDomain = GetObject($frmMain.Text)
For Each $objContainer in $objDomain
$TabPage = $tabMain.TabPages.Add(Split($objContainer.Name,"=")[1])
$ListView = $TabPage.Controls.ListView("",0,0,$TabPage.ClientWidth,$TabPage.ClientHeight-25)
$ListView.Anchor = 15
$ListView.LargeImageList = $imgLarge
$ListView.SmallImageList = $imgList
$ListView.Name = "ListView"
$ListView.OnDoubleClick = "fnOnDoubleClick()"
$ListView.Tag = $objContainer.ADsPath
$nul = $ListView.Columns.Add("Name",0.35*$ListView.ClientWidth)
$nul = $ListView.Columns.Add("AD_Name",0)
$nul = $ListView.Columns.Add("Class",0.25*$ListView.ClientWidth)
$nul = $ListView.Columns.Add("Description",0.40*$ListView.ClientWidth)
; === Status Bar ===================================================
$grpStatusBar = $TabPage.Controls.GroupBox("",1,$ListView.Bottom+3,$TabPage.ClientWidth-1,20)
$grpStatusBar.Anchor = 13
$grpStatusBar.BorderStyle = 0
$lblStatus = $grpStatusBar.Controls.Label("",0,0,0.45*$grpStatusBar.ClientWidth,20)
$lblStatus.Anchor = 1
$lblStatus.BorderStyle = 5
$lblStatus.Name = "lblStatus"
$prgProgress = $grpStatusBar.Controls.ProgressBar("",$lblStatus.Right+1,0,0.55*$grpStatusBar.ClientWidth-1,20)
$prgProgress.BorderStyle = 5
$prgProgress.Step = 1
$prgProgress.Anchor = 5
$prgProgress.Name = "prgProgress"
; ======================================================================
Next
; ======================================================================
$frmMain.Center
$frmMain.Show
While $frmMain.Visible
$=Execute($frmMain.DoEvents())
Loop
Exit(1)
Function fnOnTabChange(Optional $Folder)
Dim $objContainer
If $tabMain.SelectedIndex <> -1
If InStr($lblStatus.Text,"Enumerating") $lblStatus.Text = "" $prgProgress.Value = 0 EndIf
$ListView = $tabMain.TabPages($tabMain.SelectedIndex).Controls("ListView")
$lblStatus = $tabMain.TabPages($tabMain.SelectedIndex).Controls("lblStatus")
$prgProgress = $tabMain.TabPages($tabMain.SelectedIndex).Controls("prgProgress")
If $ListView.Items.Count = 0
$frmMain.Cursor = 11 $lblStatus.Text = "" $prgProgress.Maximum = 0
$objContainer = GetObject($ListView.Tag)
For Each $object in $objContainer $prgProgress.Maximum = $prgProgress.Maximum+1 Next
$lblStatus.Text = "Enumerating "+$prgProgress.Maximum+" objects..."
$btnCancel.Enabled = 1
For Each $object in $objContainer
If $ListView.Tag <> $objContainer.ADsPath or $btnCancel.Tag = 1 GOTO SkipEnum EndIf
Select
Case $object.Class = "organizationalUnit" $Icon = $o
Case $object.Class = "user" And $object.AccountDisabled $Icon = $ux
Case $object.Class = "user" And $object.IsAccountLocked $Icon = $ul
Case $object.Class = "user" $Icon = $u
Case $object.Class = "group" $Icon = $g
Case $object.Class = "computer" $Icon = $c
Case 1 $Icon = 45
EndSelect
$Item = $ListView.Items.Add(Split($object.Name,"=")[1],$Icon)
$Item.SubItems(1).Text = $object.Name
$Item.SubItems(2).Text = $object.Class
$Item.SubItems(3).Text = $object.PasswordLastChanged ;$object.Description
$prgProgress.PerformStep
$=Execute($frmMain.DoEvents(1))
Next
:SkipEnum
$btnCancel.Tag = 0 $btnCancel.Enabled = 0 $frmMain.Cursor = 0 $prgProgress.Value = 0
EndIf
Select
Case $ListView.View = 0 $btnView.Icon = 38
Case $ListView.View = 1 $btnView.Icon = 39
Case $ListView.View = 2 $btnView.Icon = 40
Case $ListView.View = 3 $btnView.Icon = 41
EndSelect
If $tabMain.TabPages($tabMain.SelectedIndex).Tag = ""
$tabMain.TabPages($tabMain.SelectedIndex).Tag = $ListView.Tag
$frmMain.Text = $ListView.Tag
EndIf
$lblStatus.Text = Split(Split($ListView.Tag,"=")[1],",")[0]+": "+$ListView.Items.Count+" object(s) listed"
$frmMain.Text = $ListView.Tag
$btnBack.Tag = $ListView.Tag
If $btnBack.Tag = $tabMain.TabPages($tabMain.SelectedIndex).Tag
$btnBack.Enabled = 0
Else
$btnBack.Enabled = 1
EndIf
EndIf
EndFunction
Function fnOnDoubleClick()
Dim $sItemADsPath
$sItemADsPath = "LDAP://"+$ListView.FocusedItem.SubItems(1).Text+","+Split($ListView.Tag,"//")[1]
$txtCopy.Text = $sItemADsPath
If $ListView.FocusedItem.SubItems(2).Text = "organizationalUnit" or
$ListView.FocusedItem.SubItems(2).Text = "container"
$ListView.Tag = $sItemADsPath
$ListView.Items.Clear
fnOnTabChange()
Else
If $MsgBox.Show($sItemADsPath+@CRLF+@CRLF+"Copy to clipboard?") = 6
$txtCopy.SelectionLength = Len($txtCopy.Text)
$txtCopy.Copy
EndIf
EndIf
EndFunction
Function fnOnBack()
Dim $aItemADsPath,$sItemADsPath
$aItemADsPath = Split(Split($ListView.Tag,"//")[1],",")
For $i = 1 to Ubound($aItemADsPath)
$sItemADsPath = $sItemADsPath + $aItemADsPath[$i] + ","
Next
$sItemADsPath = "LDAP://" + Left($sItemADsPath,LEN($sItemADsPath)-1)
$ListView.Tag = $sItemADsPath
$ListView.Items.Clear
fnOnTabChange()
EndFunction
Function fnRefresh()
$ListView.Items.Clear
fnOnTabChange()
EndFunction
Function fnCopy()
$txtCopy.Text = $ListView.Tag
$txtCopy.SelectionLength = Len($txtCopy.Text)
$txtCopy.Copy
EndFunction
Function fnView()
$ListView.View = $ListView.View + 1
Select
Case $ListView.View = 0 $btnView.Icon = 38
Case $ListView.View = 1 $btnView.Icon = 39
Case $ListView.View = 2 $btnView.Icon = 40
Case $ListView.View = 3 $btnView.Icon = 41
EndSelect
EndFunction
Edited by Chris S. (2004-01-07 02:29 PM)
|
Top
|
|
|
|
#92157 - 2003-06-12 08:45 PM
Re: KiXforms - Active Directory Browser
|
NTDOC
Administrator
Registered: 2000-07-28
Posts: 11623
Loc: CA
|
Really nice KiXform there Chris.
I like it. Works well on my AD. No configuration changes or anything. Just copy the code to file and run it as is.
|
Top
|
|
|
|
#92159 - 2003-06-12 08:56 PM
Re: KiXforms - Active Directory Browser
|
Radimus
Moderator
Registered: 2000-01-06
Posts: 5187
Loc: Tampa, FL
|
I like it also
problem... I have lots of tabs and have to widen the form beyond the width of my screen to see them all...
other than that, grteat job.
|
Top
|
|
|
|
#92160 - 2003-06-12 09:00 PM
Re: KiXforms - Active Directory Browser
|
Chris S.
MM club member
Registered: 2002-03-18
Posts: 2368
Loc: Earth
|
Rad, you should have some arrow buttons that you can use to navigate to the other tabs. They look something like this: [<][>]
If you don't have the arrow buttons, you may want to update to the latest version of KiXforms.
I'd prefer that the tabs "layer" when they extend beyond the edge of the object, but we take what we can get.
Ron, can I talk you into hosting a screenshot for me? Maybe a XP version of the form?
|
Top
|
|
|
|
#92161 - 2003-06-12 11:18 PM
Re: KiXforms - Active Directory Browser
|
kholm
Korg Regular
Registered: 2000-06-19
Posts: 714
Loc: Randers, Denmark
|
Thank You for sharing this Chris
This is worth studying for the use of KixForms (and the use of LDAP:)
I like your skip routine: quote:
If $btnCancel.Tag = 1 GOTO SkipEnum EndIf
This can come in handy in many of my admin scripts for pausing or stopping the script.
-Erik [ 12. June 2003, 23:32: Message edited by: kholm ]
|
Top
|
|
|
|
#92162 - 2003-06-12 11:34 PM
Re: KiXforms - Active Directory Browser
|
Chris S.
MM club member
Registered: 2002-03-18
Posts: 2368
Loc: Earth
|
Yeah, tag is a new property that Shawn put in that the coder can use as a placeholder for data. I'm using it to hold information about the current CN/OU being browsed, to set the limit for the Back button, and (as you noted) to cancel the enumeration.
One can even set tag properties as an array to hold multiple sets of data.
The tags in this script allow the Back button to work independently for each tab. Switching tabs doesn't break the back button. You'll aways go back one level (up to the "root" container). [ 12. June 2003, 23:34: Message edited by: Chris S. ]
|
Top
|
|
|
|
#92164 - 2003-06-16 06:36 PM
Re: KiXforms - Active Directory Browser
|
enzosimoni
Fresh Scripter
Registered: 2003-04-15
Posts: 31
Loc: VA,USA
|
When I try to run your script I get the following error.
error on line 5
When I set it to debug it errors out on
$frmMain.ClientSize = 1024,768
When I comment this out it errors out on line 32
$grpToolBar = $frmMain.GroupBox("",0,0,$frmMain.ClientWidth,30)
I downloaded the latest forms v 2.30b2
Anything else I need to do? I exploded the zip form onto my kixtart directory where I have all my other dlls
Thanks.
|
Top
|
|
|
|
#92166 - 2003-06-16 06:46 PM
Re: KiXforms - Active Directory Browser
|
enzosimoni
Fresh Scripter
Registered: 2003-04-15
Posts: 31
Loc: VA,USA
|
Awesome!!!
|
Top
|
|
|
|
#92167 - 2003-06-17 04:41 PM
Re: KiXforms - Active Directory Browser
|
Kdyer
KiX Supporter
Registered: 2001-01-03
Posts: 6241
Loc: Tigard, OR
|
Chris,
Very cool indeed!
A couple of ideas.. (1) Where you click the tab for say Computers or Users, add in a count of objects found. That way, when you open Computers, for example, you see 2100 objects found.
(2) Where you give the "Information.." dialog, it would be cool to be able to copy the LDAP://CN=.. to the clipboard for usage later.
(3) This is a good application for top-level objects. Maybe have a "tree" structure where you can traverse the objects downward.
Again, I can see some really good uses for this.
Kent [ 17. June 2003, 16:43: Message edited by: kdyer ]
|
Top
|
|
|
|
#92169 - 2003-06-17 06:52 PM
Re: KiXforms - Active Directory Browser
|
Kdyer
KiX Supporter
Registered: 2001-01-03
Posts: 6241
Loc: Tigard, OR
|
I see what you mean.. You can traverse (my bad). Eagerly awaiting TreeView.. I can see this being better than AD Users and computers.
Kent
|
Top
|
|
|
|
#92170 - 2003-06-17 09:15 PM
Re: KiXforms - Active Directory Browser
|
Chris S.
MM club member
Registered: 2002-03-18
Posts: 2368
Loc: Earth
|
Ok. Added a Status label that will display the number of objects in the container you are browsing. This is the total objects in the container. Clicking the "cancel" button will not affect the object count in the label.
Added two methods to copy information to the clipboard.
- Copy ToolButton - This button will copy the LDAP ADsPath into the clipboard for the current container you are browsing.
- Double-click Object - By double-clicking an object (i.e. a User account) you will be prompted with a message box asking you if you want to copy the ADsPath onto the clipboard.
|
Top
|
|
|
|
#92171 - 2003-06-17 10:04 PM
Re: KiXforms - Active Directory Browser
|
Kdyer
KiX Supporter
Registered: 2001-01-03
Posts: 6241
Loc: Tigard, OR
|
Sweet..
Looks great.
Another thing would be kinda cool would be to search for an object.
Kent
|
Top
|
|
|
|
#92172 - 2003-06-17 10:21 PM
Re: KiXforms - Active Directory Browser
|
Chris S.
MM club member
Registered: 2002-03-18
Posts: 2368
Loc: Earth
|
I knew you'd go there.
Seach entire AD or just the current container? Search on Name or other properties? Keep in mind that this is mostly for informational purposes. I didn't plan on making a replacement for AD Users & Computers.
I suppose next you'll want a filter.
How about, for now, a button to change the view? I've updated the script with a View button.
Enjoy.
|
Top
|
|
|
|
#92173 - 2003-06-17 11:25 PM
Re: KiXforms - Active Directory Browser
|
NTDOC
Administrator
Registered: 2000-07-28
Posts: 11623
Loc: CA
|
Chris, Chris... you da man
I'm really liking the developments on this tool.
I would like to add another suggestion.
Maybe have an option that allows you to build the full path as a little more useful copy.
Currently copies as: LDAP://CN=name,OU=Users,OU=test,OU=temp,DC=westcoast,DC=mycompany,DC=com
What about copying as: GetObject('LDAP://CN=name,OU=Users,OU=test,OU=temp,DC=westcoast,DC=mycompany,DC=com')
That would allow a direct paste into an editor for immediate usage.
|
Top
|
|
|
|
#92175 - 2003-06-18 03:39 PM
Re: KiXforms - Active Directory Browser
|
Chris S.
MM club member
Registered: 2002-03-18
Posts: 2368
Loc: Earth
|
Ok, Doc. I fixed the Enum/Switch tabs bug.
I also updated the label and the progress bar to attach to the TabPage instead of the form. This allows the status label to always be correct for the currently selected tab.
quote:
What about copying as: GetObject('LDAP://CN=name,OU=Users,OU=test,OU=temp,DC=westcoast,DC=mycompany,DC=com')
That would allow a direct paste into an editor for immediate usage.
Others may want to use the string as a variable or in a function and may not want the GetObject() stuff. So, I'm going to leave it as is.
|
Top
|
|
|
|
Moderator: Shawn, ShaneEP, Ruud van Velsen, Arend_, Jochen, Radimus, Glenn Barnas, Allen, Mart
|
1 registered
(Allen)
and 466 anonymous users online.
|
|
|