Windows 7 is Missing NETDOM.EXE

By , October 23, 2009 1:49 am

UPDATE: I discovered that there is a working NETDOM.EXE for Windows 7. Here’s what you need to do (on a Windows 7 machine) to get it:

  1. Install the Remote Server Administration Tools (RSAT).
  2. Go to Control Panel -> Programs and Features -> Turn Windows features on or off
  3. In the treeview, go to Remote Server Administration Tools -> Role Administration Tools -> AD DS and AD LDS Tools and select AD DS Tools. Click OK.

NETDOM should be located in your SYSTEM32 folder. If would rather use Powershell to join the domain, since it’s included with the Windows 7 RTM, then please continue reading. I apologize for any confusion.

(Begin Original Post)

Now that the title of this post has your attention, I can tell you that Windows 7 isn’t really missing this important tool that joins a machine to an Active Directory Domain in an automated fashion. Instead, this command-line utility has been superseded by a new command that’s included in Microsoft’s love-it-or-hate-it command line shell: Windows Powershell. Why? Well, Powershell is certainly more powerful than the standard command prompt. But more importantly, Windows 7 is the first version to include Windows Powershell in the RTM build. With Powershell built into Windows 7, perhaps Microsoft saw no reason to continue including and supporting our old pal, NETDOM.

Joining a Domain with Add-Computer

When you’re finished grieving over the loss of our beloved NETDOM, which has joined countless computers to countless Windows Domains (or far inferior Workgroups), it’s time to roll up your sleeves and start working with the successor command: Add-Computer. This command will only run in a Windows Powershell command prompt. The good news, however, is that you can easily run Add-Computer inside Powershell through a normal command prompt (or batch file). To do so, open a command prompt (with elevated privileges) and run this command:

powershell Add-Computer -DomainName "YOURDOMAIN"

See? That wasn’t so bad now was it? If you don’t mind entering credentials to join the domain on every single computer, that’s all you need. But unfortunately, some of us need to automate the process of joining the domain. For that, it gets more complex, and we’ll need a bit more Powershell to make it work.

Screenshot: Add-Computer -?

Screenshot: Add-Computer -?

How to Use Add-Computer

From a command prompt, you can get more detailed usage instructions for Add-Computer by using this command:

powershell Add-Computer -?

In the syntax section, you’ll find syntax switches that can be used to specify the domain name, OU path, and credentials.  For a more details and examples on Add-Computer, you can also use this command:

powershell get-help Add-Computer -detailed

The first thing you should notice is that, unlike NETDOM, there aren’t syntax switches to specify the username and password. Instead, there is a switch called “-Credential” that takes in a PSCredential object. Therefore, we need to create a PSCredential object with the credentials that will be used to join the computer to the domain before we can actually use the Add-Computer command in an automated way. To do this, we’ll need to create a Powershell script.

If you have never used Powershell before, you’ll probably say to yourself, “PSCredential object? What is that!?”  I’ll give you this very brief explanation: PSCredential is an object that can securely store Windows credentials. Furthermore, Powershell is  more like full-blown Object-Oriented scripting language than a shell language. Like DOS, it has a command prompt. However, the differences usually end there.  Anyway, this article isn’t about Powershell, but if you want to know more about it, start Googling. Or you can just continue on to get the Powershell script.

A Powershell Script to Join the Domain

The Powershell script needed to join the domain contains only two commands.  Create a new text file named “joinDomain.ps1″ and put the following powershell code into it:

$credential = New-Object System.Management.Automation.PsCredential("MY.DOMAIN.COM\user", (ConvertTo-SecureString "mypassword" -AsPlainText -Force))
Add-Computer -DomainName "MY.DOMAIN.COM" -Credential $credential -OUPath ("OU=Computers,DC=MY,DC=DOMAIN,DC=COM")

The first line of the script creates a new System.Management.Automation.PsCredential object. PsCredential takes in two parameters: a string containing a username and a secure string containing the password.  You should change “MY.DOMAIN.COM\user” to the user that will join the computer to the domain. Change “mypassword” to the password of that account.

The second line is the Add-Computer command. “MY.DOMAIN.COM” should be changed to the domain that the computer is joining.  Change OUPath to the OU String that points to the OU container that the computer object should be placed in.

Running the Script

To run the Powershell script above, you need to open an elevated command prompt. To run it, type powershell ./joinDomain.ps1 and press enter. In many cases, you will find that you’re not allowed to run the script, despite running the command as an administrator:

>powershell ./joinDomain.ps1
File joinDomain.ps1 cannot be loaded because the execution of scripts is disabled on this system. Please see "get-help about_signing" for more details.

The funny part about Powershell is that, by default, it is configured to only allow the execution of signed scripts. This is a security feature so that unauthorized or malicious scripts that could compromise the system can’t be executed. After all, Powershell is quite power-ful. Unfortunately, this really tends to confuse and frustrate people. To get around this, you can temporarily change the execution policy, and then change it back:

powershell Set-ExecutionPolicy Unrestricted
powershell ./joinDomain.ps1
powershell Set-ExecutionPolicy Restricted

You can also change the execution policy to allow only signed scripts and scripts created by you. For more information about the Powershell execution policy, check out this article.

Final Thoughts

Now that you are able to automate a domain join with Powershell instead of NETDOM, there is one final thing that I want to mention. In the script above,  the password String was converted to a SecureString by using the “-AsPlainText -Force” arguments. Using SecureString in this way is generally discouraged as it defeats the whole purpose of having a secure string. Furthermore,  having account credentials in plain text with in the script is insecure and generally a bad idea. I’m guessing that this is the reason why Microsoft left out the “/userD” and “/passwordD” parameters from the NETDOM command and made it more slightly difficult to include the credentials in plain text. You should limit the rights of the account you’re using to automatically join the domain so that it cannot be used to delete Active Directory objects, access network shares, etc. You should also consider other methods of storing the credentials. This article has an alternative method for storing credentials used in Powershell that may meet your needs.

Windows PE 3.0 and the Missing WMI Class

By , October 12, 2009 9:46 am

Since I maintain the Windows XP Image for our lab machines, I was tasked with doing the same thing with Windows 7. When I rewrote our imaging tools last Spring, I created a WinPE 2.0 image that included the WMI package so that the imaging application could perform WMI queries in PE. I used WMI only to get basic information about the machine (Such as the Manufacturer, Model, Serial Number, and Disk Information).

While upgrading the WinPE image from 2.0 to 3.0 in anticipation of deploying Windows 7, I discovered that the Windows PE 3.0 base image (the same one that comes with the Windows AIK) was missing Win32_DiskPartition. I use this class to retrieve the number of partitions on the system disk so that I can make sure that each partitition (and its volume) has been assigned a drive letter so that I can search each drive for a preexisting configuration file. But why would Microsoft remove this class!? On a standard Windows 7 machine, the command “WMIC.EXE PARTITION” returned a list of partitions on the system, confirming that I wasn’t losing my mind. However, the command returned nothing when I tried it in Windows PE 3.0.

After lots of searching, I finally came across a post on Microsoft Technet where another developer ran into the same issue. Fortunately, he found a simple, but somewhat obscure, solution:

  1. On a fully-installed Windows 7 machine, copy the contents of C:\Windows\System32\wbem
  2. Mount the Windows PE 3.0 image and replace the contents of <mountdir>\Windows\System32\wbem with the wbem folder from the previous step

Using the Windows 7 wbem folder in your WinPE 3.0 image will make it several Megabytes larger, but at least you will be able to get to the missing WMI class(es) that you need!

Update 3/11/2010: After upgrading to the latest version of the Microsoft WAIK, I was unable to overwrite existing files in the WBEM folder (Access Denied). For some reason, the permissions are different on this folder now. Here is the workaround:

  1. To take ownership of the existing WBEM folder and files, run this command: TAKEOWN /F <mountdir>\windows\system32\wbem /A /R
  2. To grant administrators full control of the existing WBEM folder and files, run this command: ICACLS <mountdir>\windows\system32\wbem /grant Administrators:F /T

Once the permissions are updated, you will be able to overwrite files in the WBEM folder.

Update 3/18/2011: I was hoping that this issue would be resolved with the release of Windows 7 SPI and WinPE 3.1. Unfortunately, the problem still exists. However, I did some additional digging and found that, for me at least, there is only one file that I need to copy to the WinPE WIM fix Win32_DiskPartition: C:\Windows\Sysm32\wbem\en-US\cimwin32.dll.mui. Since the file doesn’t exist already in a fresh WinPE WIM, should shouldn’t have to deal with the ownership and permission issues mentioned above.

63650-0C051-B0

Panorama Theme by Themocracy