VMware Cloud Community
n3o
Contributor
Contributor

Windows server cloning, how to automate joining domain

We have a test group that at anytime has about a hundred test servers. When they move to a new platform, they typically present a gold image of a Windows server, and request that the VMware admins turn it into a template and push out a hundred machines, which are then manually joined to the domain. I am trying to automate the process (especially of joining to the domain), and this is a new concept for me, any ideas/suggestions?

0 Kudos
31 Replies
daphnissov
Immortal
Immortal

Use a vCenter customization spec which has the domain information as well as account embedded. When you deploy from that template, select the customization spec and it will automatically join the domain.

0 Kudos
LucD
Leadership
Leadership

There is a great example in How to change IP and join a VM into domain by PowerCLI in VMware.
It doesn't require you to use OSCustomizationSPec.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
n3o
Contributor
Contributor

thanks for the response, would you mind sharing a screenshot of a typical customization template as you described? 

0 Kudos
n3o
Contributor
Contributor

thanks I will be looking at the link you provided

0 Kudos
vespavbb
Enthusiast
Enthusiast

Hey,

is it possible to use the script without entering the password again for $DomainAccountPWD

Because if the Script is already running with domainadminrights, i want to pass the pwd direct in the invoke command.

VCP4,VCP5,VCP6,VCP7,VCP8
0 Kudos
LucD
Leadership
Leadership

Do you mean to use the credentials from the account under which the script is running?
If yes, I don't think it is possible to retrieve the user/password for the current user to pass along.

You will at least need to enter credentials once in the script.

You could consider storing the credentials locally via the New-VICredentialStoreItem cmdlet, and then retrieving them via the Get-VICredentailstoreItem cmdlet.

That way you could a prompt for credentials


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
vespavbb
Enthusiast
Enthusiast

Yes, I wanted to avoind typing the pw twice... but ok..

 

maybe you can help me here. This is not wokring, I want to joing a VM via script invoke command. I´m not sure about the @"

And how could I join the computer to a certain OU?

# Domain account passowrd

$vm = testvm1

$userid = whoami

$DomainAccountPWD = Get-Credential $userID | ConvertTo-SecureString -asPlainText -force

 

$cmd = @"

$domain = mydomain.local

$password = $DomainAccountPWD # | ConvertTo-SecureString -asPlainText -force

$username = $userID

$credential = New-Object System.Management.Automation.PSCredential($username,$password)

Add-computer -DomainName $domain -Credential $credential

"@

Invoke-VMScript -VM $vm -ScriptText $cmd -Verbose -GuestUser $GuestUserName -GuestPassword $GuestPassword

VERBOSE: 9/27/2019 6:34:54 PM Invoke-VMScript Finished execution

ScriptOutput

-----------------------------------------------------------------------------------------------------------------------| At line:4 char:72

| + ... ew-Object System.Management.Automation.PSCredential

| + ~

| Missing argument in parameter list.

| At line:5 char:72

| + ... ew-Object System.Management.Automation.PSCredential(

| + ~

| Missing argument in parameter list.

| + CategoryInfo : ParserError: (:) [], ParentContainsErrorRecordException

| + FullyQualifiedErrorId : MissingArgument

|

|

-----------------------------------------------------------------------------------------------------------------------

VCP4,VCP5,VCP6,VCP7,VCP8
0 Kudos
vespavbb
Enthusiast
Enthusiast

without # of course-> # | ConvertTo-SecureString -asPlainText -force

VCP4,VCP5,VCP6,VCP7,VCP8
0 Kudos
LucD
Leadership
Leadership

Try escaping (with a back-tick) the variables you don't want to be substituted in the here-string

$cmd = @"

`$domain = mydomain.local

`$password = $DomainAccountPWD # | ConvertTo-SecureString -asPlainText -force

`$username = $userID

`$credential = New-Object System.Management.Automation.PSCredential(`$username,`$password)

Add-computer -DomainName `$domain -Credential `$credential

"@


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
vespavbb
Enthusiast
Enthusiast

Thanks LucD so far,

but still not working, the script hangs on, nothing happens, any idea?

Microsoft Windows [Version 10.0.14393]

(c) 2016 Microsoft Corporation. All rights reserved.

 

## Domain account passowrd

$userid = whoami

$DomainAccountPWD = Get-Credential $userID | ConvertTo-SecureString -asPlainText -force

 

 

cmd = @"

 

`$domain = $domain

`$password = $DomainAccountPWD | ConvertTo-SecureString -asPlainText -force

`$username = $userID

`$DomainCredential = New-Object System.Management.Automation.PSCredential(`$username,`$password)

Add-computer -DomainName `$domain -DomainCredential `$credential

"@

Write-Host "Invoke Script"

Invoke-VMScript -VM $vm -ScriptText $cmd -Verbose -GuestUser $GuestUserName -GuestPassword $GuestPassword

sleep -Seconds 5

Restart-VM -VM $VM -Confirm:$false

sleep -Seconds 5

VCP4,VCP5,VCP6,VCP7,VCP8
0 Kudos
LucD
Leadership
Leadership

Do you initialise the $domain variable somewhere?

I still suspect the script might be hanging on the UAC prompt.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
vespavbb
Enthusiast
Enthusiast

sure $domain is set

UAC is off on the VM... the VM is 2016win.

VCP4,VCP5,VCP6,VCP7,VCP8
0 Kudos
LucD
Leadership
Leadership

I noticed you did the ConvertTo-SecureString twice.

Can you try like this?

$domain = 'my.domain'

$userid = whoami

$DomainAccountPWD = (Get-Credential -UserName $userID).GetNetworkCredential().Password


$cmd = @"

`$domain = $domain

`$password = $DomainAccountPWD | ConvertTo-SecureString -asPlainText -force

`$username = $userID

`$DomainCredential = New-Object System.Management.Automation.PSCredential(`$username,`$password)

Add-computer -DomainName `$domain -DomainCredential `$credential

"@


Write-Host "Invoke Script"

Invoke-VMScript -VM $vm -ScriptText $cmd -Verbose -GuestUser $GuestUserName -GuestPassword $GuestPassword

sleep -Seconds 5

Restart-VM -VM $VM -Confirm:$false

sleep -Seconds 5


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
vespavbb
Enthusiast
Enthusiast

no, still same problem

Is there maybe a other option like netdom?

##

$userid = whoami

$DomainAccountPWD = Get-Credential $userID | ConvertTo-SecureString -asPlainText -force

$vm = get-vm -Name vmtest

$domain = 'my.domain'

cmd = @"

`$domain = $domain

`$password = $DomainAccountPWD

`$username = $userID

`$credential = New-Object System.Management.Automation.PSCredential(`$username,`$password)

Add-computer -DomainName `$domain -Credential `$credential

"@

Write-Host "Invoke Script"

Invoke-VMScript -VM $vm -ScriptType Powershell -ScriptText $cmd -Verbose -GuestUser $GuestUserName -GuestPassword $GuestPassword

sleep -Seconds 5

Restart-VM -VM $VM -Confirm:$false

  sleep -Seconds 5

 

##reboot and wait until vm is back 

Wait-Tools -VM $vm

VCP4,VCP5,VCP6,VCP7,VCP8
0 Kudos
vespavbb
Enthusiast
Enthusiast

if I run only this, it will not complete do not go on...

cmd = @"

`$domain = $domain

`$password = $DomainAccountPWD

`$username = $userID

`$credential = New-Object System.Management.Automation.PSCredential(`$username,`$password)

Add-computer -DomainName `$domain -Credential `$credential

"@

VCP4,VCP5,VCP6,VCP7,VCP8
0 Kudos
LucD
Leadership
Leadership

That is not the code I posted in my previous reply.
You still have the ConvetTo-SecureString in there, when assigning $DomainAccountPWD


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
vespavbb
Enthusiast
Enthusiast

If i run your script with my var,

its asking fo a values

cmdlet Get-Credential at command pipeline position 1

Supply values for the following parameters:

Message:

$DomainAccountPWD = (Get-Credential -UserName $userID).GetNetworkCredential().Password    -> is not asking for a password, just text??

VCP4,VCP5,VCP6,VCP7,VCP8
0 Kudos
LucD
Leadership
Leadership

Seems you need to provide a Message when using UserId

(Get-Credential -Message 'Provide Credentials' -UserName $userID).GetNetworkCredential().Password


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
vespavbb
Enthusiast
Enthusiast

better, but till not running. and the join is not working as well I dont get it:-(

on all Variables i get this message

not recognized as the name of a cmdlet,

|  function, script file, or operable program. Check the spelling of the name, or

|  if a path was included, verify that the path is correct and try again.

|  At line:2 char:11

is there an other way instead of @"

maybe something like that?

$userid = whoami

$DomainAccountPWD = Get-Credential $userID | ConvertTo-SecureString -asPlainText -force

$vm = get-vm -Name testvm

$domain = 'my.domain'

$credential = New-Object System.Management.Automation.PSCredential($userid,$DomainAccountPWD)

$cmd = 'Add-Computer -DomainName ' + $domain + ' -Credential ' + $credential

#Invoke-VMScript -VM $vm -ScriptType Powershell -ScriptText $cmd -Verbose -GuestUser $GuestUserName -GuestPassword $GuestPassword

Write-Host "Invoke Script"

Invoke-VMScript -VM $vm -ScriptType Powershell -ScriptText $cmd -Verbose -GuestUser $GuestUserName -GuestPassword $GuestPassword

sleep -Seconds 5

VCP4,VCP5,VCP6,VCP7,VCP8
0 Kudos