Skip to content

Instantly share code, notes, and snippets.

@mattmcnabb
Last active February 18, 2018 23:11
Show Gist options
  • Save mattmcnabb/4ef60b7e42841f60b5da to your computer and use it in GitHub Desktop.
Save mattmcnabb/4ef60b7e42841f60b5da to your computer and use it in GitHub Desktop.
Rejoin a Computer to a Domain - Dance Remix
<#
.SYNOPSIS
This script disjoins a computer from an Active Directory domain, performs a reboot and upon coming back up
joins it to the domain again and performs another reboot.
.NOTES
Requirements: You must have local admin rights on the remote computer to connect to the remote computer
.PARAMETER Computername
The name of the computer to rejoin to a domain
.PARAMETER DomainName
The NetBIOS or FQDN of the domain to rejoin the computer to
.PARAMETER UnjoinLocalCredentialXmlFilePath
If you'd rather not input a username and password every time for the local username and password to the remote
computer, you can specify the XML path of the XML file you created that stores the credential set. This will use
a credential object to use as credentials to disjoin from the domain
.PARAMETER JoinDomainCredentialXmlFilePath
If you'd rather not input a username and password every time for the domain username and password to the remote
computer, you can specify the XML path of the XML file you created that stores the credential set. This will use
a credential object to use as credentials to join the computer back from the domain.
#>
[CmdletBinding()]
param (
[Parameter(Mandatory,
ValueFromPipeline,
ValueFromPipelineByPropertyName)]
[string[]]$Computername,
[Parameter(Mandatory)]
[string]$DomainName,
[Parameter(Mandatory)]
[string]$UnjoinLocalCredentialXmlFilePath,
[Parameter(Mandatory)]
[string]$DomainCredentialXmlFilePath
)
begin {
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::Stop
Function Test-Ping ($ComputerName) {
$Result = ping $Computername -n 2
if ($Result | where { $_ -match 'Reply from ' }) {
$true
} else {
$false
}
}
function Test-DomainTrust ($Computername) {
$Result = netdom verify $Computername /Domain:$DomainName
if ($Result -match 'command completed successfully') {
$true
} else {
$false
}
}
function Wait-Reboot ($Computername,$Credential) {
while (Test-Ping -ComputerName $Computername) {
Write-Verbose "Waiting for $Computername to go offline..."
Start-Sleep -Seconds 1
}
Write-Verbose "The computer $Computername has went down for a reboot. Waiting for it to come back up..."
while (!(Test-Ping -ComputerName $Computername)) {
Start-Sleep -Seconds 5
Write-Verbose "Waiting for $Computername to come back online"
}
Write-Verbose "The computer $Computername has come online. Waiting for OS to initialize"
$EapBefore = $ErrorActionPreference
$ErrorActionPreference = [System.Management.Automation.ActionPreference]::SilentlyContinue
while (!(Get-WmiObject -ComputerName $Computername -Class Win32_OperatingSystem -Credential $Credential)) {
Start-Sleep -Seconds 5
Write-Verbose "Waiting for OS to initialize..."
}
$ErrorActionPreference = $EapBefore
## Import the XML files to create the PSCredential objects
# EDIT moved this into BEGIN since we don't need to create the creds for
# each pipeline object
$LocalCredential = (Import-CliXml -Path $UnjoinLocalCredentialXmlFilePath)
$DomainCredential = (Import-CliXml -Path $DomainCredentialXmlFilePath)
}
}
process {
foreach ($Computer in $Computername) {
try {
if (Test-Ping -ComputerName $Computer) { ## if the remote computer can be pinged
Write-Verbose "The computer '$Computer' is online"
Write-Verbose "Removing computer from domain and forcing restart"
Remove-Computer -ComputerName $Computer -LocalCredential $LocalCredential -UnjoinDomainCredential $DomainCredential -Workgroup TempWorkgroup -Restart -Force
Write-Verbose "The computer has been removed from domain. Waiting for a reboot."
Wait-Reboot -Computername $Computer -Credential $LocalCredential
Write-Verbose "The computer $Computer has been rebooted. Attempting to rejoin to domain."
Add-Computer -ComputerName $Computer -DomainName $DomainName -Credential $DomainCredential -LocalCredential $LocalCredential -Restart -Force
Write-Verbose "The computer $Computer has been rejoined to domain. Waiting for the final reboot"
Wait-Reboot -Computername $Computer -Credential $DomainCredential
Write-Verbose "The computer $Computer has been successfully rejoined to the domain $DomainName"
[pscustomobject]@{ 'Computername' = $Computer; 'Result' = $true }
} else {
throw "The computer '$Computer' is offline or name cannot be resolved"
}
} catch {
[pscustomobject]@{ 'Computername' = $Computer; 'Result' = $false; 'Error' = $_.Exception.Message }
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment