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’ !

Logging Function v2.0

As I created an earlier post with a simple logging function in poweshell, a while ago I upgraded this with a specific Error, Success and info switch. This way I can put it with simple colors as output on screen to see if something goes wrong or good. And also logging will be better searchable.

 

$Logfile = "D:\LogFile.txt"

Function LogWrite{
&lt;#
<span style="font-size: 0.95em; line-height: 1.6em;">.SYNOPSIS This functions is used to generate a log file
</span><span style="font-size: 0.95em; line-height: 1.6em;">.DESCRIPTION Function creates output on screen depending on given switch and writes this with error code to the logfile
.PARAMETER $Logstring Location to the logfile
.PARAMETER $Error Switch to identify an error message
.PARAMETER $Success Switch to identify a success message
.PARAMETER $Info Switch to identify an info message
.EXAMPLE PS C:\&gt; Logwrite -error "This is an error"
</span> .INPUTS
System.String,System.Switch
.OUTPUTS
System.String
#&gt;

[CmdletBinding()]
[OutputType([System.String])]
Param(
[string]$Logstring,
[switch]$Error,
[switch]$Success,
[switch]$Info

)
try {
if ($Error){
$logstring = (Get-Date).ToString() + " ERROR: " + $logstring
Write-Host -ForegroundColor red $logstring
}
elseif ($Success){
$logstring = (Get-Date).ToString() + " SUCCESS: " + $logstring
Write-Host -ForegroundColor green $logstring
}
elseif ($Info){
$logstring = (Get-Date).ToString() + " INFO: " + $logstring
Write-Host $logstring
}
else {
$logstring = (Get-Date).ToString() + " INFO: " + $logstring
Write-Host $logstring
}
Add-content $Logfile -value $logstring
}
catch {
throw
}
}

#Example

logwrite -success "Success creating user: $user"
logwrite -error "Error creating user $user"
logwrite -info"Success quering user: $user"

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
	}
}

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.

 

 

 

Exporting CSV files with your default delimiter

Normally when you export a csv file in powershell it uses the default delimiter comma, unless you use the -delimiter parameter to use another delimiter.

Depending on your language settings tools like Excel use a different delimiter. You can find these settings in your region/language settings -> Formats -> additional settings. Here is a field with “List seperator” which shows you the list separator selected.

You also can retrieve this with the powershell command below:

[Powershell](Get-Culture).TextInfo.ListSeparator[/powershell]

Because of this and switching between servers/workstations with different language settings this can be frustrating sometimes. This is why the –useculture parameter is available

Use the list separator for the current culture as the item delimiter. The default is a comma (,).

This parameter is very useful in scripts that are being distributed to users worldwide. To find the list separator for a culture, use the following command:

export-csv -useculture

This uses your local delimiter as delimiter for your export CSV, so as soon as you doubleclick it and it opens in excel it is already correctly seperated.

HP-AMS older then DL380Gen8 Hardware

HP-AMS keeps restarting

Problem

A few weeks ago we started to deploy HP Custom Image for ESXi 5.1.0 Update 2 on all our ESXi hosts. Everything seemed to work without problems until a colleague recently discovered in the logfiles that the HP-AMS provider keeps restarting every 5 minutes and gives an error message that it can’t start because it only works on.

We also noticed the problem only occured on ESXi hosts which are not HP DL380Gen8. So DL585 G5,G6,G7 gave these errors. Makes sense, the error also notices that it runs on Gen8 and older!

Solution

Luckily I found a VMWare article KB2085618 which described our problem:

Too bad the only solution is to remove the Agentless Management agent…by hand on the command line on 50+ ESXi hosts.

Damn! I was too lame to do this by hand so build a little powerCLI script. It’s not completed yet or error free. It was just a quick and dirty solution for fast results. So it’s not yet completed, but would like to share it already as it is faster then enabling SSH everywhere, connecting to ESXi hosts, insert commands, reboot etc.

Script

Pre-requirements

– Connect to your vCenter

– Put host in maintenance mode

– Load the module of function

– Plink installed and edited the script to use the right Plink directory

Download Plink here:

http://www.chiark.greenend.org.uk/~sgtatham/putty/download.html

 


Function Enable-TSM {
Param (
[parameter(valuefrompipeline = $true, mandatory = $true,
HelpMessage = "Enter an ESX(i) entity")]
[PSObject]$VMHost,
[switch]$Local)

process {
switch ($VMHost.gettype().name) {
"String" {
if ($Local) {$VMHost = Get-VMHost -Name $VMHost | Enable-TSM -Local}
else {$VMHost = Get-VMHost -Name $VMHost | Enable-TSM}
}
"VMHostImpl" {
if ($Local) {
$VMHost | Get-VMHostService | Where {$_.Key -eq "TSM"} | %{
if ($_.running -eq $false) {
$_ | Start-VMHostService -Confirm:$false | Out-Null
Write-Host "$($_.Label) on $VMHost started"
}
else {Write-Warning "$($_.Label) on $VMHost already started"}
}
}
else {
$VMHost | Get-VMHostService | Where {$_.Key -eq "TSM-SSH"} | %{
if ($_.running -eq $false) {
$_ | Start-VMHostService -Confirm:$false | Out-Null
Write-Host "$($_.Label) on $VMHost started"
}
else {Write-Warning "$($_.Label) on $VMHost already started"}
}
}
}
default {throw "No valid type for parameter -VMHost specified"}
}
}
}


Function Disable-TSM {
Param (
[parameter(valuefrompipeline = $true, mandatory = $true,
HelpMessage = "Enter an ESX(i) entity")]
[PSObject]$VMHost,
[switch]$Local)

process {
switch ($VMHost.gettype().name) {
"String" {
if ($Local) {$VMHost = Get-VMHost -Name $VMHost | Disable-TSM -Local}
else {$VMHost = Get-VMHost -Name $VMHost | Disable-TSM}
}
"VMHostImpl" {
if ($Local) {
$VMHost | Get-VMHostService | Where {$_.Key -eq "TSM"} | %{
if ($_.running -eq $true) {
$_ | Stop-VMHostService -Confirm:$false | Out-Null
Write-Host "$($_.Label) on $VMHost stopped"
}
else {Write-Warning "$($_.Label) on $VMHost already stopped"}
}
}
else {
$VMHost | Get-VMHostService | Where {$_.Key -eq "TSM-SSH"} | %{
if ($_.running -eq $true) {
$_ | Stop-VMHostService -Confirm:$false | Out-Null
Write-Host "$($_.Label) on $VMHost stopped"
}
else {Write-Warning "$($_.Label) on $VMHost already stopped"}
}
}
}
default {throw "No valid type for parameter -VMHost specified"}
}
}
}

These functions were still in my profile so I put them on the site but were not created by me, these are only needed to enable/disable SSH.


function Get-HP{
<#
#Help file
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
[System.String]
$VMhostName,

[switch]$Status,

[switch]$Remove
)
try {
$Hosts = Get-VMHost $VMhostName
if ($Status -eq $true){
#######Check for HP-AMS Provider Status #######
foreach ($VMHost in $Hosts){
$ESXCLI = Get-EsxCli -VMHost $VMHost
$HP = $ESXCLI.software.vib.list() | Where { $_.Name -like "hp-ams"} | Select @{N="VMHost";E={$ESXCLI.VMHost}}, Name, Version
if ($HP.name -eq "hp-ams"){
if($Hosts.Model -match "Gen8"){
Write-Host -fore Green "HP-AMS Provider found on" $HP.VMhost $hosts.model "Version:" $HP.version
}
else {
Write-Host -fore Red "Please remove HP-AMS Provider found on" $HP.VMhost $hosts.model "Version:" $HP.version
}
}
else{
Write-Host -ForegroundColor Red "No HP-AMS Provider found on $HP.VMhost $hosts.model"
}
}
}
elseif ($Remove -eq $true){
#######Remove option#######
# Maintenance mode check

Write-Host "Checking Maintenance mode"
if ((Get-VMHost $hosts | select ConnectionState).Connectionstate -ne "Maintenance")
{throw "Put host in maintenance mode please"}
else
{
Write-Host -ForegroundColor Green "Maintenance mode OK"
#2 Enable SSH
Enable-TSM $Hosts
if ((Get-VMHostService -VMHost $Hosts|?{$_.key -eq "TSM-SSH"}).running -eq "True")
{Write-Host -ForegroundColor Green "SSH running succesfull"}
else
{Write-Host -ForegroundColor Red "SSH failed starting"}

#3     HP Service stoppen middels Plink actie
# Creating alias for plink and test path
if (-not (test-path "D:\Putty\plink.EXE")) {throw "D:\Putty\plink.EXE needed"}
set-alias plink "D:\Putty\plink.EXE"
$Str1 = 'echo Y | plink -pw Password -l root '
$Stop = ' /etc/init.d/hp-ams.sh stop'
$Server = $hosts.name
$command= $str1+$server+$Stop
$output = Invoke-Expression -Command $command
$output

#4Verwijderen HP service
Write-Host "Starting removal"
$Str2 = 'plink -pw Password -l root '
$Remover = ' esxcli software vib remove -n hp-ams'
$command= $str2+$Server+$Remover
$output1 = Invoke-Expression -Command $command
$output1
if ($output1 -like "*successfully*"){
Write-Host -ForegroundColor green "Removal completed succesfully"
if ($output1 -like "*reboot*")
{
Write-Host -ForegroundColor Yellow "Reboot required and starting now"
Restart-VMhost -VMHost $Hosts -Confirm:$false|Out-Null
Write-Host -ForegroundColor Yellow "Restart started"
}
Else{
write-host "Possible dry-run?"
}
}
Else {
if ($output1 -like "*NoMatchError*"){
Write-Host "Nothing to do already removed probably restart required";Disable-TSM $Hosts
}
else{}
}

}
}
else {
Write-Host "No switch parameter found, use -remove or -status";Disable-TSM $Hosts
}
}
catch {throw}
}

Switches

-status : Checks the status of the host, is the agent installed and which model is the host.

-remove : Checks if host is in maintenance mode, stops the HP-AMS service, uninstalls the HP-AMS service and restarts the VMhost

Execution

Example for a DL585G5

get-hp -VMhostName esx1.net –Status
Please remove HP-AMS Provider found on esx1.net ProLiant DL585 G5 Version: 500.10.0.0-18.434156

Example for a DL380 Gen8

get-hp -VMhostName esx2.net -Status
HP-AMS Provider found on esx2.net ProLiant DL380p Gen8 Version: 500.10.0.0-18.434156

#Remove exection (need to paste)

ESXi Setting syslog and firewall settings with PowerCLI

Syslog and firewall configuration with PowerCLI

Setting PowerCLI

Due the arrival of some SIEM solution I needed to reconfigure ESXi hosts to not only point to our Kiwi Syslog server, but also to the appliance. So a good job for some PowerCLI

I had some trouble using the set-VMHostSysLogServer as it didn’t seem to work as expected. It worked on 2 hosts which hadn’t any syslog configured, but somehow I couldn’t set all to $Null or to the new value, very strange. But I don’t give up and found the Set-VMHostAdvancedConfiguration cmdlet to set the syslog values on another way.

get-vmhost| Set-VMHostAdvancedConfiguration -NameValue @{'Syslog.global.logHost'='syslog'} -confirm:$false

While testing I noted the message:

This cmdlet is deprecated. Use New-AdvancedSetting, Set-AdvancedSetting, or Remove-AdvancedSetting instead.

Mmm let’s have a look here:

get-vmhost|select -first 1|get-advancedsetting -Name syslog* |select name,value|Ft -a

Name                                        Value
—-                                           —–
Syslog.Remote.Port                   514
Syslog.Remote.Hostname          syslog
Syslog.Local.DatastorePath        [] /vmfs/volumes/4dd2476c-etc.

Let’s try to set it

Get-AdvancedSetting -Entity (get-vmhost|select -first 1) -Name Syslog.Remote.Hostname|Set-AdvancedSetting -Value syslog -confirm:$false

You also can set multiple values like:

Get-AdvancedSetting -Entity (get-vmhost|select -first 1) -Name Syslog.Remote.Hostname|Set-AdvancedSetting -Value syslog1,syslog2 -confirm:$false

After setting the proper syslog setting it was necessary to open the syslog firewall ports on ESXi. To do this on all hosts, it can easily be done with the onelinerbelow using the Get-VMHostFirewallException cmdlet

Get-VMHostFirewallException -VMHost (get-vmhost) -Name syslog|Set-VMHostFirewallException -Enabled:$True -Confirm:$false

Powershell logging function with date and time stamp

Logging Function

While I made this function a few times on demand with different purposes, I gathered a nice clean script somewhere (not sure where I found it) to start logging to a file.
I added the date/time stamp together with a write-host command to get the logging also on screen. This is a script I know always copy in my scripts to get a fast and simple logging function

 


#Variable to set the logfile location
$Logfile = "D:\LogFile.txt"

Function LogWrite{
<#
.SYNOPSIS
Simple function to write to a appending logfile with date and time stamp

.PARAMETER  $LogString
Input parameter which holds the data which goes to the $logfile

.PARAMETER  $Logfile
Parameter which contains the location of the logfile the information is written to

.EXAMPLE
LogWrite "Starting with $StrTitle files"
LogWrite "Found $StrTitle files with an amount of $TotalSize MB."

.NOTES
Version:        1.0
Creation Date:  26-08-2014
Purpose/Change: PRD
#>
Param ([string]$logstring)
Add-content $Logfile -value (((Get-Date).ToString()) + " " + $logstring)
Write-Host (((Get-Date).ToString()) + " " + $logstring)
}

Exection is as simple as :

logwrite "This line is being sent to screen and text file while a date & time stamp is added"

Powershell shows:

PowerCLI C:\> logwrite "This line is being sent to screen and text file while a date & time stamp is added"
30-8-2014 10:05:52 This line is being sent to screen and text file while a date & time stamp is added

And the text file:

30-8-2014 10:05:52 This line is being sent to screen and text file while a date & time stamp is added

Hopefully it can help someone just copy/paste and adjust where needed:)

Auto-update VMware tools installation fails?

Somehow we noticed a few machines where it was not possible to auto-update the VMware tools from vCenter. After a time-out of 30 minutes the task failed. Result, no VMware tools installed and a task that failed (according to vCenter) but a task keeps remaining on the ESXi host/VM.

We never encountered this issue, after looking through log files, eventvwr etc. I didn’t find a proper explanation. Somehow I suddenly got a clear moment and thought about looking in the advancedsettings from the VM because a while ago I changed the template settings according to our yearly hastle with the security baseline 🙂
Easy with powerCLI:

get-vm <vm>|Get-AdvancedSetting

Mmz I found a tools setting:

Name: isolation.tools.autoinstall.disable
Value:true

This just means that the auto-install is disabled. That explains why it won’t work automatically, and manually we didn’t encounter any issue.

Hah, this easily can be edited also with powerCLI.

get-vm <VM>|Get-AdvancedSetting -Name isolation.tools.autoinstall.disable|Set-AdvancedSetting -Value:$false -confirm:$false

DAMN!

I throw this script in our test cluster, but somehow not all machines can be edited. A little investigation leaded me to the fact that the machines which failed got a “Time-out VMware tools install task”

So what about killing the task, it was not possible through vCenter, I tried to restart the management agents on the host but that wasn’t a success also.

Then I came accross this VMware article :
http://kb.vmware.com/selfservice/microsites/search.do?language=en_US&cmd=displayKC&externalId=1038542

  1. Run this command to identify the virtual machine ID:
    # vim-cmd vmsvc/getallvms 

    You see an output similar to:

    2256   testvm          [datastore] testvm/testvm.vmx              winNetStandardGuest       vmx-07    
  2. Note the ID of the virtual machine with the ongoing VMware Tools installation. In this example, the virtual machine ID is 2256.
  3. Run this command to stop the VMware Tools installation:
    # vim-cmd vmsvc/tools.cancelinstall <vm_ID>

    Where <vm_ID> is the ID of the virtual machine noted in Step

Now the Tools upgrade task is killed, now it is possible again to vMotion, change advanced settings etc.

So now it’s possible to edit the settings. I started the script again and it went flawlessly. Next step is to try the VMware tools installation again.

I picked a machine, started install VMware tools through vCenter and waited….after 30 minutes again: TIME-OUT!
Mmmmm maybe we need to power-off/power-on the VM to pick the new setting. So again, cancelled task, checked setting. All OK.

Shutdown vmguest, power-on and reinstall VMware tools through vCenter this seems to be the magical combination.

To wrap it up:

– Cancel any running tasks on the ESX host/VM
– Change the isolation.tools.autoinstall.disable setting
– Power off/on the VM
– Reinstall VMware tools

Best is of course to change the setting while the machine is powered off.

Or just do a manual install 🙂

Last but not least I created a little script to retrieve the key, and if the key exists, and the value not equals  “true”, it sets the setting to


foreach ($VM in get-cluster *199* | Get-VM){
$Setting = $VM|Get-AdvancedSetting -Name isolation.tools.autoinstall.disable|select name, value
if ($Setting -ne $null){
if ($Setting.value -ne "false"){
$VM|Get-AdvancedSetting -Name isolation.tools.autoinstall.disable|Set-AdvancedSetting -Value:$false -Confirm:$false
}
}
}

VMWare 5.1 Security Hardening Guide 5.1

According to the VMWare hardening guide for vSphere 5.1, I had some time to edit all the templates with the desired settings.
http://www.vmware.com/files/xls/hardeningguide-vsphere5-1-ga-release-public.xlsx

I created a list of VM’s which will be edited in D:\template.txt, with a simple loop all the settings will be applied.


foreach ($VM in gc D:\template.txt){
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.copy.disable" -value $true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.dnd.disable" -value $true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.setGUIOptions.enable" -value $false -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.paste.disable" -value $true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.diskShrink.disable" -value $true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.diskWiper.disable" -value $true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.hgfsServerSet.disable" -value $true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "vmci0.unrestricted" -value $false -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.ghi.autologon.disable" -value $true -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.bios.bbs.disable" -value $true -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.getCreds.disable" -value $true -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.ghi.launchmenu.change" -value $true -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.memSchedFakeSampleStats.disable" -value $true -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.ghi.protocolhandler.info.disable" -value $true -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.ghi.host.shellAction.disable" -value $true -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.dispTopoRequest.disable" -value $true -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.trashFolderState.disable" -value $true -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.ghi.trayicon.disable" -value $true -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.unity.disable" -value $true -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.unityInterlockOperation.disable" -value $true -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.unity.taskbar.disable" -value $true -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.unityActive.disable" -value $True -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.unity.windowContents.disable" -value $True -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.unity.push.update.disable" -value $true -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.vmxDnDVersionGet.disable" -value $true -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.guestDnDVersionSet.disable" -value $true -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "RemoteDisplay.maxConnections" -value 2 -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "log.keepOld" -value "10" -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "log.rotateSize" -value "100000" -Force:$true -confirm:$false
Get-VM $VM | New-AdvancedSetting -Name "tools.setInfo.sizeLimit" -value 1048576 -Force:$true -confirm:$false
}

07-04-2014 Removed:

Get-VM $VM | New-AdvancedSetting -Name "isolation.tools.autoInstall.disable" -value $true -confirm:$false

This setting disabled “VMware tools installation from the vCenter console”. It still was possible to do it manually, but not anymore by right clicking  “Upgrade VMware tools”

 

1 2