Saltstack + vSphere: Deploying Windows VM’s with Windows Minion

Ensure that you have set up sphere provider provider, refer my previous blog

create a windows profile


root@saltyub:/# cat /etc/salt/cloud.profiles.d/w16k.conf 
  provider: vcsa
  clonefrom: w16k_salt 
#  devices: 
#   network: 
#    Network adaptor 1:
#     name: VM Network
#     adapter_type: vmxnet3
#     switch_type: standard
#     ip:
#     gateway: []
#     subnet_mask:
#     domain: ntitta.lab
  cluster: vSAN
  datastore: vsanDatastore
  power_on: True
  deploy: True
  customization: True
   master: saltyu.ntitta.lab
  win_username: administrator 
  win_password: 'P@ssw0d'
  plain_text: True
  win_user_fullname: admin
  win_run_once: 'powershell.exe c:\scripts\e.winrm.ps1'
  win_installer: /salt/minion/Salt-Minion-3000.9-Py2-AMD64-Setup.exe
  winrm_verify_ssl: False

Ensure that you have the smbprotocol and pypsexec installed

pip3 install smbprotocol
pip3 install pypsexec

on the guest windows server template, ensure vmware tools is installed and create a PowerShell script in the path: c:\scripts\e.winrm.ps1, refer salt doc for more information:

New-NetFirewallRule -Name "SMB445" -DisplayName "SMB445" -Protocol TCP -LocalPort 445
New-NetFirewallRule -Name "WINRM5986" -DisplayName "WINRM5986" -Protocol TCP -LocalPort 5986

winrm quickconfig -q
winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="300"}'
winrm set winrm/config '@{MaxTimeoutms="1800000"}'
winrm set winrm/config/service/auth '@{Basic="true"}'

$SourceStoreScope = 'LocalMachine'
$SourceStorename = 'Remote Desktop'

$SourceStore = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList $SourceStorename, $SourceStoreScope

$cert = $SourceStore.Certificates | Where-Object -FilterScript {
    $_.subject -like '*'

$DestStoreScope = 'LocalMachine'
$DestStoreName = 'My'

$DestStore = New-Object -TypeName System.Security.Cryptography.X509Certificates.X509Store -ArgumentList $DestStoreName, $DestStoreScope


winrm create winrm/config/listener?Address=*+Transport=HTTPS `@`{CertificateThumbprint=`"($cert.Thumbprint)`"`}

Restart-Service winrm

download salt windows minion installer to the below path on the salt-master:
/salt/minion/, exe can be downloaded from


Deploy Windows VM via salt:

salt-cloud -p w16k w16k-salty-minion -l debug

Deployed VM you can see firewall and salt minion installed:


[ERROR   ] Unable to execute command
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/salt/utils/", line 1005, in wait_for_psexecsvc
    stdout, stderr, ret_code = run_psexec_command(
  File "/usr/lib/python3/dist-packages/salt/utils/", line 956, in run_psexec_command
    client = Client(
  File "/usr/lib/python3/dist-packages/salt/utils/", line 879, in __init__
    self._client = PsExecClient(server, username, password, port, encrypt)
NameError: name 'PsExecClient' is not defined

cause: PsExecClient module is not installed. , use pip3 to install this

upgrade vRA 8.2 to 8.3

Upgrade LCM

Log in to LCM> Lifecycle operations> Settings> System upgrade

Create snapshot

Once snapshot is done, Click on Check for upgrade,

vRLCM will reboot as a part of the upgrade. Wait patiently… (go have a coffee)

On successfull upgrade, we should see :

Add vRA package repository to LCM

Download vRA 8.3 upgrade repository from

copy the ISO to LCM, /data directory

Now, Go back to LCM> Lifecycle operations> settings > Binary mapping>Add product binaries, enter path in base location and then cick on discover

Clock on the prelude(the one we uploaded) and click on add

wait for the import task to compleate. You can take a look at the task by clicking on requests > Click on the most recent request

On successfull import, you should see it in the binary mapping:

Upgrade VRA:

Now that the upgrade packages have been uploaded to LCM, Go into LCM > LifeCycle Operations > Environments > Click on “view details” for the vRA environment.

Triger inventory sync:

Go grab a coffee!!, Typically at this point its just waiting for vRLCM to perform the upgrade.

Click on upgrade:

Run pre-check

wait for pre-check to complete: (takes about 3-10 min)

submit upgrade task

Now, Go grab a cup of coffee, This step generally takes a while.

certificate of FQDN has expired when attempting to add a product into the usage meter, specifically when using Sectigo signed certificates.

When attempting to add a product to usage meter, the product migth fail to add if it has a certificate signed by sectigo


Resolution: Import root certificates to the appliance java keystone.

* take a snapshot of the appliance
* ssh to usage meter appliance
* change user to root

su root

* create or import the root certificate to the appliance

curl >  /home/usagemeter/root.crt

Note: if you have a different CA provider, replace the below with the path to download the root certificate or simply scp the certificate to the UM appliance.

import the certificates (run the command as it is if the root is placed in /home/usagemeter/root.crt

keytool -import -trustcacerts -file /home/usagemeter/root.crt -alias USERTRUST -keystore /usr/java/jre-vmware/lib/security/cacerts

Note: Default keystore password is


on successfull import, you should see

now, go ahead and add the product back in to usage meter:

Note: when adding vCD, Please ensure that you add the endpoint in the format https://FQDN, IE:

Troubleshooting (show fill certificate chain, check the validity of the last certificate. ):

openssl s_client -showcerts -connect vcsa.ntitta.lab:443