Link to home
Start Free TrialLog in
Avatar of higgins8529
higgins8529

asked on

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

Avatar of Ciprian Lozonschi
Ciprian Lozonschi
Flag of Czechia image

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".
Avatar of higgins8529
higgins8529

ASKER

It would only be one computer at a time. Would you be able to provide the exact syntax that I would need to use?
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.
This is for systems running PowerShell v2 so that command will not work.  Any other suggestions?
ASKER CERTIFIED SOLUTION
Avatar of higgins8529
higgins8529

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Resolved on my own