How to deploy Container Service Extension (CSE) 3.1.1?

Please find the steps to deploy Container Service Extension 3.1.1.

Step 1: Deploy CentOS 7 VM

Selected CentOS 7 as the Operating System for CSE server. CentOS 7 has higher EOL than CentOS 8. You can find the installations steps for CentOS 7 here.

Please find more details on CentOS releases below.

Kindly ensure following configurations are done in CSE VM.

  • Configure DNS.
  • Configure NTP.
  • Configure SSH.
  • SSH access for root user is enabled.

Please note the following network connections are required for rest of the configurations.

  • Access to VCD URL (https) from CSE Server.
  • The Internet access from CSE server.

Step 2: Take a snapshot of CSE server VM.

It’s recommended to take a snapshot of CSE server before continuing with Python installation. It’s an optional step.

Step 3: Install Python 3.7.3 or greater

Install python 3.7.3 or greater in 3.7.x series. Please note that python 3.8.0 and above is not supported (ref: CSE doc)
The built-in python version in CentOS 7 is 2.7. So, we’ve to install the latest in 3.7.x series, at the moment version 3.7.12 is the latest. Please follow the below steps to install Python.

yum update -y
yum install -y yum-utils
yum groupinstall -y development
yum install -y gcc openssl-devel bzip2-devel libffi-devel zlib-devel xz-devel

#Install sqlite3

cd /tmp/
curl -O
tar xvf sqlite-autoconf-3310100.tar.gz
cd sqlite-autoconf-3310100/
make install

# Install Python

cd /tmp/
curl -O
tar -xvf Python-3.7.12.tgz
cd Python-3.7.12
./configure --enable-optimizations
make altinstall
alternatives --install /usr/bin/python3 python3 /usr/local/bin/python3.7 1
alternatives --install /usr/bin/pip3 pip3 /usr/local/bin/pip3.7 1
alternatives --list

# Check Python and pip3 versions

python3 --version
pip3 --version

Step 4: Install vcd-cli

# Install and verify vcd-cli
pip3 install vcd-cli
vcd version
     vcd-cli, VMware vCloud Director Command Line Interface, 24.0.1

Step 5: Install CSE

# Install and verify cse
pip3 install container-service-extension
cse version
CSE, Container Service Extension for VMware vCloud Director, version 3.1.1

Step 6: Enable CSE client

# Create ~/.vcd-cli directory
mkdir ~/.vcd-cli

# Create profiles.yaml
cat > ~/.vcd-cli/profiles.yaml << EOF
- container_service_extension.client.cse

Step 7: Create CSE Service Role for CSE server management

[root@test ~]# cse create-service-role <vcd fqdn> -s
Username for System Administrator: administrator
Password for administrator:
Connecting to vCD:  <vcd fqdn>
Connected to vCD as system administrator: administrator
Creating CSE Service Role...
Successfully created CSE Service Role

Step 7: Create service account for CSE in VCD

Create a Service Account in VCD with the role ‘CSE Service Role’

Step 8: Create service account for CSE in vCenter

Create new role in vCenter with Power User + Guest Operations privilege. Assign the role to the service account for CSE.

  • Clone ‘Virtual Machine Power User (sample) role
  • Edit role
  • Select Virtual machine > Guest operations.

Step 9: Create a sample CSE config file and update it.

cse sample -o config.yaml

# vi config.yaml

  verify_ssl: false

  log: true
  password: my_secret_password
  port: 443
  username: administrator
  verify: false

- name: vc1
  password: my_secret_password
  username: [email protected]
  verify: false

  enforce_authorization: false
  legacy_mode: false
  log_wire: false
  no_vc_communication_mode: false
  processors: 15
    enable: true

  catalog: cse
  ip_allocation_mode: pool
  network: my_network
  org: my_org
  storage_profile: '*'

Step 7: Encrypt Configuration file

cse encrypt config.yaml --output encrypted-config.yaml

Step 8: Validate the Configuration file

chmod 600 encrypted-config.yaml
cse check encrypted-config.yaml

Step 9: Install CSE

cse install -c encrypted-config.yaml --skip-template-creation

Step 10: Validate CSE Installation

cse check encrypted-config.yaml --check-install

Step 10: List the available templates

# cse template list -c encrypted-config.yaml
Password for config file decryption:
Decrypting 'encrypted-config.yaml'
Retrieved config from 'encrypted-config.yaml'
name                                revision  local    remote      cpu    memory  description                                                        deprecated
--------------------------------  ----------  -------  --------  -----  --------  -----------------------------------------------------------------  ------------
ubuntu-16.04_k8-1.21_weave-2.8.1           1  No       Yes           2      2048  Ubuntu 16.04, Docker-ce 20.10.7, Kubernetes 1.21.2, weave 2.8.1    No
ubuntu-16.04_k8-1.20_weave-2.6.5           2  No       Yes           2      2048  Ubuntu 16.04, Docker-ce 19.03.15, Kubernetes 1.20.6, weave 2.6.5   No
ubuntu-16.04_k8-1.19_weave-2.6.5           2  No       Yes           2      2048  Ubuntu 16.04, Docker-ce 19.03.12, Kubernetes 1.19.3, weave 2.6.5   No
ubuntu-16.04_k8-1.18_weave-2.6.5           2  No       Yes           2      2048  Ubuntu 16.04, Docker-ce 19.03.12, Kubernetes 1.18.6, weave 2.6.5   No
photon-v2_k8-1.14_weave-2.5.2              4  No       Yes           2      2048  PhotonOS v2, Docker-ce 18.06.2-6, Kubernetes 1.14.10, weave 2.5.2  Yes

Step 11: Import the latest K8S template


# cse template install ubuntu-16.04_k8-1.21_weave-2.8.1 1 -c encrypted-config.yaml

It will take a while to complete the download of template, be patient.

Downloading file from '' to 'cse_cache/ubuntu-16.04-server-cloudimg-amd64.ova'...
Download complete
Uploading 'ubuntu-16.04-server-cloudimg-amd64.ova' to catalog 'cse-site1-k8s'
Uploaded 'ubuntu-16.04-server-cloudimg-amd64.ova' to catalog 'cse-site1-k8s'
Deleting temporary vApp 'ubuntu-16.04_k8-1.21_weave-2.8.1_temp'
Creating vApp 'ubuntu-16.04_k8-1.21_weave-2.8.1_temp'
Found data file: /root/.cse_scripts/2.0.0/ubuntu-16.04_k8-1.21_weave-2.8.1_rev1/
Created vApp 'ubuntu-16.04_k8-1.21_weave-2.8.1_temp'
Customizing vApp 'ubuntu-16.04_k8-1.21_weave-2.8.1_temp', vm 'ubuntu-1604-k8s1212-weave281-vm'
Found data file: /root/.cse_scripts/2.0.0/ubuntu-16.04_k8-1.21_weave-2.8.1_rev1/
Waiting for guest tools, status: "vm='vim.VirtualMachine:vm-2296', status=guestToolsNotRunning
Waiting for guest tools, status: "vm='vim.VirtualMachine:vm-2296', status=guestToolsNotRunning
Waiting for guest tools, status: "vm='vim.VirtualMachine:vm-2296', status=guestToolsNotRunning
Waiting for guest tools, status: "vm='vim.VirtualMachine:vm-2296', status=guestToolsRunning

waiting for process 1611 on vm 'vim.VirtualMachine:vm-2296' to finish (1)
waiting for process 1611 on vm 'vim.VirtualMachine:vm-2296' to finish (2)
waiting for process 1611 on vm 'vim.VirtualMachine:vm-2296' to finish (3)
waiting for process 1611 on vm 'vim.VirtualMachine:vm-2296' to finish (4)
waiting for process 1611 on vm 'vim.VirtualMachine:vm-2296' to finish (5)
waiting for process 1611 on vm 'vim.VirtualMachine:vm-2296' to finish (6)
waiting for process 1611 on vm 'vim.VirtualMachine:vm-2296' to finish (7)
waiting for process 1611 on vm 'vim.VirtualMachine:vm-2296' to finish (8)
Searching for GRUB installation directory ... found: /boot/grub
Searching for default file ... found: /boot/grub/default
Testing for an existing GRUB menu.lst file ... found: /boot/grub/menu.lst
Searching for splash image ... none found, skipping ...
Found kernel: /boot/vmlinuz-4.4.0-119-generic
Found kernel: /boot/vmlinuz-4.4.0-210-generic
Found kernel: /boot/vmlinuz-4.4.0-119-generic
Updating /boot/grub/menu.lst ... done

Generating grub configuration file ...
Found linux image: /boot/vmlinuz-4.4.0-210-generic
Found initrd image: /boot/initrd.img-4.4.0-210-generic
Found linux image: /boot/vmlinuz-4.4.0-119-generic
Found initrd image: /boot/initrd.img-4.4.0-119-generic
customization completed

Customized vApp 'ubuntu-16.04_k8-1.21_weave-2.8.1_temp', vm 'ubuntu-1604-k8s1212-weave281-vm'
Creating K8 template 'ubuntu-16.04_k8-1.21_weave-2.8.1_rev1' from vApp 'ubuntu-16.04_k8-1.21_weave-2.8.1_temp'
Shutting down vApp 'ubuntu-16.04_k8-1.21_weave-2.8.1_temp'
Successfully shut down vApp 'ubuntu-16.04_k8-1.21_weave-2.8.1_temp'
Capturing template 'ubuntu-16.04_k8-1.21_weave-2.8.1_rev1' from vApp 'ubuntu-16.04_k8-1.21_weave-2.8.1_temp'
Created K8 template 'ubuntu-16.04_k8-1.21_weave-2.8.1_rev1' from vApp 'ubuntu-16.04_k8-1.21_weave-2.8.1_temp'
Successfully tagged template ubuntu-16.04_k8-1.21_weave-2.8.1_rev1 with placement policy native.
Deleting temporary vApp 'ubuntu-16.04_k8-1.21_weave-2.8.1_temp'
Deleted temporary vApp 'ubuntu-16.04_k8-1.21_weave-2.8.1_temp'

Step 12: Confirm the template is available in CSE catalog

Login to CSE Tenant portal.
Navigate to the Libraries > Catalogs > vApp Templates. We can see the newly created K8S upstream template.

Step 13: Enable Organizations for Native deployments.

The provider must explicitly enable organizational virtual datacenter(s) to host native deployments, by running the command: vcd cse ovdc enable.

vcd login <vcd> system administrator -i
InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised.
administrator logged in, org: 'system', vdc: ''

# vcd cse ovdc enable <orgvdc> -n -o <organization>
# vcd cse ovdc enable TEST-OVDC -n -o Site1-Test

InsecureRequestWarning: Unverified HTTPS request is being made. Adding certificate verification is strongly advised.
OVDC Update: Updating OVDC placement policies
task: 10e70b37-5aa6-4cf9-b437-ef478bd9f06a, Operation success, result: success

Step 14: Check Create New Native Cluster is available now

Login to the VCD Tenant portal and navigate to More > Kubernetes Container Clusters.
Click on New.

We can see the option to ‘Create New Native Cluster’.

Step 15: Publish Right Bundle ‘cse:nativeCluster Entitlement’

  • The following article has details on differences between right bundle and roles.
  • Login to VCD as Provider and navigate to Administration > Right Bundles
  • Select ‘cse:nativeCluster Entitlement’
  • Create a backup of right bundle by Cloning.
    • Select the Rights Bundle cse:nativeCluster Entitlement.
    • Select Clone.
    • Keep the auto generaed name ‘Clone:cse:nativeCluster Entitlement’
  • Edit the right bundle cse:nativeCluster Entitlement
  • Select the following rights
  • Select ‘PUBLISH’
  • Select the specific Tenants from the list.

Step 16: Add CSE rights to Global Role ‘Organization Administrator’

  • Login as Provider and edit the Global Role ‘Organization Administrator’
  • Select same rights we selected in the last step.

How to update Photon OS 3.x Root Password History?

Sometimes it’s annoying when Photon OS based appliances doesn’t allow to use previously used password for root user. You may see the error ‘Password has been already used. Choose another‘ when you try to use the password which was used earlier.

root@test [ ~ ]# passwd
New password:
Retype new password:
Password has been already used. Choose another.

By default, Photon OS remember last Five passwords. You can see the setting ‘remember=3’ in /etc/pam.d/system-password

root@test [ ~ ]# cat /etc/pam.d/system-password
# Begin /etc/pam.d/system-password
password    requisite     minlen=8 minclass=4 difok=4 maxsequence=0 retry=3 enforce_for_root
password    requisite    retry=3 remember=5 enforce_for_root
password    required         sha512 shadow use_authtok
# End /etc/pam.d/system-password

By changing ‘remember ‘ from 5 to 0 we can disable the remember password count and reset the root password.

Upgrade VMware Cloud Director App Launchpad from 2.0 to 2.1

Please find the steps to upgrade VMware Cloud Director App Launchpad from version 2.0 to 2.1

  1. Download VMware Cloud Director App Launchpad 2.1 RPM package from here.
  2. Upload it to the App Launchpad VM.
  3. Open an SSH connection to the App Launchpad VM and log in as root.
  4. Upgrade the RPM package.
[root@test ~]# rpm -U vmware-alp-2.1.0-18834930.x86_64.rpm
warning: vmware-alp-2.1.0-18834930.x86_64.rpm: Header V3 RSA/SHA1 Signature, key ID 001e5cc9: NOKEY

Execute 'alp upgrade' to upgrade ...

  Append the excute permission to the existing logs...

5. Run the following command to upgrade App Launchpad.

[root@test ~]# alp upgrade --admin-user administrator@system --admin-pass 'passwd'
Upgraded the plugin of App Launchpad successfully.

Upgraded the management service successfully.
  [Upgrade Task]

6. Restart alp service and confirm its running.

[root@test~]# systemctl restart alp
[root@test ~]# systemctl status alp
● alp.service - VMware ALP Management Service
   Loaded: loaded (/usr/lib/systemd/system/alp.service; enabled; vendor preset: disabled)
   Active: active (running) since Thu 2021-11-18 11:46:14 +01; 14s ago
 Main PID: 29334 (java)
   CGroup: /system.slice/alp.service
           └─29334 java -jar /opt/vmware/alp/alp.jar --logging.path=log

Nov 18 11:46:14 bd1-srp-al01.acs.local systemd[1]: Stopped VMware ALP Management Service.
Nov 18 11:46:14 bd1-srp-al01.acs.local systemd[1]: Started VMware ALP Management Service.

7. Diagnose deployment errors by running the /opt/vmware/alp/bin/diagnose executable file.

The diagnose tool verifies that the services are up and running and that all configuration
requirements are met.

[root@test ~]# /opt/vmware/alp/bin/diagnose

Step 1: System diagnose
- App Launchpad service is initialized.

Step 2: Cloud Director diagnose
- Service Account for App Launchpad is good.
- App Launchpad's extension is ready.

Step 3: MQTT diagnose
- Cloud Director MQTT for extensibility is ready.

Step 4: Integration diagnose
- App Launchpad API is up, and version is 2.1.0-18834930.

Step 5: App Launchpad diagnose
- App Launchpad service is listening on port 8086.

8. Confirm the ALP version.

[root@test ~]# alp
        alp - The Cloud Director App Launchpad
        (ALP) Command-line tool

        alp <subcommand> [flags]


How to create AWS Lambda function with PowerCLI to access VMConAWS?

AWS Lambda in a nutshell

Lambda is an AWS offering to build serverless applications. It helps you to run code without provisioning or managing servers. The Lambda functions can be invoked directly through API calls or in response to events. AWS will charge the customer only for the compute time consumed by Lambda function, so no need to pay for idle time. You can learn more about lambda here.

AWS Lambda, PowerShell and PowerCLI

The code you run on AWS Lambda is uploaded as a ‘Lambda Function’. AWS Lambda natively supports PowerShell as scripting language. It helps us to write Lambda functions in PowerShell which includes commands from PowerCLI modules.

Let us see the steps to create a PowerShell based Lambda Function to get the list of VMs from a VMware Cloud on AWS SDDC. As of now the AWS Code Editor doesn’t support writing or editing PowerShell based Lambda functions. The steps discuss how to create the Lambda functions offline and deploy them in AWS Lambda.

Step 1 : Install PowerShell Core.

The Lambda functions in PowerShell require PowerShell Core 6.0, Windows PowerShell isn’t supported. If you have PowerShell Core 6.0 or above already installed, skip to step 2. The environment variable $PSVersionTable will help you to find the PowerShell version and Edition.

I’ve used Powershell Core v6.2.1 which can be downloaded from PowerShell GitHub repo.

1.1 Goto > Assets > and download the Package suitable for your OS, mine is Windows 10 and the bundle ‘PowerShell-6.2.1-win-x64.msi’ worked fine.

1.2 Once downloaded, double-click the installer and follow the prompts.

Step 2 : Install .NET Core 2.1 SDK.

Because PowerShell Core is built on top of .NET Core, the Lambda support for PowerShell uses the same .NET Core 2.1 runtime for both .NET Core and PowerShell Lambda functions. The .NET Core 2.1 SDK is used by the Lambda PowerShell publishing cmdlets to create the Lambda deployment package. The .NET Core 2.1 SDK is available at .NET downloads on the Microsoft website. Be sure to install the SDK and not the runtime installation.

Step 3 : Install Powershell module ‘AWSLambdaPSCore’

Open PowerShell Core and run the following command to install ‘AWSLambdaPSCore’ module.

Install-Module AWSLambdaPSCore -Scope CurrentUser

The following are the commands available in module ‘AWSLambdaPSCore’

Step 4 : Install PowerCLI

If you already have PowerCLI modules installed in Powershell Core, skip this step.

Open PowerShell Core and run the following command

Install-Module VMware.PowerCLI

Step 5 : Create script from PowerShell Lambda Templates.

AWSLambdaPSCore module provides some Script Templates. Get-AWSPowerShellLambdaTemplate will list out the available templates.

We will use the template ‘Basic’ to create script ‘VMC-GetVM.ps1’ for getting the VM list from VMC SDDC.

Step 6 : Modify the script to get the VMs from vCenter located VMConAWS SDDC.

If you are new to Powershell Lambda its good to go through this articleto understand Input Object, Returning Data, Additional Modules and Logging.

Open the script VMC-GetVM.ps1 in the editor, I use VSCode. Replace the content of the script with the following script.

Note: Please ensure the version of modules marked with #Requiresstatement are same as the version of modules loaded in Powershell Core. If it’s different, then update the script with version details of corresponding modules which are loaded. The following command will help to find the versions of required modules.

Get-InstalledModule VMware.*.Sdk,VMware.*.common,VMware.vim,VMware.*.Cis.Core,VMware.*.core | select Name,Version

The values for the properties (venter, vCenterUser, etc) in the object $LamdaInput will be passed when we execute the function.

# PowerShell script file to be executed as a AWS Lambda function. 
# When executing in Lambda the following variables will be predefined.
#   $LambdaInput - A PSObject that contains the Lambda function input data.
#   $LambdaContext - An Amazon.Lambda.Core.ILambdaContext object that contains information about the currently running Lambda environment.
# The last item in the PowerShell pipeline will be returned as the result of the Lambda function.
# To include PowerShell modules with your Lambda function, like the AWSPowerShell.NetCore module, add a "#Requires" statement 
# indicating the module and version.
#Requires -Modules @{ModuleName='VMware.VimAutomation.Sdk';ModuleVersion=''}
#Requires -Modules @{ModuleName='VMware.VimAutomation.Common';ModuleVersion=''}
#Requires -Modules @{ModuleName='VMware.Vim';ModuleVersion=''}
#Requires -Modules @{ModuleName='VMware.VimAutomation.Cis.Core';ModuleVersion=''}
#Requires -Modules @{ModuleName='VMware.VimAutomation.Core';ModuleVersion=''}

# Uncomment to send the input event to CloudWatch Logs
#Write-Host (ConvertTo-Json -InputObject $LambdaInput -Compress -Depth 5)

$vCenter = $lambdainput.vCenter
$vCenterUser = $lambdainput.vCenterUser
$vCenterPassword = $lambdainput.vCenterpassword
Connect-VIServer $vCenter -User $vCenterUser -Password $vCenterPassword
$vmlist = get-vm
Write-Host $vmlist.Name

Save the script.

Step 7 : Reduce the size of package

In next step we will publish the Lambda Function. While publishing, a deployment package that contains our PowerShell script ‘VMC-GetVM.ps1’ and all modules declared with the #Requires statement will be created. But the deployment may fail since the package with listed PowerCLI modules will exceed Lambda’s hard limit on Package size, ie 69905067 bytes. In that situation the following error will be thrown.

To avoid that, as a workaround, we’ve to reduce the package size by cutting down the size of PowerCLI modules. When I checked ‘VMware.VimAutomation.Core’ is the largest module which is due to  Remote Console files included in the module.

Browse to the following path and move the folder ‘VMware Remote Console’ to Documents.


Step 8 : Create IAM role to access CloudWatch Log and to execute Lambda.

Login to AWS Console and navigated to IAM. Create new role ‘lambda_basic_excution’ with the policy ‘CloudWatchLogsFullAccess’.

Step 9 : Publish to Lambda

To publish our new PowerShell based Lambda function, let’s execute the following command from Powershell Core.

Publish-AWSPowerShellLambda -ScriptPath <path>\VMC-GetVM.ps1 -Name RDPLockDown -Region <aws region> -IAMRoleArn lambda_basic_excution

It will take a while to create the package and deploy to AWS Lambda.

Step 10 : Configure environment variable.

Once the function is deployed, login to AWS Console and navigate to Lambda. Select the newly created function ‘VMC-GetVM’

Set the environment variable HOME to /tmp.

Step 11 : Install AWSPowerShell module.

To execute the newly created function from PowerShell Core we need the module ‘AWSPowerShell’. Run the following command to install it.

Install-Module AWSPowerShell

Step 12 : Execute the function

From the editor (VSCode) create new file LambdaExecute.ps1 and copy the following code.

$payload = @{    vCenter =  '<FQDN of vCenter in VMConAWS>'    vCenterUser = '<vCenter User>'    vCenterpassword = '<vCenter Password>'} | convertto-json Invoke-LMFunction -FunctionName VMC-GetVM  -Payload $payload

Once the execution completed you can see the list of VMs in CloudWatch Logs.

From AWS Console go to CloudWatch > Log Groups and select ‘ /aws/lambda/VMC-GetVM’ and click on latest log stream.

You can see the VMs list in the Message!

Powercli to create report with VM Tag, Category, Tools version and VM HW Version

Recently one of the community members had a requirement to generate report with the following details in .csv format.

– VM Name
– VMware Tools Version
– VM Hardware Version
– Category Names as columns and Tag names as values.

The following PowerCLI script will help to achieve this.

<# .SYNOPSIS Create .csv report with Virtual Machine Tag, Category, VMware tools version and VM Hardware details. .NOTES Author: Sreejesh Damodaran Site: .EXAMPLE PS> get-vmtagandcatefory.ps1


# Connect to the vCenter
Connect-VIServer vCenter1 -user user1 -Password "password"

#Create vmInfo object
$vmInfo = @()
$vmInfoTemp = New-Object "PSCustomObject"
$vmInfoTemp | Add-Member -MemberType NoteProperty -Name VMName -Value ""
$vmInfoTemp | Add-Member -MemberType NoteProperty -Name ToolsVersion -Value ""
$vmInfoTemp | Add-Member -MemberType NoteProperty -Name HWVersion -Value ""
$vmCategories = Get-TagCategory
$vmCategories | %{$vmInfoTemp | Add-Member -MemberType NoteProperty -Name $_.Name -Value "" }
$vmInfo += $vmInfoTemp

get-vm | %{
$vmInfoTemp = New-Object "PSCustomObject"
$toolsVersion = Get-VMGuest $_ | select -ExpandProperty ToolsVersion
$vmInfoTemp | Add-Member -MemberType NoteProperty -Name VMName -Value $_.Name
$vmInfoTemp | Add-Member -MemberType NoteProperty -Name ToolsVersion -Value $toolsVersion
$vmInfoTemp | Add-Member -MemberType NoteProperty -Name HWVersion -Value $_.Version
$vmtags = ""
$vmtags = Get-TagAssignment -Entity $_
$vmCategories | %{
$tempVMtag = ""
$tempCategroy = $_.Name
$tempVMtag = $vmtags | Where-Object {$ -match $tempCategroy}
$vmInfoTemp | Add-Member -MemberType NoteProperty -Name $tempCategroy -Value $
}else {
$vmInfoTemp | Add-Member -MemberType NoteProperty -Name $tempCategroy -Value ""
$vmCategories | %{
$vmInfoTemp | Add-Member -MemberType NoteProperty -Name $ -Value ""
$vmInfo += $vmInfoTemp

$vmInfo | select * -Skip 1 | Export-Csv c:\temp\tags.csv -NoTypeInformation -UseCulture

CSV Output:

PowerCLI to find vCPU to pCPU ratio and vRAM to pRAM ratio

I was in search for a script to generate report on vCPU to pCPU ratio and vRAM to pRAM at cluster level in a vCenter. Found couple of interesting community threads which address part of the requirements. Thought to consolidate (or extract:) ) the code and created the following. The report will be generated as CSV file.

[crayon lang=”powershell”]


$outputFile = “C:\CPU-Memory-Ratio.csv”
$VC = “vCenter Name”

##Connect to the vCenter
Connect-VIServer $VC -User “test” -Password “test”

$Output =@()

Get-Cluster | %{
$hypCluster = $_

## get the GenericMeasureInfo for the desired properties for this cluster’s hosts
$infoCPUMEM = Get-View -ViewType HostSystem -Property Hardware.CpuInfo,Hardware.memorysize -SearchRoot $hypCluster.Id |
Select @{n=”NumCpuSockets”; e={$_.Hardware.CpuInfo.NumCpuPackages}}, @{n=”NumCpuCores”; e={$_.Hardware.CpuInfo.NumCpuCores}}, @{n=”NumCpuThreads”; e={$_.Hardware.CpuInfo.NumCpuThreads}},@{n=”PhysicalMem”; E={“”+[math]::round($_.Hardware.MemorySize / 1GB, 0)}} |
Measure-Object -Sum NumCpuSockets,NumCpuCores,NumCpuThreads,PhysicalMem

## return an object with info about VMHosts’ CPU characteristics

$temp= New-Object psobject
$datacenter = Get-Datacenter -Cluster $hypCluster.Name
$NumVMHosts = if ($infoCPUMEM) {$infoCPUMEM[0].Count} else {0}
$NumCpuSockets = ($infoCPUMEM | ?{$_.Property -eq “NumCpuSockets”}).Sum
$NumCpuCores = ($infoCPUMEM | ?{$_.Property -eq “NumCpuCores”}).Sum
$vmdetails = Get-VM -Location $hypCluster
$NumvCPU = ( $vmdetails | Measure-Object NumCpu -Sum).Sum
$VirtualMem= [Math]::Round(($vmdetails | Measure-Object MemoryGB -Sum).Sum, 2)
$PhysicalMem = ($infoCPUMEM | ?{$_.Property -eq “PhysicalMem”}).Sum

##Calculating the vCPU to pCPU ratio AND vRAM to pRAM ratio.

if ($NumvCPU -ne “0”) {$cpuRatio= “$(“{0:N2}” -f ($NumvCPU/$NumCpuCores))” + “:1”}
if ($VirtualMem -ne “0”) {$memRatio= “$(“{0:N2}” -f ($VirtualMem/$PhysicalMem))” + “:1”}

$temp | Add-Member -MemberType Noteproperty “Datacenter” -Value $datacenter
$temp | Add-Member -MemberType Noteproperty “ClusterName” -Value $hypCluster.Name
$temp | Add-Member -MemberType Noteproperty “NumVMHosts” -Value $NumVMHosts
$temp | Add-Member -MemberType Noteproperty “NumPCPUSockets” -Value $NumCpuSockets
$temp | Add-Member -MemberType Noteproperty “NumPCPUCores” -Value $NumCpuCores
$temp | Add-Member -MemberType Noteproperty “NumvCPU” -Value $NumvCPU
$temp | Add-Member -MemberType Noteproperty “vCPU-pCPUCoreRatio” -Value $cpuRatio
$temp | Add-Member -MemberType Noteproperty “PhysicalMem(GB)” -Value $PhysicalMem
$temp | Add-Member -MemberType Noteproperty “VirtualMem(GB)” -Value $VirtualMem
$temp | Add-Member -MemberType Noteproperty “vRAM-pRAMRatio” -Value $memRatio


$Output | Sort-Object Account | Export-Csv -NoTypeInformation $outputFile


Output in table format :

[table id=4 /]

Ref :


VMware vCloud : This VM has a compliance failure against its Storage Policy.

vCloud PowerCLI




Issue :

VMs in vCloud Director displays the message : “System alert – This VM has a compliance failure against its Storage Policy.”

Symptoms :

After changing the storage profile of the VM you may observe the following error in ‘Status‘.

“System alerts – This VM has a compliance failure against its Storage Policy.”

Virtual Machine <VMName>(UUID) is NOT_COMPLIANT against Storage Policy <SP Name> as of 6/18/16 11:04 AM
Failures are:
The disk [0:0] of VM <VMName>(UUID) is on a datastore that does not support the capabilities of the disk StorageProfile <SP Name>

Resolution :

To reset the alarm in the vCloud Director.

Option 1:

  1. Click the System Alert and select ClearAll.













Option 2:

If many VMs have the same alerts then its difficult to clear one by one. In that case we can use SQL statement to clear all alerts.

  1. Log in to the database with Admin credentials using Microsoft SQL Management Studio.
  2. Run this SQL statement to display all virtual machines with the system alert:
    select * from object_condition where condition = 'vmStorageProfileComplianceFailed'


  3. Run this update statement to clear the alert in the vCD UI:
    update object_condition set ignore = 1 where condition = 'vmStorageProfileComplianceFailed'


PowerCLI to deploy VMs in VMware vCloud and connect to network

vCloud PowerCLI

This PowerCLI script will help you to deploy VMs in VMware Private vCloud and connect to network.

# Deploy VMs in  vCloud     #
# Change Log
# 1.0 This script will Create vApp and deploy VMs from the selected TemplateVM.
$vCloud_Server = "vCloud Server" # vCloud Server FQDN
$vCloud_Org    =    "Org Name"   # Org Name
$orgNetwork = "orgNwName"        # Target OrgNetworkName for the VM.
$templateVM = "TemplateVMName    # Template VM Name.
$vmCount = 2                     # No of VMs required.
$vmIndex = 4                     # VM starting index.
$vAppNamePrefix =  "RHEL-vApp"   # Prefix string in the vApp Name.
$VMNamePrefix = "RHEL-VM"        # Prefix string in the VM Name.
### Connect to the vCloud Server ###
Connect-CIServer $vCloud_Server
### Deploying VMs ###
$vmCount = $vmIndex + $vmCount
for($i=$vmIndex; $i -le $vmCount; $i++)
$vAppName = $vAppNamePrefix+"$i"
$VMName = $VMNamePrefix+"$i"
### Creating new vApp ###
New-CIVApp -Name $vAppName -OrgVdc $vCloud_Org
### Deploy the VM from template inside the newly created vApp###
New-CIVM -Name "$VMName" -VMTemplate $templateVM -VApp $vAppName -ComputerName "$VMName"
### Creating new vApp Network ###
New-CIVAppNetwork -VApp $vAppName -Direct -ParentOrgNetwork $orgNetwork
$vAppNetwork = get-civapp $vAppName | Get-CIVAppNetwork $orgNetwork
$cldVMs = get-civapp $vAppName | get-civm
### Connecting the vNIC to the network ###
### Please change the allocation model if required###
foreach ($cldvm in $cldVMs) {
    $cldvm | Get-CINetworkAdapter | Set-CINetworkAdapter -vappnetwork $vAppNetwork -IPaddressAllocationMode Pool -Connected $True
### Powering on the vApp ###
get-CIVApp -Name $vAppName | Start-CIVApp
Disconnect-CIServer $vCloud_Server -Force -Confirm:$false


Steps to find NAA ID of a RDM LUN mapped to a Windows Volume


Customer requested to increase the windows volume T:. The mentioned volume is a RAW LUN located in EMC VMAX storage. To expand the LUN storage team needs NAA ID (or WWN) of the LUN.

Its easy to find the naa id of a LUN from windows Guest OS with the help of EMC’s Inquiry (inq) tool. Please find the steps below to fetch the naa id with inq tool.



  1. Download the inq tool to the VM from following hyperlink.
    1. inq
  2. Open a CMD window.
    1. Go to RUN -> cmd
  3. CD to the directory where inq is downloaded.
  4. Find the device associated to the windows volume T:.
    1. Run the command inq -winvolwinvol
    2. Here the Device name is PHYSICALDRIVE4.
  5. Find the NAA id of the LUN associated to the Device PHYSICALDRIVE4.
    1. Run the command inq -wwn naa number
    2. You can see that naa id is displayed in WWN column!!!.

To Confirm you can use the following method.

  1. Find virtual device node of the Device.
    1. Run the command inq -btlVirtual
    2. note down the Bus (0) and Tid number (4).
  2. Open VM settings check the NAAID of the disk with Virtual Device Node “0:4”.vm settings - Virtual Devicevm settings - NAA ID

Disclaimer :

I have’nt tested it on all windows platforms and tested only with EMC storages. So use at your own risk.