I ran into an interesting problem today. Basically, a whole bunch of machine accounts got deleted from a domain. Because the machine accounts where spread across numerous OUs, the sheer numbers delete accounts, and the duration between deletion and realization, doing some type of restore would have proved interesting. So... the question was posed. How can one remotely make a large number of machines re-join the domain once their accounts have been deleted from the directory?
Naturally, some sort of automation script needed to be employed. Being PowerShell inclined, I knew what I would be using. Thus leaving the real question, how? NetDom came to mind, and I tried it. But, for some reason it seemed to need the machine account to exist in order drop the machine into a workgroup and then back into the domain.
After that failure, I turned to a trust old friend called WMI and two methods named: UnjoinDomainOrWorkgroup and JoinDomainOrWorkgroup. In the end, it worked and for everyone's benefit I have decided to post parts of the resulting script.
***NOTE***
The script requires PowerShell 2.0 CTP2. Also, it was very quick and dirty... normally I clean up my scripts with tons of error handling and such. But, I didn't have time, so be warned.
So, the script in all of its glory (Mind the Formating):
##################################################
# Main
##################################################
#--------------------
# Set Config Vars
#--------------------
$Machine_CSV = "machine_list.csv"
$DomainName = "mydomain"
#--------------------
# Define DataTables
#--------------------
$MachinesTable = new-object System.Data.DataTable
$MachinesTable.TableName = "Machines"
[Void]$MachinesTable.Columns.Add("Name")
[Void]$MachinesTable.Columns.Add("Status")
[Void]$MachinesTable.Columns.Add("UnJoinStatus")
[Void]$MachinesTable.Columns.Add("JoinStatus")
#--------------------
# Get Domain Creds
#--------------------
$DomainCred = Get-Credential
#--------------------
# Define General Trap
#--------------------
trap{write-host $_ -Foregroundcolor Red;
Continue}
$Machine_List = Import-Csv $Machine_CSV
foreach ($Record in $Machine_List){
&{
$MachineName = $($Record.MachinePath).Split(",")
$MachineParentOU = $($Record.MachinePath).SubString($($MachineName[0].Length + 1))
$MachineName = $($MachineName[0].Split("="))[1]
Add-Member -inputObject $Record -membertype noteProperty `
-name "MachineName" -value $MachineName
Write-Host "Checking $($Record.MachineName)" -NoNewline
.{
trap{Continue}
$Ping = new-object Net.NetworkInformation.Ping
$Result = $Ping.Send($Record.MachineName)
}
if ($Result.Status -eq "Success"){
write-host `t "[ONLINE]" -Foregroundcolor Green
Add-Member -inputObject $Record -membertype noteProperty `
-name "Status" -value "Online"
}
else{
write-host `t "[OFFLINE]" -Foregroundcolor Red
Add-Member -inputObject $Record -membertype noteProperty `
-name "Status" -value "Offline"
}
If ($Record.Status -eq "Online"){
$LocalMachineCred = Get-Credential
$BSTR = [System.Runtime.InteropServices.marshal]::SecureStringToBSTR($DomainCred.Password)
$Password = [System.Runtime.InteropServices.marshal]::PtrToStringAuto($BSTR)
$ObjMachine = Get-WMIObject -class "Win32_ComputerSystem" -namespace "root\cimv2" -Computer $Record.MachineName -credential $LocalMachineCred -Authentication 6 -Impersonation 3
$UnJoinStatus = $ObjMachine.UnjoinDomainOrWorkgroup($Null, $Null)
$JoinStatus = $ObjMachine.JoinDomainOrWorkgroup($DomainName, $Password, $($DomainCred.UserName), $MachineParentOU, 3)
}
[Void]$MachinesTable.Rows.Add($Record.MachineName, $Record.Status, $UnJoinStatus.ReturnValue, $JoinStatus.ReturnValue)
}
}
Write-Host
$MachinesTable
Advertisement: |
With more than ten years of experience in IT, Tyson Kopczynski has become a specialist in Active Directory, Information Assurance, Windows automation, PKI, and IT security practices. Tyson is also the founding author of the Windows PowerShell Unleashed series and has been a contributing author for such books as Microsoft Internet Security and Acceleration (ISA) Server 2006 Unleashed and Microsoft Windows Server 2008 Unleashed. He has also written many detailed technical papers and guides covering various technologies. As a consultant at Convergent Computing, Tyson works with and provides feedback for next generation Microsoft technologies since their inception and has also played a key role in expanding the automation and security practices at CCO. Tyson also holds such certifications as the Certified Information Systems Security Professional (CISSP), the SANS Security Essentials Certification (GSEC) and SANS Certified Incident Handler (GCIH), and the MCTS (Application Platform, Active Directory, and Network Infrastructure).
Certifications:
Publications:
Other Stuff:
Post new comment