Greetings,
I saw a thread in the VDM beta forum about this but it was unanswered. This question doesn't just apply to VDM, I guess, but that's what I need this for. Is there any way to customize the OU that the VDM provisioned virtual machine will be created in? Other than pre-creating the virtual machine objects in AD or moving them after?
We need to be able to enforce GPO based on the type of VDI workstation because we will have several pools for different functions. Is there any way to do this automatically?
Thanks in advance.
Yes, this is a major shortcoming in my opinion, and is forcing a bunch of kludge solutions.
As mentioned above, using the sysprep file makes the VDM option to name each host the same as the VM unavailable.
Because of this I am trying to use the Run Once script from the customization wizard.
1) Create your template, and include a script that will move the host to the appropriate ou (and then reboot to ensure that the new group policy for that ou takes effect)
Notes:
-This script is going to have to be run as a domain user that has permissions to move computers between ou's (ie. Account Operator).
-It will also need to have permission to reboot the local computer, so make sure the user is a member of the local admins group or appropriate on the template.
-I use the RunAsSPC (suggested by someone else) program to run the script as a specific domain user. RunAsSpc allows you to encrypt the users password, and also I beleive it does a checksum on the script to make sure it is not changed once you create the "crypt" file. You can then create a shortcut which will call RunAsSpc, and have it run your script with the credentials that you saved in the crypt file.
2) Create your customization specification within Virtual Center. Include all the usual items such as XP license key etc. In the Run Once section, have it login once as the local administrator, and run the shortcut you created in the previous step. This customization spec can then be used in VDM to deploy your desktops, and will call the script you included in your template.
Hey did I mention this was an ugly kludge? I'm using VI 3.0.2 and VC 2.0.2, so maybe they've made the customization wizard better in VC 2.5. All it needs to do is handle the OU change, and we wouldn't have to bother with something ugly like this. Does someone using VC 2.5 know if the customization wizard can perform the OU change (without using a sysprep file)?.
Regards
Justin
Here's the script I'm using (Can't remember where I got most of it):
Option Explicit
Dim strDestOU, strObjToMove, strObjDN, objObjToMove
Dim WshNetwork, objShell, strShutdown
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Set WshNetwork = WScript.CreateObject("WScript.Network")
'******************************************************
'* Specify OU for computer object to be moved to here!!
'******************************************************
strDestOU = "OU=Non-Persistent,OU=VDI,OU=Workstations,DC=company,dc=com"
strObjToMove = WshNetwork.ComputerName & "$" 'Append $ - Needed for computer objects
strObjDN = GetObjDN(strObjToMove, "computer")
If strObjDN <> "" Then
Set objObjToMove = GetObject("LDAP://" & strObjDN)
Call MoveUserToOU(strObjDN, strDestOU)
Else
WScript.Echo "Can't find object in AD: " & strObjToMove
End If
'* The following will initiate a reboot after 10 seconds
'*******************************************************
strShutdown = "shutdown -r -t 30"
'NOTE: Rebooting too quickly does not give the Virtual Desktop Agent enough time to communicate with the VDM server
set objShell = CreateObject("WScript.Shell")
objShell.Run strShutdown
WScript.Quit
'****************************************************************************************
'****************************************************************************************
Function MoveUserToOU(strUserDN, strDestOU)
'Moves a user to a new OU
'Just pass the DNs of the target OU and the user object
Dim objOU
Set objOU = GetObject("LDAP://" & strDestOU)
objOU.MoveHere "LDAP://" & strUserDN, vbNullString
End Function
Function GetObjDN(sObjShortName, sObjType)
'This function queries AD for a user by SAMAccountName and returns the distinguishedName for it
'(DN is used for LDAP binds...)
Dim sDomainADsPath, sProperties, strCmdTxt
Dim sUser, sPassword
Dim oCon, oCmd, oRecordSet
Dim intRecordCount
sDomainADsPath = "LDAP://" & ADRoot
Set oCon = CreateObject("ADODB.Connection")
oCon.Provider = "ADsDSOObject"
oCon.Open "ADProvider", sUser, sPassword
Set oCmd = CreateObject("ADODB.Command")
Set oCmd.ActiveConnection = oCon
sProperties = "distinguishedname"
strCmdTxt = "<" & sDomainADsPath & ">;(&(objectCategory=" & sObjType & ")(SamAccountName=" & sObjShortName & "));" & sProperties & ";subtree"
oCmd.CommandText = strCmdTxt
oCmd.Properties("Page Size") = 100
On Error Resume Next
Set oRecordSet = oCmd.Execute
On Error goto 0
intRecordCount = oRecordSet.RecordCount
If intRecordCount = 1 Then
oRecordSet.MoveFirst
While Not oRecordSet.EOF
Dim strObjDN, arrObjDN, strDNPart, intDNPart, intOUDNEntry
'Get the object's distinguishedname
strObjDN = oRecordSet.Fields("distinguishedname")
oRecordSet.MoveNext
Wend
GetObjDN = strObjDN
Else
WScript.Echo "ERROR: Expected exactly 1 record from AD. Records received = " & oRecordSet.RecordCount
'GetObjDN = False
End If
End Function ' End of GetObjDN Function
Function ADRoot()
Dim oRootDSE
On Error Resume Next
Set oRootDSE = GetObject("LDAP://RootDSE")
'If Err.Number <> 0 Then
'ADRoot = "DC=DS,DC=AD,DC=SSMHC,DC=com"
'Else
ADRoot = oRootDSE.Get("defaultNamingContext")
'End If
End Function
Hi
We had the same issue here. We solved it using the customization spezification with sysprep functionality to add the VM`s to a specific OU.
1st step:create a sysprep customization spezification on your VC, like the one below.
;SetupMgrTag
OemSkipEula=Yes
InstallFilesPath=C:\sysprep\i386
AdminPassword=*
EncryptedAdminPassword=NO
OEMSkipRegional=1
TimeZone=110
OemSkipWelcome=1
ProductKey="Your Produkt License Ke]"
FullName="Fullname for VMXP"
OrgName="ORG Name"
ComputerName=*
CountryCode=41
LanguageGroup=1 <--your regional settings
SystemLocale=00000807 <--your regional settings
UserLocale=00000807 <--your regional settings
InputLocale=0807:00000807 <--your regional settings
DistFolder=C:\sysprep\i386
DistShare=windist
DomainAdmin="User with rights to add Computer to Domain"
DomainAdminPassword=xxxxxxxx
MachineObjectOU="OU=,OU=,DC=Company,DC=com" <--This is the important part! The OU's and domain need to be correctly set!!
InstallDefaultComponents=Yes
2nd step:
Delete the entries in the following reg keys on the Template before using it for your pool's, so the computername will be created properly.
"RegisteredOrganization"="ORG"
"RegisteredOwner"="USER"
delete only the entries "ORG" and "USER" and not the key itself!!!
3rd Step:
Leave the Administrators account password the Template blank
hope that helps.
greetings Sergio
If you use the sysprep.inf file, you can't use VDM to rename the VM's during the pools provisioning phase. The sysprep file allows you only to store one hostname in it. If you use a * instead, the sysprep process adds a random Hostname for each machine....
There is another way to add the VM to a OU using a script, executed by the runonce function during the customization process.
Chris
Yes, this is a major shortcoming in my opinion, and is forcing a bunch of kludge solutions.
As mentioned above, using the sysprep file makes the VDM option to name each host the same as the VM unavailable.
Because of this I am trying to use the Run Once script from the customization wizard.
1) Create your template, and include a script that will move the host to the appropriate ou (and then reboot to ensure that the new group policy for that ou takes effect)
Notes:
-This script is going to have to be run as a domain user that has permissions to move computers between ou's (ie. Account Operator).
-It will also need to have permission to reboot the local computer, so make sure the user is a member of the local admins group or appropriate on the template.
-I use the RunAsSPC (suggested by someone else) program to run the script as a specific domain user. RunAsSpc allows you to encrypt the users password, and also I beleive it does a checksum on the script to make sure it is not changed once you create the "crypt" file. You can then create a shortcut which will call RunAsSpc, and have it run your script with the credentials that you saved in the crypt file.
2) Create your customization specification within Virtual Center. Include all the usual items such as XP license key etc. In the Run Once section, have it login once as the local administrator, and run the shortcut you created in the previous step. This customization spec can then be used in VDM to deploy your desktops, and will call the script you included in your template.
Hey did I mention this was an ugly kludge? I'm using VI 3.0.2 and VC 2.0.2, so maybe they've made the customization wizard better in VC 2.5. All it needs to do is handle the OU change, and we wouldn't have to bother with something ugly like this. Does someone using VC 2.5 know if the customization wizard can perform the OU change (without using a sysprep file)?.
Regards
Justin
Here's the script I'm using (Can't remember where I got most of it):
Option Explicit
Dim strDestOU, strObjToMove, strObjDN, objObjToMove
Dim WshNetwork, objShell, strShutdown
Const ForReading = 1, ForWriting = 2, ForAppending = 8
Set WshNetwork = WScript.CreateObject("WScript.Network")
'******************************************************
'* Specify OU for computer object to be moved to here!!
'******************************************************
strDestOU = "OU=Non-Persistent,OU=VDI,OU=Workstations,DC=company,dc=com"
strObjToMove = WshNetwork.ComputerName & "$" 'Append $ - Needed for computer objects
strObjDN = GetObjDN(strObjToMove, "computer")
If strObjDN <> "" Then
Set objObjToMove = GetObject("LDAP://" & strObjDN)
Call MoveUserToOU(strObjDN, strDestOU)
Else
WScript.Echo "Can't find object in AD: " & strObjToMove
End If
'* The following will initiate a reboot after 10 seconds
'*******************************************************
strShutdown = "shutdown -r -t 30"
'NOTE: Rebooting too quickly does not give the Virtual Desktop Agent enough time to communicate with the VDM server
set objShell = CreateObject("WScript.Shell")
objShell.Run strShutdown
WScript.Quit
'****************************************************************************************
'****************************************************************************************
Function MoveUserToOU(strUserDN, strDestOU)
'Moves a user to a new OU
'Just pass the DNs of the target OU and the user object
Dim objOU
Set objOU = GetObject("LDAP://" & strDestOU)
objOU.MoveHere "LDAP://" & strUserDN, vbNullString
End Function
Function GetObjDN(sObjShortName, sObjType)
'This function queries AD for a user by SAMAccountName and returns the distinguishedName for it
'(DN is used for LDAP binds...)
Dim sDomainADsPath, sProperties, strCmdTxt
Dim sUser, sPassword
Dim oCon, oCmd, oRecordSet
Dim intRecordCount
sDomainADsPath = "LDAP://" & ADRoot
Set oCon = CreateObject("ADODB.Connection")
oCon.Provider = "ADsDSOObject"
oCon.Open "ADProvider", sUser, sPassword
Set oCmd = CreateObject("ADODB.Command")
Set oCmd.ActiveConnection = oCon
sProperties = "distinguishedname"
strCmdTxt = "<" & sDomainADsPath & ">;(&(objectCategory=" & sObjType & ")(SamAccountName=" & sObjShortName & "));" & sProperties & ";subtree"
oCmd.CommandText = strCmdTxt
oCmd.Properties("Page Size") = 100
On Error Resume Next
Set oRecordSet = oCmd.Execute
On Error goto 0
intRecordCount = oRecordSet.RecordCount
If intRecordCount = 1 Then
oRecordSet.MoveFirst
While Not oRecordSet.EOF
Dim strObjDN, arrObjDN, strDNPart, intDNPart, intOUDNEntry
'Get the object's distinguishedname
strObjDN = oRecordSet.Fields("distinguishedname")
oRecordSet.MoveNext
Wend
GetObjDN = strObjDN
Else
WScript.Echo "ERROR: Expected exactly 1 record from AD. Records received = " & oRecordSet.RecordCount
'GetObjDN = False
End If
End Function ' End of GetObjDN Function
Function ADRoot()
Dim oRootDSE
On Error Resume Next
Set oRootDSE = GetObject("LDAP://RootDSE")
'If Err.Number <> 0 Then
'ADRoot = "DC=DS,DC=AD,DC=SSMHC,DC=com"
'Else
ADRoot = oRootDSE.Get("defaultNamingContext")
'End If
End Function
No, they haven't made it any better in 2.5. It looks pretty much exactly the same. The one really nice thing they did in 2.5 (useful for deploying servers from templates) is the ability to specify all of the network settings (for a static IP like most servers would have) and have it prompt you just for the IP address when you create the VM. That way there's no more "edit this customization before proceeding" nonsense to fix the NIC settings.
Thanks a lot for your response. I'll do it that way until they fix the wizard to allow OU selection (and it seems like it would be such an easy thing for them to do..)
Here's the script I'm running
netdom join %computername% /domain:mydom /ud:administrator /pd:password /ou:ou=vdm,ou=wks,dc=mydom,dc=local /reboot:10
Then I delete the script so the password's not sitting around in clear text. It seems to be working for me so far.
Keep all the VDI computer objects in the Computer OU. (default behaviour)
Using GPMC:
Create a GPO at the Domain level that will apply the settings you want.
Create a WMI Filter to filter objects based on Computer name prefix
Link the WMI filter to the GPO
Here is the WMI query:
Select * From Win32_ComputerSystem Where Name LIKE 'VDM%'
This should catch any computers that start with VDM, you can change VDM to whatever your naming prefix is.
For Different Pools, use a different prefix and create corresponding GPO and WMI filters.
Damn, shawneve, why didn't I think of that?
Well, if I had answer points left I'd give some to you. Next time my friend!
Just a note about my previous post using a VBscript to move the VDI from one ou to another once it was already joined to the Domain.
I have found this method to be problematic, and to fail about 20% of the time. I believe the problem is due to AD repliaction. The Virtual Center customization joins the VDI to the domain, reboots, and then the logon once functionality tries to run the ou move script. However, after the reboot, the VDI may authenticate to a different domain controller that has not yet been updated with the computer account. This causes the ou move script to fail becasue it can not look up the computers DN in AD.
So, I tried using the much more elegant netdom method (posted previously) which does the domain join, and ou move in one step. I have found it to work reliably, and is also much simpler.
Thanks
Justin
If I add a * as the computer name in the customization script, the machine wont deploy from the template complaining about machine name. Where is the customization script stored - I'll see if I can modify it manually.
See http://communities.vmware.com/message/959184#959184
This can be done elegantly with a single line runonce command that uses dsmove.exe and shutdown.exe.
This is the simplest and straight forward method to use, a quick notes though to help the process.
Most of you will be aware of this, but to help those that are not netdom.exe is not part of a standard XP build so be sure to get a copy onto the template before you ask VDI to deploy it.
You can find netdom as well as other useful tools at http://www.microsoft.com/downloads/details.aspx?FamilyId=6EC50B78-8BE1-4E81-B3BE-4E7AC4F0912D&displa...
For details on how to use netdom.exe go here: http://technet.microsoft.com/en-us/library/cc772217(WS.10).aspx
Ah and my reason for posting to this old thread... This is still necessary in VMware View 4.