Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

How do I create a script to move certain users from our GPO Exempt OU to their regular OUs at the end of each day?

Posted on 2006-04-13
15
Medium Priority
?
288 Views
Last Modified: 2011-04-14
OK, I don't know much about scripting, but I was wondering if my task is possible, and if so, how would I do it?  Is writing a script for it the best way, or is there another way?  What I need to do is make sure that any users that were moved into the GPO Exempt OU during the course of the day (we move users into that OU when we're working on their computer or software issues and we want to make sure group policy settings don't get in the way - ideally, the users are moved back into their regular OUs when we're done with them, but not all admins at my organization remember to do so all the time) are moved back into their regular OUs at the end of each day (at a determined time), making them once again subject to GPOs applied to those OUs.  

Does anyone have any ideas how to do this?  Thanks in advance for your help!
0
Comment
Question by:m1knoxg
  • 7
  • 3
  • 3
  • +1
15 Comments
 
LVL 51

Expert Comment

by:Netman66
ID: 16447186
You can do it in a script, yes.

Use DSQUERY USER to query for any user in this OU, then send the output to a text file.
Then use DSMOVE and parse the text file.

0
 

Author Comment

by:m1knoxg
ID: 16447231
OK, like I said, scripting is something I don't know much about...

How do I DSQUERY USER for my GPO Exempt OU and then send its output to a text file, and the DSMOVE?  I don't really understand how all that works...
0
 

Author Comment

by:m1knoxg
ID: 16447265
I should also mention that not all of these users/computers would be going back into the same OU - they would have to be moved back to whichever OU each of them was in before the users/computers were moved into the GPO Exempt OU.
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 51

Expert Comment

by:Netman66
ID: 16447391
You won't be able to be selective on where the users came from since this variable will be unknown after the move.

You should post a link to this question here:

http://www.experts-exchange.com/Programming/Programming_Languages/Visual_Basic/

Someone there may be able to help with a script to move the user into the GPO Exempt OU first then remember where it came from then move it back later.

You should also increase your points on this since what you are asking is not simple.

0
 

Author Comment

by:m1knoxg
ID: 16447468
Increasing point value because this doesn't appear to be an easy task...
0
 
LVL 51

Expert Comment

by:Netman66
ID: 16447484
It's not impossible, it's going to be time consuming and will need to be (most likely) done in VBScript.

0
 
LVL 23

Expert Comment

by:TheCleaner
ID: 16447747
Is the original OU the same for all users?

Basically like netman66 said, if you move someone manually into the exempt OU then there's not a way to tell which OU was their original OU.

Now, if you are stating you want a script that moves any user in "Exempt OU" to "Company Users OU"...that's not a problem, and can be easily scripted using vbscript or Netman's suggestion of DSQUERY and DSMOVE.  Then you just schedule it.

If that's what you want, let us know and we'll lay it out for you...
0
 

Author Comment

by:m1knoxg
ID: 16448544
No, the original OU may not be the same for all users.  Various users may be coming from different OUs into GPOExempt for the day for different issues.  The problem is, after we manually move those users into GPO Exempt so we can help them with a problem, some of our IT staff forget to put them back into their respective OUs from before.  Most users will be coming from the same Local Users OU, but underneath that one, there are 3 different OUs that users go into, based on which of the 3 facilities in which they are located.  So, that's what I mean about users coming from different places (also, sometimes each facility's OU has various OUs under it for users with different purposes and different settings required, which complicates putting the users back even more).  GPOExempt also has 3 OUs underneath it for each of our 3 facilities.  I don't know if that info helps in trying to achieve this very difficult task, but that's how our Active Directory structure works.  
0
 
LVL 23

Expert Comment

by:TheCleaner
ID: 16448647
Well, in that case you're going to have one seriously long script.  It would have to key in on some attribute of each user, like their location field or similar, and then move them based on that field, and even then it's not going to be easy.

Your best bet is to basically just train IT on how to do things correctly.  If they move someone, they should document where they came from, and put them back when finished.

Easier said than done, I know, but really that's going to be the easiest way to go.
0
 

Author Comment

by:m1knoxg
ID: 16448783
Well, thanks to both of you for commenting on my question.  I'm sorry that it's not really possible, but I understand why it's not.  If everyone would just move the users back after they move them in the first place, that would be good, but some people are forgetful.  :)

What are some good resources for me to look at to get acquainted with scripting?  I am totally new to the subject.  
0
 
LVL 23

Assisted Solution

by:TheCleaner
TheCleaner earned 400 total points
ID: 16449036
www.microsoft.com/technet/scriptcenter

That's a great resource for learning windows scripting.


I'm not saying what you are asking for is impossible, just difficult.

The logic would require the script to query against something in the user account to know the original OU.  This would be an attribute of some kind that is entered into the account, just like the description field.

Then the script would say, ok, if attribute = St. Louis Accounting, then move the user to the STLACCT OU.

That's the basics of it, but you sound like it will introduce other criteria for sub-OUs, etc.

Just difficult and dynamic to your organization, which would require a consultant to come in and program it....that's all.
0
 
LVL 14

Expert Comment

by:dlwyatt82
ID: 16449476
The quick solution I would recommend is to have TWO scripts.

One that your employees use to move a user into this "Exempt" OU.  Part of what this script would do is append the user's original OU to a field in the account (such as Description).

The second script would be a scheduled task to enumerate all users in the Exempt OU, read their Description (or whichever attribute you choose to have the first script use) to determine their proper OU, and move them back.  This script should write a log with records of failures, so you have a reference when a user's original OU can't be determined (or doesn't exist, etc).

Here is a quick example of what these scripts will probably look like.

*** NOTE *** I ran out of time typing this at the office, so I'm just posting what's done so far.  If no one else completes this for you, I will pick it up again when I have time.

'**************************************
' Script #1 - Move User to Exempt OU
'
' Argument:  /u:LoginName
'
' Attempts to move the user account with sAMAccountName <LoginName>
' to the Exempt OU.  Stores the user's original OU in the user's
' Description attribute for later use.
'
' This sample attempts to run in the same domain the administrator
' is currently logged on to (using rootDSE)
'
'**************************************

Option Explicit

Const cExemptOU = "OU=Exempt"

Dim objRootDSE, objAdoCon, objAdoCmd, objAdoRS, objUser, objExemptOU
Dim strDomainDN, strExemptOU, strLogin, strADsPath, strDesc

If (Not WScript.Arguments.Named.Exists("u")) Then
  WScript.Echo "Usage:  cscript " & WScript.ScriptName & " /u:<LoginName>"
  WScript.Quit 1
End If

strLogin = WScript.Arguments.Named.Item("u")

On Error Resume Next
Set objRootDSE = GetObject("LDAP://rootDSE")
strDomainDN = objRootDSE.Get("defaultNamingContext")

If (Err.Number) Then
  WScript.Echo "Error determining the current user's domain: " & _
               Hex(Err.Number) & ", " & Err.Description
  WScript.Quit 1
End If

strExemptOU = cExemptOU & ", " & strDomainDN

Set objExemptOU = GetObject("LDAP://" & strExemptOU)

If (Err.Number) Then
  WScript.Echo "Error binding to Exempt OU: " & Hex(Err.Number) & ", " & Err.Description
  WScript.Quit 1
End If

' We've determined the current domain and that the Exempt OU exists.  Now, try to find the user
' object in Active Directory.

Set objAdoCon = CreateObject("ADODB.Connection")
Set objAdoCmd = CreateObject("ADODB.Command")

objAdoCon.Open "Provider=ADsDSOObject;"
Set objAdoCmd.ActiveConnection = objAdoCon

objAdoCmd.CommandText = "SELECT ADsPath FROM 'LDAP://" & strDomainDN & "' WHERE " & _
                        "objectCategory='person' AND objectClass='user' AND " & _
                        "sAMAccountName='" & strLogin & "'"

Set objAdoRS = objAdoCmd.Execute

If (Err.Number) Then
  WScript.Echo "Error searching Active Directory: " & Hex(Err.Number) & ", " & Err.Description
  WScript.Quit 1
End If

strADsPath = ""
Do While (Not objAdoRS.EOF)
  strADsPath = objAdoRS.Fields("ADsPath").Value
  objAdoRS.MoveNext
Loop

If (strADsPath = "") Then
  WScript.Echo "User '" & strLogin & "' was not found in Active Directory."
  WScript.Quit 1
End If

Set objUser = GetObject(strADsPath)

If (Err.Number) Then
  WScript.Echo "Error binding to user account: " & Hex(Err.Number) & ", " & Err.Description
  WScript.Quit 1
End If

If (objUser.Parent = objExemptOU.Get("ADsPath")) Then
  WScript.Echo "User '" & strLogin & "' is already in the Exempt OU."
  WScript.Quit 1
End If

objUser.Description = objUser.Description & "<|>" & objUser.Parent & "<|>"
objUser.SetInfo

If (Err.Number) Then
  WScript.Echo "Error setting user description: " & Hex(Err.Number) & ", " & Err.Description
  WScript.Quit 1
End If

0
 

Author Comment

by:m1knoxg
ID: 16453230
Thanks to Netman66 and TheCleaner for your help so far.  Thanks to dlwyatt82 for the example you typed out for me.  I will have to better educate myself on scripting to see what all of that means before I try it on any users.  
0
 
LVL 14

Accepted Solution

by:
dlwyatt82 earned 1600 total points
ID: 16453859
OK, here are the two completed scripts.  Let me say up front that these have not been tested, as I do not have an Active Directory domain suitable for this test at present.  There is plenty of error trapping in each script (in the form of Echo statements in script #1, and a log file in script #2), and I am happy to help you debug them if unexpected errors occur.

'**************************************
' Script #1 - Move User to Exempt OU
'
' Argument:  /u:LoginName
'
' Attempts to move the user account with sAMAccountName <LoginName>
' to the Exempt OU.  Stores the user's original OU in the user's
' Description attribute for later use.
'
' This sample attempts to run in the same domain the administrator
' is currently logged on to (using rootDSE)
'
'**************************************

Option Explicit

Const cExemptOU = "OU=Exempt"

Dim objRootDSE, objAdoCon, objAdoCmd, objAdoRS, objUser, objExemptOU
Dim strDomainDN, strExemptOU, strLogin, strADsPath, strDescPre, strDescPost
Dim objRegExp, colMatches, objMatch

If (Not WScript.Arguments.Named.Exists("u")) Then
  WScript.Echo "Usage:  cscript " & WScript.ScriptName & " /u:<LoginName>"
  WScript.Quit 1
End If

strLogin = WScript.Arguments.Named.Item("u")

On Error Resume Next
Set objRootDSE = GetObject("LDAP://rootDSE")
strDomainDN = objRootDSE.Get("defaultNamingContext")

If (Err.Number) Then
  WScript.Echo "Error determining the current user's domain: " & _
               Hex(Err.Number) & ", " & Err.Description
  WScript.Quit 1
End If

strExemptOU = cExemptOU & ", " & strDomainDN

Set objExemptOU = GetObject("LDAP://" & strExemptOU)

If (Err.Number) Then
  WScript.Echo "Error binding to Exempt OU: " & Hex(Err.Number) & ", " & Err.Description
  WScript.Quit 1
End If

' We've determined the current domain and that the Exempt OU exists.  Now, try to find the user
' object in Active Directory.

Set objAdoCon = CreateObject("ADODB.Connection")
Set objAdoCmd = CreateObject("ADODB.Command")

objAdoCon.Open "Provider=ADsDSOObject;"
Set objAdoCmd.ActiveConnection = objAdoCon

objAdoCmd.CommandText = "SELECT ADsPath FROM 'LDAP://" & strDomainDN & "' WHERE " & _
                        "objectCategory='person' AND objectClass='user' AND " & _
                        "sAMAccountName='" & strLogin & "'"

Set objAdoRS = objAdoCmd.Execute

If (Err.Number) Then
  WScript.Echo "Error searching Active Directory: " & Hex(Err.Number) & ", " & Err.Description
  WScript.Quit 1
End If

strADsPath = ""
Do While (Not objAdoRS.EOF)
  strADsPath = objAdoRS.Fields("ADsPath").Value
  objAdoRS.MoveNext
Loop

If (strADsPath = "") Then
  WScript.Echo "User '" & strLogin & "' was not found in Active Directory."
  WScript.Quit 1
End If

Set objUser = GetObject(strADsPath)

If (Err.Number) Then
  WScript.Echo "Error binding to user account: " & Hex(Err.Number) & ", " & Err.Description
  WScript.Quit 1
End If

If (objUser.Parent = objExemptOU.Get("ADsPath")) Then
  WScript.Echo "User '" & strLogin & "' is already in the Exempt OU."
  WScript.Quit 1
End If

' Process user's description attribute.  Make sure an ADsPath hasn't already been stored
' but not removed.  If so, just replace what's there.

Set objRegExp = New RegExp
objRegExp.Global = False
objRegExp.Pattern = "^(.*)<\|>[^<]+<\|>(.*)$"

If (objRegExp.Test(objUser.Description)) Then
  Set colMatches = objRegExp.Execute(objUser.Description)
  For Each objMatch In colMatches
    strDescPre = objMatch.SubMatches(0)
    strDescPost = objMatch.SubMatches(1)
  Next
Else
  strDescPre = objUser.Description
  strDescPost = ""
End If

objUser.Description = strDescPre & "<|>" & objUser.Parent & "<|>" & strDescPost
objUser.SetInfo

If (Err.Number) Then
  WScript.Echo "Error setting user description: " & Hex(Err.Number) & ", " & Err.Description
  WScript.Quit 1
End If

Set objUser = Nothing
objExemptOU.MoveHere strADsPath, vbNullString

If (Err.Number) Then
  WScript.Echo "Error moving the user object: " & Hex(Err.Number) & ", " & Err.Description
  Err.Clear
 
  ' Attepmt to revert user's description
  Set objUser = GetObject(strADsPath)
  If (Not Err.Number) Then
    objUser.Description = strDescPre & strDescPost
    objUser.SetInfo
  End If
  Set objUser = Nothing
 
  WScript.Quit 1
End If

WScript.Echo "User '" & strLogin & "' was successfully moved to the Exempt OU."

' **************************
' End of Script #1
' **************************

'**************************************
' Script #2 - Move users in Exempt OU back to
'             their original locations.
'
' Enumerates the user objects in the Exempt OU, and attempts
' to move them back to their original locations based on
' the contents of their Description attribute.
'
' This sample attempts to run in the same domain as the account
' used to run the script.
'
'**************************************

Option Explicit

Const cExemptOU = "OU=Exempt"
Const cLogFile = "ExemptMoves.txt"

Const ForAppending = 8

Dim objRootDSE, objUser, objExemptOU, objUserOU
Dim strDomainDN, strExemptOU, strDescPre, strDescPost, strParent
Dim objRegExp, colMatches, objMatch
Dim objFSO, objLogFile

On Error Resume Next

' Open log file.
Set objFSO = CreateObject("Scripting.FileSystemObject")
If (objFSO.FileExists(cLogFile)) Then
  Set objLogFile = objFSO.OpenTextFile(cLogFile, ForAppending)
Else
  Set objLogFile = objFSO.CreateTextFile(cLogFile)
End If

If (TypeName(objLogFile) <> "TextStream") Then
  ' If log file can't be opened, exit with error code 2
  WScript.Quit 2
End If

objLogFile.WriteLine vbCrLf & CStr(Now) & " - Script starting."

Set objRootDSE = GetObject("LDAP://rootDSE")
strDomainDN = objRootDSE.Get("defaultNamingContext")

If (Err.Number) Then
  objLogFile.WriteLine "Error determining the current user's domain: " & _
                       Hex(Err.Number) & ", " & Err.Description
  WScript.Quit 1
End If

strExemptOU = cExemptOU & ", " & strDomainDN

Set objExemptOU = GetObject("LDAP://" & strExemptOU)

If (Err.Number) Then
  objLogFile.WriteLine "Error binding to Exempt OU: " & Hex(Err.Number) & ", " & Err.Description
  WScript.Quit 1
End If

' We've determined the current domain and that the Exempt OU exists.  Enumerate the user objects

objExemptOU.Filter = "user"
  For Each objUser In objExemptOU
 
  ' Process user's description attribute.  Make sure an ADsPath hasn't already been stored
  ' but not removed.  If so, just replace what's there.
 
  Set objRegExp = New RegExp
  objRegExp.Global = False
  objRegExp.Pattern = "^(.*)<\|>([^<]+)<\|>(.*)$"
 
  If (objRegExp.Test(objUser.Description)) Then
    Set colMatches = objRegExp.Execute(objUser.Description)
    For Each objMatch In colMatches
      strDescPre = objMatch.SubMatches(0)
      strParent = objMatch.SubMatches(1)
      strDescPost = objMatch.SubMatches(2)
    Next
   
    ' Attempt to bind to target OU
    Set objUserOU = GetObject(strParent)
    If (Err.Number) Then
      objLogFile.WriteLine "User: " & objUser.Get("sAMAccountName") & " Could not bind to user's parent OU '" & _
        strParent & "': " & Hex(Err.Number) & ", " & Err.Description
      Err.Clear
    Else    
      ' Attempt to revert user's description
      objUser.Description = strDescPre & strDescPost
      objUser.SetInfo
     
      If (Err.Number) Then
        objLogFile.WriteLine "User: " & objUser.Get("sAMAccountName") & " Description attribute could " & _
          "not be modified: " & Hex(Err.Number) & ", " & Err.Description
        Err.Clear
      End If
     
      ' Attempt to move the user back.
      objUserOU.MoveHere objUser.Get("ADsPath"), vbNullString
     
      If (Err.Number) Then
        objLogFile.WriteLine "User: " & objUser.Get("sAMAccountName") & " User could not be moved to " & _
          "OU '" & strParent & "': " & Hex(Err.Number) & ", " & Err.Description
        Err.Clear
      End If
    End If
  Else
    objLogFile.WriteLine "User: " & objUser.Get("sAMAccountName") & " Description attribute could " & _
                         "not be parsed."
  End If
   
  Set objUserOU = Nothing
Next

objLogFile.Close

' *************************
' End of Script #2
' *************************
0
 

Author Comment

by:m1knoxg
ID: 16454191
Thanks, dlwyatt82.  I will take a look at your scripts after I finish educating myself on what all that stuff means, which may take a while, given my lack of experience in this area.  :)  You've been very helpful so far.
0

Featured Post

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Numerous times I have been asked this questions that what is it that makes my machine log on so slow, there have been cases where computers took 23 minute exactly after taking password and getting to the desktop. Interesting thing was the fact th…
While rebooting windows server 2003 server , it's showing "active directory rebuilding indices please wait" at startup. It took a little while for this process to complete and once we logged on not all the services were started so another reboot is …
This Micro Tutorial will teach you how to add a cinematic look to any film or video out there. There are very few simple steps that you will follow to do so. This will be demonstrated using Adobe Premiere Pro CS6.
Enter Foreign and Special Characters Enter characters you can't find on a keyboard using its ASCII code ... and learn how to make a handy reference for yourself using Excel ~ Use these codes in any Windows application! ... whether it is a Micr…

569 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question