Click here to Skip to main content
Licence CPOL
First Posted 3 Aug 2006
Views 19,988
Bookmarked 16 times

Move Computers in Active Directory Using a SQL Server Datasource

By | 3 Aug 2006 | Article
Move multiple computers from one OU to another using a SQL Server table as a datasource.
 
Part of The SQL Zone sponsored by
See Also

Introduction

I recently began a project which involved installing a .msi package on approximately 450 computers. The organization previously implemented projects like this by visiting each desktop, but I suggested AD group policy instead. For a number of reasons, I needed to implement the GPO on the computer node, but there were two main problems: I had a list of user accounts but not computers, and I needed to move the PCs from the Computers OU to the new OU that was linked with my software distribution GPO.

Getting Started

The first step was to start capturing which PCs were tied to my list of known users. I created a *simple* logon script that captured the user name and the computer name, and wrote that to a log file:

@echo off
REM collect user name and computer name
echo %username%,%computername% >> \\servername\sharename\userpclog.txt

After about a month, I had 3500 entries. I imported the file into SQL Server, and then created a View to give me my PC-to-user list. There were 450 computers for 398 users (some users such as interns, temp staff, etc. use any available PC). I did not have info on 28 users but that I could deal with.

Move Active Directory Objects

The basic process for moving the PC from one OU to another is to create a connection to the database, get the list of PC names, then loop through the dataset and create a new DirectoryEntry instance with the current record as the Common Name (CN) in the LDAP path.

First, create a new console application in Visual Studio 2005. You will need to add references to System.DirectoryServices and System.Data. By default, you will have a file called Program.cs. Replace the contents of that file with the code below, and replace the connection to the database, command string, and LDAP paths as needed.

using System;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.DirectoryServices;

class ChangeOU
{
    static void Main(string[] args)
    {
        //Set the move-to path
        string m_movetopath = "LDAP://OU=newtestou," + 
                              "DC=northamerica,DC=fabrikam,DC=com";

        DirectoryEntry DeMoveTo = new DirectoryEntry(m_movetopath);
        
        //Connect to database and get list of PC names
        string ConnectionString = "server=myservername;
        Trusted_Connection=yes; database=Users";
        string CommandString = "SELECT computername FROM vwUserpc";
        SqlDataAdapter sda = new SqlDataAdapter(CommandString, 
                                                ConnectionString);
        DataSet ds = new DataSet();
        sda.Fill(ds);
        DataTable dt = ds.Tables[0];

        foreach (DataRow dr in dt.Rows)
        {
            string pc = (string)dr["computername"].ToString();
            pc.Trim();

            //This is a fixed value.
            string MovePath = "LDAP://CN=" + pc + 
                              ",OU=testou,DC=northamerica," + 
                              "DC=fabrikam,DC=com";

            //For each PC name move it to the new OU
            try
            {
                DirectoryEntry DeMoveFrom = new DirectoryEntry(MovePath);
                DeMoveFrom.MoveTo(DeMoveTo);
            }
            catch (Exception ex)
            {
                Console.Write(ex.Message);
                Console.Write(pc);
            }
        }

        Console.Write("\r\n");
        Console.WriteLine("Completed.");

    }//end Main
} //end class

One thing that is fairly important to note is that I am a domain admin, so creating the DirectoryEntry instances works "without" security; otherwise, you will need to add the security parameters.

Conclusions

The code may seem pretty straightforward, yet I could not find any examples like this. So, I am writing it up for future reference. I hope you find it useful.

Note: Part of this project also involved scripting an ODBC connection in the registry. These scripts are included in the source files.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

smoore4

Database Developer

United States United States

Member

I am an MBA, MCSA, MCDBA, and recently MCITP: Database Administrator 2008. Although employed as a DBA, I do a good deal of sys admin work and development using .NET. Technically, I like to focus on business intelligence, database design, messaging architectures and web development/design.

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
-- There are no messages in this forum --
Permalink | Advertise | Privacy | Mobile
Web04 | 2.5.120517.1 | Last Updated 3 Aug 2006
Article Copyright 2006 by smoore4
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid