Get-View to speed up things using regex

I was playing around with the get-view cmdlet and found something I didn’t know yet.

On the site there is an example

Get-View -ViewType VirtualMachine -Filter @{"Name" = "VM"}

Cool, let’s test that. Hey , why do I get 2 items returned?
I searched for a VM called “Test” and there returned 2 VM’s which are started with “Test”.

I didn’t know that, in the description of the filter object you see:

Specifies a hash of <name>-<value> pairs, where <name> represents the property value to test, and <value> represents a regex pattern the property must match. If more than one pair is present, all the patterns must match.

Ah…

So let’s throw some regex in then:

One way to tighten our patterns is to define a pattern that describes both the start and the end of the line using the special ^ (hat) and $ (dollar sign) metacharacters. Maybe not the best option but it works fine.

To do an exact match on “Test””we use : “^Test$

Now let’s start exact match on Test and do a reset of the VM:

(get-view -ViewType VirtualMachine -Filter @{"name"="^Test$"}).ResetVM()

Cool that works, I’m no regex expert, but the way mentioned above works, because the start..end of the line only exists of VM names.

It would be nicer to use a word boundary so you capture the word only and not the line.

So we can also use \bServername\b:


get-view -ViewType VirtualMachine -Filter @{"name"="\bTest\b"}

Both options work, but may come in handy for the future.

So what I learned, the filter object can be ‘regexed’ !

PowerCLI: Show HBA Path Status *Updated*

Because our storage team was doing some upgrades lately they asked if I could the check the storage path status. We have 2 FC HBA’s per server which are connected to a seperate FC switch. Storage normally upgrades 1 path then we check to be sure before starting to upgrade the other path.

Got my inspiration from internet and credits go to them :
https://jfrmilner.wordpress.com/2011/08/27/checking-for-dead-paths-on-hbas-with-powercli/ * Used the output as a starting point where I want to go.
http://practical-admin.com/blog/powercli-show-hba-path-status/
* Pefect clean use of the get-view feature, only nasty part was the end

$result += "{0},{1},{2},{3},{4}" -f $view.Name.Split(".")[0], $hba, $active, $dead, $standby
}
}

ConvertFrom-Csv -Header "VMHost", "HBA", "Active", "Dead", "Standby" -InputObject $result | ft -AutoSize

Which I changed by creating a new object.

$row = "" | Select VMhost,HBA,Active,Dead
$row.VMhost = $view.Name.Split(".")[0]
$row.HBA = $hba
$row.Active = $active
$row.Dead = $dead
$result += $row
}
}
$result|ft -AutoSize

This object then can easily be exported to CSV/Table whatever you like. It also can be easy to for a wrap up like I made at the end.

$result |Measure-Object -Property Active,Dead -Sum|select property,sum|ft -AutoSize

Especially in a larger environment you don’t have to keep scrolling to see where it failed, just look at the summary to see if you need to scroll up 🙂


cls
function Check-DeadPaths{
<#
    .SYNOPSIS
        This function checks and reports path status
    .DESCRIPTION
         This function checks and reports path status
    .PARAMETER Outputfile
        Specify a output file, exported in CSV format.
    .EXAMPLE
        PS C:\> Check-DeadPaths -Outputfile "C:\temp\output.csv"
    .INPUTS
        System.String
    .OUTPUTS
        System.Collections.Hashtable
#>
[CmdletBinding(
    SupportsShouldProcess = $true, ConfirmImpact = "Low")]
    [OutputType([Hashtable])]
	param(
    [Parameter(Mandatory = $false)]
    [string]$Outputfile
	)
    BEGIN {
        try {
        }
        catch {
            Throw
        }
    }
	PROCESS {
        try {
		    if ($pscmdlet.ShouldProcess){
				$views = Get-View -ViewType "HostSystem" -Property Name,Config.StorageDevice
				$result = @()
				foreach ($view in $views | Sort-Object -Property Name) {
					Write-Host "Checking" $view.Name
					$view.Config.StorageDevice.ScsiTopology.Adapter|Where-Object{ $_.Adapter -like "*FibreChannelHba*" } | ForEach-Object{
						$active,$standby,$dead = 0
						$key = $_.Adapter
						$wwn = $view.Config.StorageDevice.HostBusAdapter|Where-Object{$_.key -eq $key}
						$_.Target | ForEach-Object{
							$_.Lun | ForEach-Object{
								$id = $_.ScsiLun
								$multipathInfo = $view.Config.StorageDevice.MultipathInfo.Lun | ?{ $_.Lun -eq $id }
								$active = ([ARRAY]($multipathInfo.Path | ?{ $_.PathState -like "active" })).Count
								$standby = ([ARRAY]($multipathInfo.Path | ?{ $_.PathState -like "standby" })).Count
								$dead = ([ARRAY]($multipathInfo.Path | ?{ $_.PathState -like "dead" })).Count
							}
						}
						$row = "" | Select VMhost,HBA,PortWorldWideName,NodeWorldWideName,Active,Dead
						$row.VMhost = $view.Name.Split(".")[0]
						$row.HBA = $_.Adapter.Split("-")[2]
						$row.PortWorldWideName = "{0:X}" -f $wwn.PortWorldWideName
						$row.NodeWorldWideName = "{0:X}" -f $wwn.NodeWorldWideName
						$row.Active = $active
						$row.Dead = $dead
						$result += $row
					}
				}
            }
		}
        catch {
            [String]$returnMessage = "Failed to create Kibana dashboard for environment $Environment.`r`nScriptname: " + $_.InvocationInfo.ScriptName + "`r`nLine: " + $_.InvocationInfo.ScriptLineNumber + "`r`nError: " + $_.Exception.Message
        }
$result|ft -AutoSize
Write-Host "Total Wrap up:"
$result |Measure-Object -Property Active,Dead -Sum|select property,sum|ft -AutoSize
if ($outputfile){
		$result|Export-Csv $outputfile -Confirm:$false -useculture -NoTypeInformation
	}
 
	END {
        try {
            return @{returnMessage = $returnMessage}
        }
        catch {
            Throw
        }
    }
}

vCenter 6 creating global roles with PowerCLI

While middle in the migration from a vCenter 5.1 environment to a vCenter 6.x environment I wanted to use the Global Roles so I don’t have to set them per vCenter anymore.

So how do I create those global roles?

Well the important thing is to connect to your vCenter (Connect-VIServer) using the administrator@vsphere.local user (or your SSO user if you configured a different one)

Because you login with the SSO user you can create the global roles by just using the New-VIRole command.

Example:
So in with the function below I tried to create a simple function with parameters -From and -To to simply recreate the roles from vCenter1 to vCenter2.
I make use of the logwrite function I posted earlier to spam some messages on screen and to a text file

Before:
– I expect you to be connected to both vCenters using the Connect-VIServer cmdlet.

function Migrate-VIrole{
	<#
		.SYNOPSIS
			Migrates the VCenter roles from one vCenter to another
		.DESCRIPTION
			A detailed description of the function.
		.PARAMETER  $From
			This is the vCenter to read from
		.PARAMETER  $To
			This is the vCenter to build the datacenter on
		.EXAMPLE
			PS C:\> Migrate-VIRole -From vCenter1 -To vCenter2
		.INPUTS
			System.String
		.OUTPUTS
			System.String
	#>
	[CmdletBinding()]
	[OutputType([System.String])]
	param(
		[Parameter(Position=1, Mandatory=$true)]
		[ValidateNotNull()]
		[System.String]
		$From,
		[Parameter(Position=2, Mandatory=$true)]
		[ValidateNotNull()]
		[System.String]
		$To
	)
	try{
	#Grabbing roles from an to in array
	$ArrRolesFrom = Get-VIRole -Server $From |?{$_.IsSystem -eq $False}
	$ArrRolesTo = Get-VIRole -Server $To |?{$_.IsSystem -eq $False}
	
	#Checking for existing roles
	foreach ($Role in $ArrRolesFrom){
		if($ArrRolesTo|where{$_.Name -like $role})
			{
		Logwrite -Error "$Role already exists on $To"
		logwrite -Info "Checking permissions for $role"
			[string[]]$PrivsRoleFrom = Get-VIPrivilege -Role (Get-VIRole -Name $Role -Server $From) |%{$_.id}
			[string[]]$PrivsRoleTo = Get-VIPrivilege -Role (Get-VIRole -Name $Role -Server $To) |%{$_.id}
				foreach ($Privilege in $PrivsRoleFrom){
					if ($PrivsRoleTo | where {$_ -Like $Privilege})
					{
					Logwrite -Error "$Privilege already exists on $role"
					}
					else
					{
						#Setting privileges
						Set-VIRole -Role (Get-VIRole -Name $Role -Server $To) -AddPrivilege (Get-VIPrivilege -Id $PrivsRoleFrom -Server $To)|Out-Null
						Logwrite -Success "Setting $privilege on $role"
					}
				}
			}
			else
			{
				#Creating new empty role
				New-VIrole -Name $Role -Server $To|Out-Null
				Logwrite -Success "Creating $Role on $To" 
				Logwrite -Info "Checking permissions for $role"
				[string[]]$PrivsRoleFrom = Get-VIPrivilege -Role (Get-VIRole -Name $Role -Server $From) |%{$_.id}
				[string[]]$PrivsRoleTo = Get-VIPrivilege -Role (Get-VIRole -Name $Role -Server $To) |%{$_.id}
				foreach ($Privilege in $PrivsRoleFrom)
				{
					if ($PrivsRoleTo|where {$_ -Like $Privilege})
					{
						Logwrite -Error "$Privilege already exists on $role"
					}
					else
					{
					#Setting privileges
					Set-VIRole -role (get-virole -Name $Role -Server $To) -AddPrivilege (get-viprivilege -id $PrivsRoleFrom -server $To)|Out-Null
					logwrite -success "Setting $privilege on $role"
					}
				}
			}
		}
	}
	catch 
	{
		throw
	}
}

KDC has no support for encryption type (14)

This morning was like every morning, everything up and running and had good cup of coffee. All VMware components worked fine.

After that I went to a meeting, had some talk with colleagues and came back to my workplace. Mmm a colleague tells me that he can’t login to vCenter anymore, we have 2 seperate vCenters in 2 diffent datacenters. Somehow he couldn’t login in both vCenters. Strange, as they have very few components shared.

First thing I tought of was authentication, logged in with admin@vsphere.local user in webclient and checked SSO settings. When testing the connection I got an error.

The settings in SSO for LDAP are:

  • Reuse session (this was our setting and didn’t work anymore)
  • Password (this works with my own user account so AD should be ok?)
  • Anonymous (Prohibited error)

So somehow, when I use the option password the authentication to AD is fine, but with reuse session I get an error.

Let’s check the SSO logging :

C:\Program Files\VMware\Infrastructure\SSOServer\logs\imsTrace.log

The errors I found where like:

Caused by: javax.security.sasl.SaslException: GSS initiate failed [Caused by GSSException: No valid credentials provided (Mechanism level: KDC has no support for encryption type (14))]
Caused by: GSSException: No valid credentials provided (Mechanism level: KDC has no support for encryption type (14))

So let’s ask the security team if happened something in the time I had a meeting.

“Uh yes we upgraded the functional domain level from Windows2003 to Windows2008”

*To be sure I rebooted the vCenters in the meanwhile

Ah so we might have a trigger which caused this issue. When searching the internet I find a similar error messages:

http://visualplanet.org/blog/?p=20

http://www.winsysadminblog.com/2013/02/fixing-kdc-authentication-problems-when-upgrading-your-domain-and-forest-functional-level-from-2003-to-2008-r2/

I adviced the security team to restart the Domain Controllers or restart the service. Because the impact of restarting the service is unknown we decided to restart the domain controllers later that evening.

As a workaround I used the SSO “Password” option with a service account to let people login and don’t disturb the backup process.

The day after domain controllers where rebooted, I changed the authentication type back to “Reuse session” and tested the connection….BINGO! Worked again.

The problem was probably like described in the posts, there isn’t much public information on this I could find. Our security team even verified with Microsoft for impact and stuff, but never had this mentioned.

Well took me a few minutes of my day :S

 

PowerCLI Start and stop VM using get-view

Intro

When trying to stop and start a bunch of servers I noticed that using the normal commands it took a while to shutdown all VM’s mostly because the tasks are started after each other. When You select the bunch of VM’s in vCenter, right click and select shutdown it will almost instantly start the requests tasks.

get-vm | shutdown-vmguest -confirm:$false

Fine-Tuning

I have test set of 5 CentOS Virtual machines which are all named with CENTOS in the name.

Using the measure-command command I measured the time it took to run the commands.

Command TotalSeconds
measure-command {(get-vm -name centos*)|Start-VM -Confirm:$false -RunAsync}|select totalseconds|ft -a 3,32
measure-command {(get-vm -name centos*)|Shutdown-VMGuest -Confirm:$false}|select totalseconds|ft -a 6,18

Not too bad you would say using 5 VM’s

But let’s extrapolate this for more machines

Amount VM Start(Sec) Stop(Sec) Start(Min) Stop(Min)
1,00 0,66 1,24 0,01 0,02
50,00 33,20 61,80 0,55 1,03
100,00 66,40 123,60 1,11 2,06
500,00 332,00 618,00 5,53 10,30
1000,00 664,00 1236,00 11,07 20,60

As you can see this is gaining a lot more time.

Now I build 2 commands which do exact the same thing only using the get-view commands.

measure-command {(Get-View -ViewType VirtualMachine -property Name -Filter @{“Name” = “CentOS*”}).ShutdownGuest()} |select totalseconds|ft -a 2,33
measure-command {(Get-View -ViewType VirtualMachine -property Name -Filter @{“Name” = “CentOS*”}).PowerOnVM_Task($null)} |select totalseconds|ft -a 1,64

When we extrapolate this one we see a lot of change

Aantal VM Start(Sec) Stop(Sec) Start(Min) Stop(Min)
1,00 0,2 0,04 0,00 0,00
50,00 10,00 2,00 0,17 0,03
100,00 20,00 4,00 0,33 0,07
500,00 100,00 20,00 1,67 0,33
1000,00 200,00 40,00 3,33 0,67

 Conclusion

Starting VM’s from 11 to 3 minutes and stopping from 20,60 minutes to 0,67 minutes. That’s an incredible time win when doing this with a lot of servers.

As you can see if you have a small set of VM’s or time enough (batch jobs) it might be easier to use the common cmdlets. Those will do the actions you want plus it’s more readable for colleague’s who can understand Powershell but using the VI APIs might be a bridge too far.

I haven’t been able to test it in real practice at the moment, so the extrapolation is based on the amount of time it took to power on and shutdown 5 Test VM’s.

 

VCSA API and plugin commands

When I first logged in to the appliance I noticed there is a complete list of API’s and plugins.

The complete list and description can be found here:

Plug-Ins in the vCenter Server Appliance Shell
API Commands in the vCenter Server Appliance Shell

So let’s play a bit :

Command> help pi com.vmware.vimtop
top
Display vSphere processes information.

Wonder if that will display a top view, let’s hit it !

Command> pi com.vmware.vimtop

vimtop

Nice, but it also possible just to hit “vimtop” from command.

What more do we have :

Looks that besides the root account there will be a user

Command> com.vmware.appliance.version1.localaccounts.user.list
Config:
Configuration:
Username: root
Status: enabled
Role: superAdmin
Passwordstatus: valid
Fullname: root
Email:
Configuration:
Username: postgres
Status: disabled
Role:
Passwordstatus: notset
Fullname:
Email:

Mm strange, this doesn’t look like the complete list, when I look to the users from a shell environment I see the users below:

localhost:~ # cut -d: -f1 /etc/passwd
bin
daemon
dhcpd
haldaemon
ldap
mail
man
messagebus
nobody
ntp
polkituser
postfix
root
sshd
stunnel
uuidd
wwwrun
nginx
tcserver
cm
netdumper
vapiEndpoint
postgres
mbcs
eam
deploy
vdcs
vpx-workflow
vsm
vsphere-client
perfcharts
vpostgres

 

Like you probably noticed in the normal mode you only can do some API and plugin calls. But you can switch to shell.

Switching to shell

Connected to service
* List APIs: "help api list"
* List Plugins: "help pi list"
* Enable BASH access: "shell.set --enabled True"
* Launch BASH: "shell"

Standard shell access is disabled, this can be seen by using shell.get

Command> shell.get
Config:
Enabled: False
Timeout: 0

Now let’s enable the access :

Command> shell.set --enabled True
Command> shell.get
Config:
Enabled: True
Timeout: 3597

Once we entered shell, we can use some basic linux commands


localhost:/ # df -h
Filesystem                            Size  Used Avail Use% Mounted on
/dev/sda3                              11G  3.7G  6.6G  36% /
udev                                  4.0G  164K  4.0G   1% /dev
tmpfs                                 4.0G   32K  4.0G   1% /dev/shm
/dev/sda1                             128M   38M   84M  31% /boot
/dev/mapper/core_vg-core               25G  173M   24G   1% /storage/core
/dev/mapper/log_vg-log                9.9G  1.1G  8.3G  12% /storage/log
/dev/mapper/db_vg-db                  9.9G  199M  9.2G   3% /storage/db
/dev/mapper/dblog_vg-dblog            5.0G  171M  4.5G   4% /storage/dblog
/dev/mapper/seat_vg-seat              9.9G  188M  9.2G   2% /storage/seat
/dev/mapper/netdump_vg-netdump       1001M   18M  932M   2% /storage/netdump
/dev/mapper/autodeploy_vg-autodeploy  9.9G  151M  9.2G   2% /storage/autodeploy
/dev/mapper/invsvc_vg-invsvc          5.0G  157M  4.6G   4% /storage/invsvc
localhost:/ # mount
/dev/sda3 on / type ext3 (rw)
proc on /proc type proc (rw)
sysfs on /sys type sysfs (rw)
udev on /dev type tmpfs (rw,mode=0755)
tmpfs on /dev/shm type tmpfs (rw,mode=1777)
devpts on /dev/pts type devpts (rw,mode=0620,gid=5)
/dev/sda1 on /boot type ext3 (rw,noexec,nosuid,nodev,noacl)
/dev/mapper/core_vg-core on /storage/core type ext3 (rw)
/dev/mapper/log_vg-log on /storage/log type ext3 (rw)
/dev/mapper/db_vg-db on /storage/db type ext3 (rw,noatime,nodiratime)
/dev/mapper/dblog_vg-dblog on /storage/dblog type ext3 (rw,noatime,nodiratime)
/dev/mapper/seat_vg-seat on /storage/seat type ext3 (rw,noatime,nodiratime)
/dev/mapper/netdump_vg-netdump on /storage/netdump type ext3 (rw)
/dev/mapper/autodeploy_vg-autodeploy on /storage/autodeploy type ext3 (rw)
/dev/mapper/invsvc_vg-invsvc on /storage/invsvc type ext3 (rw,noatime,nodiratime)
none on /var/lib/ntp/proc type proc (ro,nosuid,nodev)

localhost:/var/log # tail -f messages.log
2015-04-28T12:51:30.980333+00:00 localhost kernel: [1652125.714038] IPfilter Dropped: IN=eth0 OUT= MAC=01:00:5e:00:00:01:00:22:bd:37:fc:00:08:00 SRC=145.70.12.252 DST=224.0.0.1 LEN=36 TOS=0x00 PREC=0xC0 TTL=1 ID=61046 PROTO=2
2015-04-28T12:51:42.931041+00:00 localhost su: (to vpostgres) root on none
2015-04-28T12:51:50.860391+00:00 localhost kernel: [1652145.593672] IPfilter Dropped: IN=eth0 OUT= MAC=01:00:5e:00:00:01:00:22:bd:37:fc:00:08:00 SRC=145.70.12.252 DST=224.0.0.1 LEN=36 TOS=0x00 PREC=0xC0 TTL=1 ID=5260 PROTO=2
2015-04-28T12:51:51.044384+00:00 localhost kernel: [1652145.777641] IPfilter Dropped: IN=eth0 OUT= MAC=01:00:5e:00:00:01:00:22:bd:37:fc:00:08:00 SRC=145.70.12.252 DST=224.0.0.1 LEN=36 TOS=0x00 PREC=0xC0 TTL=1 ID=5416 PROTO=2
2015-04-28T12:52:15.344457+00:00 localhost su: (to vpostgres) roo

Something else I noticed when enabling shell access the timeout starts counting down. As soon as I keep hitting

Command> shell.get
Config:
Enabled: True
Timeout: 3597
Command> shell.get
Config:
Enabled: True
Timeout: 3596
Command> shell.get
Config:
Enabled: True
Timeout: 3596
Command> shell.get
Config:
Enabled: True
Timeout: 3596
Command> shell.get
Config:
Enabled: True
Timeout: 3595

You see the timeout decrease I guess it’s in seconds so 3600 seconds = 60 minutes = 1 hour.

It’s possible to change the timeout using the shell.set command


Command> shell.set -help
shell.set: error: unrecognized arguments: -help
Command> shell.set --help

Usage:
shell.set [--help/-h] --enabled BOOL --timeout INT
Description:
Set enabled state of BASH, that is, access to BASH from
within the controlled CLI.
Input Arguments:
--enabled BOOL
Enabled can be set to true or false
--timeout INT
The timeout (in seconds) specifies how long you enable the
Shell access.

VMware vCenter Server + PSC Appliance 6.x deployment

Choices ?

Due the expansions of the limitations in the vSphere appliances, it now could be a worth replacing the Windows vCenter servers by appliances. Because I’m reasearching the upgrade to 6.x I need to make a decision to go for Windows or the Appliance. Too bad VMware’s Update manager is still a Windows-only product, but ok, I could live with that.

Because we have two sites I normally go for 2 single vCenter installations with their own databases, SSO, VUM etc. So they will be separate entities, no matter what happens on one of the sites, there is no relation, so the surviving one will keep working.

When digging through the new documentation and install guides there are basically a few major decisions to make. Because it’s not able to change this after deployment you have to think beforehand and
make the right decisions.

Below are a few “Major” choices for your design which I will explain later from my point of view. There are several good blog posts on the internet already.
Choice 1 : Embedded or external Platform Service Controller
Choice 2 : Internal or external Database
Choice 3 : One or more vCenters
Choice 4 : Windows, appliance or both ?
Choice 5 : New install or upgrade

Which are beautifully explained in the install guide:
http://pubs.vmware.com/vsphere-60/index.jsp?topic=%2Fcom.vmware.vsphere.install.doc%2FGUID-ACCD2814-0F0A-4786-96C0-8C9BB57A4616.html

At the moment I’m not going to explain or discuss the decisions and facts I used to choose for this setup.

Design6As you can see I chose to setup 1 vCenter per site (like I used to do before) and made a local external PSC for each site and connected them in the same “Site”. So basically the PSC’s will replicate with each other across the sites, while the vCenters are local.

What does that PSC do actually? Well it handles vCenter Single Sign On, vSphere License Service, VMware Certifcate Authority. Those components where previously part of the vCenter Installation, by seperating them, it now is also possible to link both PSCs.

Because I join the second PSC to the same site it’s possible to use Enhanced Linked Mode out of the box. The site below will explain what it means. It’s awesome that roles/permissions etc. now can be managed from a single point.
http://pubs.vmware.com/vsphere-60/index.jsp#com.vmware.vsphere.install.doc/GUID-91EF7282-C45A-4E48-ADB0-5A4230A91FF2.html

Migrate Windows vCenter Server to vCenter Appliance?

Yes it’s  possible, haven’t tried it yet, but came accross this fling which let’s you migrate a Windows vCenter server with an external SQL Database to a vCenter Appliance with Embedded vPostgres Database

https://labs.vmware.com/flings/vcs-to-vcva-converter

Design  & Installation

For my testing purposes I decided to deploy 4 appliances, 2x vCenter server and 2x Platform Service Controller.

Instead of using the CD-ROM and follow the instructions (which I did already a few times), I decided to create a simple deployment script. It is possible to deploy the appliances with a pretty simple script and configuration file. Let’s dive in here:

You”ll need the installation CD and mount that to a Windows machine where you start the deployment using the deploy command which is located on the CD-ROM.

Secondly you need a few .json files which hold the configuration for the VCSA deployment.

To follow the example as in the picture I have 4 .json files, 2 for the vCenters and 2 for the PSC controllers.

Let’s start setting up the PSC Controllers and SSO Site, choose 1 to deploy first, I take PSC_Site1

The first part is the deployment information, what is the hostname where the PSC needs to be deployed too, fill in the username,password,datastore,network etc.

Next is the VCSA information, what is the root password of the appliance, does SSH need to be enabled and

After that there are some seperate configuration options for setting up the SSO domain. Because it’s the first one, the option “first-instance” is set to true, the rest looks self explanatory so fill it in like you designed it.

PSC Site 1 JSON

{
"__comments":
[
"Template to deploy PSC Controller Site1."
],

"deployment":
{
"esx.hostname":"ESX_Site1",
"esx.datastore":"Datastore_Site1",
"esx.username":"root",
"esx.password":"VMWare!",
"deployment.network":"VLAN1234",
"deployment.option":"infrastructure",
"appliance.name":"PSC_Site1",
"appliance.thin.disk.mode":false
},

"vcsa":
{
"system":
{
"root.password":"VCSA_VMWare!",
"ssh.enable":true
},

"sso":
{
"password":"SSO_VMWare!",
"domain-name":"vsphere.local",
"site-name":"vSphere_Test",
"first-instance":true
},

"networking":
{
"ip.family":"ipv4",
"mode":"static",
"ip":"192.168.1.214",
"prefix":"24",
"gateway":"192.168.1.254",
"dns.servers":"192.168.1.203",
"system.name":"SSO_Site1"
}
}
}

Nice, now we have the configuration file for the first External SSO server in the domain. In the JSON directory on the CD are some examples for the different installations. We now need to build the second external PSC controller on a different host in a different physical site, but still need to connect it to the primary site which is created above.

PSC Site 2 JSON


{
"__comments":
[
"Template to deploy PSC Controller Site2."
],

"deployment":
{
"esx.hostname":"ESX_Site2",
"esx.datastore":"Datastore_Site2",
"esx.username":"root",
"esx.password":"VMWare!",
"deployment.network":"VLAN1234",
"deployment.option":"infrastructure",
"appliance.name":"PSC_Site2",
"appliance.thin.disk.mode":true
},

"vcsa":
{
"system":
{
"root.password":"VCSA_VMWare!",
"ssh.enable":true
},

"sso":
{
"password":"SSO_VMWare!",
"domain-name":"vsphere.local",
"site-name":"vSphere_Test",
"replication-partner-hostname":"192.168.1.214"
},

"networking":
{
"ip.family":"ipv4",
"mode":"static",
"ip":"192.168.1.215",
"prefix":"24",
"gateway":"192.168.1.254",
"dns.servers":"192.168.1.203",
"system.name":"192.168.1.215"
}
}
}

As you can see, you configure the replication partner and site name where the second PSC needs to connect/register too.

Good, this will later on deploy the upper part of the picture and configure and SSO Domain which exists of 2 PSC Servers.

vCenter JSON

Let’s configure 2 vCenters, because the configuration is just the same, I’ll post only 1 example. I configure vCenter Site 1 here:


{
"__comments":
[
"Template to deploy vCenter Server Site1."
],

"deployment":
{
"esx.hostname":"ESX_Site1",
"esx.datastore":"Datastore_Site1",
"esx.username":"root",
"esx.password":"VMware!",
"deployment.network":"VLAN1234",
"deployment.option":"management-tiny",
"appliance.name":"vCenter_Site1",
"appliance.thin.disk.mode":true
},

"vcsa":
{
"system":
{
"root.password":"VCSA_VMware!",
"ssh.enable":true,
"platform.service.controller":"192.168.1.214"
},

"sso":
{
"password":"SSO_VMware!",
"domain-name":"vsphere.local",
"site-name":"vSphere_Test"
},

"networking":
{
"ip.family":"ipv4",
"mode":"static",
"ip":"192.168.1.216",
"prefix":"24",
"gateway":"192.168.1.254",
"dns.servers":"192.168.1.203",
"system.name":"192.168.1.216"
}
}
}

The second vCenter configuration file is the except the relation to the PSC which connects to the “local PSC”.
“platform.service.controller”:”192.168.1.215″

So let’s wrap it up, I have 4 .json files which hold the configuration of 1 external PSC controller, which is the first of the site. Then a second PSC is deployed which is connected to the first PSC “Site”.

After that we deploy two vCenters which connect to the PSC Site within their own site.

Good that’s a start. On the Installation CD there is  a file called  : vcsa-deploy.exe which can be found here Z:\vcsa-cli-installer\win32\vcsa-deploy.exe

All command line options an configuration can be found here:

http://www.vmware.com/files/pdf/products/vsphere/VMware-vsphere-60-vcenter-server-appliance-cmdline-install.pdf

Now let’s create a simple deployment batch file which contains the installation.

As you can see, you start the vcsa-deploy.exe, with the json file we created, save the log file to a directory and turn off the SSL verification.


Z:\vcsa-cli-installer\win32\vcsa-deploy.exe D:\JSON\PSC_Site1.json --log D:\JSON\PSC_Heerlen_install.log --no-esx-ssl-verify --verbose
Z:\vcsa-cli-installer\win32\vcsa-deploy.exe D:\JSON\PSC_Site2.json --log D:\JSON\PSC_Beek_install.log --no-esx-ssl-verify
Z:\vcsa-cli-installer\win32\vcsa-deploy.exe D:\JSON\VC_Site1.json --log D:\JSON\VC_Heerlen_install.log --no-esx-ssl-verify
Z:\vcsa-cli-installer\win32\vcsa-deploy.exe D:\JSON\VC_Site2.json --log D:\JSON\VC_Beek_install.log --no-esx-ssl-verify

Let’s fire it up  :

deplot

Cool let’s keep it running until it ‘s finished. I experienced that after it’s finished there seem to be some background tasks, so let it run for a few more minutes to let it sync and setup correctly.

Done?

Now let’s go to the webclient: https://192.168.1.216/vsphere-client

And login with “Administrator@vsphere.local” and the password you provided in the configuration. You’ll now see your 2 vCenters connected in the same interface.

Ah pretty, now let’s see what we can do.

For example go to the “Adminstration” tab, here we can see “Global permissions, licensing etc.”What about cross  vMotion to another datacenter, I read about that..let’s see:

Right click a virtual machine and select the “Migrate” option, choose the option to “Change both compute resource and storage” (because you don’t have the same shared storage on the other side, at least I don’t). Cool, now I can select other vCenters and underlying resources. Select the resource you want to move to, select the datastore, select another network if needed and click “Finish”.

Awesome that worked flawless.

I’m still doing some more testing and will update the text and pictures asap. This was a quick reference & braindump

 

sVmotion single files to another datastore PowerCLI oneliner

I needed to move a lot of VM disks from one to another datastore, and was too lazy to do it with the gui, and click on advanced etc.
So I created a nice oneline which helped me move them pretty good, (of course you can add -runasync) to do more disks simultaneously

get-HardDisk -vm (get-vm -Datastore "old_Datastore")|where {$_.filename -match "old_Datastore"} | Move-HardDisk -Datastore "New_Datastore" -confirm:$false

Performance research ESXi hosts with esxtop and more

Gathering & Analysing performance data

For a performance research I need to gather & analyse the esxtop statistics during a 2 hour window on about 10 ESXi hosts with about 15 VM’s where I need to gather the data from .One requirement was a perfromance data with a delay of 15 seconds and capture it between 08:00 and 10:00 (+1 timezone). Focus on CPU and disk statistics

So let’s break it up in some steps:

1) Gather ESXtop data on specific time using Crontab
2) Retrieve & Extract data from datastores using PowerCLI
3) Analyse data using Perfmon
4) Plot data with Datplot

Gather ESXtop data on specific time using Crontab

ESXtop batch mode command

First we need to know how to retreive data and which command we need to schedule, while scavenging the internet I saw a lot of good explained esxtop posts which helped me creating the command below which I wanted to schedule:

export DATE=$(date +%Y-%m-%d-%H-%M-%S) && export HOSTNAME=$(hostname) && /sbin/esxtop -b -d 15 -n 480 | gzip -9c > /vmfs/volumes/Datastore/Logging/$HOSTNAME-$DATE.csv.gz

To break it up, I used the post below to create the first part of the command, this is about setting the hostname and date variable and execute the ESXtop command and saving it to a filename where the time and hostname are added. Nothing much to explain here.

http://vbyron.com/blog/performance-analytics-esxi-esxtop-mongodb/

export DATE=$(date +%Y-%m-%d-%H-%M-%S) && export HOSTNAME=$(hostname) && <command>

I wasn’t completely happy with the ESXtop command in the post so I used Duncan’s post to complete it for my needs. I used it a few times before, because the direct zip the output is extremely handy.
http://www.yellow-bricks.com/esxtop/

esxtop -b -d 15 -n 480 | gzip -9c > /vmfs/volumes/Datastore/Logging/$HOSTNAME-$DATE.csv.gz

So let’s start esxtop in batchmode (-b) with a delay (-d) of 15 seconds, because we need to capture it for 2 hours  ( 7200 sec / 15 sec interval  = 480 samples) so the iterations (-n) are set to 480. To use the handy gzip command, pipe the output and set a location where to store the data. Make sure the path you set is available, as you can see I used a seperate “logging” directory, only flaw was that when the directory doesn’t exist, the data isn’t gathered. You might just want to dump it in the root of the datastore.

Ok, to wrap it up, we now have a nice command which gathers the ESXtop data according to requirements and save it as a zip file with the hostname and time & date stamp.

Scheduling using Crontab

To schedule the command on a specific date/time we use crontab for scheduling. More explanation on how to use crontab can be found here:

http://nl.wikipedia.org/wiki/Cronjob

Important is the part below which explains how the scheduling is done.

 # * * * * *  command to execute
 # │ │ │ │ │
 # │ │ │ │ │
 # │ │ │ │ └───── day of week (0 - 6) (0 to 6 are Sunday to Saturday, or use names; 7 is Sunday, the same as 0)
 # │ │ │ └────────── month (1 - 12)
 # │ │ └─────────────── day of month (1 - 31)
 # │ └──────────────────── hour (0 - 23)
 # └───────────────────────── min (0 - 59)

 

Also for this part are a few good posts around, as well as a VMware article with some basic explanation:

http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1033346

First start by enabling SSH on the ESXi host, and make a connection to your host. Once you are connected to the host, open the crontab file:

cd /var/spool/cron/crontabs/
vi ./root

Now you’re in the crontab file, there should be already some settings configured. Because we use VI to edit the file, first press <i> to go to insert mode.

Next add the line below the last one with a simple copy/paste.

0    7    10   2   *   export DATE=$(date +%Y-%m-%d-%H-%M-%S) && export HOSTNAME=$(hostname) && /sbin/esxtop -b -d 15 -n 480 | gzip -9c > /vmfs/volumes/Datastore/Logging/$HOSTNAME-$DATE.csv.gz

As you can see, I start the job at 0 minutes, 7 hours, 10th of 2nd month(February), no specific day.

Huh wait….07:00 wasn’t the requirement 08:00 ? Yes that’s true, but 08:00 is our local time, as ESXi hosts run in UTC mode, you need to set the time right in UTC.

The enable the scheduled job we need to restart the crond process. First retrieve the ID of the process using:

cat /var/run/crond.pid

Next kill the process ID:

Kill -HUP <Proc ID>

And start Crond:

crond

That’s it, now disconnect from your host and disable SSH if that’s your default.

Retrieve and extract the data with PowerCLI

Because I didn’t want to open all the datastores, copy files and extract them manually I just made a simple PowerCLI script (without error handling)

First I created an alias for 7zip which will be used later to extract the .gz files.

# Creating alias for 7-zip and test path
if (-not (test-path "C:\Program Files\7-Zip\7z.exe")) {throw "C:\Program Files\7-Zip\7z.exe needed"}
set-alias sz "C:\Program Files\7-Zip\7z.exe

Now we can use the alias sz to extract the files.


$datastores = Get-Datastore Datastore1,Datastore2
foreach ($datastore in $datastores){
Write-Host "Mounting $Datastore" -ForegroundColor Magenta
if (Get-PSDrive|?{$_.name -eq "ds"}){
Remove-PSdrive ds -Force | Out-Null
New-PSDrive -Location $datastore -Name ds -PSProvider VimDatastore -Root "\" |Out-Null
Set-Location ds:\
Write-Host "Copying datastore items from $datastore" -ForegroundColor Magenta
copy-DatastoreItem -Item ds:\Logging\* -Destination D:\Troubleshooting\LoggingGZ
}
else {
New-PSDrive -Location $datastore -Name ds -PSProvider VimDatastore -Root "\" |Out-Null
Set-Location ds:\
Write-Host "Copying datastore items from $datastore" -ForegroundColor Magenta
copy-DatastoreItem -Item ds:\Logging\* -Destination D:\Troubleshooting\LoggingGZ -Force
}
write-host -ForegroundColor Magenta "Done"
}

I got some errors with mounting and dismounting the PSdrive, so  I created a simple if statement to work around it.

Now we have the data local, we can extract it using the alias created earlier.


$GZ = gci D:\Troubleshooting\LoggingGZ\ | where {$_.name -like "*.gz"}
$path = "D:\Troubleshooting\LoggingGZ"
cd $path
#Extract all GZ files and move to folder \Logging
Write-Host "Extracting .gz files" -ForegroundColor Magenta
$GZ  | %{sz e -y $_.fullname}
Write-Host "Moving CSV files" -ForegroundColor Magenta
gci $path|?{$_.name -like "*.csv"}|% {Move-Item -Force $_ "D:\Troubleshooting\Logging\"}
Write-Host "Done" -ForegroundColor Magenta

There we go, now we have the original .gz files retrieved and also an unpacked CSV version.

 

Analyse data using Perfmon

Right..the CSV files are between 100 and 500 MB, (if you use the -a switch in ESXtop) to capture “all” statistics it will be even larger.

So as we don’t need all the data I extract only what I need so the files become easier to handle.

First start perfmon (Start->Run->Perfmon)

Right click on the screen and select “Properties” – > “Tab Source”
Select “Log files” -> “Add” and browse to on of your CSV files.

Next go to “tab Data” -> “Add”  to select the counters we need.

I need the counters below for 2 VM’s

Group CPU // % Costop/ %Ready /%Wait / %Run
Physical Disk SCSI Device // Average Driver ms/cmd / average guest ms/cmd

Select the right counters and instances you want to, now we only selected the data we want to work with. What about saving it to a new CSV file.

Right click on the screen and select “Save data as..”, select a filename and location and the filetype you want. You also could use *.blg format so you could later load multiple BLG files in Perfmon to compare between ESX hosts.
Now the file has shrunk from 166 MB to 308 KB…that’s better to handle.

You could use the perfmon tool to do further troubleshooting but I found another cool tool named : Datplot

Plot data using Datplot

After you donwloaded and succesfully installed Datplot it took me a few seconds to see how things worked. Not that hard, but here are some starting tips

#Import data
File -> Load new datasource and select your CSV file.

Next you get a few questions you need to answer, enter the lines where the columns and data starts. So for an ESXtop file that will be :

Get column (parameter) names from line : 1 (this is the header line)
Get column (parameter) names from line : 0 (no unit line)
Get column (parameter) names from line : 2 (here starts the data)

Column Delimiter : , (Comma)
Number decimal symbol : . (Dot)

Select “import data”, now the data is imported and you see an empty graph.

#Plot something
Next in the upper right corner there is a dropdown menu where you need to select the X-Axis. Select the first option (which is the time) and click apply.

So what’s next : let’s add some data

Right click on the graph and select “Datacurve -> Add”
Select the parameter you want to plot. You need to plot the parameters one by one. You can plot multiple parameters and even select to target on the left or right y-axis. This way you could add different parameter values in one graph.

What if you want to split it out, that’s also possible, when you right click and select “Graph pane -> Add” you’ll see a 2nd graph appear. Here you can plot more data.

Nice thing is you can split different graph on the same timeline. Another cool thing is that you can add an “Event line”.

With this line you could for excample point out a spike -> “right click on spike  -> event line -> add”

This way a vertical line is drawn through both graphs which also displays the values on that time for all lines.

Also adding a box with the Min/mean/max values can be handy, add this through the “Edit Menu” -> “Toggle min/max/mean” -> Select the location.

Some other things you can do is save as different image formats, add lines/text.

Will add some screenshots later.

 

 

 

HP Power settings to maximize perfomance

Below are some BIOS settings we set on our ESXi hosts, but also on other HP DL series servers. Everything is used for maximum performance, we don’t look for powersaving features. Or processor C-states which scale up/down the frequencies, this mostly has a negative impact on hard working machines.

HP Power settings to maximize perfomance

Setting Value Description
Intel Turbo Boost Technology Enabled Allows processors to make a transition to a frequency that is higher than its rated speed
Thermal Configuration Optimal/Increased Cooling Use the one that provides the desired performance for the lowest power consumption
HP Power Profile Maximum Performance Disables all power management options that may negatively affect performance
HP Power Regulator HP Static High Performance Keeps processors in their maximum power/performance state
Intel QPI Link Power Management Disabled Precludes placing unutilized QPI links into low power state

Minimum Processor Idle Power Core State

No C-States

Precludes processor transitions into low power core C-States
Minimum Processor Idle Power Package State No Package State

Precludes processor transitions into low power package C-States

Energy/Performance Bias

Maximum Performance

Configures processor subsystems for high performance/low latency
Collaborative Power Control Disabled Precludes the OS from changing clock frequency
DIMM Voltage Preference Optimized for Performance Runs DIMMs at a higher voltage if it increases performance

Dynamic Power Capping Functionality

Disabled This option allows for disabling System ROM Power Calibration during the boot process
Doing so accelerates boot times but precludes enabling of a Dynamic Power Cap

Memory Power Savings Mode

Maximum Performance

This option configures several memory parameters to optimize the memory subsystems performance and is configured to Balanced by default

These are quite the main features to disable.

References:

http://www.vmware.com/files/pdf/techpaper/VMW-Tuning-Latency-Sensitive-Workloads.pdf

http://h10032.www1.hp.com/ctg/Manual/c01804533.pdf

 

 

1 2 3 4