VMware Cloud Community
Christian96
Contributor
Contributor

PowerCLI Commands during Instant Cone process

Hi guys,

I am having a big problem executing PowerCLI commands in a Powershell script when creating Instant Clones.

The script is executed through VMware ClonePrep Guest Customization.

The call $VCSession = Connect-VIServer -Server $VCServer -Credential $cred is not executed.

This line is not executed and not written to the log. Basically, the vCenter Server is reachable from this network and when I run the script manually after the cloning process, it runs through successfully.

- I have TLS1.2 enabled on the master machine:
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

- The VMware.PowerCLI modules are installed:
Install modules -Name "VMware.PowerCLI" -Scope AllUsers

- Connect to the vCenter Server manually:
Connect-VIServer vcs2.itwm.fhg.de

and disable certificate checking for the first time:
Set-PowerCLIConfiguration -InvalidCertificateAction Ignore.

The saved user running the script has admin privileges.

I also do not see any PowerCLI Connects on the vCenter Server under Events during the clone process.

Do you guys have any idea where the error could be?

Thanks a lot for the help!

Kind regards,
Christian

0 Kudos
22 Replies
LucD
Leadership
Leadership

I understand that the account under which you did a Connect-VIServer without credentials, is not the same as the account in the $cred variable?


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

0 Kudos
Christian96
Contributor
Contributor

The account for the Connect-VIServer command is always the same (admin@domain)

I have created PSCredential object and put the username and password in it.

The password is saved as a securestring and stored in the same directory as the PS Script.

So with the same credentials the manual connect works but not the automatic one during the cloning process.

0 Kudos
LucD
Leadership
Leadership

Your example of the manual Connect-VIServer doesn't seem to have any credentials passed.
Are you relying on integrated authentication?
How exactly did you specify the user account?
As domain\use or as user@domain?

Which PowerCLI/PowerShell version are you using?
Against which version of vSphere?


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

0 Kudos
Christian96
Contributor
Contributor

I have put the script in the attachment for better clarification.

In it you can see how the credentials are stored.

Here are the technical data:
Agent Version: 8.0 (2006)
RDSH server OS version: Windows Server 2016
Connection Server version: 8.0 (2006)

PowerCLI version
----------------
VMware PowerCLI 12.1.0 build 17009493
---------------
Component Versions
---------------
VMware Common PowerCLI Component 12.1 build 16997174
VMware Cis Core PowerCLI Component PowerCLI Component 12.1 build 16997582
VMware VimAutomation VICore Commands PowerCLI Component PowerCLI Component 12.1 build 16997984

PSVersion 5.1.14393.3866

0 Kudos
LucD
Leadership
Leadership

I normally do the following to create a PSCredential password

$password = Get-Content 'C:\Windows\System32\Sysprep\ITWM\securestring.txt' | 
    ConvertTo-SecureString -AsPlainText -Force


Also worth checking, are you sure there is no extra blank or another type of white space (<CR>/<LF>) present in that .txt file.


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

0 Kudos
Christian96
Contributor
Contributor

So far, I have never had any problems with this method.

The password is saved correctly and is also read and used correctly when executed manually.

Therefore I do not assume a problem with the $password variable.

I created the log file myself to analyze the problem more precisely. It can happen that there are too many white spaces in it.

Thanks a lot for the help and the tips!

0 Kudos
LucD
Leadership
Leadership

You are suppressing any errors on the Connect-VIServer in the script.
I would use the Connect-VIServer in a try-catch construct with -ErrorAction Stop on the Connect-VIServer cmdlet.
In the Catch block you can check what $error[0] shows as exception


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

0 Kudos
Christian96
Contributor
Contributor

okay, i will try these:

try{
$VCSession = Connect-VIServer -Server $VCServer -Credential $cred -ErrorAction Stop
Get-Date | Out-File $log -Append
$VCSession | Out-File $log -Append
}
catch{
$error[0] | Out-File $log -Append
}

0 Kudos
Christian96
Contributor
Contributor

Thank you for your help!

The new Log shows the failure:

Connect-VIServer : Cannot validate argument on parameter 'Credential'. The
argument is null or empty. Provide an argument that is not null or empty, and
then try the command again.
At C:\Windows\temp\vmware\instant_clone_wts.ps1:70 char:69
+ ... ession = Connect-VIServer -Server $VCServer -Credential $cred -ErrorA ...
+ ~~~~~
+ CategoryInfo : InvalidData: (:) [Connect-VIServer], ParameterBi
ndingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutom
ation.ViCore.Cmdlets.Commands.ConnectVIServer

If someone has ideas how to solve this I would be very grateful.

0 Kudos
LucD
Leadership
Leadership

Did you already try adding those switches on the ConvertTo-SecureString cmdlet?


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

0 Kudos
Christian96
Contributor
Contributor

Now i added those switches on the ConvertTo-SecureString cmdlet und got a new log.

Connect-VIServer : 31.12.2020 11:46:07 Connect-VIServer Cannot complete login
due to an incorrect user name or password.
At C:\Windows\temp\vmware\instant_clone_wts.ps1:70 char:22
+ ... VCSession = Connect-VIServer -Server $VCServer -Credential $cred -Err ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Connect-VIServer], InvalidLog
in
+ FullyQualifiedErrorId : Client20_ConnectivityServiceImpl_Reconnect_SoapE
xception,VMware.VimAutomation.ViCore.Cmdlets.Commands.ConnectVIServer

Unfortunately I don't understand the error message, because with the same credentials everything works when I run it manually.
Perhaps because the securestring is read incorrectly?

0 Kudos
LucD
Leadership
Leadership

I suspect the issue might be in that .txt file from which you read the password.
Perhaps, as a test, try hard-coding the password in the script


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

0 Kudos
Christian96
Contributor
Contributor

Hello,

now I get the known error again:

Connect-VIServer : Cannot validate argument on parameter 'Credential'. The
argument is null or empty. Provide an argument that is not null or empty, and
then try the command again.
At C:\Windows\temp\vmware\instant_clone_wts.ps1:71 char:69
+ ... ession = Connect-VIServer -Server $VCServer -Credential $cred -ErrorA ...
+ ~~~~~
+ CategoryInfo : InvalidData: (:) [Connect-VIServer], ParameterBi
ndingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutom
ation.ViCore.Cmdlets.Commands.ConnectVIServer

The password is now in plain text in the $password variable.

I suspect that the $cred object is not created correctly or the -Credential parameter is not read correctly in the Connect-VIServer cmdlet.

0 Kudos
LucD
Leadership
Leadership

Without seeing the code you are currently using, there is not a lot I can suggest.


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

0 Kudos
Christian96
Contributor
Contributor

Good morning,

I attached the current script (without password of course) with the current log again.

I have shortened the log because it became very long due to the do-until loop.

 

0 Kudos
LucD
Leadership
Leadership

You are not converting the password to a SecureString before creating the PSCredential objecy.

You should do something like this

$userName = 'whatever'
$password = "PasswordInPlainText"

$secPswd = ConvertTo-SecureString -String $password -AsPlainText -Force
$cred = New-Object -TypeName System.Management.Automation.PSCredential -argumentlist $username, $secPswd

 


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

Christian96
Contributor
Contributor

Thank you very much!

Now the script was executed successfully.

However only on 2 of 3 clones... for whatever reason 😕
I have to check this again more exactly.

Now I have to take the password from the script, because the servers should finally run in production area.

Do you have an idea how I can store the password as SecureString correctly?

 

0 Kudos
LucD
Leadership
Leadership

That is a basic question, with no definitive answer I'm afraid.
It depends on the platform where you run this.
For example, the PowerCLI New-VICredentialSToreItem only works on a Windows platform.
And since it uses DPAPI, you can only use this with the same user account and on the same station.

The ConvertTo-SecureString cmdlet uses the same DPAPI calls, and it is bound to the same user on the same station.

Unless you use the Key parameter with the cmdlet.
But then the problem just shifts to how to store and protect that "key".

Similar to the CliXml method.

Store

Get-Credential | Export-Clixml -Path C:\Temp\cred.xml

Retrieve

$cred = Import-Clixml -Path C:\Temp\cred.xml

But again, this only protects your password (for the same user and on the same station) on a Windows platform.
The cmdlets work on a Linux platform, but the password is not encrypted in any way.

All that is why there are 3th party secret managers, like for example The Vault.
But most of these require a kind of setup (repository, separate station...).

So sorry, I have no answer with a simple/straightforward/secure solution.


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

Christian96
Contributor
Contributor

yes, I know the problem.

However, it raises the following question for me:

I run the same script with the SecureString already stored on the new system. Without changing anything from the master image. And it works perfectly.

Here should the error appear that the credentials are wrong (SecureString does not match the system - same user).
There is no error... it runs without problems.

If I run the same script with the same SecureString as a ClonePrep script the above mentioned error message comes up... for the reason you described very well.

One idea would be to delete the script at the end, since it is only executed once and is no longer in use after that. On the master machine, the password could remain in plain text, no one has access there.

____________

After another try, the script ran successfully on all machines.

0 Kudos