title: Rename computer and join to domain in one step with PowerShell
body: <p><strong>Goal:</strong> On a computer running Windows Server 2008 R2, use PowerShell 2.0 to:</p>
  
  <ol>
  <li>Rename the computer</li>
  <li>Join the computer to a domain</li>
  </ol>
  
  <p><strong>Condition:</strong> Steps 1 and 2 must be performed together, i.e., without a computer restart between them</p>
  
  <h2>Functions I'm Using</h2>
  
  <p>These are the PowerShell functions I've created for each step.</p>
  
  <h3>Rename Computer</h3>
  
  <p>According to my Internet research, PowerShell 2.0 at one point before release had a built-in cmdlet called <strong>Rename-Computer</strong>, but it was removed for reasons unknown in CTP 3. My version uses WMI.</p>
  
  <pre><code>function Rename-Computer
  {
      param ( [Parameter(Mandatory=$true)][string]$name )
  
      process
      {
          try
          {
              $computer = Get-WmiObject -Class Win32_ComputerSystem
              $result = $computer.Rename($name)
  
              switch($result.ReturnValue)
              {       
                  0 { Write-Host "Success" }
                  5 
                  {
                      Write-Error "You need administrative rights to execute this cmdlet" 
                      exit
                  }
                  default 
                  {
                      Write-Host "Error - return value of " $result.ReturnValue
                      exit
                  }
              }
          }
          catch
          {
              Write-Host "Exception occurred in Rename-Computer " $Error
          }
      }
  }
  </code></pre>
  
  <h3>Join Computer to Domain</h3>
  
  <p>As you can see, this function is really just a wrapper for the built-in cmdlet <strong>Add-Computer</strong> that gathers the domain name and creates some credentials to use. </p>
  
  <pre><code>function Join-ComputerToDomain
  {
      param ( [Parameter(Mandatory=$true)][string]$domain )
  
      process
      {
          try
          {
              $_domainCredential = $Host.UI.PromptForCredential("Enter domain credentials", "Enter domain credentials to be used when joining computer to the domain", "", "NetBiosUserName")
              Add-Computer -DomainName $_domain -cred $_domainCredential
          }
          catch
          {
              Write-Error "Exception occurred in Join-ComputerToDomain " $Error
          }
      }
  }
  </code></pre>
  
  <h2>Steps I've Tried</h2>
  
  <h3>Attempt 1</h3>
  
  <ol>
  <li>Call <strong>Rename-Computer</strong></li>
  <li>Call <strong>Join-ComputerToDomain</strong></li>
  <li>Restart</li>
  </ol>
  
  <p><strong>Result:</strong> Output from Rename-Computer indicates that name was changed, but after restart, name <strong>did not</strong> change, but computer <strong>was</strong> joined to domain</p>
  
  <h3>Attempt 2</h3>
  
  <ol>
  <li>Call <strong>Join-ComputerToDomain</strong></li>
  <li>Call <strong>Rename-Computer</strong></li>
  <li>Restart</li>
  </ol>
  
  <p><strong>Result:</strong> Return value from Rename-Computer is 1326 (Logon failure: unknown user name or bad password). I assume this is because domain credentials are required for the rename once it's joined to the domain. I attempted to use credentials with the Get-WmiObject call in Rename-Computer, but it threw an error about not being able to use different credentials on the local system. </p>
  
  <h3>Attempt 3</h3>
  
  <ol>
  <li>Call <strong>Rename-Computer</strong></li>
  <li>Restart</li>
  <li>Call <strong>Join-ComputerToDomain</strong></li>
  <li>Restart</li>
  </ol>
  
  <p><strong>Result:</strong> Everything works as expected, but extra restart required. Works but I want to eliminate the restart at step 2. </p>