Category Archives: vCenter

Configuring vSphere 7 Auto Deploy

Whilst continuing to prepare for my VMware Certified Advanced Professional Deploy Exam, I have been configuring vSphere Auto Deploy. As with my blog post on vCenter Profiles, I am covering Auto Deploy as its not something I have ever used in any great depth. As always, I used the official VMware documentation to guide me.

Lets get started!

In my lab I am using vCenter 7.0 Update 3c and using nested hosts for the Auto Deploy hosts. I am also using a RHEL server for the TFTP requirement along with DHCP provided by my layer 3 switch.

Depending on whether you are using BIOS or UEFI you will need to set the appropriate DHCP options; 66 & 67.

I am using EFI, therefore using UEFI DHCP Boot File Name : snponly64.efi.vmw-hardwired as the value for DHCP option 067.

Here are the two DHCP options I have set:

066 : 10.200.15.22
067 : snponly64.efi.vmw-hardwired

In the vSphere Client Select the Auto Deploy menu:

If you haven’t setup Auto Deploy previously, click Enable Auto Deploy and Image Builder.

You now need to download the required files, including the boot files mentioned earlier, that you will need to host on your TFTP server by selecting the Download TFTP Zip File link:

Copy the downloaded file to your TFTP server using something like WinSCP and extract the ZIP file to the TFTPRoot directory you configured as part of the TFTP server installation/setup.

Your directory should then look something like this:

Now using PowerShell 5.1 (PowerShell 7 is not supported by the VMware.ImageBuilder module), connect to the vCenter Server and run the following commands to set up the software depots:

Connect-VIServer <vcsa-fqdn> -Credential $creds
Add-EsxSoftwareDepot https://hostupdate.vmware.com/software/VUM/PRODUCTION/main/vmw-depot-index.xml

You can check you have added the depot successfully by running the following:

Get-EsxImageProfile

Now to create the Deploy Rules. I will be using the latest image; ESXi-7.0U3c-19193900-standard, deploying to my ‘virtual-cluster’ and providing it with a host profile I already had. I have also provided an IP address range for the hosts I want to include. You can also just use the ‘-AllHosts’ parameter if you don’t want to restrict.

New-DeployRule -Name "Lab Auto Deploy Rule" -Item "virtual-cluster", "ESXi-7.0U3c-19193900-standard", "Virtual Cluster Hosts" -Pattern "ipv4=10.200.40.10-10.200.40.20"

My host profile contains a few basic settings such as the root password, NTP settings & NIC configurations. There are plenty of host configuration options that can be set in this profile, configure the settings you need for your environment or lab.

You will be able to see the rules in the vSphere Client once complete.

<Side Note>

If you want to be able to manually add rules in the vSphere Client, you will need to manually add the software depot using the same URL used earlier.

You will then be able to manually create Deploy Rules.

</Side Note>

Now back to it…

You will see the Deploy Rule is currently inactive:

Running the following activates the rule:

Add-DeployRule -DeployRule "Lab Auto Deploy Rule"

You can now see the status is Active in the UI.

If using the vSphere Client, you can use the ‘Activate/Deactivate Rules’ button instead if you didn’t want to use PowerShell.

Now before we start deploying hosts, we need to create some! In this case they will be nested hosts with minimum configurations. We will also need some DHCP reservations and appropriate DNS records.

Once in place, we can go ahead an boot the hosts.

Now heading back to the vSphere UI, you will find your newly deployed host(s)!

From a troubleshooting perspective, you will be wanting to take a look in syslog.log on the host. This helped me identify my issues when I hadn’t applied a firewall rule correctly!

As always, thanks for reading!

If you like my content, consider following me on Twitter so you don’t miss out!

https://platform.twitter.com/widgets.js

Different Tools; Same Result – vSphere Tags

Following the last blog post on create vSphere Port Groups, let’s take a look at creating Tags and Tag Categories.

Let’s first look at the process via the GUI, in this case, the vSphere Client. (Based on vSphere 7.0.3c)

vSphere Client

I wont go into to much detail here as this information is readily available, but here is a brief run through.

After logging into the vSphere Client, select the menu followed by Tags & Custom Attributes.

You the have the option to select either Tags or Categories, followed by the ‘New’ option.

For Categories you need to provide the Category name, optional description, the cardinality (single or multiple) and select the objects that can have this tag associated with it.

Then with Tags, you need to provide the name, optional description and the category the tag will be part of.

Now this may be ok for one or two, but if you need to create in bulk, this will take a while! Lets look as some alternatives.

PowerShell

Firstly, PowerShell, specifically the VMware PowerCLI PowerShell module. Here are examples of the using the cmdlets New-TagCategory and New-Tag to create the same thing we did in the vSphere Client.

#Tag Categories
New-TagCategory -Name "costcentre" -Description "Created with PowerCLI" -Cardinality "MULTIPLE" -EntityType "VirtualMachine", "Datastore"
#Tags
New-Tag -Name "0001" -Category "costcentre" -Description "Created with PowerCLI"

Below is the output from PowerShell after running the script above:

Name                                     Cardinality Description
----                                     ----------- -----------
costcentre                               Multiple    Created with PowerCLI

Name                           Category                       Description
----                           --------                       -----------
0001                           costcentre                     Created with PowerCLI

Now this isn’t much quicker than doing it in the vSphere Client so here is one way to create in bulk.

Here is a custom array with multiple categories and the additional values needed to create a Category.

$TagCategories = @(
    [pscustomobject]@{Name = "costcentre"; Cardinality = "MULTIPLE"; EntityType = "VirtualMachine", "Datastore" }
    [pscustomobject]@{Name = "environment"; Cardinality = "SINGLE"; EntityType = "VirtualMachine", "Datastore" }
    [pscustomobject]@{Name = "nsx-tier"; Cardinality = "MULTIPLE"; EntityType = "VirtualMachine" }
)
foreach ($Category in $TagCategories) {
    New-TagCategory -Name $Category.Name -Cardinality $Category.Cardinality -EntityType $Category.EntityType -Description "Created with PowerCLI"
}

Here is the output:

Name                                     Cardinality Description
----                                     ----------- -----------
costcentre                               Multiple    Created with PowerCLI
environment                              Single      Created with PowerCLI
nsx-tier                                 Multiple    Created with PowerCLI

And now the same principal but with Tags.

$Tags = @(
    [pscustomobject]@{Name = "0001"; Category = "costcentre" }
    [pscustomobject]@{Name = "0002"; Category = "costcentre" }
    [pscustomobject]@{Name = "0003"; Category = "costcentre" }
    [pscustomobject]@{Name = "0004"; Category = "costcentre" }
    [pscustomobject]@{Name = "environment"; Category = "environment" }
    [pscustomobject]@{Name = "production"; Category = "environment" }
    [pscustomobject]@{Name = "pre-production"; Category = "environment" }
    [pscustomobject]@{Name = "test"; Category = "environment" }
    [pscustomobject]@{Name = "development"; Category = "environment" }
    [pscustomobject]@{Name = "web"; Category = "nsx-tier" }
    [pscustomobject]@{Name = "app"; Category = "nsx-tier" }
    [pscustomobject]@{Name = "data"; Category = "nsx-tier" }
)
foreach ($Tag in $Tags) {
    New-Tag -Name $Tag.Name -Category $Tag.Category -Description "Created with PowerCLI"
}

Output:

Name                           Category                       Description
----                           --------                       -----------
0001                           costcentre                     Created with PowerCLI
0002                           costcentre                     Created with PowerCLI
0003                           costcentre                     Created with PowerCLI
0004                           costcentre                     Created with PowerCLI
environment                    environment                    Created with PowerCLI
production                     environment                    Created with PowerCLI
pre-production                 environment                    Created with PowerCLI
test                           environment                    Created with PowerCLI
development                    environment                    Created with PowerCLI
web                            nsx-tier                       Created with PowerCLI
app                            nsx-tier                       Created with PowerCLI
data                           nsx-tier                       Created with PowerCLI

That is just one way to create multiple Categories and Tags. You could take this information from a CSV file using the ‘Get-Content’ cmdlet as an alternative to creating the array manually.

Terraform

Now let’s take a look at using Terraform to achieve the same result. Terraform is an infrastructure and code tool used to manage infrastructure in the form of configuration files and state:

#Providers
provider "vsphere" {
  vsphere_server       = "vcsa-fqdn"
  user                 = "domain\\user"
  password             = "password"
  allow_unverified_ssl = false
}
#Tag categories
resource "vsphere_tag_category" "costcentre" {
  name        = "costcentre"
  description = "Managed by Terraform"
  cardinality = "MULTIPLE"
  associable_types = [
    "VirtualMachine",
    "Datastore",
  ]
}
resource "vsphere_tag_category" "environment" {
  name        = "environment"
  description = "Managed by Terraform"
  cardinality = "SINGLE"
  associable_types = [
    "VirtualMachine",
    "Datastore",
  ]
}
resource "vsphere_tag_category" "nsx-tier" {
  name        = "nsx-tier"
  description = "Managed by Terraform"
  cardinality = "MULTIPLE"
  associable_types = [
    "VirtualMachine"
  ]
}
#Tags
#Local values
locals {
  costcentre_tags  = ["0001", "0002", "0003", "0004"]
  environment_tags = ["production", "pre-production", "test", "development"]
  nsx_tier_tags    = ["web", "app", "data"]
}
#Resources
resource "vsphere_tag" "costcentre-tags" {
  for_each    = toset(local.costcentre_tags)
  name        = each.key
  category_id = vsphere_tag_category.costcentre.id
  description = "Managed by Terraform"
}
resource "vsphere_tag" "environment-tags" {
  for_each    = toset(local.environment_tags)
  name        = each.key
  category_id = vsphere_tag_category.environment.id
  description = "Managed by Terraform"
}
resource "vsphere_tag" "nsx-tier-tags" {
  for_each    = toset(local.nsx_tier_tags)
  name        = each.key
  category_id = vsphere_tag_category.nsx-tier.id
  description = "Managed by Terraform"
}

Lets break this down.

First we are specifying which terraform provider we want to use, this will be the vSphere provider in this case. We are then providing some parameters for the provider to connect to your vCenter instance; VCSA FQDN and credentials. You would want make use of variables for this data, but for this blog I am keeping it simple.

provider "vsphere" {
  vsphere_server       = "vcsa-fqdn"
  user                 = "domain\\user"
  password             = "password"
  allow_unverified_ssl = false
}

We then have three vsphere_tag_category resource blocks, one for each of the categories we want to create. This again provides values for cardinality and associable types like we did in PowerShell.

resource "vsphere_tag_category" "costcentre" {
  name        = "costcentre"
  description = "Managed by Terraform"
  cardinality = "MULTIPLE"
  associable_types = [
    "VirtualMachine",
    "Datastore",
  ]
}
resource "vsphere_tag_category" "environment" {
  name        = "environment"
  description = "Managed by Terraform"
  cardinality = "SINGLE"
  associable_types = [
    "VirtualMachine",
    "Datastore",
  ]
}
resource "vsphere_tag_category" "nsx-tier" {
  name        = "nsx-tier"
  description = "Managed by Terraform"
  cardinality = "MULTIPLE"
  associable_types = [
    "VirtualMachine"
  ]
}

Next we are going to create the tags, but I am going to use a set of local variables to then pass into the three vsphere_tag resource blocks to reduce the amount of repeating code.

Here are the local variables. This is similar to creating the array we did in PowerShell.

locals {
  costcentre_tags  = ["0001", "0002", "0003", "0004"]
  environment_tags = ["production", "pre-production", "test", "development"]
  nsx_tier_tags    = ["web", "app", "data"]
}

And then the resource blocks, notice the for_each parameter. For each Tag Category, it will cycle through each value in the locals array for each category. This is just like we did in PowerShell foreach function earlier.

resource "vsphere_tag" "costcentre-tags" {
  for_each    = toset(local.costcentre_tags)
  name        = each.key
  category_id = vsphere_tag_category.costcentre.id
  description = "Managed by Terraform"
}
resource "vsphere_tag" "environment-tags" {
  for_each    = toset(local.environment_tags)
  name        = each.key
  category_id = vsphere_tag_category.environment.id
  description = "Managed by Terraform"
}
resource "vsphere_tag" "nsx-tier-tags" {
  for_each    = toset(local.nsx_tier_tags)
  name        = each.key
  category_id = vsphere_tag_category.nsx-tier.id
  description = "Managed by Terraform"
}

Now when we run ‘terraform apply’ from the command line to apply for code, this is the output:

Terraform used the selected providers to generate the following execution plan. Resource actions are indicated with the following symbols:
  + create
    
Terraform will perform the following actions:

  # vsphere_tag.costcentre-tags["0001"] will be created
  + resource "vsphere_tag" "costcentre-tags" {
      + category_id = (known after apply)
      + description = "Managed by Terraform"
      + id          = (known after apply)
      + name        = "0001"
    }

  # vsphere_tag.costcentre-tags["0002"] will be created
  + resource "vsphere_tag" "costcentre-tags" {
      + category_id = (known after apply)
      + description = "Managed by Terraform"
      + id          = (known after apply)
      + name        = "0002"
    }

  # vsphere_tag.costcentre-tags["0003"] will be created
  + resource "vsphere_tag" "costcentre-tags" {
      + category_id = (known after apply)
      + description = "Managed by Terraform"
      + id          = (known after apply)
      + name        = "0003"
    }

  # vsphere_tag.costcentre-tags["0004"] will be created
  + resource "vsphere_tag" "costcentre-tags" {
      + category_id = (known after apply)
      + description = "Managed by Terraform"
      + id          = (known after apply)
      + name        = "0004"
    }

  # vsphere_tag.environment-tags["development"] will be created
  + resource "vsphere_tag" "environment-tags" {
      + category_id = (known after apply)
      + description = "Managed by Terraform"
      + id          = (known after apply)
      + name        = "development"
    }

  # vsphere_tag.environment-tags["pre-production"] will be created
  + resource "vsphere_tag" "environment-tags" {
      + category_id = (known after apply)
      + description = "Managed by Terraform"
      + id          = (known after apply)
      + name        = "pre-production"
    }

  # vsphere_tag.environment-tags["production"] will be created
  + resource "vsphere_tag" "environment-tags" {
      + category_id = (known after apply)
      + description = "Managed by Terraform"
      + id          = (known after apply)
      + name        = "production"
    }

  # vsphere_tag.environment-tags["test"] will be created
  + resource "vsphere_tag" "environment-tags" {
      + category_id = (known after apply)
      + description = "Managed by Terraform"
      + id          = (known after apply)
      + name        = "test"
    }

  # vsphere_tag.nsx-tier-tags["app"] will be created
  + resource "vsphere_tag" "nsx-tier-tags" {
      + category_id = (known after apply)
      + description = "Managed by Terraform"
      + id          = (known after apply)
      + name        = "app"
    }

  # vsphere_tag.nsx-tier-tags["data"] will be created
  + resource "vsphere_tag" "nsx-tier-tags" {
      + category_id = (known after apply)
      + description = "Managed by Terraform"
      + id          = (known after apply)
      + name        = "data"
    }

  # vsphere_tag.nsx-tier-tags["web"] will be created
  + resource "vsphere_tag" "nsx-tier-tags" {
      + category_id = (known after apply)
      + description = "Managed by Terraform"
      + id          = (known after apply)
      + name        = "web"
    }

  # vsphere_tag_category.costcentre will be created
  + resource "vsphere_tag_category" "costcentre" {
      + associable_types = [
          + "Datastore",
          + "VirtualMachine",
        ]
      + cardinality      = "MULTIPLE"
      + description      = "Managed by Terraform"
      + id               = (known after apply)
      + name             = "costcentre"
    }

  # vsphere_tag_category.environment will be created
  + resource "vsphere_tag_category" "environment" {
      + associable_types = [
          + "Datastore",
          + "VirtualMachine",
        ]
vsphere_tag.environment-tags["production"]: Creating...
vsphere_tag.environment-tags["pre-production"]: Creating...
vsphere_tag_category.nsx-tier: Creation complete after 0s [id=urn:vmomi:InventoryServiceCategory:20a2167a-b0f8-4a60-9d29-6c7ca57711ef:GLOBAL]
vsphere_tag.nsx-tier-tags["data"]: Creating...
vsphere_tag.nsx-tier-tags["app"]: Creating...
vsphere_tag.nsx-tier-tags["web"]: Creating...
vsphere_tag_category.costcentre: Creation complete after 0s [id=urn:vmomi:InventoryServiceCategory:28a909f5-ee41-4d94-b228-b5e96e09284e:GLOBAL]
vsphere_tag.costcentre-tags["0004"]: Creating...
vsphere_tag.costcentre-tags["0002"]: Creating...
vsphere_tag.costcentre-tags["0003"]: Creating...
vsphere_tag.environment-tags["development"]: Creation complete after 0s [id=urn:vmomi:InventoryServiceTag:5b63e350-ef6e-4bbc-a633-09c9047b327b:GLOBAL]
vsphere_tag.costcentre-tags["0001"]: Creating...
vsphere_tag.environment-tags["pre-production"]: Creation complete after 0s [id=urn:vmomi:InventoryServiceTag:e2a8737c-e42a-4c6f-b9a8-716a1681d0c0:GLOBAL]
vsphere_tag.nsx-tier-tags["data"]: Creation complete after 0s [id=urn:vmomi:InventoryServiceTag:b9d3394d-388c-4018-b7b2-9e4d3da8287b:GLOBAL]
vsphere_tag.costcentre-tags["0002"]: Creation complete after 0s [id=urn:vmomi:InventoryServiceTag:8a482528-5d67-40e9-86cb-4dbf566f85ac:GLOBAL]
vsphere_tag.nsx-tier-tags["web"]: Creation complete after 0s [id=urn:vmomi:InventoryServiceTag:5a325904-4dfd-46ac-b0db-37fd6fda1533:GLOBAL]
vsphere_tag.environment-tags["production"]: Creation complete after 0s [id=urn:vmomi:InventoryServiceTag:89c609b9-7f90-457d-9f71-0bd0b7cc667d:GLOBAL]
vsphere_tag.nsx-tier-tags["app"]: Creation complete after 0s [id=urn:vmomi:InventoryServiceTag:45c2dd0e-533a-4917-82be-987d3245137a:GLOBAL]
vsphere_tag.costcentre-tags["0004"]: Creation complete after 0s [id=urn:vmomi:InventoryServiceTag:230db56e-7352-4e14-ba63-0ad4b4c0ba18:GLOBAL]
vsphere_tag.environment-tags["test"]: Creation complete after 0s [id=urn:vmomi:InventoryServiceTag:ebcf1809-8cae-4cb2-a5fa-82a492e54227:GLOBAL]
vsphere_tag.costcentre-tags["0001"]: Creation complete after 0s [id=urn:vmomi:InventoryServiceTag:e4649ad2-08d2-4dcd-aabf-4e2d74f93a36:GLOBAL]
vsphere_tag.costcentre-tags["0003"]: Creation complete after 0s [id=urn:vmomi:InventoryServiceTag:18de9eca-456c-4539-ad6c-19d625ac5be7:GLOBAL]

Apply complete! Resources: 14 added, 0 changed, 0 destroyed.

For more information on the vSphere provider from Terraform, check out this link.

I hope this has given you some idea’s on how you can perhaps leverage other options beside the GUI, especially when looking to build or configure in bulk. All the code in this blog can be found on my GitHub here.

Thanks for reading!

vCenter Server Profiles

Whilst beginning preparations to take the VMware Certificated Advanced Professional Deploy exam, I have started to look into the features and topics that I’m not overly familiar with. To help with the learning process, I am going to be deploying and configuring these features, and writing blogs on many of the topics to help cement the information. Hopefully these will be useful for anyone else learning or researching these topics!

The first one; vCenter Server Profiles!

Background

vCenter Server Profiles (Section 7.2.4 Configure VMware vCenter Server® profiles in the Exam Blueprint) were first introduced in vSphere 7.0. These addressed the challenges around configuration consistency in large multi vCenter environments by allowing a ‘base’ or ‘source’ vCenter configuration to be exported, modified and imported into multiple other vCenter’s.

Not only does this help ensure a consistent configuration for things like NTP, Syslog, SSH and security settings on the appliance, but also Roles and Users can be copied to all vCenter servers quickly and easily. The Roles and Users can be a great help if you have a role on all vCenter servers for things like backup solutions or templating.

The profile or configuration is exported as a JSON file, therefore this easily allows you to store this as a source control tool such as GitHub to enable you to track and review changes to the configuration. This can be really useful when it comes to larger teams with many updates happening.

The export and import process is all done via API’s. More on that later, first lets take a look at this in the form of a high level diagram!

API’s

As mentioned earlier, vCenter Server Profiles are currently managed via API’s, not the GUI. They can be found in the Developer Center within vCenter itself as you can see below:

There are 5 API’s in total I am going to be working with as part of this blog:

  • Acquiring a SessionID token – Required to authenticate.
  • Getting a list of profiles.
  • Exporting a profile.
  • Validating a profile.
  • Importing a profile.

I will be using PowerShell to make the API calls, lets take a look at the code to do each step as well as the output.

Acquiring a SessionID Token

There are a few variable values you will need to fill out here; Username, Password and the FQDN of the source vCenter Server.

#Authentication
$User = "administrator@vsphere.local"
$Pass = "SecurePassword!"
$Auth = $User + ":" + $Pass
$Encoded = [System.Text.Encoding]::UTF8.GetBytes($Auth)
$EncodedAuth = [System.Convert]::ToBase64String($Encoded)
$Headers = @{"Authorization" = "Basic $($EncodedAuth)" }
$sourcevcenter = "vm-vcsa-01.smt.com"
#Get Session ID
$Session = Invoke-RestMethod -Method POST -Uri "https://$($sourcevcenter)/rest/com/vmware/cis/session" -Headers $Headers
$SessionID = $Session.Value
$SessionID

Now when you run this, a value is outputted. This is what we will use to authenticate the other API calls.

d84b95e370f1ed68b997f4affbe6feba

Listing Profiles

Now lets look at listing the available profiles. You will notice the output may remind you of the diagram above.

$SessionHeaders = @{'vmware-api-session-id' = "$($SessionID)"
}
Invoke-RestMethod -Method GET -Uri "https://$($sourcevcenter)/api/appliance/infraprofile/configs" -Headers $SessionHeaders

Note the SessionID variable being used here. This is the value from the previous step.

name                info
----                ----
ApplianceManagement Appliance Mangment Service
ApplianceNetwork    Appliance Network Configuration
AuthManagement      Authentication & Authorization Management

Exporting a Profile

Now to export the profile. As mentioned earlier, the configuration is outputted to a JSON file to a path of your choosing.

$SessionHeaders = @{
    "vmware-api-session-id" = "$($SessionID)"
    "Content-type"          = "application/json"
}
$Export = Invoke-RestMethod -Method POST -Uri "https://$($sourcevcenter)/api/appliance/infraprofile/configs?action=export" -Headers $SessionHeaders
$Export | Out-File "C:\temp\vcenter-profile-export.json"

Here is a trimmed look at the content of the file:

{"action":"RESTART_SERVICE","productName":"VMware vCenter Server","creationTime":"2021-12-30T18:12:42+0000","version":"7.0.3.00100","profiles":{"ApplianceNetwork":{"description":"Appliance Network Configuration","action":"RESTART_SERVICE","actionOn":{"VC_SERVICES":["applmgmt"],"SYSTEMD":["systemd-networkd","systemd-resolved"]},"version":"7.0","config":{"/etc/sysconfig/proxy":{"HTTPS PROXY":"\"\"","SOCKS PROXY":"\"\"","FTP PROXY":"\"\"","GOPHER PROXY":"\"\"","PROXY ENABLED":"\"no\"","SOCKS5 SERVER":"\"\"","HTTP PROXY":"\"\"","NO PROXY":["\"localhost","127.0.0.1\""]},"/etc/systemd/resolved.conf":{"Fallback DNS":null,"LLMNR is enabled":"false","DNS":"127.0.0.1 10.200.15.1"}},"name":"ApplianceNetwork"},"AuthManagement":{"description":"Authentication & Authorization Management","action":"NO_ACTION","version":"1.0","config":{"Lockout Policy":{"Maximum number of failed login attempts":5,"Time interval between failures":180,"Unlock time":300},"Password Policy":{"Minimum special characters":1,"Minimum alphabetic characters":2,"Minimum uppercase characters":1,"Minimum lowercase characters":1,"Minimum numeric characters":1,"Minimum adjacent identical characters":3,"Previous password reuse restriction":5,"Maximum lifetime":90,"Maximum length":20,"Minimum length":8},"Token Policy":{"Clock tolerance ms":600000,"Maximum token renewal count":10,"Maximum token delegation count":10,"Maximum Bearer RefreshToken lifetime":21600000,"Maximum HoK RefreshToken lifetime":2592000000}
...
Trimmed to save the scrolling...
...
{"principal":{"name":"VSPHERE.LOCAL\\NsxAuditors","group":true},"roles":[741131114],"propagate":true},{"principal":{"name":"VSPHERE.LOCAL\\NsxViAdministrators","group":true},"roles":[-2094871953],"propagate":true},{"principal":{"name":"VSPHERE.LOCAL\\NsxAdministrators","group":true},"roles":[-1723127349],"propagate":true},{"principal":{"name":"VSPHERE.LOCAL\\RegistryAdministrators","group":true},"roles":[1006],"propagate":true},{"principal":{"name":"SMT.COM\\stephan","group":false},"roles":[-1],"propagate":true},{"principal":{"name":"VSPHERE.LOCAL\\vStatsGroup","group":true},"roles":[-292639496],"propagate":true}]},"name":"AuthManagement"},"ApplianceManagement":{"description":"Appliance Mangment Service","action":"RESTART_SERVICE","actionOn":{"VC_SERVICES":["applmgmt"],"SYSTEMD":["sendmail","rsyslog"]},"version":"7.0","config":{"/etc/applmgmt/appliance/appliance.conf":{"Is shell Enabled":false,"Shell Expiration Time":null,"TimeSync Mode (Host/NTP)":"NTP"},"/etc/sysconfig/clock":{"Time zone":"\"Europe/London\"","UTC":"1"},"/usr/bin/systemctl/sshd.service":{"Enable SSH":"true"},"/etc/ntp.conf":{"Time servers":["uk.pool.ntp.org"]},"/etc/mail/sendmail.cf":{"SMTP Port":null,"Mail server":null},"/etc/vmware-syslog/syslog.conf":{"Port [2]":null,"Port [1]":null,"Port [0]":null,"Protocol [2]":null,"Remote Syslog Host [1]":null,"Protocol [1]":null,"Remote Syslog Host [0]":null,"Protocol [0]":null,"Remote Syslog Host [2]":null},"/etc/pam.d/system-auth":{"Deny Login after these many Unsuccessful Attempts.":"3","Unlock root after (seconds)":"300","On Error Login will be.":"fail","Include Root user for SSH lockout.":true,"Unlock user after (seconds)":"900"},"/etc/shadow":{"root":{"maximumDays":"","warningDays":"7"},"bin":{"maximumDays":"90","warningDays":"7"},"daemon":{"maximumDays":"90","warningDays":"7"},"messagebus":{"maximumDays":"90","warningDays":"7"},"systemd-bus-proxy":{"maximumDays":"90","warningDays":"7"},"systemd-journal-gateway":{"maximumDays":"90","warningDays":"7"},"systemd-journal-remote":{"maximumDays":"90","warningDays":"7"},"systemd-journal-upload":{"maximumDays":"90","warningDays":"7"},"systemd-network":{"maximumDays":"90","warningDays":"7"},"systemd-resolve":{"maximumDays":"90","warningDays":"7"},"systemd-timesync":{"maximumDays":"90","warningDays":"7"},"nobody":{"maximumDays":"90","warningDays":"7"},"rpc":{"maximumDays":"90","warningDays":"7"},"ntp":{"maximumDays":"90","warningDays":"7"},"sshd":{"maximumDays":"90","warningDays":"7"},"smmsp":{"maximumDays":"90","warningDays":"7"},"apache":{"maximumDays":"90","warningDays":"7"},"sso-user":{"maximumDays":"90","warningDays":"7"},"vpostgres":{"maximumDays":"","warningDays":"7"},"vapiEndpoint":{"maximumDays":"90","warningDays":"7"},"eam":{"maximumDays":"90","warningDays":"7"},"vlcm":{"maximumDays":"90","warningDays":"7"},"vsan-health":{"maximumDays":"90","warningDays":"7"},"vsm":{"maximumDays":"90","warningDays":"7"},"vsphere-ui":{"maximumDays":"90","warningDays":"7"},"wcp":{"maximumDays":"","warningDays":"7"},"content-library":{"maximumDays":"90","warningDays":"7"},"imagebuilder":{"maximumDays":"90","warningDays":"7"},"perfcharts":{"maximumDays":"90","warningDays":"7"},"vpgmonusr":{"maximumDays":"","warningDays":"7"},"vtsdbmonusr":{"maximumDays":"","warningDays":"7"},"Send Waring before this No of Days.":null,"Password validity (days)":null}},"name":"ApplianceManagement"}}}

At this point you can modify this file as needed. For example, you may need to modify the DNS configuration for a group of vCenter Servers to use a different one than that of the source vCenter, or you may want to remove all but the Appliance configuration.

Validating a Profile

Next we are looking at validating the profile against the target/remote vCenter that you want to apply it to. Be sure to get a session ID for the target vCenter Server to pass into this command!

$destinationvcenter = "vm-vcsa-02.smt.com"
$SessionHeaders = @{
    "vmware-api-session-id" = "$($SessionID)"
    "Content-type"          = "application/json"
}
$body = Convertto-json @{
    'config_spec' = Get-Content "C:\temp\vcenter-profile-export.json"
}
$validate = Invoke-RestMethod -Method POST -Uri "https://$($destinationvcenter)/api/appliance/infraprofile/configs?action=validate&vmw-task=true" -Headers $SessionHeaders -Body $body
$validate

The below output confirms the file is good to go.

912f7205-2e8f-429f-8b86-9610e5eac8f4:com.vmware.appliance.infraprofile.configs

Importing a Profile

Now to the good bit, importing the config! Like before, make sure to get a session ID for the target vCenter Server to pass into this command!

$destinationvcenter = "vm-vcsa-02.smt.com"
$SessionHeaders = @{
    "vmware-api-session-id" = "$($SessionID)"
    "Content-type"          = "application/json"
}
$body = @{
    'config_spec' = Get-Content "C:\temp\vcenter-profile-export.json"
}
$Import = Invoke-RestMethod -Method POST -Uri "https://$($destinationvcenter)/api/appliance/infraprofile/configs?action=import&vmw-task=true" -Headers $SessionHeaders -Body (Convertto-json $body)
$Import

Before:

Output from running the import commands:

d843c731-c631-4b9b-87fe-4894134f433c:com.vmware.appliance.infraprofile.configs

After:

PowerShell Functions

Now to make this a bit easier (and to practice my PowerShell Function skills), I have made 5 PowerShell Functions that can be used. The code for each can be found here.

Get-vCenterAPISessionID

Get-vCenterAPISessionID -vCenterFQDN vm-vcsa-02.smt.com -UserName administrator@vsphere.local -Password SecurePassword!
9ee52fe13c7ae8d42f777cadccf6b70d

Get-vCenterProfiles

Get-vCenterProfiles -vCenterFQDN vm-vcsa-01.smt.com -SessionID 9ee52fe13c7ae8d42f777cadccf6b70d
name                info
----                ----
ApplianceManagement ApplianceManagement
ApplianceNetwork    ApplianceNetwork
AuthManagement      Authentication & Authorization Management

Export-vCenterProfiles

Export-vCenterProfiles -vCenterFQDN vm-vcsa-02.smt.com -SessionID 9ee52fe13c7ae8d42f777cadccf6b70d -ExportPath C:\temp

Validate-vCenterProfiles

Validate-vCenterProfiles -vCenterFQDN vm-vcsa-03.smt.com -SessionID 2b3fdd91604f67d124af041a23b46a1a -jsonPath C:\temp
21bfd471-95e3-48d3-841d-8452f2a09527:com.vmware.appliance.infraprofile.configs

Import-vCenterProfiles

Import-vCenterProfiles -vCenterFQDN vm-vcsa-03.smt.com -SessionID 2b3fdd91604f67d124af041a23b46a1a -jsonPath C:\temp
4a742b45-c52e-4aa9-a67b-fe588084f02c:com.vmware.appliance.infraprofile.configs

Log File location on the vCenter Server: /var/log/vmware/infraprofile/infraprofile-svcs.log. This is were you need to be looking when troubleshooting!

Here’s a snippet:

2022-01-01T14:31:30.911Z [Thread-45 [] INFO  com.vmware.appliance.infraprofilev1.core.ProfileOperations  opId=] Complete importProfile ApplianceManagement
2022-01-01T14:31:31.072Z [Thread-45 [] INFO  com.vmware.appliance.infraprofilev1.plugins.ApplianceManagementPlugin  opId=] Start importing non generic format file /usr/bin/systemctl/sshd.service
2022-01-01T14:31:31.074Z [Thread-45 [] INFO  com.vmware.appliance.infraprofilev1.util.MiscUtils  opId=] Performing unmask operation on following System services: [[sshd.service]]
2022-01-01T14:31:31.439Z [Thread-45 [] INFO  com.vmware.appliance.infraprofilev1.util.MiscUtils  opId=] Performing enable operation on following System services: [[sshd.service]]
2022-01-01T14:31:31.864Z [Thread-45 [] INFO  com.vmware.appliance.infraprofilev1.util.MiscUtils  opId=] Performing start operation on following System services: [[sshd.service]]
2022-01-01T14:31:31.877Z [Thread-45 [] INFO  com.vmware.appliance.infraprofilev1.plugins.ApplianceManagementPlugin  opId=] Complete importing non generic format file /usr/bin/systemctl/sshd.service
2022-01-01T14:31:31.877Z [Thread-45 [] INFO  com.vmware.appliance.infraprofilev1.plugins.ApplianceManagementPlugin  opId=] Start importing non generic format file /etc/ntp.conf
2022-01-01T14:31:31.878Z [Thread-45 [] INFO  com.vmware.appliance.infraprofilev1.plugins.ApplianceManagementPlugin  opId=] Complete importing non generic format file /etc/ntp.conf
2022-01-01T14:31:31.878Z [Thread-45 [] INFO  com.vmware.appliance.infraprofilev1.plugins.ApplianceManagementPlugin  opId=] Start importing non generic format file /etc/mail/sendmail.cf
2022-01-01T14:31:31.882Z [Thread-45 [] INFO  com.vmware.appliance.infraprofilev1.plugins.ApplianceManagementPlugin  opId=] Complete importing non generic format file /etc/mail/sendmail.cf
2022-01-01T14:31:31.882Z [Thread-45 [] INFO  com.vmware.appliance.infraprofilev1.plugins.ApplianceManagementPlugin  opId=] Start importing non generic format file /etc/vmware-syslog/syslog.conf
2022-01-01T14:31:32.963Z [Thread-45 [] INFO  com.vmware.appliance.infraprofilev1.plugins.ApplianceManagementPlugin  opId=] Complete importing non generic format file /etc/vmware-syslog/syslog.conf

Thanks for reading!

Failed to Deploy OVF Package – vSphere Content Libraries

I recently came across an issue with creating subscribed VMware Content Libraries, and deploying templates from a Content Library.

An error similar to the one below, would be received when attempting to deploy a VM template or OVF from a Content Library, or an error related to connection issues when setting up a subscribed Content Library.

Failed to deploy OVF Package.  ThrowablePrxy.cause A general system error occurred: Transfer failed.

After some investigation, I came to see that vCenter was attempting to communicate with linked vCenter’s and hosts via the web proxy that was configured in the VAMI, when attempting to deploy an OVF from a Content Library or when trying to synchronise a library.

As I didn’t want this traffic going via the proxy as it is internal traffic, a support ticket was logged. It was advised to add proxy exceptions, or bypasses, to the proxy file located here on a vCenter Server Appliance:

/etc/sysconfig/proxy

As this information isn’t something I managed to find documented publicly and support couldn’t provide me with anything as they were using internal documentation to assist, I thought I would write a quick post on it to help anyone facing the same issue!

Note: Always test in a non production environment and contact official support channels!

To begin reviewing and editing this file, you will need to SSH to the VCSA using the below command using your SSH tooling of choice.

ssh root@vm-vcsa-01.smt-lab.local

Using the following cat command you can then view the file:

cat /etc/sysconfig/proxy

Here is what the default file looks like with the HTTP and HTTPS options set:

# Enable a generation of the proxy settings to the profile.
# This setting allows to turn the proxy on and off while
# preserving the particular proxy setup.
#
PROXY_ENABLED="no"

# Some programs (e.g. wget) support proxies, if set in
# the environment.
# Example: HTTP_PROXY="http://proxy.provider.de:3128/"
HTTP_PROXY="proxy.smt-lab.local"

# Example: HTTPS_PROXY="https://proxy.provider.de:3128/"
HTTPS_PROXY="proxy.smt-lab.local"

# Example: FTP_PROXY="http://proxy.provider.de:3128/"
FTP_PROXY=""

# Example: GOPHER_PROXY="http://proxy.provider.de:3128/"
GOPHER_PROXY=""

# Example: SOCKS_PROXY="socks://proxy.example.com:8080"
SOCKS_PROXY=""

# Example: SOCKS5_SERVER="office-proxy.example.com:8881"
SOCKS5_SERVER=""

# Example: NO_PROXY="www.me.de, do.main, localhost"
NO_PROXY="localhost, 127.0.0.1"

Take note of the section at the bottom, “NO_PROXY”. This is where we need to add the fqdn’s of any hosts and VCSA’s you wish to deploy to, or subscribe with. If however you don’t want to maintain this for each and every host, you can add a wild card:

.*.domain.name

Note the ‘.’ at the beginning!

For instance, in my lab I would add the following entry to the NO_PROXY list:

.*.smt-lab.local

To edit this we can use the VI editor (More info on using VI here.):

vi /etc/sysconfig/proxy

Edit the file to include the FQDN’s or a wildcard, based on your requirements.

# Example: NO_PROXY="www.me.de, do.main, localhost"
NO_PROXY="localhost, 127.0.0.1, .*.smt-lab.local"

I found a short period of time is needed for this to take effect. Or you can reboot the VCSA to speed things along.

Following this, you will then be able to deploy or subscribe without issue!

Hope this has been useful and thanks for reading!

Enabling Native KMS in vSphere 7.0 Update 2

Some time back I wrote about setting up and enabling a HyTrust Key Management setup for vSphere to make use of VM and vSAN encryption. Following the release of vSphere 7.0 Update 2, VMware have introduced native key management capabilities! This is a great feature as you no longer require a potentially expensive separate key management solution to make use of vSphere’s encryption offerings.

Lets take a look at this new capability by heading over to the Key Providers menu on your vCenter object, and selecting ‘Add Native Key Provider’:

Give your provider a name:

It then needs backing up! There is an option to do this next to the ‘Add’ option, or in the flow graphic at the bottom:

It is recommended to protect this with a password, make sure you keep this safe along with the key itself, after it downloads when you hit ‘Back Up Key Provider’. You won’t be able to restore the provider without it should you have a need to. Without the provider, any VM’s or data encrypted with it will be lost.

Once its backed up and safely stored you will have an active KMS! You can choose to set it to default if you have more than one key provider if you wish. Any VM’s that are encrypted from the point of changing the default, will be with the new provider, any already encrypted VM’s will continue to be encrypted with the original key.

If you head over to vSAN services, you will now have your native key provider available and can enable Data-At-Rest encryption as well as Data-In-Transit encryption:

Likewise, if you edit the settings of a VM via the VM Options tab you will be able to enable VM encryption:

There you have it, a native Key Management capability, in built with vSphere 7.0 Update 2.

Thanks for reading!

Administering ESXi Hosts With ESXCLI using PowerCLI

There are times as a vSphere admin, you are going to want to run ESXCLI commands against multiple ESXi Hosts from a central location. This could be for configuration / administration, reporting, patching or a number of other things.

Recently I have been testing different values in the /DataMover/MaxHWTransferSize advanced setting. To make life easier, I wanted a way to change multiple hosts quickly and easily. To do this, I customised a script that Luc Dekens posted as a solution to a problem someone was having that can be used to send ESXCLI commands to multiple hosts using PowerCLI and plink.exe. This slightly modified version uses a CSV file as a source containing my hosts FQDN and the username and password I will be connecting with.

Plink, which is part of the PuTTy suite, can can be found here.

When using this script, you need to either run the script from a directory containing the plink executable, copy it to where you want to run the script, or adjust the script to include the path to the plink executable… whichever takes your fancy.

Disclaimer: Always complete your own testing in an appropriate environment and refer to the vendors official documentation!

$Hosts = Import-Csv C:\ESXiHosts.csv
$Commad = 'esxcfg-advcfg -s 16384 /DataMover/MaxHWTransferSize'

Foreach ($H in $Hosts) {
    #Starting the SSH Service if not already started
    $SSHService = Get-VMHostService -VMHost $H.HostName | where {$_.Key -eq 'TSM-SSH'}
    if ($SSHService.Running -eq 'True') {
        Write-Host "****************************" -ForegroundColor Blue
        Write-Host "WARNING: SSH already enabled, this will be stopped on completion of this script" -ForegroundColor Yellow
    }
        Else {

            Write-Host "Starting SSH Service on Host $($H.HostName)" -ForegroundColor Green
            Start-VMHostService -HostService $SSHService -Confirm:$false > $null
        }
    #Running the defined ESXCLI Command(s)
    Write-host "Running remote SSH commands on $($H.HostName)." -ForegroundColor Green
    Echo Y | ./plink.exe $H.HostName -pw $H.Password -l $H.UserName $Commad
    
    #Stopping the SSH Service
    $SSHService = Get-VMHostService -VMHost $H.HostName | where {$_.Key -eq 'TSM-SSH'}
    if ($SSHService.Running) {
        Write-Host "Stopping SSH Service on Host $($H.HostName)" -ForegroundColor Green
        Stop-VMHostService -HostService $SSHService -Confirm:$false > $null
        Write-Host "****************************" -ForegroundColor Blue
    }
}
Write-Host "Complete $(Get-Date)" -ForegroundColor Green

You can run as many commands as you need by declaring another ‘Command’ variable at the beginning of the script and adding another line to the ‘Running the defined ESXCLI Command(s)’ section.

When run, it will then cycle through each of the ESXi hosts from your CSV file, enable SSH (if its not already enabled), accept the host key, run the commands you have specified and finally turn the SSH service off.

Here you can see it has set the MaxHWTransferSize to 16384 on each host.

You will see the Recent Task pane show the SSH Service starts and stops.

The commands passed in can be anything you need. All you need to do is change the commands that are defined in the variables section. For example, restarting the management agents –

$commad = 'etc/init.d/hostd restart'
$commad2 = 'etc/init.d/vpxa restart'

I hope this has been of use for anyone needing a centralised, quick way to administer multiple hosts via ESXCLI.

Thanks for reading!

Deploying vCenter 7.0 via the CLI

Recently I decided it was time to add a second vCenter 7.0 Appliance to my main lab environment after the lab containing my SRM and vSphere Replication installation ceased to exist…

I thought I would take the CLI route as its been a while, and thought I’d share!

To begin, you need to decide what you are deploying. There are four deployment options available to you, which you can see listed below. To see the options, mount the vCenter ISO image, browse to vcsa-cli-installer\templates\install, and you will find 4 templates;

  • Embedded on ESXi
  • Embedded on VC
  • Embedded replication on ESXi
  • Embedded replication on VC.

Note there is not a distributed option here anymore as this is depreciated in 7.0.

For my lab I will be using the 3rd option; ‘Embedded replication on ESXi’. Firstly because I’m deploying to a standalone host and not to an existing vCenter. Secondly as I already have an existing VCSA and SSO Domain. This new VCSA will be added, or linked to the existing VCSA for my ‘Recovery’ site, in my Site Recovery Manager (SRM) setup.

If you are looking to deploy your first VCSA, onto a standalone host, you will want to use the ‘Embedded on ESXi’ template.

Once you have decided on the template that suits your scenario, you are going to add some details to this template, such as the ESXi host information you are deploying to, networking information, NTP and in my case SSO details as I will be adding it to an existing SSO Domain. One important value is the deployment size (deployment_option in the example below).

A useful command that can be run to help you decide what size appliance is suitable for your needs is:

vcsa-deploy --supported-deployment-sizes

This outputs the vCenter sizing to assist you. It shows you the resource requirements as well as the amount of hosts and VM’s each can support.

Information 
Options 
tiny 
——supported—deployment—sizes 
about deployment sizes: 
vCPUs Memory CGB) Storage CGB) HostsCup to) VMsCup to) 
tiny—Istorage 
tiny—xlstorage 
small 
small—Istorage 
small—xlstorage 
medium 
medium—Istorage 
medium—xlstorage 
large 
large—Istorage 
large—xlstorage 
xlarge 
xlarge—lstorage 
xlarge—xlstorage 
2 
2 
2 
8 
8 
8 
16 
16 
16 
24 
24 
24 
12 
12 
12 
19 
19 
19 
28 
28 
28 
37 
37 
37 
56 
56 
56 
463 
1538 
3293 
528 
1583 
3343 
748 
1748 
3568 
1113 
1813 
3573 
1853 
1953 
3713 
16 
16 
16 
lee 
lee 
uee 
uee 
leee 
leee 
leee 
2eee 
2eee 
lee 
lee 
lee 
leee 
leee 
leee 
leeee 
leeee 
leeee 
35eee 
35eee

For my lab, ‘tiny’ covers my needs.

Here is the json file I used for the deployment in my lab.  I have excluded the passwords for obvious reason, but it can be ran like this, and will prompt you for the passwords in the terminal.

{
    "__version": "2.13.0",
    "__comments": "Sample template to deploy a vCenter Server Appliance with an embedded Platform Services Controller as a replication partner to another embedded vCenter Server Appliance, on an ESXi host.",
    "new_vcsa": {
        "esxi": {
            "hostname": "smt-lab-esx-04.smt-lab.local",
            "username": "root",
            "password": "",
            "deployment_network": "vSS_PG_Management",
            "datastore": "smt-lab-vmfs-02a"
        },
        "appliance": {
            "__comments": [
                "You must provide the 'deployment_option' key with a value, which will affect the VCSA's configuration parameters, such as the VCSA's number of vCPUs, the memory size, the storage size, and the maximum numbers of ESXi hosts and VMs which can be managed. For a list of acceptable values, run the supported deployment sizes help, i.e. vcsa-deploy --supported-deployment-sizes"
            ],
            "thin_disk_mode": true,
            "deployment_option": "tiny",
            "name": "smt-lab-vcsa-02"
        },
        "network": {
            "ip_family": "ipv4",
            "mode": "static",
            "system_name": "smt-lab-vcsa-02.smt-lab.local",
            "ip": "10.200.15.249",
            "prefix": "24",
            "gateway": "10.200.15.254",
            "dns_servers": [
                "10.200.15.10"
            ]
        },
        "os": {
            "password": "",
            "ntp_servers": "0.uk.pool.ntp.org",
            "ssh_enable": true
        },
        "sso": {
            "password": "",
            "domain_name": "vsphere.local",
            "first_instance": false,
            "replication_partner_hostname": "smt-lab-vcsa-01.smt-lab.local",
            "sso_port": 443
        }
    },
    "ceip": {
        "description": {
            "__comments": [
                "++++VMware Customer Experience Improvement Program (CEIP)++++",
                "VMware's Customer Experience Improvement Program (CEIP) ",
                "provides VMware with information that enables VMware to ",
                "improve its products and services, to fix problems, ",
                "and to advise you on how best to deploy and use our ",
                "products. As part of CEIP, VMware collects technical ",
                "information about your organization's use of VMware ",
                "products and services on a regular basis in association ",
                "with your organization's VMware license key(s). This ",
                "information does not personally identify any individual. ",
                "",
                "Additional information regarding the data collected ",
                "through CEIP and the purposes for which it is used by ",
                "VMware is set forth in the Trust & Assurance Center at ",
                "http://www.vmware.com/trustvmware/ceip.html . If you ",
                "prefer not to participate in VMware's CEIP for this ",
                "product, you should disable CEIP by setting ",
                "'ceip_enabled': false. You may join or leave VMware's ",
                "CEIP for this product at any time. Please confirm your ",
                "acknowledgement by passing in the parameter ",
                "--acknowledge-ceip in the command line.",
                "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++"
            ]
        },
        "settings": {
            "ceip_enabled": true
        }
    }
}


Once you have prepared your file, there are a couple of commands you can run from a PowerShell prompt to validate your configuration before deploying, saving you some time should mistakes have been made. The first being:

.\vcsa-deploy.exe install --accept-eula --acknowledge-ceip --verify-template-only <Path to json File>

This completes some basic checks to ensure your json file is correct, here is a successful output:

[START] Start executing Task: To validate CLI options at 
Command line arguments verfied . 
[SUCCEEDED] Successfully executed Task 'CLIOptionsVaIidationTask: Executing CLI 
optionsvalidation task' in TaskFIow 'template_validation' at 
[START] Start executing Task: To validate the syntax of the template. at 
Template syntax validation for template 
'M: . json' succeeded . 
Syntax validation for all templates succeeded . 
[SUCCEEDED] Successfully executed Task 'SyntaxVaIidationTask: Executing 
Template Syntax Validation task' in TaskFIow 'template_validation' at 
[START] Start executing Task: To check the version of each template, and for 
each older template that supports CEIP, convert it to the latest template 
format, and save it to the Template Blackboard at 
Template version processing for template 
'M: . json' succeeded . 
Version processing for all templates succeeded . 
[SUCCEEDED] Successfully executed Task 'VersionprocessingTask: Executing 
Template Version processing task' in TaskFIow 'template_validation' at 
[START] Start executing Task: To validate the template structure against the 
rules specified by a corresponding template schema. at 
Template structure validation for template 
'M: . json' succeeded . 
Structure validation for all templates succeeded . 
[SUCCEEDED] Successfully executed Task 'StructureVaIidationTask: Executing 
Template Structure Validation task' in TaskFIow 'template_validation' at 
[START] Start executing Task: To create a dependency graph for the provided 
templates, with an edge pairing two templates that are dependent on each other. 
Such graph relationships will affect whether certain templates can be deployed 
in parallel, or must be deployed sequentially. at 
Dependency processing for all templates succeeded . 
[SUCCEEDED] Successfully executed Task 'DependencyprocessingTask: Executing 
Template Dependency processing task' in TaskFIow 'template_validation' at 
Template verification completed . 
----------------------------------= 12 : l€:eu

Secondly:

.\vcsa-deploy.exe install --accept-eula --acknowledge-ceip --precheck-only <Path to json File>

This will perform a more in depth validation, checking things like the credentials for your SSO domain, DNS or whether the IP or name you plan to use for your VCSA is in use already.

Note: Make sure you have your DNS setup correctly and is resolving the appliance FQDN!

It will also provide warnings if it thinks you might not be using an appropriate template. I originally specified a host what was already managed by vCenter, so it warned me like so:

DRS Warning: The target ESXi host ' smt—lab .10caI' is managed by 
of these hosts are in a cluster, and DRS 
vcenter server '1€.2€€.15.25€' . 
If any 
is enabled, vMotion can take effect and 
adversely impact the installation, 
upgrade, or migration processes. 
It is 
recommended that you use the 
*_on_vc.json template file for the target ESXi host if it is managed by a 
vCenter Server, and ensure the ESXi hosts you have specified are not members of 
clusters with DRS set to Fully Automated during the installation, upgrade, or 
migration processes.

You will get a similar output to the first command, should you pass all the tests. If not you will need to look at resolving them to ensure you get a successful deployment.

The Install!

Once you are confident you have everything in place, including DNS, and your configuration files are correct, you are ready to install:

.\vcsa-deploy.exe install --accept-eula --acknowledge-ceip --no-ssl-certificate-verification <Path to json File>

Here is a cut down version of the output you will see during the deployment:

 ====== [START] Start executing Task: To validate CLI options at 12:46:25 ======
 Command line arguments verfied.
  [SUCCEEDED] Successfully executed Task 'CLIOptionsValidationTask: Executing CLI
 optionsValidation task' in TaskFlow 'template_validation' at 12:46:26
  [START] Start executing Task: To validate the syntax of the template. at
 12:46:27
 Template syntax validation for template
 'M:\Software\VMware\vCenter\embedded_vCSA_replication_on_ESXi.json' succeeded.
 Syntax validation for all templates succeeded. 

 ====== [START] Start executing Task: Perform precheck tasks. at 12:46:39 ======
  [START] Start executing Task: Verify that the provided credentials for the
 target ESXi/VC are valid at 12:46:45
 The certificate of server 'smt-lab-esx-04.smt-lab.local' will not be verified
 because you have provided either the '--no-ssl-certificate-verification' or
 '--no-esx-ssl-verify' command parameter, which disables verification for all
 certificates. Remove this parameter from the command line if you want server
 certificates to be verified. 

 ================== [START] Start executing Task:  at 12:47:47 ==================
 = [SUCCEEDED] Successfully executed Task '' in TaskFlow 'install' at 12:47:47 =
  [START] Start executing Task: Check whether the datastore's free space
 accommodate the VCSA's deployment option at 12:47:51
  [SUCCEEDED] Successfully executed Task 'Running precheck: TargetDsFreespace' in
 TaskFlow 'install' at 12:47:51 

 ==========VCSA Deployment Progress Report==========         Task: Install
 required RPMs for the appliance.(RUNNING 5/100)   - Setting up storage
 VCSA Deployment is still running 

 ==========VCSA Deployment Progress Report==========         Task: Install
 required RPMs for the appliance.(SUCCEEDED 100/100)       - Task has completed
 successfully.         Task: Run firstboot scripts.(SUCCEEDED 100/100) - Task has
 completed successfully.
 Successfully completed VCSA deployment.  VCSA Deployment Start Time:
 2020-12-28T13:19:19.291Z VCSA Deployment End Time: 2020-12-28T14:18:27.103Z
  [SUCCEEDED] Successfully executed Task 'MonitorDeploymentTask: Monitoring
 Deployment' in TaskFlow 'embedded_vCSA_replication_on_ESXi' at 14:18:45
 Monitoring VCSA Deploy task completed
 The certificate of server 'smt-lab-vcsa-02.smt-lab.local' will not be verified
 because you have provided either the '--no-ssl-certificate-verification' or
 '--no-esx-ssl-verify' command parameter, which disables verification for all
 certificates. Remove this parameter from the command line if you want server
 certificates to be verified.
 == [START] Start executing Task: Join active domain if necessary at 14:18:59 ==
 Domain join task not applicable, skipping task
  [SUCCEEDED] Successfully executed Task 'Running deployment: Domain Join' in
 TaskFlow 'embedded_vCSA_replication_on_ESXi' at 14:18:59
  [START] Start executing Task: Provide the login information about new
 appliance. at 14:19:10
     Appliance Name: smt-lab-vcsa-02
     System Name: smt-lab-vcsa-02.smt-lab.local
     System IP: 10.200.15.249
     Log in as: Administrator@vsphere.local
  [SUCCEEDED] Successfully executed Task 'ApplianceLoginSummaryTask: Provide
 appliance login information.' in TaskFlow 'embedded_vCSA_replication_on_ESXi' at
 14:19:10
 =================================== 14:19:16 =================================== 

Once complete, you will now have a second vCenter appliance deployed in Linked mode with the original.  Here it is once I had configured a datacenter and cluster with two hosts.

v @ smt-lab-vcsa-02_smt-lab.locaI 
smt-lab-dc02 
a:] smt-lab-cl-wl-02a 
(Maintenance Mode) 
smt-lab-esx-07_smt-lab_local (Maintenance Mode)

And there you have it, thanks for reading!

Using Tags To Automate The Assigning Of vCenter Object Permissions

Tags are a really useful component in VMware. They can be used for all manor of things, whether it’s for storage policies, backups, identifying a group of objects or in the case of this post, managing permissions.

Having a method of easily assigning permissions to singular or multiple objects in vCenter can be a great benefit to a vSphere Admin as it’s gives them greater control over the environment they manage.

Lets take a look at what is needed to get this setup:

  • Script
  • Tag Category & Tags for each support role.
  • AD Security Groups
  • AD Service Account
  • vCenter Roles (one for the service account, then one for each of the support roles)
  • PowerCLI VICredentials
  • Scheduled Task

In this example I will use 4 common support teams that could be used, DBA, EUC, Operations and Storage. These can be anything you have a requirement for.

Script

Here is the script that applies the permissions based on the assigned tags. It can also be found here on GitHub. Save this on your management server of choice, or wherever you intend to run the scheduled task as a .PS1 file. In this example it’s saved on a management server in C:\Scripts\VI_Permissions.ps1.

#Load PowerCLI Modules
Import-module VMware.PowerCLI

#Get the Credentials
$creds = Get-VICredentialStoreItem -file  C:\Scripts\VM_Tagging_Perms.creds
 
#Connect to vCenter
Connect-VIServer -Server $creds.host -User $creds.User -Password $creds.Password -Force

#Tags
$dbaT = "Support Team/DBA_Team"
$storT = "Support Team/Storage_Team"
$eucT = "Support Team/EUC_Team"
$operT = "Support Team/Operations_Team"

#Active Directory Groups
$dbaG = "smt-lab\dba_admins"
$storG ="smt-lab\storage_admins"
$eucG = "smt-lab\euc_admins"
$OperG = "smt-lab\operations_users"

#Roles
$dbaR = "DBA VM Administrator"
$storR = "Storage VM Administrator"
$eucR = "End User VM Administrator"
$OperR = "Operations Users"


$VMs = Get-VM

ForEach ($VM in $VMs) {

        $TAGS = Get-TagAssignment -Entity $VM | Select @{l='SupportTeam';e={('{0}/{1}' -f $_.tag.category, $_.tag.name)}}, Entity

                                If ($TAGS.SupportTeam -contains $dbaT)  {New-VIPermission -Principal $dbaG -Role $dbaR -Entity $vm.name} Else {Get-VIPermission -Entity $vm.Name -Principal $dbaG | Remove-VIPermission -Confirm:$false}
                                If ($TAGS.SupportTeam -contains $storT) {New-VIPermission -Principal $storG -Role $storR -Entity $vm.Name} Else {Get-VIPermission -Entity $vm.Name -Principal $storG | Remove-VIPermission -Confirm:$false}
                                If ($TAGS.SupportTeam -contains $eucT) {New-VIPermission -Principal $eucG -Role $eucR -Entity $vm.Name}  Else {Get-VIPermission -Entity $vm.Name -Principal $eucG | Remove-VIPermission -Confirm:$false}
                                If ($TAGS.SupportTeam -contains $operT) {New-VIPermission -Principal $OperG -Role $OperR -Entity $vm.Name}  Else {Get-VIPermission -Entity $vm.Name -Principal $OperG | Remove-VIPermission -Confirm:$false}
                        }

Tag Category & Tags

Now onto Tag Categories and Tags in vCenter. Create a Tag category called ‘Support _Teams’ (Or something of your choosing, just make sure you are consistent throughout):

Or using PowerShell – New-TagCategory -Name Support_Teams -Cardinality Multiple -EntityType All

You can select as many object types as you wish and you will also want to allow multiple tags per object.

Now create a tag for each of the support teams in the tag category you just created:

New-Tag -Name Storage_Team -Category "Support_Teams"
New-Tag -Name DBA_Team -Category "Support_Teams"
New-Tag -Name EUC_Team -Category "Support_Teams"
New-Tag -Name Operations_Team -Category "Support_Teams"
Storage_Team 
DBA—Team 
EUC_Team 
Operations _ Team 
Support Team 
Support Team 
Support Team 
Support Team

Create AD groups

Now for some corresponding AD Security Group for each role you wish to have:

Name 
dba admins 
operation 
storage_ad, 
Type 
Security Group 
Security Group... 
Security Group, 
Security Group

Service Account (AD User)

Now to create an AD user account that will be used to apply the permissions within vCenter. This will be the account that will be used to run the scheduled task, connect to vCenter and will have the appropriate permissions to assign permissions for the support roles.

Name 
Type 
tag_permissions User

Support Team Roles

Now we need to create a suitable role for each team.  In this example I have copied the Virtual Machine Power User role, but these roles can contain which ever privilege’s you require.

Under ‘Administration > Roles’ you will see the options to either create a new Role or copy an existing.  From here you will be able to assign it a name and specify the privilege’s you require.

Roles 
Roles provider: 
Admlnlstrator 
Read-only 
No access 
AppdAppllenceUser 
AutoUpdateUser 
VSPHERE.LOCAL v 
DESCRIPTION 
Datastore 
USAGE 
PRIVILEGES 
Content llbrery edmlnlstretor (sample) 
Content Llbrery Reglsry admlnlstrator (sample) 
Datastore consumer (sample) 
DBA VM Admlnlstretor 
End User VM Admlnlstretor 
Network admlnlstretor (sample) 
No cryptography admlnlstrator 
No Trusted Infrastructure admlnlstretor 
NSX Admlnlstretor 
NSX Auditor 
NSX VI Admlnlstretor 
Operatlons Users 
Resource pool admlnlstretor (sample) 
SRM Admlnlstrator 
42 items 
Browse datastore 
Global 
Cancel task 
Scheduled task 
Create tasks 
• Modify task 
• Remove task 
• Run task 
Virtual machine 
Change Configuration 
Acquire disk lease 
Add existing disk 
Add new disk 
Add or remove device 
Advanced configuration 
Change CPU count 
Change Memory 
Change Settings 
Change resource 
o Modify device settings 
Remove disk

You will be referencing these Role names in the script so make sure you continue to match the names thought the process.

Permissioning Role

As mentioned in the service account section, the account (tag_permissions) running the scheduled task will need permissions in vCenter through a role.  The privileges this role will hold, needs to include all the privilege’s that are referenced in all of your Support Team Roles in order for it to have the right to assign the permissions. For example, if all your support roles are a copy of the ‘Virtual Machine power user’ role, your tagging permissions role will need to contain the same privileges.

Depending on how broad the scope of your support team roles, you may want to use the ‘Administrator’ or the ‘No cryptography administrator’ role.  This is entirely up to you and how you manage your estate.

For this example in my lab, I will use the predefined ‘Administrator’ role to grant the ‘tag_permissions’ AD account permissions at the Global Root, ensuring you have selected the ‘Propagate to children’ option.

Change Role 
Domain 
User/Group 
Role 
Global Permission Root 
SMT-LABLOCAL 
tag_permissions 
Administrator 
Propagate to children 
CANCEL

You could create a copy of the ‘Administrator’ role and name it something like ‘VI Permissions Service’ for instance, to give you flexibility to modify it in the future as well as making it easy to identify. With any high privileged account, ensure you secure it appropriately.

Create VI Credential Item

Now to create an encrypted credentials file that the service account running the scheduled task can import and then use to connect to vCenter without any intervention.

The AD account that is used to run the scheduled task, must be the account that also creates the credentials file as this is the only user that can use it.  It will require permissions to run PowerShell and have access to a folder location to store the credentials file on your chosen management server.

To begin, start a PowerShell session in the context of the service account:

Windows Security 
Run as different user 
Please enter credentials to use for 
Domain: smt-lab 
OK 
Cancel

Note: Ensure the server that you are running this scheduled task from has PowerCLI installed.  Installing PowerCLI.

Then run the following, entering your vCenter FQDN and the user and password that you created:

New-VICredentialStoreItem -host "smt-lab-vcsa-01.smt-lab.local" -user "smt-lab\tag_permissions" -password "VMware123!" -file C:\Scripts\VM_Tagging_Perms.creds
PS C: 
_Perms . creds 
New—VIC redenti al Storeltem 
C: \ Scri pts ng 
-host 
smt—lab. local" -user 
"smt—l ssion 
s" -password 
"VMware123! " 
Hos t 
User 
smt—1ab—vcsa—01 s 
smt—l . 
C: \ Scri ng_Perms . creds

Ensure you are storing the file somewhere with appropriate access to allow this but, also to restrict any unnecessary access.  The credentials file can have the password read if the user account that created it is compromised and gains access to the file using those windows credentials.

Scheduled Task

Now for the last component, the scheduled task. On a management server or a server of your choosing, create a scheduled task:

Vl_permissions Properties (Local Computer) 
General Triggers Actions Conditions Settings 
History 
Location: 
Author: 
VI Permissions 
SMT- LA8\Administrator 
Description: 
Security options 
When running the task, use the following user account: 
SMT- LA rmissio ns 
C) Run only when user is logged on 
@ Run whether user is logged on or not 
Change User or Group... 
[3 Do not store password. The task will only have access to local computer resources. 
Run with highest privileges 
Hidden 
Configure for: 
Windows Vista" , Windows Server" 2008 
Cancel

Assign an appropriate schedule that suits the level of change and size of your environment:

Vl_permissions Properties (Local Computer) 
General Triggers Actions Conditions Settings 
History 
Location: 
Author: 
VI Permissions 
SMT- LA8\Administrator 
Description: 
Security options 
When running the task, use the following user account: 
SMT- LA rmissio ns 
C) Run only when user is logged on 
@ Run whether user is logged on or not 
Change User or Group... 
[3 Do not store password. The task will only have access to local computer resources. 
Run with highest privileges 
Hidden 
Configure for: 
Windows Vista" , Windows Server" 2008 
Cancel

Now configure the trigger to execute the script:

(9 
Create Task 
General Triggers Actions Conditions Settings 
When you create a task, you must specify the action that will occur when your task starts. 
Action 
Start a program 
New... 
Details 
powershell -File 
Edit... 
Delete

Now thats everything you need to set this up, so lets give it a run though!

Assigning Tags and Permissions

Lets take a look at my demo VM permissions before we begin assigning permissions:

Lets check the VM permissions before having any tags assigned:

Get-TagAssignment -Entity $VM
$VM | ForEach-Object {Get-VIPermission -Entity $_ | Where {$_.Principal -like "*smt-lab*"} | Select Principal, Role}

Note that the tag_permissions account has been propagated from the root permissions you set earlier.

—TagAssignment 
-Entity 
ps Get 
ForEach—Object {Get—VIPermission 
principal 
Role 
SMT-LAB\tag_ 
permissions Admin 
—Entity 
Where 
principal 
—like 
Select principal, 
Role} 
SMT-LAB\Stephan 
Admin

Now assign a tag or two from the ones you created earlier using ‘New-TagAssignment’:

New-TagAssignment -Tag DBA_Team -Entity $VM
New-TagAssignment -Tag Operations_Team -Entity $VM
DBA_Team 
Tag 
Support 
Tag 
Support 
New—TagAssignment —Tag 
Team/DBA_Team 
New—TagAssignment —Tag 
Team/Operations_Team 
-Entity $VM 
Entity 
tfdemol 
Operations_Team —Entity $VM 
Entity 
tfdemol

Now you can either manually run the scheduled task or wait until its next scheduled run time.  Once the job has run, you can now check the tags match the permissions assigned by running the following:

Get-TagAssignment -Entity $VM
$VM | ForEach-Object {Get-VIPermission -Entity $_ | Where {$_.Principal -like "smt-lab"} | Select Principal, Role}
—Entity 
Tag 
Support 
Support 
Get—TagAssignment 
Team/DBA_Team 
Team/Operations_Team 
ForEach—Object {Get—VIPermission 
Entity 
tfdemol 
tfdemol 
—Entity 
Where 
principal 
—like 
Select principal, 
Role} 
principal 
SMT 
SMT 
SMT 
SMT 
—LAB\dba_admins 
—LAB\operations_users 
—LAB\tag_permissions 
—LAB\Stephan 
Role 
DBA VM Administrator 
Operations Users 
Admin 
Admin

You will see that the two tags assigned align with the the two AD groups being granted the corresponding role.

Now let do this for multiple VM’s:

Here I have multiple VM’s in the variable ‘$VM’ and I am assigning two tags to each of them.

$VM | ForEach-Object {New-TagAssignment -Tag DBA_Team -Entity $_}
$VM | ForEach-Object {New-TagAssignment -Tag Storage_Team -Entity $_}
DBA_Team 
Tag 
Support 
Support 
Support 
Support 
Support 
Tag 
Support 
Support 
Support 
Support 
Support 
—Object 
ForEach 
Team/DBA_Team 
Team/DBA_Team 
Team/DBA_Team 
Team/DBA_Team 
Team/DBA_Team 
—Object 
ForEach 
Team/Storage_Team 
Team/Storage_Team 
Team/Storage_Team 
Team/Storage_Team 
Team/Storage_Team 
{New—TagAssignment —Tag 
Entity 
Demopho€€6 
Demophoe€5 
Demopho€€2 
Demopho€€u 
Demophoe€3 
—Entity $_} 
{New—TagAssignment —Tag 
Storage_Team 
Entity 
Demopho€€6 
Demopho€€5 
Demopho€€2 
Demopho€€u 
Demopho€€3 
—Entity $_}

You can now see the tags assigned:

$VM | ForEach-Object {Get-TagAssignment -Entity $_}
{Get—TagAssignment 
Entity 
Tag 
Support 
Support 
Support 
Support 
Support 
Support 
Support 
Support 
Support 
Support 
ForEach—Object 
Team/Storage_Team 
Team/DBA_Team 
Team/Storage_Team 
Team/DBA_Team 
Team/Storage_Team 
Team/DBA_Team 
Team/Storage_Team 
Team/DBA_Team 
Team/Storage_Team 
Team/DBA_Team 
—Entity $_} 
Demophoe€6 
Demopho€€6 
Demopho€€5 
Demophoe€5 
Demopho€€2 
Demopho€€2 
Demophoeeu 
Demopho€€u 
Demophoe€3 
Demophoe€3

Following the script / job being run:

 $VM | ForEach-Object {Get-VIPermission -Entity $_ | Where {$_.Principal -like "*smt-lab*"} | Select Principal, Role} 
ForEach 
principal 
—Object {Get—VIPermission 
Role 
DBA VM Administrator 
—Entity 
Where 
principal 
—like 
Select principal, 
Role} 
SMT 
SMT 
SMT 
SMT 
SMT 
SMT 
SMT 
SMT 
SMT 
SMT 
SMT 
SMT 
SMT 
SMT 
SMT 
SMT 
SMT 
SMT 
SMT 
SMT 
—LAB\dba_admins 
—LAB\storage_admins 
—LAB\tag_permissions 
—LAB\Stephan 
—LAB\dba_admins 
—LAB\storage_admins 
—LAB\tag_permissions 
—LAB\Stephan 
—LAB\dba_admins 
—LAB\storage_admins 
—LAB\tag_permissions 
—LAB\Stephan 
—LAB\dba_admins 
—LAB\storage_admins 
—LAB\tag_permissions 
—LAB\Stephan 
—LAB\dba_admins 
—LAB\storage_admins 
—LAB\tag_permissions 
—LAB\Stephan 
Storage VM Administrator 
Admin 
Admin 
DBA VM Administrator 
Storage VM Administrator 
Admin 
Admin 
DBA VM Administrator 
Storage VM Administrator 
Admin 
Admin 
DBA VM Administrator 
Storage VM Administrator 
Admin 
Admin 
DBA VM Administrator 
Storage VM Administrator 
Admin 
Admin

As in the singular example, you will see that the two tags assigned, align with the the two AD groups being granted the corresponding role.

Removing Tags and Permissions

Now lets look at removing permissions, in this case, the Operations Team permissions from a VM:

Get-TagAssignment -Entity $VM | Where {$_.Tag -like "*Operations*"} | Remove-TagAssignment -Confirm:$false

Leaving it with just the ‘DBA_Team’ Tag assigned:

Once the script has run:

$VM | ForEach-Object {Get-VIPermission -Entity $_ | Where {$_.Principal -like "*smt-lab*"} | Select Principal, Role}

Reviewing Permissions

Finally, if you want to know which objects are supported by a specific team and have access you can check this by running:

Get-TagAssignment | Where {$_.Tag -like "Support_Teams/DBA_Team"}

You now have a way of assigning and removing permissions from vCenter objects using Tags. In this example I have used virtual machine object, but depending on your requirements, and the scope you set on the tag category, you could use this for other vCenter objects.

Thanks for reading!

vSphere 7.0 Certificate Management

vCenter 7.0 brings many new features, one of which is a much smoother certificate management experience. There are now 4 main ‘modes’ for certificate management.

These are; Fully Managed Mode, Hybrid Mode, Subordinate CA Mode and finally Full Custom Mode. There is a great article here from Bob Plankers explaining the difference between each.

As mentioned in Bob’s blog, Hybrid Mode is the recommend option, and I will show you that process here in this blog.

Firstly, in your vSphere Client, browse to Administration > Certificates. Then click Actions and select ‘Generate Certificate Signing Request (CSR)’.

Complete the required fields with your information, making sure you have at least added the common name as a Subject Alternative Name to avoid issues with modern browsers. Click Next.

Finally, copy or download your CSR to generate the certificate on the CA of your choosing. Click Finish when ready.

Generate CSR 
1 Enter Info 
2 Generate CSR 
Generate CSR 
X 
Copy or download the CSR below and provide it to your Certificate Authority 
to be signed. 
---BEGIN CERTIFICATE REQUEST.... 
MllDrZCCAPCCAQAwfZEmMCQGAIUEAWWdC210LWXhYi12Y3NhLTAXLnNtdCISY 
Wiu 
bG9jYWwxCzAJBgNVBAYTAkdCMREwDwYDVQQlDAhMYWJzaGIyZTERMA8GA 
IUEBWWI 
TGFilENPdHkXEDAoagNVBAOMB3NtdCISYWlXEDAOBgNVBASMB3NtdCISYWlW 
ggEi 
MAOGcsqGSlb3DaEBAGUAA41BDWAwggEKAOlBAQCXZYRq1HAU7M601HmvuT 
EsFnNZlpP2sBz4C9K87Wi/4kgLMq04LCTjCK08SPa+6w7AwVjmFja1np4hrSVl+N 
mh5dUOUDFHgKqFeuIAvjfXCAEVS4ircreCN7KfW12ytfUin8ce8qEu5DouguhWhl 
oi5Fa1xOGKybZFzLpySsA7rdJ6bYcJYeyn+uf7YHbO+dWHz3XZ9FG7M8fCbtLdW 
COPY 
CANCEL 
DOWNLOAD 
BACK 
FINISH

Once you have your certificate, return to Administration > Certificates and this time select ‘Import and Replace Certificate’.

You then need to select the second option. This may seem slightly deceiving but it effectively is the option you need when you have generated the CSR from vCenter like this.

Now browse and select both your freshly produced certificate, and the root certificate or certificate chain if you have issuing CA’s.

Replace Certificate 
1 Choose appropriate option 
2 Replace with signed certificate 
Replace with external CA certificate 
vCenter server services will be automatically restarted after successful replacement Of the machine SSL certificate. 
Machine SSL Certificate 
Chain of trusted root certificates 
Certificate: 
Data: 
Version: 3 (Ox2) 
BROWSE FILE 
MllDNjCCAh6gAWlBAglUZHHFEZH7/jq1Z9NXjm+ORhgflOSWDQYJKOZlhVCNA 
GEL 
CANCEL 
BROWSE FILE 
BACK 
REPLACE

Hit replace, then wait for the Web Client to restart with the new certificate.

Now one final step is needed to complete Hybrid Mode. You need to download the VMCA Root certificate from https://<vCenterFQDN by clicking the ‘Download trusted root CA certificates’ option and distributing it to your vSphere admins.

Once distributed and installed on your vSphere admins client devices, they should not get certificate errors when either browsing to vCenter or the hosts it manages.

You could however, get this error due to the default certificate having a 5 year validity period and not being within the new ‘standard’ of 398 days.

NET::ERR_CERT_VALIDITY_TOO_LONG

If you receive this, you will want to adjust the vpxd.certmgmt.certs.daysValid value in the vCenter Advanced Settings. It defaults to 1825, making it 365 (one year) will stop this.

You can then renew the certificate on each host by clicking ‘Renew’ in the Configure > Certificates menu –

Before (5 years) –

After (1 Year)-

If you want to do this renewal via PowerCLI (because…well why wouldn’t you!?) there is a nice function here by Ankush Sethi which does a great job.

Thanks for reading.

VM and vSAN Encryption

In this day an age, securing data is a must.  In this post I’d like to show you two options for protecting your data; vSAN Encryption & VM Encryption.

To achieve either of these you need to have connected a Key Management Server (or Cluster) to your vCenter server.  Check out my previous post of how to do that – Deploying and Connecting a Key Management Server to vCenter.

Lets talk though VM Encryption first.

VM Encryption is achieved using storage policies.  By Default after configuring a KMS server, the ‘VM Encryption’ is available for use.  Alternatively,  you can create your own custom VM Encryption storage policy to include additional host based services such as caching and Storage I/O.

For a new VM, select the ‘Encrypt this virtual machine’ option on the ‘Select Storage’ section of the New Virtual Machine wizard. Then select the default encryption policy, or a custom one if you have one.

Then when customising your hardware you will see the following notification –

Once deployed, you will see confirmation of the virtual machines encryption status on the VM’s summary tab.

Encryption 
Encrypted with standard key provider

For an existing VM, it’s a slightly different approach.

Firstly, power off the VM. Edit the VM’s settings and on the VM Options tab, expand the Encryption option and select your desired VM Encryption policy like so –

Below the policy you will see the option to select which disks you want to encrypt. In this test VM’s case, there is only one disk, disk 0.  You can choose to only encrypt the VM and not the disks if you have a use case to do so. Disks you choose not to encrypt will have the datastore default policy applied to them.

Alternatively, you can take a different route by editing the storage policy of a powered off VM to achieve the same result. Here you can also choose to ‘Configure per disk’. This is a useful option if you only have select hard disks you need to encrypt.

The VM will then reconfigure, this may take some time depending on the size of the disks, so make sure you factor this into your downtime window!

If you check out the performance backend monitor you will notice an increase in throughput an I/O while this is happening.

One disk at a time copies data from unencrypted to new encrypted disk.  Once done, it attaches the new encrypted disk and deletes the old unencrypted disk.  You will need enough disk space on the datastore to allow the duplication of the largest disk attached to the VM.

Once the task is complete, you will notice you have an updated encryption status.

Now the flip side, un-encrypting a VM.  

This is a reverse of the process.  Power off the VM, change the storage policy to a non Encryption policy and power back on when complete.

Now on to vSAN Encryption.

To enable encryption for an entire vSAN cluster, its just a few clicks but there are a few things to be aware of.

  1. Make sure you have adequate free space within the vSAN cluster to allow for the rolling reformatting of the disk groups.
  2. There will be increased IO during this operation, make sure you choose an appropriate maintenance window to do this in so as to not cause unwanted impacts to your workloads.

To enable this feature, select the cluster you wish to enable encryption on and browse to the ‘Configure > vSAN > Services option.

Click to enable ‘Data-At-Rest Encryption’.

You have the option to check the ‘Wipe residual data option’ if you have a need to.  Bare in mind, wiping the storage can take a significant amount of time, so only use this option if you need to wipe existing data.

The final option is ‘Allow Reduced Redundancy’.  This option will allow vSAN to run your workload at a reduced redundancy level during the encryption process.  Make sure you understand the risks before using this option.

Hit apply and the cluster will begin reconfiguring.

Task Name 
Remove dlsk group from 
the vSAN cluster 
Peform dlsk format 
converslon resource check 
task 
Peform vSAN resource 
check task 
Convert dlsk format for 
Update vSAN configuratlon 
Update vSAN configuratlon 
Update vSAN configuratlon 
Remedlate vSAN cluster 
Configure the host key 
Configure the host key 
Configure the host key 
Reconfigure vSAN cluster 
Target 
smt-Iab-esx-01_smt-Ie___ 
smt-Iab-esx-01_smt-Ie___ 
smt-lab-cl-mn-01 
smt-lab-cl-mn-01 
smt-lab-esx-03_smt-l_ 
smt-Iab-esx-01_smt-Ie___ 
smt-lab-cl-mn-01 
smt-lab-esx-03_smt-L__ 
smt-Iab-esx-01_smt-Ie___ 
smt-lab-cl-mn-01 
Status 
Completed 
Completed 
Completed 
Completed 
Completed 
Completed 
Completed 
Completed 
Completed

Once it has cycled through each host in the cluster you will be able to see that the encryption status is now ‘Enabled’

Thanks for reading!

« Older Entries