HOWTO: Change a Computer Name Programmatically

ID: Q193068


The information in this article applies to:
  • Microsoft Win32 Application Programming Interface (API), included with:
    • Microsoft Windows NT 4.0
    • Microsoft Windows 2000


********************************************************************
BETA INFORMATION BETA INFORMATION BETA INFORMATION BETA
This article discusses a Beta release of a Microsoft
product. The information in this article is provided as-is
and is subject to change without notice.
No formal product support is available from Microsoft for
this Beta product. For information about obtaining support
for a Beta release, please see the documentation included
with the Beta product files, or check the Web location
from which you downloaded the release.
BETA INFORMATION BETA INFORMATION BETA INFORMATION BETA
******************************************************************** 

SUMMARY

Occasionally, you might need to rename a Windows 2000, Windows NT, or Windows 9x computer account programmatically. This article provides sample code that demonstrates how to accomplish this task.


MORE INFORMATION

Windows 2000 provides a new API called NetRenameMachineInDomain that makes it easy to rename an account programmatically. The sample code provided in this article does a version check and executes the correct code path based on the version of the operating system.

Under Windows NT 4.0, you cannot run this code from a remote computer. It must be run on the target computer.

If the computer account that you want to rename is a Windows 9x account, the task is slightly more complicated. Because Windows 9x does not implement the 32-bit version of NetUserSetInfo, you must also do one of the following to proceed:

  • Separate the code into two different executables. Run one on the Windows 9x computer and call SetComputerName. Run the other one on a Windows NT computer and call NetUserSetInfo to rename the account on the Domain Controller.


  • Add thunking code and call the 16-bit version of NetUserSetInfo.


Sample Code


   #define UNICODE
   #define _UNICODE
   /*++

   Module Name:

       chngmachname.c

   Abstract:

      This sample changes the computer name for the local Windows NT
      computer.

      This sample uses NetUserSetInfo() to change the account name on the
      domain PDC and SetComputerName() to change the name on the local
      computer.

      When targeting a domain controller for account update operations,
      you need to make sure you target the primary domain controller for
      the domain. The account settings are replicated by the primary domain
      controller to each backup domain controller as appropriate. You can
      use the NetGetDCName() Lan Manager API call to get the primary domain
      controller computer name from a domain name.

      NOTE: You must restart the computer after running this code to
      implement the changes.

      Link with netapi32.lib user32.lib

      David Mowers (davemo)   Jun-01-1998


   --*/ 

   #include <windows.h>
   #include <lm.h>

   int
   __cdecl
   wmain(
      int argc,
      wchar_t *argv[]
      )
   {
      LPWSTR          wComputerName;
      DWORD           dwNameSize;
      LPWSTR          wNewComputerName=NULL;
      LPWSTR          wDCName=NULL;
      USER_INFO_0     ui_0;
      NET_API_STATUS  nas;
      NTSTATUS        Status;
      OSVERSIONINFO   OSVersionInfo;
      BOOL            bSuccess = FALSE;


      if( argc < 2 ) {
         wprintf(L"Usage: %s <new_computer_name>\n", argv[0]);
         return 0;
      }

      // 
      // Process the command line arguments, and
      // prepare new computer name.
      // 
      wNewComputerName = LocalAlloc(LPTR,
         (MAX_COMPUTERNAME_LENGTH+3)*sizeof(WCHAR));

      lstrcpy(wNewComputerName,argv[1]);

      lstrcat(wNewComputerName,L"$");

      CharUpper(wNewComputerName);

      // 
      // Look up the PDC for the target computer.
      // 
      nas = NetGetDCName(
         NULL,
         NULL,
         (LPBYTE *)&wDCName
         );

      if(nas != NERR_Success)
      {
         wprintf(L"NetGetDCName error! (%lu)\n", nas);
         goto cleanup;
      }

      wprintf(L"Changing account name on server \\\\%s\n",wDCName);

      // 
      // Windows 2000 implements a new API for changing the computer
      // name. Failure to use this API for a Windows 2000 computer in a
      // Windows 2000 Domain can cause serious problems.
      // 
      // If you do not have the Windows 2000 headers and libraries,
      // comment out this section to avoid linker errors.
      // 
      // 
      GetVersionEx(&OSVersionInfo);

      if(OSVersionInfo.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
      {
         wprintf(L"For Windows 9x, please see the comments section\n");
         goto cleanup;
      }

      if(OSVersionInfo.dwMajorVersion > 4)
      {

         nas = NetRenameMachineInDomain(
            wDCName,             // Do this operation at the DC.
            wNewComputerName,    // New computer name.
            NULL,                // Assume you are the domain admin.
            NULL,                // No password either.
            NETSETUP_ACCT_CREATE // Necessary flag.
            );

         if(nas != NERR_Success)
         {
            wprintf(L"NetRenameMachineInDomain error! (%lu)\n", nas);
            goto cleanup;
         }

         wprintf(L"Computer name changed to %s using
                 NetRenameMachineInDomain()", argv[1]);

         bSuccess = TRUE;

         goto cleanup;

      }

      // 
      // Use uppercase original command line argument
      // without a trailing dollar sign for SetComputerName.
      // 
      if(!SetComputerName(CharUpper(argv[1])))
      {
         wprintf(L"SetComputerName error! (%lu)\n", GetLastError());
         goto cleanup;
      }

      wprintf(L"Computer Name changed locally to %s\n", argv[1]);

      // 
      // Get the local computer name.
      // 
      dwNameSize = (MAX_COMPUTERNAME_LENGTH+3)*sizeof(WCHAR);

      wComputerName = LocalAlloc(LPTR,dwNameSize);

      if(!GetComputerName(wComputerName,&dwNameSize))
      {
         wprintf(L"GetComputerName error! (%lu)\n", GetLastError());
         goto cleanup;
      }

      // 
      // All computer accounts have a trailing $.
      // 
      lstrcat(wComputerName,L"$");

      // 
      // And they need to be uppercase.
      // 
      CharUpper(wComputerName);

      ui_0.usri0_name= wNewComputerName;

      nas = NetUserSetInfo(
         wDCName,         // PDC where the operation will take place.
         wComputerName,   // User name.
         0,               // Information level.
         (LPBYTE)&ui_0,   // New information.
         NULL
         );

      if(nas != NERR_Success)
      {
         wprintf(L"NetUserSetInfo error! (%lu)\n", nas);

         // 
         // Change the local computer name back to what it was originally.
         // 
         lstrcpyn(wComputerName,wComputerName,lstrlen(wComputerName));
         SetComputerName(wComputerName);

         goto cleanup;
      }

      bSuccess = TRUE;

   cleanup:

      if(wDCName != NULL)
      {
         // 
         // A buffer was allocated for the PDC name. Free it.
         // 
         NetApiBufferFree(wDCName);
      }

      if(wComputerName)
         LocalFree(wComputerName);

      if(bSuccess)
         wprintf(L"Reboot your computer now to complete name change!\n");
      else
         wprintf(L"Computer name change operation failed!\n");

      return bSuccess ;

   } 

Additional query words: account rename

Keywords : kbKernBase kbWinOS2000 kbSDKPlatform kbSDKWin32 kbSecurity kbCodeSam
Version : winnt:4.0
Platform : winnt
Issue type : kbhowto


Last Reviewed: October 15, 1999
© 2000 Microsoft Corporation. All rights reserved. Terms of Use.