Hi Guys and Gals,
Long time no see. Took me some time to move into our new house which had to be decorated with wallpaper, flooring, additional electric and internet wiring etc. So March 2015 will leave a gap in my blog archive, but I’m hoping to compensate this with writing some new articles.
One of them is this one: Put the domain join where it belongs. If you are like me, I like to work with one MDT deploymentshare to rule them all. When looking on social.technet in the MDT forum’s I see many people struggling to combine build and deployment shares together, or shares that have separate settings regarding computer deployment or domain membership.
Now MDT offers four options to create a deploymentshare so flexible you’ll only need one share to truly rule them all:
- The customsettings.ini
- Multiple customsettings.ini
- The MDT Database
- Task Sequence Variables
Allow me to explain each option and the pro’s and con’s:
Customsettings.ini: hey If you can manage it per model, macaddress, tasksequenceid etc. thats fine! But usually you are going to end up with a conflict that either strikes your build deployment or your deploy deployment. Most issues I see here are domainjoin and capture related.
figure 1.1: CustomSettings.ini
Multiple customsettings.ini, you can specify which ini file to process right into your task sequence “gather” step; this makes your deploymentshare more flexible and forces a specific task sequence to use a different ini file for processing then let’s say the default task sequence. Editing the Gather step is an option, but since you’ll have to edit it multiple times in one task sequence, it’s easy overlooked and prone to error when making typo’s
figure 1.2: Multiple customsetttings.ini
If you are planning on changing the gather step’s, then please take into consideration there are four of them in every deployment task sequence:
The first is during Initialization, the second during Preïnstall the third during State Restore and the last one can be found during Imaging
figure 1.3: Configuring different CustomSetting.ini
Then there is the MDT Database, store settings that would otherwise end-up in your customsettings.ini individually based per machine, make and/or model, roles or location, a very good alternative to use but a little bit overpowered when just wanting to make the difference between machines joining a domain or getting captured.
figure 1.4: Using the MDT database integration
figure 1.5: Properties of a MDT database object (A customsetting.ini of your own)
Task Sequence variables, this to me is the most powerful option of all. Let’s say I want to specify a property which may not occur anywhere else, simply put a task sequence variable at the front of your task sequence.
figure 1.6: Using task sequence variables in your task sequence
Just as you would post information about capturing your reference build in the build task sequence, you could do exactly the same for the following values regarding domain joins:
- JoinDomain=contoso
- DomainAdmin=mdt-domainjoin
- DomainAdminDomain=contoso
- DomainAdminPassword=P@$$w0rd
- MachineObjectOU=OU=Computers,OU=Laptops,DC=contoso,DC=local
This prevents machines that are intended to be captured, end up domain joined and machines that are deployed and are domain joined to be captured (which will result in error, since sysprep will not allow a domain joined machine to be generalized for capture).
Hope this helps in gaining insight in how to achieve a more flexible MDT deployment.
Cheers! Rens
Hi Rens,
I’m just getting started with MDT/WDS and so far things are going okay but from what I’ve read on countless pages, there’s no real 1 way to do this… which can be frustrating for someone new! I’ve run into a bit of a scenario that I was hoping you might be of help with (and this page I thought would answer but I’m still confused).
From the method I used, my domain join is in the CustomSettings.ini and it works – good – however I notice that after each reboot of the deployment process after the domain join has occurred, the process stops on our logon banner and I need to click Okay in order to proceed to the next stage. I thought about moving the domain join to the last possible step as a task sequence but then the updates would fail because it wouldn’t know how to reach the wsus server (hostname).
Is there a way to suppress the OKAY click during the deployment? Or maybe there’s a better way to do this.
I’m going to read over your post again as it was a bit confusing at first…
Thanks!
Hi Marc,
If I understand you correctly you have configured a GPO that is linked to the organizational unit where the machine resides under, that set’s a logon message between logging in and entering the user credentials.
Deploying machines which join the domain into an OU that has policies residing under that OU can cause much pain during deployment. My advise would be to create a separate staging OU and afterwards move the machine to the correct OU automatically with a script or manually. This way machine’s will not be bothered with policies during the deployment.
Cheers! Rens
Wow I never would have thought to do that! Good idea 🙂 Thanks Rens for the prompt reply.
–Update–
This is going to take some work… the interactive logon message was set in the default domain policy which is applied to Authenticated Users on the whole domain :-S
I wasn’t responsible for configuring AD/GP waaaay back in the day and I’ve been slowly cleaning it up but haven’t touched the default policy yet… (I remember reading somewhere that you should NEVER use this policy for anything…guess my predecessors didn’t read that same article.. hah).
They also used the default Computers container…grrr…
I’m thinking I should just remove the interactive logon portion and place that in it’s own GPO instead of completely overhauling the default policy right now.
Hi Marc,
Yeah that’s a pain in the butt. Perhaps you can create a designated OU, and enable “Block Inheritance”, although I’m currently not aware if also the default domain policy is blocked by this action. But hey worth a shot, enable block inheritance and do a resultant set of policy (RSOP)
Cheers! Rens
Rens if you’re ever in Ottawa I owe you a beer!
Still learning GPO and I’ve already had my few “oops” moments (like enabling windows firewall across the domain including all servers…)
Block Inheritance was exactly the feature I was looking for but I didn’t know what it was called or if the option was even available.
I had a few Enforced policies but I’ve remedied those.
This should make the deployments much smoother!
Marc,
I hold you to that one 🙂 Glad I’d could help. I wish you many luck on your MDT endeavors, and If you ever needed the help again, please let me know.
Cheers! Rens
Hi,
I already have a working MDT which I have connecting to a domain specified in the CustomSettings.ini. What I now want to do is during the build have the option of joining it to one of 4 domain. Ideally I would like to have a drop down field and then automatically use the correct account name and password for that chosen domain from the customsettings.ini..
I know I could this by having multiple customsettings.ini files (one for each domain) but as the whole of the ini file, apart from the domain, will be the same, I wondered if there was a cleaner way to do this from the one ini file..?
What you need sir, is…: DomainOUlist.xml
See these links how to achieve this:
https://scriptimus.wordpress.com/2013/02/11/mdt-2012-domainous-list/
https://anothermike2.wordpress.com/2012/04/21/back-to-basic-domainoulist-xml-or-not/
Let me know if this is what you are looking for
Cheers! Rens
Rens,
Having much trouble automating the steps for tablets to consistently join the domain wirelessly after deploying the image via USB stick. Seems that task sequence and unattend both run before the wireless connection is complete. I can insert the wireless profiles in a task sequence step without a problem and I even inserted a wait step in the task sequence but the connection still only seems to be consistently available after the desktop finishes loading on the first login. Even the SetupComplete.cmd finishes too early. Once the desktop is loaded I can manually run a script with elevated privileges but that’s not going to work when I’m not at the machine and takes too much time anyway when I have 500 machines to do.
Any ideas on how I can delay a running a final task sequence step until after the desktop is completely loaded?
Thanks for any help you might be able to give!
Gregg,
I’ve never done partially completion of the task sequence with Wifi, I wouldn’t recommend it either, since Wifi isn’t that reliable to me as cable.
If you want to wait for tasks running in a CMD to complete, you could use START /WAIT, see this link for more information: http://ss64.com/nt/start.html
Hope that can be helpful to you.
Cheers! Rens
Just wanted to let you know how this has worked out. After reading many forum articles we found that there was no Reverse Lookup Zone established in DNS for this network. This created enough of a delay in retrieving domain info that the process failed half the time. Once this was put in place with the appropriate PTR for the local DC, the domain join began working just fine via wireless. There were (and still are) some tweaks to make things more compact and efficient but it works fine, I’ve had no failures since DNS was fixed.
We are currently using a method that copies the wireless profile xml files from the %scriptroot% folder during post-install phase, then in SetupComplete.cmd a “netsh wlan add profile” command installs them and waits 30 seconds for a connection to be established. SetupComplete then runs a vbscript which does the domain join as well as placing the machine in the proper OU.
I have seen that we could probably eliminate the vbscript that does the domain join and just allow the TS to do it but it didn’t work initially so we went with the vbscript. On further experimentation it seems that the TS doesn’t like when the unattend file has the domain join information in it. The deployment hangs for 15-20 minutes waiting for the unattend to do the domain join which fails because the wireless connection isn’t made at that point, but when it finally times out the TS will then do the domain join itself because the SetupComplete has run by then and created the wireless connection.
As always, thanks for your help! It was a big part of the troubleshooting process.
Hi Gregg,
Thanks for getting back to me. Good you figured out a way to get around your problem. Also I’m glad I’d could be of some assistance for the troubleshooting part.
Cheers! Rens
Hi Rens,
We have our MDT environment set to join machines to join the domain literally after the OS is installed and drivers injected. This is however caused us many problems because then the task sequence has to install 4 apps and they sometimes fail because of the GPOs that are applied. Would moving the domain join until after the apps are installed do any harm? Don’t really want to create a staging OU with block inheritance on..
Cheers
Hi Riz,
It’s worth a try certainly. Just place the “Recover from Domain” in the “State Restore” step after the installation of your applications. But keep in mind that anything domain related will not work before you join the domain. Also it would be a possibility to join the domain force a GPO update, perform a wait and reboot and then install your applications.
So I think you have some options here!
Good luck!
Cheers! Rens
Hi Rens,
I’ve moved it but it still seems to be joining the domain before installing apps and not after?
Riz,
Seems or do you know that for sure? Look at your bdd.log on the deployed machine. To my knowledge if you remove the “Recover From Domain” step it should not recover from the domain. Otherwise an option would be to pass along the domain join variables like Task Sequence Variables after the installation of the applications and then manually call the script that is responsible for the domain join. This is: “ZTIDomainJoin.wsf” and can be find in the .\DeploymentShare\Scripts folder, you can call the script with a variable: cscript.exe [//nologo] %SCRIPTROOT%\ZTIDomainJoin.wsf [/debug:true]
Cheers! Rens
Hi Rens,
I’ve checked and its definitely still joining the domain before the app installs. How would i move this till after the apps have all been installed? Like previously stated i moved the recover from domain task and it didnt make a difference.
Hi Riz,
To my knowledge this would only work to remove the recover from domain step, and call the script manually in a later more desirable phase. Have a look in the deploymentshare\scripts folder to find a script called ZTIDomainJoin.wsf, this script can be called by yourself too!
Cheers! Rens
I have a script that you can use arguments with that allows for joining to the domain. It was written in VBScript, but this can be done using Powershell as well, using the Add-Computer CMDLet. In any case, here is the script.
It can be used in a task sequence step like
Name:
Join “%OSDDomainName%” Domain as “%OSDJoinAccount%”
Command Line:
cscript.exe “%SCRIPTROOT%\Custom-ZTIDomainJoin.vbs” /JoinDomain /Domain:”%OSDDomainName%” /SvcAcct:”%OSDJoinAccount%” /SvcAcctPw:”%OSDJoinPassword%”
This script will pass the values specified in customsettings.ini or the credentials specified from the credential prompt if not provided in bootstrap.ini and join the device to the domain. It will make a new computer object if one does not exist in Active Directory and update an existing object if one does.
***The only caveat is that you have to remove any domain lines from Unattend.xml files associated with your task seqences. This way, when MST runs ZTIConfigure.wsf to write values to the Unattend.xml file, it will not have a place to put them and therefore not join the device to the domain until you tell it to do so later in the task sequence. It can be done automatically for all future task sequences by editing the template Unattend files within the MDT install directory.***
‘Define Target Computer
strComputer = “.”
‘Set object values
Set oArguments = WScript.Arguments.Named
Set oShell = CreateObject(“WScript.Shell”)
Set oWMI = GetObject(“winmgmts:{impersonationLevel=impersonate}!\\” & strComputer & “\root\CIMV2”)
‘Define ASCII Characters
chrSpace = Chr(32)
chrSingleQuote = Chr(39)
chrDoubleQuote = Chr(34)
‘Show Script Usage
If (oArguments.Exists(“?”)) And (WScript.Arguments.Count = “1”) Then
WScript.Echo(WScript.ScriptName & chrSpace & “Usage:” & _
vbCrLf & vbCrLf & _
“Script Interpreter: [cscript.exe] or [wscript.exe]” & _
vbCrLf & vbCrLf & _
“Script Location:” & chrSpace & chrDoubleQuote & Replace(oShell.CurrentDirectory & “\” & WScript.ScriptName, “\\”, “\”) & chrDoubleQuote & _
vbCrLf & vbCrLf & _
“Optional Arguments:” & _
vbCrLf & vbCrLf & _
“[/JoinDomain]” & chrSpace & “And” & chrSpace & “[/Domain:” & chrDoubleQuote & “MyDomain.com” & chrDoubleQuote & “]” & _
vbCrLf & vbCrLf & _
“[/JoinWorkgroup]” & chrSpace & “And” & chrSpace & “[/WorkGroup:” & chrDoubleQuote & “MyWorkGroup” & chrDoubleQuote & “]” & _
vbCrLf & vbCrLf & _
“[/Rename]” & chrSpace & “And” & chrSpace & “[/Name:” & chrDoubleQuote & “MyDeviceName” & chrDoubleQuote & “]” & _
vbCrLf & vbCrLf & _
“[/SvcAcctDmn:” & chrDoubleQuote & “MyDomain” & chrDoubleQuote & “]” & _
vbCrLf & vbCrLf & _
“[/SvcAcct:” & chrDoubleQuote & “MyDomain\MySvcAcct” & chrDoubleQuote & “]” & _
vbCrLf & vbCrLf & _
“[/SvcAcctPw:” & chrDoubleQuote & “MySvcAcctPw” & chrDoubleQuote & “]” & _
vbCrLf & vbCrLf & _
“[/UnjoinDomain]” & _
vbCrLf & vbCrLf & _
“[/Restart]”)
WScript.Quit
End If
‘Define Required Arguments
argDomain = Trim(UCase(oArguments.Item(“Domain”)))
argWorkGroup = Trim(UCase(oArguments.Item(“Workgroup”)))
argSvcAcct = Trim(UCase(oArguments.Item(“SvcAcct”)))
argSvcAcctDmn = Trim(UCase(oArguments.Item(“SvcAcctDmn”)))
argSvcAcctPw = oArguments.Item(“SvcAcctPw”)
‘Define Optional Arguments
If (oArguments.Exists(“Name”)) Then
argName = Left(oArguments.Item(“Name”), 15)
argName = Replace(argName, chrSpace, “”)
argName = UCase(argName)
End If
If (oArguments.Exists(“OU”)) And Not (oArguments.Exists(“OU”)) = “” And Not IsNull(oArguments.Exists(“OU”)) Then
argOU = oArguments.Item(“OU”)
argOU = Trim(argOU)
Else
argOU = Null
End If
‘Define Variables
‘Amount of seconds to wait “Change the first number only as WScript.Sleep method expects the value in milliseconds.”
intSeconds = Int(15 * 1000)
‘Gather Information From WMI
‘Query #1 – Win32_BIOS
Set oBIOS = oWMI.ExecQuery(“Select * From Win32_BIOS”)
If (oBIOS.Count > 0) Then
For Each oItem In oBIOS
If Not IsNull(oItem.SerialNumber) Then
strSerialNumber = Left(oItem.SerialNumber, 15)
strSerialNumber = Trim(UCase(strSerialNumber))
End If
Next
End If
‘Query #2 – Win32_OperatingSystem
Function RestartDevice
Set oWMI = GetObject(“winmgmts:{(Shutdown)}//” & strComputer & “/root/cimv2”)
Set oOperatingSystem = oWMI.ExecQuery(“Select * From Win32_OperatingSystem”)
If (oOperatingSystem.Count > 0) Then
For Each oItem In oOperatingSystem
If (oItem.Primary = True) Then
RestartDevice = oItem.Reboot()
End If
Next
End If
End Function
‘Query #3 – Win32_ComputerSystem
Set oComputerSystem = oWMI.ExecQuery(“Select * From Win32_ComputerSystem”)
‘Process the collection only if the query has results
If (oComputerSystem.Count > 0) Then
‘Begin a for loop on the collection
For Each oItem In oComputerSystem
‘Determine the value of the “DNSHostName” property
If Not IsNull(oItem.DNSHostName) And Not IsNull(oItem.Domain) Then
strDNSHostName = Trim(UCase(oItem.DNSHostName & “.” & oItem.Domain))
End If
‘Determine the value of the “Domain” property
If Not IsNull(oItem.Domain) Then
strDomain = Trim(UCase(oItem.Domain))
End If
‘Determine the value of the “PartOfDomain” property
If Not IsNull(oItem.PartOfDomain) Then
strPartOfDomain = Trim(UCase(oItem.PartOfDomain))
End If
‘Determine the value of the “Name” property
If Not IsNull(oItem.Name) Then
strComputerName = Trim(UCase(oItem.Name))
End If
‘Determine the value of the “Username” property
If Not IsNull(oItem.UserName) Then
strDomainUserName = Trim(oItem.UserName)
If InStr(oItem.UserName, “\”) > 0 Then
strUserName = Mid(oItem.UserName, InStr(oItem.UserName, “\”) + 1)
strUserName = Trim(strUserName)
End If
End If
‘Determine the value of the “Workgroup” property
If Not IsNull(oItem.Workgroup) And (oItem.PartOfDomain = False) Then
strWorkgroup = Trim(UCase(oItem.Workgroup))
End If
‘Rename the device using the name specified in ArgName (Specified name will be truncated to 15 characters for computer name limit)
If (oArguments.Exists(“Rename”)) And (oArguments.Exists(“Name”)) And Not (ArgName = “”) Then
RenameDevice = oItem.Rename(argName, argSvcAcct, argSvcAcctPw)
WScript.Sleep(intSeconds)
If (RenameDevice = “0”) Then
WScript.Echo(chrDoubleQuote & strComputerName & chrDoubleQuote & chrSpace & “was successfully renamed to” & chrSpace & chrDoubleQuote & argName & chrDoubleQuote & “.” & vbCrLf)
Else
WScript.Echo(chrDoubleQuote & strComputerName & chrDoubleQuote & chrSpace & “was not renamed successfully.” & chrSpace & “(” & RenameDevice & “)” & “.” & vbCrLf)
WScript.Quit(RenameDevice)
End If
‘Rename the device using its serial number truncated to 15 characters for computer name limit
ElseIf (oArguments.Exists(“Rename”)) And Not (oArguments.Exists(“Name”)) Then
RenameDevice = oItem.Rename(strSerialNumber, argSvcAcct, argSvcAcctPw)
WScript.Sleep(intSeconds)
If (RenameDevice = “0”) Then
WScript.Echo(chrDoubleQuote & strComputerName & chrDoubleQuote & chrSpace & “was successfully renamed to” & chrSpace & chrDoubleQuote & strSerialNumber & chrDoubleQuote & “.” & vbCrLf)
Else
WScript.Echo(chrDoubleQuote & strComputerName & chrDoubleQuote & chrSpace & “was not renamed successfully.” & chrSpace & “(” & RenameDevice & “)” & “.” & vbCrLf)
WScript.Quit(RenameDevice)
End If
End If
‘Remove device from the Domain
If (strPartOfDomain = “TRUE”) And (oArguments.Exists(“UnjoinDomain”)) Then
UnjoinDomain = oItem.UnjoinDomainOrWorkgroup(argSvcAcctPw, argSvcAcct)
WScript.Sleep(intSeconds)
If (UnjoinDomain = “0”) Then
WScript.Echo(chrDoubleQuote & strComputerName & chrDoubleQuote & chrSpace & “was successfully removed from the” & chrSpace & chrDoubleQuote & strDomain & chrDoubleQuote & chrSpace & “domain.” & vbCrLf)
Else
WScript.Echo(chrDoubleQuote & strComputerName & chrDoubleQuote & chrSpace & “was unsuccessful” & chrSpace & “(” & UnjoinDomain & “)” & chrSpace & “in being removed from the” & chrSpace & chrDoubleQuote & strDomain & chrDoubleQuote & chrSpace & “domain.” & vbCrLf)
WScript.Quit(UnjoinDomain)
End If
End If
‘Join the specified Domain
If (strPartOfDomain = “FALSE”) And (oArguments.Exists(“JoinDomain”)) And (oArguments.Exists(“Domain”)) And Not (argDomain = “”) And Not (oArguments.Exists(“JoinWorkGroup”)) Then
Const Join_Domain = 1
Const Acct_Create = 2
Const Win9x_Upgrade = 16
Const Domain_Join_If_Joined = 32
Const Join_Unsecure = 64
Const Machine_Password_Passed = 128
Const Deferred_Spn_Set = 256
Const Install_Invocation = 262144
fJoinOptions = Join_Domain + Acct_Create
JoinDomain = oItem.JoinDomainOrWorkgroup(argDomain, argSvcAcctPw, argSvcAcct, argOU, fJoinOptions)
WScript.Sleep(intSeconds)
If (JoinDomain = “0”) Then
WScript.Echo(chrDoubleQuote & strComputerName & chrDoubleQuote & chrSpace & “was successful in joining the” & chrSpace & argDomain & chrSpace & “domain.” & vbCrLf)
Else
WScript.Echo(chrDoubleQuote & strComputerName & chrDoubleQuote & chrSpace & “was unsuccessful” & chrSpace & “(” & JoinDomain & “)” & chrSpace & “in joining the” & chrSpace & chrDoubleQuote & argDomain & chrDoubleQuote & chrSpace & “domain.” & vbCrLf)
WScript.Quit(JoinDomain)
End If
End If
‘Join the specified Workgroup
If (strPartOfDomain = “FALSE”) And (oArguments.Exists(“JoinWorkGroup”)) And (oArguments.Exists(“WorkGroup”)) And Not (argWorkGroup = “”) And Not (oArguments.Exists(“JoinDomain”)) Then
JoinWorkGroup = oItem.JoinDomainOrWorkgroup(argWorkgroup, argSvcAcctPw, argSvcAcct, Null, 0)
WScript.Sleep(intSeconds)
If (JoinWorkGroup = “0”) Then
WScript.Echo(chrDoubleQuote & strComputerName & chrDoubleQuote & chrSpace & “was successful in joining the” & chrSpace & argWorkgroup & chrSpace & “workgroup.” & vbCrLf)
Else
WScript.Echo(chrDoubleQuote & strComputerName & chrDoubleQuote & chrSpace & “was unsuccessful” & chrSpace & “(” & JoinWorkgroup & “)” & chrSpace & “in joining the” & chrSpace & chrDoubleQuote & argWorkgroup & chrDoubleQuote & chrSpace & “workgroup.” & vbCrLf)
WScript.Quit(JoinWorkGroup)
End If
End If
Next
End If
‘Provide information about the device
If (oArguments.Exists(“Info”)) Then
If Not (strDNSHostName = “”) Then
WScript.Echo(“FDQN:” & chrSpace & strDNSHostName & vbCrLf)
End If
If Not (strDomain = “”) Then
WScript.Echo(“Domain:” & chrSpace & strDomain & vbCrLf)
End If
If Not (strPartOfDomain = “”) Then
WScript.Echo(“Currently joined to a domain:” & chrSpace & strPartOfDomain & vbCrLf)
End If
If Not (strComputerName = “”) Then
WScript.Echo(“Computer name:” & chrSpace & strComputerName & vbCrLf)
End If
If Not (strDomainUserName = “”) Then
WScript.Echo(“Current Username w/ Domain:” & chrSpace & strDOmainUserName & vbCrLf)
End If
If Not (strUserName = “”) Then
WScript.Echo(“Current Username w/o Domain:” & chrSpace & strUserName & vbCrLf)
End If
If Not (strWorkgroup = “”) And (strPartOfDomain = “FALSE”) Then
WScript.Echo(“Workgroup:” & chrSpace & strWorkgroup & vbCrLf)
End If
End If
‘Optionally Restart Device
If (oArguments.Exists(“Restart”)) Then
Call RestartDevice
End If
Using this method, you will not have to rearrange you Active Directory policies or containers, just to accommodate deployment as it will somewhere towards the last step.
If anybody needs help or wants to exchange ideas, just shoot me an email, I will be glad to help when and where I can.
Hope this helps somebody!
Rens, Hey I wanted to toss you a question if I may.. I’m moving from a fully working MDT 2013 server to a new (physical) one. The old deployment share is gone 🙁
I am now on MDT 2013 U2 with the Win10 ADK. I have a nice customsettings.ini that I used previously to join the domain among other things. Currently my apply image task works perfectly except for naming the computer. The gui prompts and we enter a variable but it’s never actually applied. Which (I believe) stops the domainjoin, bitlockering, local admins being set and a few other things.
If I specify the following:
SkipDomainMembership=YES
JoinDomain=domain.org
MachineObjectOU=”OU=Computers,DC=domain,DC=org”
DomainAdmin=Deploy
DomainAdminDomain=domain.org
DomainAdminPassword=password
This worked before but not now.. do I have the correct syntax?
Hi Ben,
Thanks for reaching out to me. What I’m missing is the SkipComputerName=NO, as a test you can provide the OSDComputerName=”name of your computer” in the customsettings.ini or as a Task Sequence Variable in a task sequence.
Also please have look at these two articles I wrote, to see if this might help:
http://renshollanders.nl/2015/04/mdt-put-the-domain-join-where-it-belongs/
http://renshollanders.nl/2013/02/mdt-2012-settings-for-fully-automated-lti-deployment-part-ii-customsettings-ini/
Cheers! Rens
Thanks Rens. My problem remains. Here is the bdd.log: http://s000.tinyupload.com/?file_id=58216503391068727149 and my cs.ini: http://s000.tinyupload.com/?file_id=82358153991377526503
If you could eyeball those and let me know Id be very grateful.
Thanks!
Ben,
I’ve looked at your bdd.log and cs.ini. Basically your cs.ini there’s nothing wrong. What I did notice is that in your entire BDD.log not once the property “OSDComputerName” occurs, which means no valid computername has been parsed through. Did you already test with a task sequence variable called “OSDComputerName” and the value: “name of your computer”. To test this, set SkipComputerName to YES in your cs.ini.
Afterwards view the log file with CMtrace or trace.exe and create a filter “When the entry text” CONTAINS “Property” this will give you a clear sight of which properties are processed.
If that wouldn’t help, I would suggest you recreate a new deploymentshare, and use a original ISO / media from Microsoft to just do a test deployment to verify everything works as it should.
Cheers! Rens
Hello guys
I am currently in a process of developing windows 10 roll out. My domain join sequence in the Rule is
JoinDomain=xxx.com
MachineObjectOU=OU=Workstations,OU=Hardware,DC=xxx,DC=com
I dunt want to use the Domain Admin credential as it could be a security issue as the password is sent over the network in plain text. Is there anyway i can use other credentials for joining the domain. Like the one which has limited privileges of joining the domain
Hi,
Check this blog on how to create an MDT domain join account without setting too much privileges: https://jonconwayuk.wordpress.com/2011/10/20/minimum-permissions-required-for-account-to-join-workstations-to-the-domain-during-deployment/
Cheers! Rens
Thank you for your prompt response. So if i create an account like this what do i need to put in the rules will it be domainadmin= or something else ?
Hi,
You are welcome, yes the account you create you will need to provide it instead of the domainadmin.
Cheers! Rens
Apologies for being a pain but let say the example account name is MDT then the rules would look like
JoinDomain=xxx.com
MachineObjectOU=OU=Workstations,OU=Hardware,DC=xxx,DC=com
DomainAdmin=MDT
DomainAdminPassword=abc123
can you please clarify this
Hey,
No problem! This is all correct! You just need to make sure your account is allowed to join machines more then 10 times. See this article for reference: https://support.microsoft.com/en-us/kb/243327
Cheers! Rens
HI Rens
I need to copy some folders into the program files during the installation procedure. The files are present on a shared folder and cannot be moved on the WDS server as the folders get updates periodically. Can you please guide me as to how should i go about my script. I tried to map the drives using the net use cmd in powershell but its doesnt map the drive. Any idea ?
Hi Hasan,
Thank you for your question. The question you ask is on entire different topic then what my post addresses, but to keep it simple. I would use a CMD based script which does the following:
1. Map the drive with net use n: \\server\share
2. Copy the files for example with %~DP0 which represents the absolute path
3. Deletes the just created mapping
Make sure your permissions for this share is set so that users can read / append files but cannot alter it, this should be held to the persons maintaining the files.
See an example here: http://ss64.com/nt/syntax-args.html and http://ss64.com/nt/pushd.html
Cheers! Rens
Hi Rens. I am deploying Windows 10 LTSB to a Virtual Machine, on a Windows 10 workstation, using MDT 2013. Everything is working correctly except the computer name is not matching the OSD computer name. It works totally fine on a physical machine. Loading a Windows 7 image on the same virtual works fine also. Any ideas? here are my settings:
[Settings]
Priority=Default,Architecture,ByVMType,ByDesktopType,ByLaptopType,Model,SendMail
Properties=OSDSendMailFrom,OSDSendMailTo,OSDSendMailSubject,OSDSendMailBody,OSDSendMailSMTPServer,OSDSendMailIncludeBDDLog
[Default]
OSInstall=Y
_SMSTSOrgName=xxxxxxxxxxxsktop Image Builder for %OSDComputerName%
ApplyGPOPack=NO
AreaCode=517
CountryCode=001
Dialing=TONE
DoCapture=YES
FinishAction=REBOOT
FullName=xxxxxxxxxxxxxxxxxxxxxxxxxx
SkipApplications=YES
SkipCapture=YES
ComputerBackupLocation=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxs
BackupFile=W7ENTSP1x64EN.wim
SkipAdminPassword=YES
AdminPassword=xxxxxxxxxx
;SkipDomainMembership=YES
JoinWorkGroup=WORKGROUP
;JoinDomain=xxxxxxxxxxx
;MachineObjectOU=OU=Computers,OU=xxxx,OU=Corporate,DC=xx,DC=xxxxxxx,DC=org
;DomainErrorRecovery=Auto
SkipBitLocker=YES
DomainAdmin=xxxxxxxxxxx
DomainAdminDomain=xxxxxxxxx
DomainAdminPassword=xxxxxxxx
SkipProductKey=YES
SkipSummary=YES
SkipFinalSummary=YES
SkipTimeZone=YES
TimeZoneName=Eastern Standard Time
SkipUserData=YES
UserDataLocation=NONE
UserDomain=ad.caajlh.org
SkipLocaleSelection=YES
KeyboardLocale=en-US
UserLocale=en-US
UILanguage=en-US
WSUSServer=http://xxxxxxxxx
EventService=http://xxxxxxxxx
[ByVMType]
Subsection=ISVM-%ISVM%
[IsVM-True]
SkipComputerName=NO
[ByDesktopType]
Subsection=Desktop-%IsDesktop%
[ByLaptopType]
Subsection=Laptop-%IsLaptop%
[Desktop-True]
SkipComputerName=YES
OSDComputerName=%AssetTag%D
[Laptop-True]
SkipComputerName=YES
OSDComputerName=%AssetTag%L
[Latitude E5500]
XResolution=1280
YResolution=800
[Latitude E5510]
XResolution=1366
YResolution=768
[Latitude E5520]
XResolution=1366
YResolution=768
[Latitude E5530 non-vPro]
XResolution=1366
YResolution=768
[Latitude E5540]
XResolution=1366
YResolution=768
[Latitude E5550]
XResolution=1366
YResolution=768
[Latitude E5570]
XResolution=1366
YResolution=768
[SendMail]
OSDSendMailFrom=xxxxxxxx
OSDSendMailTo=xxxxxxxxx
OSDSendMailSubject=%OSDComputerName% is now reloaded
OSDSendMailBody=The computer %OSDComputerName% was installed at #Now()#.
OSDSendMailSMTPServer=email.xxxx.org
OSDSendMailIncludeBDDLog=NO
Hi Jim,
Thank you for your question first of all, you can simply your customsettings.ini on the resolution part. Just put the following properties in your cs.ini and it will suffice for all models:
XResolution=1
YResolution=1
This forces Windows to perform an optimization to detect the highest / native resolution. This way you can shorten your cs.ini and aren’t bound any longer to make/model resolution schemes.
Now for your question, I think you should review your bdd.log since all properties from your customsettings and their order/priority are echoed into that log file. I suspect you need to change the priority of your virtuale machine and desktop. Also check if your VM isn’t detected also as a Desktop, this is often so. This can also be reviewed in your bdd.log.
Cheers! Rens
Thanks for the advice Rens. I am very new to MDT (first attempt) and appreciate
the help.
Hi,
No problem, glad I’d could help. Altough my site isn’t updated as frequently anymore as I want it to be, I’ll remain giving answers on questions being asked.
Cheers and good luck! Rens
I have set this:
https://i.imgur.com/qiADaoS.png
But It’s still missing after selecting the task sequence:
https://i.imgur.com/999R5ZZ.png
Hello Esben,
What happens when you set the SkipDomainMembership to YES and look at the BDD.log. I think it will get parsed through. Otherwise have a look at the log file if no other settings bothers you during deployment.
Cheers! Rens
I have added both SkipDomainMembership=YES and SkipComputerName=NO to the task sequence to no effect.
CS.INI:
http://pastebin.com/raw/z78i67Dz
Bootstrap.ini:
http://pastebin.com/raw/0wuxcUQ8
Esben,
Can you provide a copy of your bdd.log? Put the following in your cs.ini then grab the logfile from the computer you are trying to deploy:
SLShareDynamicLogging=%deployroot%\logs\%computername%
Cheers! Rens
http://pastebin.com/raw/2FsDdh8H
Hi Esben,
The BDD.log isn’t complete, usually it’s a file size between 280 and 340 kb. With all the parsed customsettings.ini properties in it.
So you have to sit and wait out the entire deployment.
Cheers! Rens
That was the log up until this point:
https://i.imgur.com/7ltlpCA.png
which is where the issue is.
I will run it through the rest of the sequence and give you a complete log.
http://www40.zippyshare.com/v/lhKkazbC/file.html
Hi Esben, I’ve taken a look at your BDD.log and what I can see, first the DomainJoin property is empty, then it gets provided with XX.xx as you have masked your companysettings. Afterwards the DomainJoin property is emptied again, and after this it gets set again. However I cannot see why it is emptied.
Did you try to do a deployment with SkipDomainMembergship set to YES? Because I really never have any issues with setting and parsing the task sequence variables as I’ve explained in my blogpost.
Cheers! Rens
With SkipDomainMembership=YES and SkipComputerName=NO set in CS.ini:
http://www2.zippyshare.com/v/n1S5CZSd/file.html
It did fail to join the domain, but our setup requires the machine-objects to be pre-populated before allowing joins, so unless you see some other issue that’s to be expected since I hadn’t created one…
For some reason my capture task sequence fails with joindomain in CS.ini, so my initial goal was to be able to prepopulate the fields without joindomain in CS.ini.
Update: Nope, didn’t join the domain. Ended up in the “123” workgroup
I don’t know what I’m missing.
The only thing I want is for MDT to ask for computer name.
I have the customsettings.ini set for the domain and the OU location but when i start the MDM it still show if i want to join a workgroup or a domain.
Please help
Hi Frank,
SkipDomainMembership should be set to YES
SkipComputerName should be set to NO
Cheers! Rens
Hi Rens,
I have tried using the task sequence variables method however it doesn’t appear to be parsing them, is there a way to verify that they are being read?
Cheers! Scott
Hi,\litetouch.vbs /inifile: /tasksequenceid:
sure, try this: cscript
You’ll find a MININT folder on the machine you ran the aboven commandline on, view the bdd.log with CMtrace.exe to see which settings have parsed.
Cheers! Rens
Hello Rens,
How can we move domain join to end of the task sequence?
We have a TS which works good. But we are making some changes to our policies, taking local admin rights from everyone one, once joined domain. So I want to install applications before joining domain
Thanks
Hi Aravind,
Sure you can place the domain join at the end, but this has to be done without the recover from domain step in the MDT task sequence. Either you call the ZTIDomainJoin.wsf script yourself (variables used during the task sequence such as domain join information can still be used) or you use a custom script (again the same variables that are already present can be used)
Cheers! Rens
Hi Rens,
I am glad to see this blog helping a lot everyone for resolving the MDT related issues.
It would be very helpful to me if you guide me how to fix the issue related to the domain join in my new MDT server.
First of all I am able to capture the image and deploy the image successfully without any error. However the machine is not getting joined to the company domain after the deployment.
Before capturing I am removing the machine from the domain. and using the .wim file for the deployment.
I have gone through lot of blogs but didn’t able to get the proper info.
I hope you will help me to fix this issue.
Thank you in advance.
Hi Syed,
Sure no problem. In your bdd.log you will find the properties that are used to do the deployment with. You can read and create a filter to search for all properties with cmtrace.exe. Find for the Domain Join settings to see if they are present. Also during deployment you can find a unique per deployment unattend.xml for your computer first in X:\MININT (during WinPE) and after in C:\MININT (during Windows setup) check the unattend to see the domain join settings are there.
perform a domain join manually to verify the account is OK, and has enough privileges to join machines to the desired OU.
Let me know the results.
Cheers! Rens
Hi Rens,
im on mdt 8450…
are you saying setting joindomain variable in task sequence only works if you set skipdomainmembership in customsettings.ini?
i find that joindomain and osdcomputername variables come into effect when placed in customsettings.ini but not when placed in task sequence itself (at least to the extent that when the deploy wizard pops up the variables are not populated as desired)
ty
Hi Nicholas,
Sorry for the late response, I was abroad for some time not checking my blog. If you put the variables at the beginning of your TS everything should work just fine. You can see the processing of them in bdd.log. Think you need to set SkipDomain question in CS.ini
Cheers! Rens
Hi Rens,
I was hoping to follow your recommendations and put the domain join at the end of the task sequence, however I realized the domain join needs to stay in its default location because subsequent tasks require access to a network share within the domain. The problem with the domain join in the default location is that after the domain join and reboot, it applies group policies which break MDT automation, specifically the logon notice which has been well documented in other Google results. I’ve temporarily removed the group policy setting for the logon notice, however, now MDT just sits at the logon prompt. It no longer logs in automatically as the local administrator as it did after the initial reboot If I manually log in as the local administrator or domain administrator, then MDT will pick up where it left off and complete properly. I can’t figure out how to get MDT to logon automatically after joining the domain. Any advice is much appreciated. Thanks.
Ryan,
What happens when you let the machines come in a OU with block inheritance on them? Cause that would be the ‘normal’ thing to do.
Other options is to do it later manually instead of using the MDT automated task of joining the domain, but then you cannot access resources on the network that require domain level authentication.
Cheers! Rens
Hi Rens,
I am new to MDT & WDS.
Currently I have setup WDS & MDT(Win 2012r2) on 1 server and obtaing DHCP from dedicated server.
When i try to deploy a win 7 Image it ask for Admin credentials, but this information is already in custom.ini & Bootstrap.
Settings]
Priority=Default
Properties=MyCustomProperty
[Default]
OSInstall=Y
SkipBDDWelcome=YES
UserID=xxx
UserDomain=xxxxx
UserPassword=xxxx
SkipCapture=YES
SkipProductKey=YES
SkipComputerBackup=YES
SkipBitLocker=YES
KeyboardLocale=0809:00000809
UserLocale=en-GB
UILanguage=en-GB
SkipTimeZone=YES
TimeZoneName=GMT Standard Time
EventService=http://MDT:9800
WSUSServer=http://xxxxx
bootstrap:
[Settings]
Priority=Default
[Default]
DeployRoot=\\MDT\DeploymentShare$
UserID=xxxx
UserDomain=xxxxx
UserPassword=xxxx
KeyboardLocale=en-GB
SkipBDDWelcome=YES
Also I would like to image pc from another location, so that they can pull the image from central location.
Any help appreciated.
Hello,
Nice articles you write!
I’m stuck on following issue: i have created an auto domain logon script for a specific user for certain installations. After those sysprep should initialize. Being on the domain, this will not be possible, so I need to unjoin from the domain. Powershell script Remove-Computer not working strangely. Do you have experience with this or can you advise with clear example?*
Regards,
W.
I actually found a much easier and better method to deal with the problem of domain policies interfering with the final stages of MDT deployments. Basically, all we need to do is suppress the scripted reboot that happens right after MDT joins the domain. This allows for MDT to fly through the rest of the task sequence and perform software installs and any other tasks you’ve created after joining the domain without reboots, therefore, preventing any group policies from the domain to interfere since you haven’t rebooted yet. Then, when the task sequence finishes, you can automatically reboot the machine by adding FinishAction=RESTART to your CustomSettings.ini.
All you have to do is edit the ZTIDomainJoin.wsf script by “commenting out” the two lines that end with “true”. Just type an apostrophe in front of each of the lines as illustrated below:
oEnvironment.Item(“LTISuspend”) = “”
‘oEnvironment.Item(“SMSTSRetryRequested”) = “true”
‘oEnvironment.Item(“SMSTSRebootRequested”) = “true”
iRetVal = SUCCESS
This method is much cleaner because it does not require messing with Unattend.xml or altering the task sequence order or removing MDT’s built-in method to join the domain or using any 3rd party vbs scripts to join the domain.