KiXforms Forum Index KiXforms
The Forum for the KiXforms Community
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 
 Quick Links 
Site News
Downloads
Documentation
Donations
Script Archive
Tracking Systems

Manage Local Admins via Active Directory

 
Post new topic   Reply to topic    KiXforms Forum Index -> Script Archive
View previous topic :: View next topic  
Author Message
maciep
KiXforms Regular
KiXforms Regular


Joined: 01 May 2003
Posts: 43
Location: Pittsburgh,PA

PostPosted: Fri Jan 21, 2005 3:37 pm    Post subject: Manage Local Admins via Active Directory Reply with quote

During our build process here, we add our group to the local admins on the machine. After the machine is imaged, we drop a utility on the administrators desktop to allow the builder to add their appropriate support groups to the local admins.

But if for some reason they don't or they are removed or they have another group they need to add after the machine is deployed or they would like to remove admins that have been added against their knowledge, the various support groups need a utility to manage local admins on their pc's.

For the most they are broken up nicely in Active Directory, so i wrote this KiXform to allow them to accomplish the task by selecting their OU, users to be added and users to removed.

The search for users is done against Active Directory based on the defaultNamingContext. And when they are added/removed from machines the script assumes @domain is the users' domain. That works well for us here.

Also, the form can be used to just to a dump a list of machines and the AD locations by selecting simple logging and not selecting any users to add or remove from admin on the machine. If that's the case, i forgo the ping and just search AD and log the machine name and adspath (reformatted).

I hope somebody finds this useful. If you have any questions or suggestions, feel free to let me know. I may or may not update the form depending on how i lazy i'm feeling.
Back to top
View user's profile Send private message
maciep
KiXforms Regular
KiXforms Regular


Joined: 01 May 2003
Posts: 43
Location: Pittsburgh,PA

PostPosted: Fri Jan 21, 2005 3:38 pm    Post subject: Reply with quote

Made some minor changes

Here's the code:

Code:

break on

;**********************************************
; Initialize ADO connections for AD
;**********************************************
$objConnection = CreateObject("ADODB.Connection")
$objConnection.Open("Provider=ADsDSOObject;")
$objCommand = CreateObject("ADODB.Command")
$objCommand.ActiveConnection = $objConnection

$objCommand.Properties("Page Size").Value = 100
$objCommand.Properties("Cache Results").Value = (not 1)

$excelPath = readvalue("HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\excel.exe", "Path") + "excel.exe"
$bCanceling = (not 1)
;**********************************************
; Declare log files
;**********************************************
$detailedLog = @scriptdir + "\results.log"
$simpleLog = @scriptdir + "\results.csv"

;**********************************************
; Create System object
;**********************************************
$Sys = createobject("Kixtart.System")

;**********************************************
; Account Search Form
;**********************************************
$Form2 = $Sys.Form
$Form2.Size = 400,400
$Form2.FormBorderStyle = $Sys.FormBorderStyle.Fixed3D
$Form2.MaximizeBox = (not 1)
$Form2.Visible = (not 1)
$Form2.Text = "Select Users"

$lblUsers = $Form2.Controls.Label()
$lblUsers.Location = 15,30
$lblUsers.Size = 300,20
$lblUsers.Text = "Search for users. Use a semicolon (;) to seperate multiple users"

$txtUsers = $Form2.Controls.Textbox()
$txtUsers.Location = 15,50
$txtUsers.Size = 300,20

$btnUsers = $Form2.Controls.Button()
$btnUsers.Location = 325,50
$btnUsers.Size = 50,20
$btnUsers.Text = "Find"
$btnUsers.Default = 1
$btnUsers.OnClick = "FindUsers() $txtUsers.SetFocus()"

$lvUsers = $Form2.Controls.ListView()
$lvUsers.Location = 15,90
$lvUsers.Size = 360,150
$lvUsers.GridLines = (not 0)
$lvUsers.FullRowSelect = (not 0)
$lvUsers.MultiSelect = (not 0)
$ = $lvUsers.Columns.Add("Name",100)
$ = $lvUsers.Columns.Add("AdsPath",250)

$cbSelectOnly = $Form2.Controls.Checkbox()
$cbSelectOnly.Location = 15, 250
$cbSelectOnly.Width = 200
$cbSelectOnly.Text = "Add Selected Items Only"
$cbSelectOnly.OnClick = "$$lvUsers.SetFocus()"

$btnOK = $Form2.Controls.Button()
$btnOK.Location = 125,310
$btnOK.Size = 50,25
$btnOK.Text = "OK"
$btnOK.OnClick = "$$Form2.Tag=$$lvUsers.Items.Count $$Form2.Hide"

$btnCancel = $Form2.Controls.Button()
$btnCancel.Location = 215,310
$btnCancel.Size = 50,25
$btnCancel.Text = "Cancel"
$btnCancel.OnClick = "$$Form2.Tag=0 $$Form2.Hide"


;**********************************************
; The main form. 
;**********************************************
; Create the form
$Form = $Sys.Form
$Form.Size = 600,600
$Form.FormBorderStyle = $Sys.FormBorderStyle.Fixed3D
$Form.MaximizeBox = (not 1)
$Form.Visible = (not 0)
$Form.Text = "Local Administrator Maintenance"

;----------------------------------------------
; AD GroubBox
;----------------------------------------------
$grpAD = $Form.Controls.GroupBox()
$grpAD.Location = 15,15
$grpAD.Size = 350,395
$grpAD.Text = "Select a container"

; AD treeview
$trvAD = $grpAD.Controls.TreeView()
$trvAD.Size = 300,345
$trvAD.Location = 15,15
$trvAD.OnBeforeExpand = "OnBeforeExpand()"

;----------------------------------------------
; Search depth groupbox
;----------------------------------------------
$grpDepth = $Form.Controls.GroupBox()
$grpDepth.Location = 375,15
$grpDepth.Size = 200,80
$grpDepth.Text = "Search Depth"

; Subtree radio button
$rbSubtree = $grpDepth.Controls.RadioButton
$rbSubtree.Location = 15,15
$rbSubtree.Text = "Subtree"
$rbSubtree.Checked = not 0

; One Level radio button
$rbOneLevel = $grpDepth.Controls.RadioButton
$rbOneLevel.Location = 15,45
$rbOneLevel.Text = "One Level"

;----------------------------------------------
; Add Local Admins Group Box
;----------------------------------------------
$grpAdd = $Form.Controls.GroupBox()
$grpAdd.Location = 375,100
$grpAdd.Size = 200,150
$grpAdd.Text = "Add Local Administrators"

; Add admins list view
$lvAdd = $grpAdd.Controls.ListView()
$lvAdd.Location = 10,15
$lvAdd.Size = 180,95
$lvAdd.GridLines = (not 0)
$lvAdd.FullRowSelect = (not 0)
$ = $lvAdd.Columns.Add("Name",60)
$ = $lvAdd.Columns.Add("AdsPath",115)
$lvAdd.OnMouseEnter = "for each $$item in $$lvAdd.SelectedItems " +
                      "$$lvAdd.ToolTipText=$item.Text + @@crlf + $$item.SubItems(1).Text next"

; Add admins 'add' button
$btnAdd = $grpAdd.Controls.Button()
$btnAdd.Location = 40,120
$btnAdd.Size = 50,20
$btnAdd.Text = "Add"
$btnAdd.OnClick = "AddUsers()"

; Add admins 'remove' button
$btnRemove = $grpAdd.Controls.Button()
$btnRemove.Location = 100,120
$btnRemove.Size = 50,20
$btnRemove.Text = "Remove"
$btnRemove.OnClick = "for each $$item in $$lvAdd.SelectedItems $$item.Remove next " +
                     "$$cbDetailed.Enabled = $$lvRemove.Items.Count + $$lvAdd.Items.Count"

;----------------------------------------------
; Remove Local Admins Group Box
;----------------------------------------------
$grpRemove = $Form.Controls.GroupBox()
$grpRemove.Location = 375,260
$grpRemove.Size = 200,150
$grpRemove.Text = "Remove Local Administrators"

; Remove admins list view
$lvRemove = $grpRemove.Controls.ListView()
$lvRemove.Location = 10,15
$lvRemove.Size = 180,95
$lvRemove.GridLines = (not 0)
$lvRemove.FullRowSelect = (not 0)
$ = $lvRemove.Columns.Add("Name",60)
$ = $lvRemove.Columns.Add("AdsPath",115)

; Remove admins 'add' button
$btnAdd2 = $grpRemove.Controls.Button()
$btnAdd2.Location = 40,120
$btnAdd2.Size = 50,20
$btnAdd2.Text = "Add"
$btnAdd2.OnClick = "AddUsers2()"

; Remove admins 'remove' button
$btnRemove2 = $grpRemove.Controls.Button()
$btnRemove2.Location = 100,120
$btnRemove2.Size = 50,20
$btnRemove2.Text = "Remove"
$btnRemove2.OnClick = "for each $$item in $$lvRemove.SelectedItems $$item.Remove next " +
                      "$$cbDetailed.Enabled = $$lvRemove.Items.Count + $$lvAdd.Items.Count"

;----------------------------------------------
; Logging Group Box
;----------------------------------------------
$grpLog = $Form.Controls.GroupBox()
$grpLog.Location = 15,425
$grpLog.Width = 350
$grpLog.Text = "Logging Options"

; Simple logging check box
$cbSimple = $grpLog.Controls.Checkbox()
$cbSimple.Location = 10,20
$cbSimple.Width = 330
$cbSimple.Checked = (not 0)
$cbSimple.Text = "Simple Logging - CSV (name,AD location,status,added,removed)"

; Detailed logging check box
$cbDetailed = $grpLog.Controls.Checkbox()
$cbDetailed.Location = 10,60
$cbDetailed.Width = 330
$cbDetailed.Enabled = (not 1)
$cbDetailed.Text = "Detailed Logging - Step by step with time stamp"

;----------------------------------------------
; Progress Bar
;----------------------------------------------
; Progress Label
$labProgress = $Form.Controls.Label
$labProgress.Location = 375,425
$labProgress.Width = 200
$labProgress.Text = "Status: "

; Progress Bar
$pbProgress = $Form.Controls.ProgressBar
$pbProgress.Location = 375,460
$pbProgress.Size = 200,20
$pbProgress.Step = 1
$pbProgress.Minimum = 0

;----------------------------------------------
; Button to start search
;----------------------------------------------
$btnSearch = $Form.Controls.Button
$btnSearch.Location = 415,500
$btnSearch.Size = 50,25
$btnSearch.Text = "Search"
$btnSearch.OnClick = "Search()"

;----------------------------------------------
; Button to close form
;----------------------------------------------
$btnCancel = $Form.Controls.Button
$btnCancel.Location = 490,500
$btnCancel.Size = 50,25
$btnCancel.Text = "Cancel"
$btnCancel.OnClick = "Cancel()"

;----------------------------------------------
; Initialize AD tree
;----------------------------------------------
InitAD()

;----------------------------------------------
; Start the form
;----------------------------------------------
While $Form.Visible
 $=Execute($Form.DoEvents)
Loop
Exit 1


;************************* Functions **************************

function InitAD()
   dim $rootDSE,$strDomain,$p, $t
   $rootDSE = getobject("LDAP://RootDSE")
   $strDomain = $rootDSE.Get("defaultNamingContext")
   $p = $trvAD.Nodes.Add(join(split(join(split($strDomain,"DC="),""), ","),"."))
   $p.Tag = $strDomain
   $t = $p.Nodes.Add("")
endfunction

;-------------------------------------------------------------

function OnBeforeExpand()
   dim $path, $filter, $root
   dim $cont, $t, $b
   if $trvAD.EventNode.Nodes.Count = 1
      if $trvAD.EventNode.Nodes(0).Text = ""
         $Form.Cursor = 11
         $trvAD.EventNode.Nodes.Remove($trvAD.EventNode.Nodes(0))
         $path = $trvAD.EventNode.Tag
         $filter = "Container", "OrganizationalUnit"
         $root = getobject("LDAP://" + $path)
         $root.Filter = $filter
         for each $cont in $root
            $t = $trvAD.EventNode.Nodes.Add(split($cont.Name,"=")[1])
            $t.Tag = $cont.distinguishedName
            $b = $t.Nodes.Add("")
         next
        $Form.Cursor = 1
     endif
   endif
   $trvAD.EventNode.Expand()
endfunction


;-------------------------------------------------------------

function Search()
   dim $objRecordSet,$logEntry, $count
   dim $curComputer,$domain, $adsPath
   dim $temp, $handle, $handle2, $, $item
     
   $domain = @domain
   $count = 0
   $handle = 0
   $handle2 = 0
   if $cbDetailed.Checked and $cbDetailed.Enabled
      if exist($detailedLog)
         del $detailedLog
      endif
      $handle = freefilehandle()
      $ = open($handle, $detailedLog,5)
   endif

   if $cbSimple.Checked
      if exist($simpleLog)
         del $simpleLog
      endif
      $handle2 = freefilehandle()
      $ = open($handle2,$simpleLog,5)
      $ = writeline($handle2,"Computer,AD Location,Status,Added,Removed" + @crlf)
   endif
   
   if $Form2.Visible
      $Form2.Hide()
   endif
   ToggleAll((not 1))
   $objCommand.CommandText = "SELECT Name,adsPath FROM 'LDAP://" + $trvAD.SelectedNode.Tag +
                              "' WHERE objectCategory='computer'"
   $objCommand.Properties("SearchScope").Value = iif($rbSubtree.Checked,2,1)
   $labProgress.Text = "Status: Searching for machines"
   $objRecordSet = $objCommand.Execute()
   
   $pbProgress.Value = $pbProgress.Minimum
   $pbProgress.Maximum = $objRecordSet.RecordCount
   $labProgress.Text = "Status: " + $pbProgress.Maximum + " machines found"
   sleep 2
   
   $objRecordSet = $objCommand.Execute()
   $objRecordSet.MoveFirst()
   while not $objRecordSet.EOF
      $count = $count + 1
      $curComputer = $objRecordSet.Fields("Name").Value

      ; Create adsPath in form OU\SubOU1\SubOU2...
      $adsPath = split($objRecordSet.Fields("adsPath").Value, "DC=")[0]
      $adsPathArray = split($adsPath, ",")
      $adsPath = ""
      for $j = ubound($adsPathArray) to 1 step -1
         $adsPath = $adsPath + "\" + split($adsPathArray[$j], "=")[1]
      next
      $adsPath = substr($adsPath,2)
      $logEntry = $curComputer + "," + $adsPath
     
      Log($handle,"Processing Record: " + $count)
      Log($handle, "Machine: " + $curComputer)
     
      $labProgress.Text = "Status: Checking " + $curComputer + " (" + $count + ")"
      if $lvAdd.Items.Count or $lvRemove.Items.Count
         if cstr(WMIPing($curComputer))
            Log($handle, $curComputer + ": Ping Successful")
            $logEntry = $logEntry + ",Pings"
           
            $objAdmins = getobject("WinNT://" + $curComputer + "/Administrators, group")
            if @error = 0
               if $lvAdd.Items.Count
                  Log($handle, $curComputer + ": ADDING LOCAL ADMINS")
                  $temp = ""
                  for each $item in $lvAdd.Items
                     $user = "WinNT://" + $domain + "/" + $item.Text
                     if not $objAdmins.IsMember($user)
                        Log($handle, $curComputer + ": Adding " + $item.Text)
                        $objAdmins.Add($user)
                        if @error
                           Log($handle, $curComputer + ": Error adding " + $user + " - " + @serror)
                        else
                           $temp = $temp + ";" + $item.Text
                           Log($handle, $curComputer + ": " + $item.Text + " added successfully")
                        endif
                     else
                        Log($handle, $curComputer + ": " + $item.Text + " already an admin")
                     endif
                  next
               endif             
               $logEntry = $logEntry + "," + substr($temp,2)
               $temp = ""

               if $lvRemove.Items.Count
                  Log($handle, $curComputer + ": REMOVING LOCAL ADMINS")
                  for each $item in $lvRemove.Items
                     $user = "WinNT://" + $domain + "/" + $item.Text
                     if $objAdmins.IsMember($user)
                        Log($handle, $curComputer + ": Removing " + $item.Text)
                        $objAdmins.Remove($user)
                        if @error
                           Log($handle, $curComputer + ": Error removing " + $user + " - " + @serror)
                        else
                           $temp = $temp + ";" + $item.Text
                           Log($handle, $curComputer + ": " + $item.Text + " removed successfully")
                        endif
                     else
                        Log($handle, $curComputer + ": " + $item.Text + " is not an admin")
                     endif
                  next
               endif
               $logEntry = $logEntry + "," + substr($temp,2)
            else
               $logEntry = $logEntry + "," + @serror + "," + @serror
               Log($handle, $curComputer + ": Error getting local admins - " + @serror)
               Log($handle, $curComputer + ": Skipping record")
            endif
         else
            $logEntry = $logEntry + ",Doesn't Ping"
            Log($handle, $curComputer + ": Doesn't ping")
            Log($handle, $curComputer + ": Skipping record")
         endif
      endif
      if $handle2
         $ = writeLine($handle2, $logEntry + @crlf)
      endif
      Log($handle, "Moving to next record" + @crlf)
     
      $=Execute($Form.DoEvents(1))
      if $bCanceling
         if $handle
            $ = close($handle)
         endif
         if $handle2
            $ = close($handle2)
         endif
         $labProgress.Text = "Status: "
         $pbProgress.Value = 0
         ToggleAll((not 0))
         $bCanceling = (not 1)
         Exit
      endif
      $pbProgress.PerformStep()
      $objRecordSet.MoveNext
   Loop
   
   $labProgress.Text = "Status: "
   $pbProgress.Value = 0
   if $handle
      $ = close($handle)
   endif
   if $handle2
      $ = close($handle2)
   endif
   ToggleAll((not 0))
   if $handle2
      $message =  "" + $count + " total machines found" + @crlf + @crlf + "View Simple results log?"
      if $Sys.MessageBox.Show($message,"Results",4) = 6
         if not exist($excelPath)
            $ = $Sys.MessageBox.show("Cannot find excel.exe")
         else
            shell $excelPath + " " + $simpleLog
         endif
      endif
   endif
   
   if $handle
      $message =  "" + $count + " total machines found" + @crlf + @crlf + "View Detailed results log?"
      if $Sys.MessageBox.Show($message,"Results",4) = 6
         run "notepad.exe " + $detailedLog
      endif
   endif
endfunction

-------------------------------------------------------------

function AddUsers()
   dim $item, $
   InitUsers()
   While $Form2.Visible
      $=Execute($Form2.DoEvents)
   Loop
   if $Form2.Tag
      if $cbSelectOnly.Checked
         for each $item in $lvUsers.SelectedItems
            $lvAdd.Items.Add($item.Text).SubItems(1).Text = $item.SubItems(1).Text
         next
      else
         for each $item in $lvUsers.Items
            $lvAdd.Items.Add($item.Text).SubItems(1).Text = $item.SubItems(1).Text
         next
      endif
      $cbDetailed.Enabled = (not 0)
   endif
endfunction
         
;-------------------------------------------------------------

function AddUsers2()
   dim $item, $

   InitUsers()
   While $Form2.Visible
      $=Execute($Form2.DoEvents)
   Loop
   if $Form2.Tag
      if $cbSelectOnly.Checked
         for each $item in $lvUsers.SelectedItems
            $lvRemove.Items.Add($item.Text).SubItems(1).Text = $item.SubItems(1).Text
         next
      else
         for each $item in $lvUsers.Items
            $lvRemove.Items.Add($item.Text).SubItems(1).Text = $item.SubItems(1).Text
         next
      endif
      $cbDetailed.Enabled = (not 0)
   endif
endfunction

;-------------------------------------------------------------

function InitUsers()
   $lvUsers.Items.Clear()
   $cbSelectOnly.Checked = (not 1)
   $txtUsers.Text = ""
   $txtUsers.SetFocus()
   $Form2.Visible = (not 0)
endfunction

;-------------------------------------------------------------

function FindUsers()
   dim $users,$objRecordSet, $user
   dim $name, $path, $item, $count
   dim $rootDSE,$strDomain

   $rootDSE = getobject("LDAP://RootDSE")
   $strDomain = $rootDSE.Get("defaultNamingContext")
   $users = split($txtUsers.Text, ";")
   for each $user in $users
      $count = 0
      $user = trim($user)
      $objCommand.CommandText =
         "SELECT adsPath,name,saMAccountName FROM "
         + "'LDAP://" + $strDomain + "' WHERE objectCategory<>'computer' and saMAccountName='" + $user + "'"

      $objRecordSet = $objCommand.Execute()
      while not $objRecordSet.EOF
         $count = $count+1
         $path = $objRecordSet.Fields("adsPath").Value
         $name = $objRecordSet.Fields("saMAccountName").Value
         $lvUsers.Items.Add($name).SubItems(1).Text = $path
         $objRecordSet.MoveNext
      Loop
      if $count = 0
         $ = $Sys.MessageBox.Show("Could not find " + $user)
      endif
   next
   $txtUsers.Text = ""
endfunction

;-------------------------------------------------------------

Function wmiPing($Address,Optional $Timeout,Optional $BlockSize)
   Dim $Query,$oWMI,$oItem,$cItems

   $Query = "Select ResponseTime,StatusCode From Win32_PingStatus Where Address='" + $Address + "'"
   If $Timeout
      $Query = $Query + " And TimeOut=" + $Timeout
   EndIf
   If $BlockSize
      $Query = $Query + " And BufferSize=" + $BlockSize
   EndIf
   $oWMI = GetObject("winmgmts:root\cimv2")
   $cItems = $oWMI.ExecQuery($Query)
   For Each $oItem In $cItems
      If (VarTypeName($oItem.StatusCode) = 'Null') Or $oItem.StatusCode
         Exit 1
      Else
         $wmiPing = $oItem.ResponseTime
      EndIf
   Next
EndFunction

;---------------------------------------------------------------------------------------------------------------------------------------

function Log($fileHandle,$logMsg)
   dim $date
   if $fileHandle
      $date = substr(@date,6) + '/' + substr(@date,1,4)
      $ = writeline($fileHandle,$date + " " + @time + " : " + $logMsg + @crlf)
   endif
endfunction
   

;---------------------------------------------------------------------------------------------------------------------------------------

function ToggleAll($bEnabled)
   $grpAD.Enabled = $bEnabled
   $trvAD.Enabled = $bEnabled
   $grpDepth.Enabled = $bEnabled
   $rbSubtree.Enabled = $bEnabled
   $rbOneLevel.Enabled = $bEnabled
   $grpAdd.Enabled = $bEnabled
   $lvAdd.Enabled = $bEnabled
   $btnAdd.Enabled = $bEnabled
   $btnRemove.Enabled = $bEnabled
   $grpRemove.Enabled = $bEnabled
   $lvRemove.Enabled = $bEnabled
   $btnAdd2.Enabled = $bEnabled
   $btnRemove2.Enabled = $bEnabled
   $grpLog.Enabled = $bEnabled
   $cbSimple.Enabled = $bEnabled
   $btnSearch.Enabled = $bEnabled
   $cbDetailed.Enabled = ($bEnabled and $cbDetailed.Enabled)
endfunction

;---------------------------------------------------------------------------------------------------------------------------------------

function Cancel()
   if $btnSearch.Enabled
      $objConnection = 0
      $objCommand = 0
      if $Form2.visible
         $Form2.Hide
      endif
      $Form.Hide
   else
      $bCanceling = (not 0)
   endif
endfunction
Back to top
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    KiXforms Forum Index -> Script Archive All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001, 2005 phpBB Group