Generally we recommend not to join any Cameyo servers into an Active Directory domain. However, sometimes it is necessary to do so.
This guide explains how to prepare the master server to successfully join elastic servers.
Good to know:
Every server is created from the master and therefore has the same name as the master and also the same SID.
The process needs multiple reboots (and therefore some time)
The process needs a third party product SIDCHG that needs to be purchased (trial available)
The master server MUST NOT be joined to the domain
Steps:
Create a user in your Active Directory that only has rights to join a machine to the domain, nothing else
Get the MAC address of the master server
PS >Get-NetAdapterGet the DNS server IP
Install PSTools into C:\Tools\PSTools (C:\Tools\PSTools\PsExec.exe is required)
Install SIDCHG into C:\ProgramData\Cameyo (C:\ProgramData\Cameyo\sidchg64.exe is required)
Purchase a license for SIDCHG or get the trial key for testing
On the master server create a new PowerShell script in C:\ProgramData\Cameyo with the name StartupRegisterJoin.ps1 and add the following content to it:
$user = "<domain>\<username>" $pass = "<password>" $domain = "<FQDN>" $joinOU = "<ADFullOUPath>" $masterMAC = "<MacAddressOfMaster" $DNSserver = "<DNSServerIPAddress>" $SIDCHGLicense = "<SIDCHGLicenseKey>" $envir = (dir env:) | Out-String New-EventLog -LogName "Cameyo" -Source "StartupRegisterJoin" -ErrorAction SilentlyContinue $cred = New-Object System.Management.Automation.PSCredential -ArgumentList ($user, ($pass | ConvertTo-SecureString -AsPlainText -Force)) #$suffix = (Get-NetAdapter | Where Status -eq Up)[0].MacAddress.Split("-")[3..6] -join "" $hostname = $env:CAMEYO_SERVERNAME if (-not (gwmi win32_computersystem).PartOfDomain -and (Get-NetAdapter).MacAddress -ne $masterMAC) { Write-EventLog -LogName "Cameyo" -Source "StartupRegisterJoin" -Message "Starting RegisterJoin" -EventId 0 -EntryType Information Write-EventLog -LogName "Cameyo" -Source "StartupRegisterJoin" -Message ("User: "+($env:USERNAME)+"`n`nEnvironment Variables:"+($envir)) -EventId 1 -EntryType Information if ($hostname -ne $env:COMPUTERNAME) { # Stage 1 Write-EventLog -LogName "Cameyo" -Source "StartupRegisterJoin" -Message "Created hostname '$hostname' ($env:CAMEYO_SERVERNAME)" -EventId 2 -EntryType Information Write-EventLog -LogName "Cameyo" -Source "StartupRegisterJoin" -Message "Stopping Cameyo service" -EventId 3 -EntryType Information Stop-Service RapStartSvc -ErrorAction SilentlyContinue Write-EventLog -LogName "Cameyo" -Source "StartupRegisterJoin" -Message "Setting TrustedHosts to '$domain'" -EventId 4 -EntryType Information Set-Item WSMan:\localhost\Client\TrustedHosts -Value $domain -Force $ifindex = (Get-NetAdapter).ifIndex Write-EventLog -LogName "Cameyo" -Source "StartupRegisterJoin" -Message "Setting DNS Server to $DNSserver (IF:$ifindex)" -EventId 5 -EntryType Information Set-DnsClientServerAddress -InterfaceIndex $ifindex -ServerAddresses ($DNSserver) Write-EventLog -LogName "Cameyo" -Source "StartupRegisterJoin" -Message "Rename Computer to $host" -EventId 6 -EntryType Information Rename-Computer $hostname Write-EventLog -LogName "Cameyo" -Source "StartupRegisterJoin" -Message "Running SIDCHG64... and reboot" -EventId 7 -EntryType Information &"$env:ProgramData\Cameyo\sidchg64.exe" /F /R /KEY=$SIDCHGLicense Sleep -Seconds 60 Restart-Computer } else { # Stage 2 Write-EventLog -LogName "Cameyo" -Source "StartupRegisterJoin" -Message "Set Cameyo service to automatic" -EventId 8 -EntryType Information Set-Service RapStartSvc -StartupType Automatic Write-EventLog -LogName "Cameyo" -Source "StartupRegisterJoin" -Message "Join computer '$hostname' to domain '$domain'" -EventId 9 -EntryType Information Add-Computer -DomainName $domain -Restart -Credential $cred -OUPath $JoinOU } } else { if ((gwmi win32_computersystem).PartOfDomain -and $hostname -eq $env:COMPUTERNAME) { # Stage 3 Write-EventLog -LogName "Cameyo" -Source "StartupRegisterJoin" -Message "Add domain users to local Remote Desktop Users group" -EventId 10 -EntryType Information &C:\Tools\PSTools\PsExec.exe -accepteula -nobanner -s -d -i -u $user -p $pass -c net.exe localgroup "Remote Desktop Users" "$domain\Domain Users" /add Write-EventLog -LogName "Cameyo" -Source "StartupRegisterJoin" -Message "Unregister scheduled task" -EventId 11 -EntryType Information Unregister-ScheduledTask -TaskName "Cameyo StartupRegisterJoin" -Confirm:$false Write-EventLog -LogName "Cameyo" -Source "StartupRegisterJoin" -Message "Removing script" -EventId 12 -EntryType Information Remove-Item -Path "$env:ProgramData\Cameyo\StartupRegisterJoin.ps1" } else { # Master Write-EventLog -LogName "Cameyo" -Source "StartupRegisterJoin" -Message "Running on master therefore not doing anything" -EventId 9999 -EntryType Information } }
Change the variables at the top of the script accordingly
Example:$user = "ELASTIC\JoinUser" $pass = "ygHuBbYd5CYlSfhRFFmw" $domain = "elastic.local" $joinOU = "OU=uswest2,OU=Cameyo servers,DC=elastic,DC=local" $masterMAC = "00-0D-2D-24-67-21" $DNSserver = "10.0.0.4" $SIDCHGLicense = "7qrd3-Kj#Zx-iC5dn-eZ"
Run the following script (with elevated rights) on the master server to create a scheduled task to run the join script above:
$taskname = "Cameyo StartupRegisterJoin" $action = New-ScheduledTaskAction -Execute "PowerShell.exe" -Argument "-File ""$env:ProgramData\Cameyo\StartupRegisterJoin.ps1""" $trigger = New-ScheduledTaskTrigger -AtStartup $sysuser = "SYSTEM" $settings = New-ScheduledTaskSettingsSet Register-ScheduledTask -User "SYSTEM" -Action $action -TaskName $taskName -Trigger $trigger -RunLevel Highest
Go to the elastic cluster and configure one idle reserver instance:
This is needed to prevent users from have failed sessions, because the creation of a new server takes so long that a session would run into a timeout if the server doesn’t already existAlso on the elastic cluster set the the following PowerTag:
!SHORTNAMEPATTERN=yourcompanyname-app%randnum%
Make sure the name doesn’t exceed 15 characters as this is the limit of hostname (by Microsoft)
The elastic server will get that name as Windows hostname as well as the DNS hostname (.cameyo.net)!
With the above steps your automatically created machines will be joined to the domain, however they won’t be ever deleted from the domain.
Cleanup:
The following script gets the servers from the Cameyo API and deletes every machine that isn’t found in the cluster, therefore make sure you create an OU for each cluster and join the machines into that OU:
$clientSecret = "<CameypAPIClientSecret>" $companyId = "<CameyoCompanyId>" $serverGroup = "<ServerGroupId>" $searchBase = "<ADFullOUPath>" $computers = Get-ADComputer -Filter * -SearchBase $searchBase $serverlist = Invoke-RestMethod -Uri ("https://api.cameyo.com/servergroups/$serverGroup/list?clientId=$companyId&clientSecret=$clientSecret") -Method GET -ContentType "application/text; charset=UTF-8" foreach ($computer in $computers) { $id = $serverlist | where name -Match $computer.Name if ($id) { "Keep $($computer.Name)" } else { "Delete $($computer.Name)" #Remove-ADComputer $computer.Name } }
For safety reasons the Remove-ADComputer command has been commented out to not accidentally delete machines. It needs to be un-commented.
The password for the join user will be in clear text in the joining script, however, we delete the script after joining, so that it’s not accessible/visible on an elastic server