VMware Cloud Community
ToddBertschi
Contributor
Contributor

Problems passing Domain credentials to script block on a remote machine to create a child domain

Hello all

I'm beating my head against a wall with something. I'm developing a script that deploys a 2 level domain onto vCenter and I'm running into problems with the code when deploying the child domain. Specifically, I'm having issues getting my credentials to pass to the guest VM. I'm using Invoke-VMScript because the networking is generally unreachable but I can connect to vCenter just fine. Oh and these VM's are Windows 2016 with a GUI and I'm current on PS patches/levels.

#DC Names
$DomainControllerVMName_01 = "AD01"
$DomainControllerVMName_02 = "AD02"
#$DomainMode = "WinThreshold"
#$ForestMode = "WinThreshold"
#$DomainName = "Datum.local"

$ChildDomainName = "child.datum.local"

#DC Credentials
    $DCLocalUser_01 = "$DomainControllerVMName_01\administrator"
    $DCLocalPWord_01 = ConvertTo-SecureString -String "P@ssw0rd123" -AsPlainText -Force
    $DCLocalCredential_01 = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $DCLocalUser_01, $DCLocalPWord_01

   $DCLocalUser_02 = "$DomainControllerVMName_02\administrator"
    $DCLocalPWord_02 = ConvertTo-SecureString -String "P@ssw0rd123" -AsPlainText -Force
    $DCLocalCredential_02 = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $DCLocalUser_02, $DCLocalPWord_02
#Domain Credentials
    $DomainUser = "Datum\administrator"
    $DomainPWord = ConvertTo-SecureString -String "P@ssw0rd123" -AsPlainText -Force
    $DomainCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $DomainUser, $DomainPWord

# Script Blocks
# Install Roles/Features
$InstallADRole = @'
Install-WindowsFeature -Name "AD-Domain-Services" -IncludeManagementTools
'@
#Install parent domain
$ConfigureNewDomain = @"
Install-ADDSForest -InstallDns -ForestMode $ForestMode -DomainMode $DomainMode -DomainName $DomainName -SafeModeAdministratorPassword (ConvertTo-SecureString -String "P@ssw0rd123" -AsPlainText -Force) -Force
"@

# Install Child domain

$ConfigureChildDomain = @"
Install-ADDSDomain -Credential $DomainCredential -InstallDNS -CreateDNSDelegation -DomainMode $DomainMode -NewDomainName $ChildDomainName -ParentDomainName $DomainName -SafeModeAdministratorPassword (ConvertTo-SecureString -String "P@ssw0rd123" -AsPlainText -Force) -Force -NoRebootOnCompletion
"@

# Begin  Install of DC01

Invoke-VMScript -ScriptText $InstallADRole -VM $DomainControllerVMName_01 -GuestCredential $DCLocalCredential_01

Invoke-VMScript -ScriptText $ConfigureNewDomain -VM $DomainControllerVMName_01 -GuestCredential $DCLocalCredential_01

# Begin Install of DC02

Invoke-VMScript -ScriptText $InstallADRole -VM $DomainControllerVMName_02 -GuestCredential $DCLocalCredential_02

Invoke-VMScript -ScriptText $ConfigureChildDomain -VM $DomainControllerVMName_02 -GuestCredential $DCLocalCredential_02

There is of course other things that happen like reboots, delays and checks for services starting but it's really the child domain that stumps me. At this point AD01 is up and configured and AD02 has it's roles added. I've been running individual commands all day trying to figure this out. No matter what I try I keep getting a 'Cannot bind parameter 'Credential' and it can't convert the "System,Management.Automation.PSCredential value of type "System.String". I'm assuming it's because the password is encrypted and the remote system can't un-encrypt it. I've also moved the domain credentials to the $ConfigureChildDomain script block and changed double quotes to singles but it's just not clicking with me. Anyone have any insight? This is actually a problem I'll have later on as well so any help is appreciated.

 

Peace

Reply
0 Kudos
9 Replies
LucD
Leadership
Leadership

The error seems to indicate that you are passing a string instead of a PSCRedential on the GuestCredential parameter at one point.

Can you check the content and type of the variable you use on the GuestCredential parameter, just before doing the Invoke-VMScript?

Can you perhaps show the exact error message you are getting?


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

Reply
0 Kudos
ToddBertschi
Contributor
Contributor

Test
Reply
0 Kudos
ToddBertschi
Contributor
Contributor

PS Z:\SharedFolders> Z:\SharedFolders\Creds.ps1

ScriptOutput
-----------------------------------------------------------------------------------------------------------------------|  Install-ADDSDomain : Cannot bind parameter
'Credential'. Cannot convert the
|  "System.Management.Automation.PSCredential" value of type "System.String" to type
|  "System.Management.Automation.PSCredential".
|  At line:1 char:35
|  + ... SDomain -Credential System.Management.Automation.PSCredential -Instal ...
|  +                         ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|      + CategoryInfo          : InvalidArgument: (:) [Install-ADDSDomain], ParameterBindingException
|      + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.DirectoryServices.Deployment.PowerShell.Command
|     s.InstallADDSDomainCommand
|   
|  
-----------------------------------------------------------------------------------------------------------------------


PS Z:\SharedFolders> $DomainCredential

UserName                                Password
--------                                --------
datum\administrator System.Security.SecureString

PS Z:\SharedFolders> $DomainCredential.GetType()

IsPublic IsSerial Name                                     BaseType                                                                                                       
-------- -------- ----                                     --------                                                                                                       
True     True     PSCredential                             System.Object                                                                                                  

PS Z:\SharedFolders> $DomainCredential.GetNetworkCredential()

UserName                                           Domain                                            
--------                                           ------                                            
administrator                                      datum                                             

PS Z:\SharedFolders> $DomainCredential.GetNetworkCredential().Password
P@ssw0rd123

PS Z:\SharedFolders>

Reply
0 Kudos
ToddBertschi
Contributor
Contributor

Ignore that test. For some reason I couldn't post. Issue on my end.

But that should be the error and details you asked for. I took the original code from above, unscrubbed it (passwords and domain names), reset my ISE and re-connected to clear all variables and ran it to get that error.

One other thing that probably doesn't matter... This is a piece of a much larger program. In the larger program most of these variables are in a separate PS script that is dot-sourced at the start. I do that to make it easier to change variables and to keep users out of the main code. During the troubleshooting, I moved the variables over to the same script. It shouldn't be a problem but I just wanted to mention it.

Reply
0 Kudos
LucD
Leadership
Leadership

Ok, I think I see what is happening there.

The error you are getting is from the Credential parameter on the script in $ConfigureChildDomain

The content of that variable is a here-string with double quotes, meaning that the variables in there will be substituted as with normal variable substitution in a string.

The substitution of a PSCredential object will result in the typename of the object, hence the 'System.Management.Automation.PSCredential' in the error.

You can verify that by using it in a normal string.

For example

Write-Host "Test $ConfigureChildDomain"

will result in

Test Install-ADDSDomain -Credential System.Management.Automation.PSCredential -InstallDNS -CreateDNSDelegation -DomainMode  -NewDomainName child.datum.local -ParentDomainName  -SafeModeAdministratorPassword (ConvertTo-SecureString -String "P@ssw0rd123" -AsPlainText -Force) -Force -NoRebootOnCompletion

And in fact the variable substitution is nothing more than doing

$DomainCredential.ToString()

To fix the issue you could only use strings in the here-string, and create the PSCredential object in the code that you send to the VM's guest OS.

Also note that you will have to escape the variables that you don't want to have substituted (with a back-tick).

Your code could be

# Install Child domain


$user = "Datum\administrator"

$pswd = "P@ssw0rd123"


$ConfigureChildDomain = @"

`$DomainUser = $user

`$DomainPWord = ConvertTo-SecureString -String $pswd -AsPlainText -Force

`$DomainCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList `$DomainUser, `$DomainPWord


Install-ADDSDomain -Credential `$DomainCredential -InstallDNS -CreateDNSDelegation -DomainMode $DomainMode -NewDomainName $ChildDomainName -       ParentDomainName $DomainName -SafeModeAdministratorPassword `$DomainCredential -Force -NoRebootOnCompletion

"@

Invoke-VMScript -ScriptText $ConfigureChildDomain -VM $DomainControllerVMName_02 -GuestCredential $DCLocalCredential_02


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

Reply
0 Kudos
ToddBertschi
Contributor
Contributor

Okay. I think I have it. I figured I was goofing up my variables and I had completely forgotten about the back-tick. I'm going to take the code you provided and see if I can make it work in my environment. The first error is that the module 'datum' could not be loaded on line 3 char 15.
Reply
0 Kudos
LucD
Leadership
Leadership

Try replacing

$user = "Datum\administrator"

with

$user = 'Datum\administrator'


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

Reply
0 Kudos
ToddBertschi
Contributor
Contributor

Yup, that was the easy fix. I also had issues with my actual password having characters that needed escaping as well. Well, when I say they needed escaping what I really mean is I came up with a better password without using those characters.

Reply
0 Kudos
ToddBertschi
Contributor
Contributor

Well after banging my head against this for the last 2 days I finally realized I don't need it. I'm building a domain environment and my idea of having changeable user names and passwords is nice, but everything is going to be the same until the later steps when I add users. That’s when I'll be resetting passwords and users but for now I'll be using the same name and password for everything. Here is the code I ended up with (with the one huge line just chopped a bit for readability.

$ConfigureChildDomain = @'

$DomainUser = 'datum\administrator'

$DomainPWord = 'P@ssw0rd123' | ConvertTo-SecureString -AsPlainText -Force

$DomainCredential = New-Object -TypeName System.Management.Automation.PSCredential($DomainUser,$DomainPWord)

Install-ADDSDomain -CreateDnsDelegation -Credential $Credential -DatabasePath 'C:\Windows\NTDS' -DomainMode 'WinThreshold' -DomainType 'ChildDomain' -InstallDNS -LogPath 'C:\Windows\NTDS'

-NewDomainName 'child' -NewDomainNetBiosName 'CHILD' -ParentDomainName 'datum.local' -SiteName 'Default-First-Site-Name' -SysvolPath 'C:\Windows\SYSVOL' -SafeModeAdministratorPassword

(ConvertTo-SecureString -String "P@ssw0rd123" -AsPlainText -Force) -Force

 ‘@

 

The good thing is thanks to this problem, I have a better understanding of variables and how they are substituted. Thank you for your help LucD.

Reply
0 Kudos