VMware Horizon Community
davebaker87
Enthusiast
Enthusiast

Hybrid AD Join as a DEM startup task on Instant clones

We're running a federated environment and need to hybrid AD join our instant clone machines. I've recently moved a customer to DEM (from Appsense). Appsense had the ability to run commands in the SYSTEM context and this worked perfectly for instant clones because it was possible to run dsregcmd /join twice , once at startup, and once at user logon. This was a desired state because each device ID was unique to the clone, and the user PRT was issued correctly. 

I have seen many threads describing the problem where the clones are joined '70% of the time' or some fail - this is probably because the clones are joining, but are using the same device ID as the template account - and this eventually breaks something in azure...

I am testing using DEM startup tasks to run dsregcmd and finding that , despite configuring the local gpo settings on the image (startup and shutdown scripts pointing to c:\program files\immidio\flex profiles\flexengine.exe and -startuptasks/-shutdowntasks) and setting a Startup task of:

cmd.exe "/c dsregcmd.exe /join" 

The template VM is being joined to azure, and not the child VM's. 

Does anybody know if it's possible to view logging for a startup tasks in DEM? Also, has anybody else achieved hybrid AD join using DEM ?

 

Reply
0 Kudos
15 Replies
anil_agarwal
VMware Employee
VMware Employee

If you enable DEBUG level logging, you can see all log messages related to launching of the tasks, condition match as well as if timeout occurred on these tasks. You would also get windows event logs for launching tasks. But, DEM logs provide more details. It would be good to find out whether these tasks ran to completion or were terminated because of some issues such as windows timeout policy.

davebaker87
Enthusiast
Enthusiast

Thanks for coming back to me - I have enabled debug logging (using FlexDebug.txt file) and checked  Flexengine.log and -asyn.log but the computer startup tasks are not listed there?

Tags (1)
Reply
0 Kudos
Bickity
Contributor
Contributor

We ran across the same issue when updating our base image to 20h2. What we found was that you need to delete the scheduled task that performs the hybrid join from your base image, so that when the template joins AD it won't hybrid join Azure. In Task Scheduler - \Microsoft\Windows\Workplace Join\Automatic-Device-Join. We took an export of the task, and we import it back once the clone has gotten its proper name on the domain. I know you asked if anyone had accomplished this in DEM, but we are not using DEM to perform this action. But I think this will help get you there.

Reply
0 Kudos
davebaker87
Enthusiast
Enthusiast

Thanks for that - I have tried deleting the scheduled task (but not re-importing it?). Instead, I created my own Scheduled Task that runs dsregcmd.exe /join during Startup but it's not clear if this is running or not.

At what point in the logon sequence do you reimport/recreate the scheduled task, and what triggers do you configure for it?

Reply
0 Kudos
Bickity
Contributor
Contributor

We put the task back during the provisioning phase of the clone, so its there before a user logs on. We are just waiting for the machine name to change from the template name, to the actual machine name we have set on our pools. We do all of this through a powershell script that does quite a bit of customization during the provisioning of the clone, and we do not start the Horizon agent until it is all complete.

Reply
0 Kudos
davebaker87
Enthusiast
Enthusiast

I see - so you shift the join process to the Post-Synchronization script , and presumably Post-Synchronization settings run after the child VM has been forked and it has a hostname? Maybe I need to look into this. Do you use psexec to run the task as system or re-import the task?

Reply
0 Kudos
domdsouza
Enthusiast
Enthusiast

I have a custom powershell script that gets called on machine startup via a scheduled task. The scheduled task is configured to run as SYSTEM. All this does is check to see if the machine name matches a certain criteria (based on your naming scheme). Once it meets that criteria only then it launches the initializevdi script.

ComputerStartup Script

$computername = [System.Environment]::MachineName

if((Get-WmiObject -Class Win32_ComputerSystem).PartofDomain)
{
if($computername -match "vdi")
 {
   Start-Process -FilePath $InitializeVDI -ArgumentList "optional arguments"
 }
}

 

InitializeVDI script
#Other initialization tasks 
#Inject SCP values if not present in the AD schema
$tenantId = "<guid>"
$tenantName = "company.com"
New-Item -Path HKLM:\Software\Microsoft\Windows\CurrentVersion\CDJ -Name AAD -Force
Set-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\CDJ\AAD -Name TenantId -Value $tenantId
Set-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\CDJ\AAD -Name TenantName -Value $tenantName
#Re-create scheduled task
Invoke-Command -scriptblock {
  cmd.exe /c "C:\<FolderPath>\CreateSchtask.cmd"
} -computername .
#Start Horizon Agent Service
Set-Service -Name "WSNM" -StartupType Automatic
Start-Service -Name "WSNM"
#End script

 

CreateSchtask.cmd
"C:\Windows\System32\schtasks.exe" /create /xml c:\<FolderPath>\Automatic-Device-Join.xml /TN "\Microsoft\Windows\Workplace Join\Automatic-Device-Join" >> C:\<FolderPath>\crtask.log

davebaker87
Enthusiast
Enthusiast

Thank you so much dude - your input re. using post-sync script to perform the /join process has fixed it for me. Love these forums..

So here's the fix I've implemented on an instant clone pool:

1/ Delete the Workplace-Join task that auto-joins the user to AAD.

2/ Create a .bat file with the following:

cd c:\windows\system32\ 

dsregcmd.exe /leave

sleep 10

dsregcmd /join

3/ Put the .bat file in master image and reference it as the post Synchronization script in the pool settings.

With this in place, all the child VM's join azure and at each user logon a PRT token is issued correctly. I suspect you could expand on this and add a shutdown task to perform a dsregcmd /leave - but this isn't supported by microsoft and isn't necessary either. We have all our VM's living in azure from the point they are created in the pool and this seems to work fine.

Again, thank you for taking the time to reply to me, you've saved me many hours of pain.

Tags (1)
davebaker87
Enthusiast
Enthusiast

I spoke too soon on this - it turns out this is not working reliably at all when ran as a post-sync script - in larger pools (more than 100 VM's) I'm seeing them sit in a customizing state , then either Error state (with no error output) or Error 'failed to execute post synchronization - waited 55 seconds'.

I have adjusted the post sync script to the following:

c:\windows\system32\dsregcmd.exe /join

gpupdate /force

It seems relatively stable in smaller pools and the machines rebuild (albeit a bit slower than before) - but it's causing all kinds of error/hung machines in our prod pools. I've changed the default ExecTimeout value on the master image from the default of 20 second, to 40 seconds, but this doesn't seem to have made much difference. I'm wondering if the .bat file needs to have a timeout of some sort, or perhaps as the other posts suggest there is a timing issue where the child vm doesn't have it's hostname or IP at the time post-sync is running (is this possible?)

Reply
0 Kudos
domdsouza
Enthusiast
Enthusiast

Timing and state of the machine is everything. Which is why I had it in a powershell checking name and if it's joined to the domain before attempting anything AAD related.

On another note, I do think the dsregcmd has a bug of some sort. MS claims to have fixed it with 20H2, but everything that they claimed to have fixed didn't happen to us with 1809, but we now see it in 20H2. 

Releasing Windows 10 Build 19042.962 (20H2) to Release Preview Channel | Windows Insider Blog

 

Reply
0 Kudos
domdsouza
Enthusiast
Enthusiast

Also, if you don't have the scheduled task that was deleted, you will get tons of these warning messages in the "User Device Registration" event viewer folder.

Failed to enable task \Microsoft\Windows\Workplace Join\Automatic-Device-Join. Error: The system cannot find the file specified.

Reply
0 Kudos
blue_calx
Enthusiast
Enthusiast

Why join the gold image to the domain? I thought it was best practice not to

Tags (1)
Reply
0 Kudos
domdsouza
Enthusiast
Enthusiast

Correct. Gold image should not be joined to the domain. Hence all the customizations to join after it's published to a pool.

Reply
0 Kudos
davebaker87
Enthusiast
Enthusiast

I hear you - I've now left site so the customer needs to implement trusted locations and turn off the conditional access policy that enforces hybrid ad join for all VM's. I cannot understand why they enabled it in the first place...

I've had to leave them with a half baked solution, oh well.

Reply
0 Kudos
normeyj
Contributor
Contributor

With the powershell startup script for the name seems not to be working for me.   Is this two seperate scripts Dom?

Reply
0 Kudos