Windows Vista Forums

Move computer and Laptop to correct OU
  1. #1


    Deathrow Guest

    Move computer and Laptop to correct OU

    Hello,



    I have been working on getting a script that will prompt the user with a
    MsgBox asking if its weather a desktop and laptop and then ask for the laptop
    or pc number then move it to the right OU as per selection made in the MsgBox.

    Let say the Default LDAP:\\"CN=Computers,DC=CAECORP,DC=CAE,DC=COM"

    If MsgBox selection = Laptop then
    LDAP:\\"OU=Laptops,OU=CAE,DC=CAECORP,DC=CAE,DC=COM"

    If MsgBox selection = Desktop then
    LDAP:\\"OU=Desktop,OU=CAE,DC=CAECORP,DC=CAE,DC=COM"

    Thanks for you help


      My System SpecsSystem Spec

  2. #2


    Richard Mueller [MVP] Guest

    Re: Move computer and Laptop to correct OU


    "Deathrow" <Deathrow@xxxxxx> wrote in message
    news:75284516-3A11-4C76-963E-5AB8A32B17EE@xxxxxx

    > Hello,
    >
    > I have been working on getting a script that will prompt the user with a
    > MsgBox asking if its weather a desktop and laptop and then ask for the
    > laptop
    > or pc number then move it to the right OU as per selection made in the
    > MsgBox.
    >
    > Let say the Default LDAP:\\"CN=Computers,DC=CAECORP,DC=CAE,DC=COM"
    >
    > If MsgBox selection = Laptop then
    > LDAP:\\"OU=Laptops,OU=CAE,DC=CAECORP,DC=CAE,DC=COM"
    >
    > If MsgBox selection = Desktop then
    > LDAP:\\"OU=Desktop,OU=CAE,DC=CAECORP,DC=CAE,DC=COM"
    >
    > Thanks for you help
    >
    You use the MoveHere method of the parent container/OU object to move
    objects. You pass the ADsPath of the object to be moved to the method. In
    brief:
    =========
    ' Retrieve Distinguished Name of current computer.
    Set objSysInfo = CreateObject("ADSystemInfo")
    strComputerDN = objSysInfo.ComputerName

    ' Bind to destination container/OU object.
    Set objLaptops =
    GetObject(LDAP://ou=Laptops,ou=CAE,dc=CAECORP,dc=CAE,dc=com)

    ' Move current computer object to destination.
    objLaptops.MoveHere "LDAP://" & strComputerDN, vbNullString
    ===========
    In this case it makes sense to me to determine if the computer is a laptop
    or desktop programmatically and move all computer objects in bulk yourself.
    The Win32_SystemEnclosure class of WMI can be used, but there are several
    possible values that need to be considered. There are values for Desktop,
    Low Profile Desktop, Pizza Box, Tower, Portable, Laptop, Notebook, Sub
    Notebook, etc. See this link:

    http://www.microsoft.com/technet/scr..._cpm_btnz.mspx

    You would also probably want to skip DC's and servers, but the DomainRole
    property of the Win32_ComputerSystem class of WMI can be used for this. See
    this link:

    http://www.microsoft.com/technet/scr..._srv_yzhs.mspx

    A script could use ADO to retrieve the sAMAccountName of all computers in
    the domain. See this link for information on using ADO to retrieve
    information from AD:

    http://www.rlmueller.net/ADOSearchTips.htm

    You can restrict the query to your default container, cn=Computers. Just
    assign the DN of this container as the base of the query. You would
    enumerate the resulting recordset and retrieve the value of sAMAccountName
    for each computer. You would strip off the trailing "$" from the
    sAMAccountName to get the NetBIOS name, then connect to each computer with
    WMI, use the DomainRole property of the Win32_ComputerSystem class to skip
    all but member workstations, then use the Win32_SystemEnclosure class to
    determine if the workstation is a desktop or laptop, and move the computer
    accordingly to the proper OU. You could first code the script to output the
    computer NetBIOS name, the computer role, and enclosure type. This would let
    you know what you have and if the any machines should not be moved.

    I like to do things like this myself, rather than relying on others to run a
    script on each computer. And how do you ensure the script isn't run twice? I
    hope this helps.

    --
    Richard Mueller
    MVP Directory Services
    Hilltop Lab - http://www.rlmueller.net
    --



      My System SpecsSystem Spec

  3. #3


    Deathrow Guest

    Re: Move computer and Laptop to correct OU

    Thanks for you reply Richard,

    Here is what i got so far :

    strComputer = "."
    Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

    Set colOSes = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
    For Each objOS in colOSes
    strComputer = objOS.CSName

    next

    'Where to search from
    strSoeg = "'LDAP://cn=computers,dc=CAECORP,DC=CAE,DC=COM' WHERE
    objectCategory='computer' AND name=" 'LDAP path to search

    ' Where to move the desktops
    strDestination = "LDAP://OU=COMPUTERS,OU=CAE,DC=CAECORP,DC=CAE,DC=COM" '
    LDAP path of destination

    Const ADS_SCOPE_SUBTREE = 2

    Set objConnection = CreateObject("ADODB.Connection")
    Set objCommand = CreateObject("ADODB.Command")
    objConnection.Provider = "ADsDSOObject"
    objConnection.Open "Active Directory Provider"
    Set objCommand.ActiveConnection = objConnection

    objCommand.Properties("Page Size") = 1000
    objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE

    ' Search command
    objCommand.CommandText = _
    "SELECT ADsPath FROM " & strSoeg & "'" & strComputer & "'"
    ' Search
    Set objRecordSet = objCommand.Execute

    objRecordSet.MoveFirst
    Do Until objRecordSet.EOF
    strADsPath = objRecordSet.Fields("ADsPath").Value
    Set objNewOU = GetObject(strDestination)

    Set objMoveComputer = objNewOU.MoveHere (strADsPath, "CN=" & strComputer)
    objRecordSet.MoveNext
    Loop

    msgbox Strcomputer & "has been move to" & strDestination



    ' Clean up
    set objNewOU = nothing
    set objMoveComputer = nothing
    set objRecordSet = nothing
    set objCommand = nothing
    set objConnection = nothing

    What a have missing now is that part :


    Set colChassis = objWMIService.ExecQuery _
    ("Select * from Win32_SystemEnclosure",,16)
    For Each objChassis in colChassis
    For Each objItem in objChassis.ChassisTypes
    Select Case objItem
    Case 1 strChassis = "Maybe Virtual Machine"
    Case 2 strChassis = "??"
    Case 3 strChassis = "Desktop"
    Case 4 strChassis = "Thin Desktop"
    Case 5 strChassis = "Pizza Box"
    Case 6 strChassis = "Mini Tower"
    Case 7 strChassis = "Full Tower"
    Case 8 strChassis = "Portable"
    Case 9 strChassis = "Laptop"
    Case 10 strChassis = "Notebook"
    Case 11 strChassis = "Hand Held"
    Case 12 strChassis = "Docking Station"
    Case 13 strChassis = "All in One"
    Case 14 strChassis = "Sub Notebook"
    Case 15 strChassis = "Space-Saving"
    Case 16 strChassis = "Lunch Box"
    Case 17 strChassis = "Main System Chassis"
    Case 18 strChassis = "Lunch Box"
    Case 19 strChassis = "SubChassis"
    Case 20 strChassis = "Bus Expansion Chassis"
    Case 21 strChassis = "Peripheral Chassis"
    Case 22 strChassis = "Storage Chassis"
    Case 23 strChassis = "Rack Mount Unit"
    Case 24 strChassis = "Sealed-Case PC"

    End Select
    Next
    Next

    and change the destination to
    "LDAP://OU=laptops,OU=CAE,DC=CAECORP,DC=CAE,DC=COM" if its case
    8,9,10,11,12,14,18,21

    This will be use as a final script in the Task Sequencer for MDT2008 in the
    deployment process so it will only run once.

    It's been a while since i play with VBS so i kinda re-learning :-)

    Thanks




    "Richard Mueller [MVP]" wrote:

    >
    > "Deathrow" <Deathrow@xxxxxx> wrote in message
    > news:75284516-3A11-4C76-963E-5AB8A32B17EE@xxxxxx

    > > Hello,
    > >
    > > I have been working on getting a script that will prompt the user with a
    > > MsgBox asking if its weather a desktop and laptop and then ask for the
    > > laptop
    > > or pc number then move it to the right OU as per selection made in the
    > > MsgBox.
    > >
    > > Let say the Default LDAP:\\"CN=Computers,DC=CAECORP,DC=CAE,DC=COM"
    > >
    > > If MsgBox selection = Laptop then
    > > LDAP:\\"OU=Laptops,OU=CAE,DC=CAECORP,DC=CAE,DC=COM"
    > >
    > > If MsgBox selection = Desktop then
    > > LDAP:\\"OU=Desktop,OU=CAE,DC=CAECORP,DC=CAE,DC=COM"
    > >
    > > Thanks for you help
    > >
    >
    > You use the MoveHere method of the parent container/OU object to move
    > objects. You pass the ADsPath of the object to be moved to the method. In
    > brief:
    > =========
    > ' Retrieve Distinguished Name of current computer.
    > Set objSysInfo = CreateObject("ADSystemInfo")
    > strComputerDN = objSysInfo.ComputerName
    >
    > ' Bind to destination container/OU object.
    > Set objLaptops =
    > GetObject(LDAP://ou=Laptops,ou=CAE,dc=CAECORP,dc=CAE,dc=com)
    >
    > ' Move current computer object to destination.
    > objLaptops.MoveHere "LDAP://" & strComputerDN, vbNullString
    > ===========
    > In this case it makes sense to me to determine if the computer is a laptop
    > or desktop programmatically and move all computer objects in bulk yourself.
    > The Win32_SystemEnclosure class of WMI can be used, but there are several
    > possible values that need to be considered. There are values for Desktop,
    > Low Profile Desktop, Pizza Box, Tower, Portable, Laptop, Notebook, Sub
    > Notebook, etc. See this link:
    >
    > http://www.microsoft.com/technet/scr..._cpm_btnz.mspx
    >
    > You would also probably want to skip DC's and servers, but the DomainRole
    > property of the Win32_ComputerSystem class of WMI can be used for this. See
    > this link:
    >
    > http://www.microsoft.com/technet/scr..._srv_yzhs.mspx
    >
    > A script could use ADO to retrieve the sAMAccountName of all computers in
    > the domain. See this link for information on using ADO to retrieve
    > information from AD:
    >
    > http://www.rlmueller.net/ADOSearchTips.htm
    >
    > You can restrict the query to your default container, cn=Computers. Just
    > assign the DN of this container as the base of the query. You would
    > enumerate the resulting recordset and retrieve the value of sAMAccountName
    > for each computer. You would strip off the trailing "$" from the
    > sAMAccountName to get the NetBIOS name, then connect to each computer with
    > WMI, use the DomainRole property of the Win32_ComputerSystem class to skip
    > all but member workstations, then use the Win32_SystemEnclosure class to
    > determine if the workstation is a desktop or laptop, and move the computer
    > accordingly to the proper OU. You could first code the script to output the
    > computer NetBIOS name, the computer role, and enclosure type. This would let
    > you know what you have and if the any machines should not be moved.
    >
    > I like to do things like this myself, rather than relying on others to run a
    > script on each computer. And how do you ensure the script isn't run twice? I
    > hope this helps.
    >
    > --
    > Richard Mueller
    > MVP Directory Services
    > Hilltop Lab - http://www.rlmueller.net
    > --
    >
    >
    >

      My System SpecsSystem Spec

  4. #4


    Richard Mueller [MVP] Guest

    Re: Move computer and Laptop to correct OU


    "Deathrow" <Deathrow@xxxxxx> wrote in message
    news:59586177-2BC1-48B5-BAC1-ADC566847295@xxxxxx

    > Thanks for you reply Richard,
    >
    > Here is what i got so far :
    >
    > strComputer = "."
    > Set objWMIService = GetObject("winmgmts:" _
    > & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
    >
    > Set colOSes = objWMIService.ExecQuery("Select * from
    > Win32_OperatingSystem")
    > For Each objOS in colOSes
    > strComputer = objOS.CSName
    >
    > next
    >
    > 'Where to search from
    > strSoeg = "'LDAP://cn=computers,dc=CAECORP,DC=CAE,DC=COM' WHERE
    > objectCategory='computer' AND name=" 'LDAP path to search
    >
    > ' Where to move the desktops
    > strDestination = "LDAP://OU=COMPUTERS,OU=CAE,DC=CAECORP,DC=CAE,DC=COM" '
    > LDAP path of destination
    >
    > Const ADS_SCOPE_SUBTREE = 2
    >
    > Set objConnection = CreateObject("ADODB.Connection")
    > Set objCommand = CreateObject("ADODB.Command")
    > objConnection.Provider = "ADsDSOObject"
    > objConnection.Open "Active Directory Provider"
    > Set objCommand.ActiveConnection = objConnection
    >
    > objCommand.Properties("Page Size") = 1000
    > objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE
    >
    > ' Search command
    > objCommand.CommandText = _
    > "SELECT ADsPath FROM " & strSoeg & "'" & strComputer & "'"
    > ' Search
    > Set objRecordSet = objCommand.Execute
    >
    > objRecordSet.MoveFirst
    > Do Until objRecordSet.EOF
    > strADsPath = objRecordSet.Fields("ADsPath").Value
    > Set objNewOU = GetObject(strDestination)
    >
    > Set objMoveComputer = objNewOU.MoveHere (strADsPath, "CN=" & strComputer)
    > objRecordSet.MoveNext
    > Loop
    >
    > msgbox Strcomputer & "has been move to" & strDestination
    >
    >
    >
    > ' Clean up
    > set objNewOU = nothing
    > set objMoveComputer = nothing
    > set objRecordSet = nothing
    > set objCommand = nothing
    > set objConnection = nothing
    >
    > What a have missing now is that part :
    >
    >
    > Set colChassis = objWMIService.ExecQuery _
    > ("Select * from Win32_SystemEnclosure",,16)
    > For Each objChassis in colChassis
    > For Each objItem in objChassis.ChassisTypes
    > Select Case objItem
    > Case 1 strChassis = "Maybe Virtual Machine"
    > Case 2 strChassis = "??"
    > Case 3 strChassis = "Desktop"
    > Case 4 strChassis = "Thin Desktop"
    > Case 5 strChassis = "Pizza Box"
    > Case 6 strChassis = "Mini Tower"
    > Case 7 strChassis = "Full Tower"
    > Case 8 strChassis = "Portable"
    > Case 9 strChassis = "Laptop"
    > Case 10 strChassis = "Notebook"
    > Case 11 strChassis = "Hand Held"
    > Case 12 strChassis = "Docking Station"
    > Case 13 strChassis = "All in One"
    > Case 14 strChassis = "Sub Notebook"
    > Case 15 strChassis = "Space-Saving"
    > Case 16 strChassis = "Lunch Box"
    > Case 17 strChassis = "Main System Chassis"
    > Case 18 strChassis = "Lunch Box"
    > Case 19 strChassis = "SubChassis"
    > Case 20 strChassis = "Bus Expansion Chassis"
    > Case 21 strChassis = "Peripheral Chassis"
    > Case 22 strChassis = "Storage Chassis"
    > Case 23 strChassis = "Rack Mount Unit"
    > Case 24 strChassis = "Sealed-Case PC"
    >
    > End Select
    > Next
    > Next
    >
    > and change the destination to
    > "LDAP://OU=laptops,OU=CAE,DC=CAECORP,DC=CAE,DC=COM" if its case
    > 8,9,10,11,12,14,18,21
    >
    > This will be use as a final script in the Task Sequencer for MDT2008 in
    > the
    > deployment process so it will only run once.
    >
    > It's been a while since i play with VBS so i kinda re-learning :-)
    >
    > Thanks
    I think it should be safe to assume that all computer objects in
    "cn=Computer" are workstations, not servers and not Domain Controllers. The
    leaves just whether the workstation is a desktop or laptop.

    If it is necessary to skip servers and DC's, I think a better plan is to
    check the operatingSystem attribute of the computer object and make sure the
    string "server" is not found. This is less work than the DomainRole method
    of the Win32_ComputerSystem I mentioned before. It means I don't need to
    waste time connecting to the remote machine.

    I would use the LDAP syntax in the ADO query. I would suggest (not tested):
    ============
    Option Explicit



    Dim adoCommand, adoConnection, strBase, strFilter, strAttributes

    Dim objRootDSE, strDNSDomain, strQuery, adoRecordset, strAdsPath

    Dim objLaptops, objDesktops, strComputer, objShell

    Dim objWMIService, colChassis, objChassis, intType



    ' Bind to the target OU's, where computer objects will be moved.

    Set objLaptops =
    GetObject("LDAP://ou=Laptops,ou=CAE,dc=CAECORP,dc=CAE,dc=com")

    Set objDesktops =
    GetObject("LDAP://ou=Desktops,ou=CAE,dc=CAECORP,dc=CAE,dc=com")



    ' The objShell object must have global scope for the

    ' PingMachine function used to check if remote computers

    ' are available.

    Set objShell = CreateObject("Wscript.Shell")



    ' Setup ADO objects.

    Set adoCommand = CreateObject("ADODB.Command")
    Set adoConnection = CreateObject("ADODB.Connection")
    adoConnection.Provider = "ADsDSOObject"
    adoConnection.Open "Active Directory Provider"
    adoCommand.ActiveConnection = adoConnection



    ' Search the "cn=Computers" container.

    Set objRootDSE = GetObject("LDAP://RootDSE")

    strDNSDomain = objRootDSE.Get("defaultNamingContext")
    strBase = "<LDAP://cn=Computers," & strDNSDomain & ">"


    ' Filter on computer objects that do not have the string "server"

    ' in the operatingSystem attribute.
    strFilter = "(&(objectCategory=person)(objectClass=user)" _

    & "(!operatingSystem=*server*))"



    ' Comma delimited list of attribute values to retrieve.
    strAttributes = "ADsPath,sAMAccountName"



    ' Construct the LDAP syntax query.
    strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
    adoCommand.CommandText = strQuery
    adoCommand.Properties("Page Size") = 100
    adoCommand.Properties("Timeout") = 30
    adoCommand.Properties("Cache Results") = False



    ' Run the query.
    Set adoRecordset = adoCommand.Execute


    ' Enumerate the resulting recordset.
    Do Until adoRecordset.EOF

    ' Retrieve values.
    strAdsPath = adoRecordset.Fields("AdsPath").Value

    strComputer = adoRecordset.Fields("sAMAccountName").value

    ' Strip off trailing "$" to get NetBIOS name.

    strComputer = Left(strComputer, Len(strComputer) - 1)

    ' Ping the remote computer to make sure it is available.

    If (PingMachine(strComputer, 1, 750) = True) Then

    ' Connect to remote computer with WMI.

    ' Trap error if WMI not installed or blocked.

    On Error Resume Next

    Set objWMIService = GetObject("winmgmts:" _
    & "{impersonationLevel=impersonate,authenticationLevel=Pkt}!\\"
    _
    & strComputer & "\root\cimv2")

    If (Err.Number <> 0) Then

    On Error GoTo 0

    Wscript.Echo strComputer " cannot connect with WMI"

    Else

    On Error GoTo 0

    ' Retrieve chassis type.

    Set colChassis = objWMIService.ExecQuery _

    ("SELECT * FROM Win32_SystemEnclosure")

    For Each objChassis In colChassis

    For Each intType in objChassis.ChassisTypes

    Select Case intType

    Case 3, 4, 6, 7

    ' Desktop workstation. Move to Desktop OU.

    objDesktops.MoveHere strAdsPath, vbNullString

    Case 8, 9, 10, 11, 14

    ' Laptop workstation. Move to Laptop OU.

    objLaptops.MoveHere strAdsPath, vbNullString

    Case Else

    Wscript.Echo strComputer " is unhandled type " &
    CStr(intType)

    End Select

    Next

    Next

    End If

    Else

    Wscript.Echo strComputer & " not available"
    End If
    adoRecordset.MoveNext
    Loop



    ' Clean up.

    adoRecordset.Close

    adoConnection.Close



    Function PingMachine(ByVal strHost, ByVal intPings, ByVal intTO)
    ' Returns True if strHost can be pinged.
    ' Variable objShell has global scope
    ' and must be declared in the main program.

    ' Requires WSH 5.6.

    Dim strResults
    Dim objExecObject

    If (intPings = "") Then
    intPings = 2
    End If
    If (intTO = "") Then
    intTO = 750
    End If

    ' Ping the machine.
    Set objExecObject = objShell.Exec("%comspec% /c ping -n " _
    & CStr(intPings) & " -w " & CStr(intTO) & " " & strHost)

    ' Read the output.
    Do Until objExecObject.StdOut.AtEndOfStream
    strResults = objExecObject.StdOut.ReadAll
    Loop

    Select Case InStr(strResults, "TTL=")
    Case 0
    ' No response.
    PingMachine = False
    Case Else
    ' Computer responded to ping.
    PingMachine = True
    End Select
    End Function


    --
    Richard Mueller
    MVP Directory Services
    Hilltop Lab - http://www.rlmueller.net
    --



      My System SpecsSystem Spec

  5. #5


    Richard Mueller [MVP] Guest

    Re: Move computer and Laptop to correct OU

    Sorry, I made some mistakes in the code I pasted earlier. I forgot some "&"
    concatenation characters in a few Wscript.Echo statements. I think the
    statements should be:

    Wscript.Echo strComputer & " cannot connect with WMI"

    Wscript.Echo strComputer & " is unhandled type " & CStr(intType)

    A bigger mistake is that I copied the wrong ADO filter. It should be:

    strFilter = "(&(objectCategory=computer)" _
    & "(!operatingSystem=*server*))"

    The filter I pasted was for user objects. Also, when I pasted the code the
    extra carriage returns makes it nearly impossible to use. The line wrapping
    also doesn't help. Sorry about that.

    Finally, when I tested I found that some older client computers (Windows
    2000) have unknown chassis type. There is no problem for XP and above.

    --
    Richard Mueller
    MVP Directory Services
    Hilltop Lab - http://www.rlmueller.net
    --



      My System SpecsSystem Spec

Move computer and Laptop to correct OU problems?

Similar Threads
Thread Thread Starter Forum Replies Last Post
problem getting correct realtek driver for toshiba laptop David Vista General 8 13 Sep 2009
Move Outlook .pst files from old XP computer to new Vista computer Crausch Vista file management 15 14 Jul 2009
WDS | Install Vista with correct computer name Pjotrs Sokolovs Vista installation & setup 0 10 Dec 2008
Blue Screen appears when I move my laptop xbabyabyx Vista performance & maintenance 3 31 Jan 2008
Can I move Office XP from old XP computer to new Vista computer? Hi Ho Silver Vista General 3 10 Apr 2007