Windows AD Join Script

We are using the attached script to join a newly imaged computer to our domain.  This script queries for the domain, domain admin credentials, new computer name and the old computer the new computer is replacing. It will then query for the OU of the old computer being replaced, rename the new computer and then add it to the domain.  

Occasionally the script will fail to rename the system after is does the join to AD.  Is there a better way to do the rename? I have pasted the script below. Any suggestions you could provide would be greatly appreciated.

<#

.SYNOPSIS
   This script is designed to join a newly imaged computer to the domain.  
.PARAMETER NewVUTag
    The new name of the computer being built.  The name it will use to join the domain. 
.PARAMETER OldVUTag
    The name of the computer being replaced.  
.PARAMETER Domain
    THe Full Qualified Domain Name (FQDN) of the AD Domain 
.PARAMETER DomainAdmin
    The SamAccountName or UPN of the domain administrator account to be used to make domain changes.
.PARAMETER User
    The local user account to add to the administrators group.

#>

[CmdletBinding()]
param(     
	[Parameter(Mandatory=$true)][string]$NewVUTag,     
	[Parameter(Mandatory=$true)][string]$OldVUTag,
	[Parameter(Mandatory=$false)][string]$Domain = "contoso.local",
	[Parameter(Mandatory=$false)][string]$DomainAdmin = "svc_adjoin",
)

Function yyyymmdd{

    $yr = [string](Get-Date).Year
    $mo = [string](Get-Date).Month
    If ($mo.Length -eq 1){$mo = "0$mo"}

    $dd = [string](Get-Date).Day
    If ($dd.Length -eq 1){$dd = "0$dd"}
    $yyyymmdd = $yr + $mo + $dd

    return $yyyymmdd
}

#LogFile
$Filename = yyyymmdd
$Filename = ".\$Filename.log"

$localpath = Split-Path -Parent $MyInvocation.MyCommand.Path
$domainsuffix = "@" + $domain
#if SamAccountName used, change to UPN:
if ( -not ($DomainAdmin.Contains($domainsuffix))){
    $DomainAdmin = $DomainAdmin + "@" + $Domain
}

# Check if script is running as Adminstrator and if not use RunAs
Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - Checking if script is running as Administrator"
$IsAdmin = ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole]"Administrator")
if (-not $IsAdmin){
    Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - The script is NOT running as Administrator, restarting PowerShell as Administrator..."
    $cmd = $MyInvocation.MyCommand.Path + " -NewVUTag $NewVUTag -OldVUTag $OldVUTag -Domain $Domain -DomainAdmin $DomainAdmin -HotFixUrl $HotFixUrl"
    $arguments = "-NoProfile -NoExit -Command ""& {$cmd} """ 
    Start-Process "$psHome\powershell.exe" -Verb Runas -ArgumentList $arguments -WorkingDirectory $localpath -ErrorAction 'stop'
    Break              
}
else{
    Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - The script is already running as Administrator"
}

$password = Read-Host -AsSecureString "Please enter the password for $DomainAdmin"
$domaincreds = New-Object System.Management.Automation.PSCredential($DomainAdmin,$password)
$passwordtext = (New-Object System.Management.Automation.PSCredential 'N/A', $password).GetNetworkCredential().Password

#Check Credentials
$results = $null
$adshare = "\\$domain\NETLOGON"
$a = & net.exe use $adshare /d hg st 2>&1 | Out-Null
$results = & net.exe use $adshare $passwordtext /USER:$DomainAdmin
if ($results -eq $null){
    Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - Authentication failed - please verify your username and password."
    exit #terminate the script.
}
else{
    Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - Successfully authenticated with domain $domain"
    $a = & net.exe use $adshare /d 
}

#Check CPU architecture:
if ($env:Processor_Architecture -eq 'x86' -and (Test-Path env:\PROCESSOR_ARCHITEW6432)){
    Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - Detected WOW layer 64 bit OS running 32 bit process..."
    $hotfix = "Windows6.1-KB958830-x64-RefreshPkg.msu"
}
elseif ($env:Processor_Architecture -eq 'x86'){
    Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - Detected 32 bit OS..."
    $hotfix = "Windows6.1-KB958830-x86-RefreshPkg.msu"
}
elseif ($env:Processor_Architecture -eq 'AMD64'){
    Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - Detected 64 bit OS..."
    $hotfix = "Windows6.1-KB958830-x64-RefreshPkg.msu"
}
else{
    Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - Unable to detect CPU architecure, exiting..."
    break
}

#Enable the features and import the AD Module:
Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - Enabling Active Directory Features in Optional Features"
& dism.exe /Online /Enable-Feature /FeatureName:RemoteServerAdministrationTools  /FeatureName:RemoteServerAdministrationTools-Roles /FeatureName:RemoteServerAdministrationTools-Roles-AD  /FeatureName:RemoteServerAdministrationTools-Roles-AD-Powershell | Out-Null

Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - Importing Active Directory Module..."
Import-Module ActiveDirectory -WarningAction SilentlyContinue
Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - Module succesfully Imported"

#Get old computer's OU
Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - Getting the replacement computer's OU..."
$dn = (Get-ADComputer $OldVUTag -Server $Domain -Credential $domaincreds).DistinguishedName
$ou = $dn.Substring($OldVUTag.Length + 4)
Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - Target OU is $ou ..."

#Make sure there is not an AD Object with the new computer name
$pc = hostname
$dn = $null
$dn = (Get-ADComputer -filter {Name -eq $NewVUTag} -Server $Domain -Credential $domaincreds).DistinguishedName
Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - Checking for existing AD Object with the new computer name: $dn..."
if ($dn -ne $null) {Remove-ADComputer -Identity "$dn" -Server $Domain -Credential $domaincreds -Confirm:$false}
$dn = $null
$dn = (Get-ADComputer -filter {Name -eq $pc} -Server $Domain -Credential $domaincreds).DistinguishedName
Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - Checking for existing AD Object with the image computer name: $dn..."
if ($dn -ne $null) {Remove-ADComputer -Identity "$dn" -Server $Domain -Credential $domaincreds -Confirm:$false}
$dn = $null
$pc = $null
start-sleep 5

#Add to domain
Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - Adding new computer from to domain $Domain..."
Add-Computer -Credential $domaincreds -DomainName $Domain -OUPath $ou
start-sleep 5

#Get Computername and Rename with WMI
Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - Renaming new computer to $NewVUTag..."
$Computer = Get-WmiObject Win32_ComputerSystem
ForEach-Object {$Computer.Rename("$NewVUTag",$domaincreds.GetNetworkCredential().Password,$domaincreds.Username)}

#Add local user account to the administrators group
$group = "Administrators"
$Host.UI.RawUI.ForegroundColor = "Cyan"
do {
    $user = Read-Host "Enter the User ID you wish to grant administrator rights on this PC and press ENTER"
    $query = Read-Host "Entered user is: ""$user""`nIs this correct (yes/no)?"
} while ($query -eq "no")
$pc = hostname
$objUser = [ADSI]("WinNT://vuad/$user") 
$objGroup = [ADSI]("WinNT://$pc/$group") 
$objGroup.PSBase.Invoke("Add",$objUser.PSBase.Path)

$Host.UI.RawUI.ForegroundColor = "Green"
Add-Content -PassThru -Path $Filename "Please confirm REBOOT of the system to complete the changes. Make note of any errors reported above."
 
Restart-Computer -Confirm

Open in new window

higgins8529Asked:
Who is Participating?
 
higgins8529Author Commented:
Issue was caused by a race condition with the sequences of events within the script.
0
 
lciprianionutCommented:
For Add-Computer why don't you use param -NewName (Specifies a new name for the computer in the new domain. This parameter is valid only when one computer is being added or moved.) instead of section "#Get Computername and Rename with WMI".
0
 
higgins8529Author Commented:
It would only be one computer at a time. Would you be able to provide the exact syntax that I would need to use?
0
How do you know if your security is working?

Protecting your business doesn’t have to mean sifting through endless alerts and notifications. With WatchGuard Total Security Suite, you can feel confident that your business is secure, meaning you can get back to the things that have been sitting on your to-do list.

 
lciprianionutCommented:
Something like this:

Add-Content -PassThru -Path $Filename "$(Get-Date -Format s) - Adding new computer to domain $Domain, renaming new computer to $NewVUTag"
Add-Computer -Credential $domaincreds -DomainName $Domain -OUPath $ou -NewName $NewVUTag

And you can comment lines from 133 to 136, and later perhaps remove.
0
 
higgins8529Author Commented:
This is for systems running PowerShell v2 so that command will not work.  Any other suggestions?
0
 
higgins8529Author Commented:
Resolved on my own
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.