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:)

Locked files ESXi5.1

Locked files 101

Locked files ?

Since  a few months we see more and more “consolidation needed messages” in our vCenter environment, we’re still searching for the reason. Of course we used some VMware articles to get in a bit deeper. But for a successful we need to remove the file lock. I made a little procedure which worked best for us. The information also can be found in the VMware KB’s but sometimes it’s a bit confusing because you have different approaches in different versions.

Investigating virtual machine file locks on ESXi/ESX (10051)Unable to delete the virtual machine snapshot due to locked files (2017072)
Unable to perform operations on a virtual machine with a locked disk (1003397)
Investigating hosted virtual machine lock files (1003857)

Find locked files

It’s easiest to power off the VM. So you’re sure there shouldn’t be any lock anymore. If you’re not sure or have a lot of disks it can be a b*tch to check for locks using the vmkfstools -D. It’s doable, but I found a easier way using the touch command.

Start a SSH session to one of the ESXi hosts in the cluster where the VM resides you want to investigate.

Move to the location of the VM on the datastore: # cd /vmfs/volumes/<datastore>/<VMname>
Now use the touch * command to change the datestamp of all file in this directory. If you have  a lock you will get output like :

touch: VM1-flat.vmdk: Device or resource busy
touch: VM1_3-flat.vmdk: Device or resource busy

Who owns me?

We know now that the 2 files above are in some kind of lock and cannot be written to. Now we can move on using the vmkfstools command to see which ESXi host owns the file.

# vmkfstools -D VM1-flat.vmdk
Lock [type 10c00001 offset 13957120 v 448, hb offset 3510272
gen 41, mode 2, owner 00000000-00000000-0000-000000000000 mtime 845230
num 1 gblnum 0 gblgen 0 gblbrk 0]

We now see 2 things Mode 2 which indicates the kind of lock. See the list below with the kind of modes there can be:

  • mode 0 = no lock
  • mode 1 = is an exclusive lock (vmx file of a powered on VM, the currently used disk (flat or delta), *vswp, etc.)
  • mode 2 = is a read-only lock (e.g. on the ..-flat.vmdk of a running VM with snapshots)
  • mode 3 = is a multi-writer lock (e.g. used for MSCS clusters disks or FT VMs)

We see mode 2 which indicates a file lock. Normally there also is an owner, but this shows only zeroes so we can’t use this information.

In the few lines below we see this information about the Read Only Owner:


RO Owner[0] HB Offset 3510272 53baaace-0e95cf36-46a4-441ea15dea84

Addr <4, 5, 119>, gen 269, links 1, type reg, flags 0, uid 0, gid 0, mode 600
len 34359738368, nb 32768 tbz 7056, cow 0, newSinceEpoch 32768, zla 3, bs 1048576

The read only owner of this lock is MAC address 441ea15dea84 which converts to 44:1e:a1:5d:ea:84.

Find the MAC

A fast and easy way to find the corresponding MAC address is with powerCLI. Because we know the cluster where it happens I came up with the command line below:

get-cluster *001*|Get-VMHost|Get-VMHostNetworkAdapter|where {$_.Mac -eq "<strong>44:1e:a1:5d:ea:84</strong>"}|select vmhost,,mac

VMHost                                                                                  Mac
——                                                                                          —
ESX.host.net                              44:1e:a1:5d:ea:84
Now we put this host in maintanance and reboot. Normally the file lock should be gone now and we can consolidate the VM.

Could not connect using the requested protocol PowerCLI

Problem

Suddenly (during a failover test) I noticed a script didn’t work anymore. The script I used connects directly to an ESX host. And I got the error below, somehow I never ever had this before and we used this script for a long time. So something changed, but when and why did this happen was still on my research list. After a google search for “requested protocol” error I found the solution

Connect-VIServer : 22-3-2014 9:03:07 Connect-VIServer Could not connect using the requested protocol.
At C:\Users\ee34028.adm\Documents\WindowsPowerShell\Microsoft.PowerShell_profile.ps1:361 char:42
+ $currentConnection = Connect-VIServer <<<< $vcHost -Credential $cred
 + CategoryInfo : ObjectNotFound: (:) [Connect-VIServer], ViServerConnectionException
 + FullyQualifiedErrorId : Client20_ConnectivityServiceImpl_Reconnect_ProtocolError,VMware.VimAutomation.ViCore.Cmdlets.Commands.ConnectVIServer

Solution

To get rid of this problem there is a solution that sets the powerCLI configuration to “Use no proxy”

The solution is described in:
Connecting to the AutoDeploy server fails with the error: Could not connect using the requested protocol (2011395)

Open your powerCLI console as administrator (else you don’t have sufficient rights to edit this setting)
To show the current configuration use “Get-powerCLIconfiguration

C:\>Get-PowerCLIConfiguration

Proxy Policy Default Server
                               Mode
-------------------------       ---------------
UseSystemProxy      Single

As you can see it uses the system’s proxy. To change this use “Set-PowerCLIConfiguration -ProxyPolicy NoProxy -Confirm” to set the proxy settings to “NoProxy”
You can choose two proxy policies

C:\>Set-PowerCLIConfiguration -ProxyPolicy NoProxy -Confirm
Perform operation?
Performing operation 'Update vSphere PowerCLI configuration.'?
[Y] Yes [A] Yes to All [N] No [L] No to All [S] Suspend [?] Help (default is "Y"): y
Proxy Policy Default Server 
                     Mode 
------------         --------------- 
NoProxy              Single

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

PowerCLI function to grab WWPN’s

PowerCLI function to grab WWPN’s

Why?

As speaking with our storage administrators they sometimes ask for the exact WWPN so they are sure to remove the right LUNs etc. Because it’s a few mouseclicks to find the WWPN and it’s hard to copy, I managed to get it done by a little PowerCLI function below.

Function


function Get-WWN{
<#
.SYNOPSIS
Get WWN name from ESX hosts
.DESCRIPTION
This scripts gathers the WWN portname from ESX hosts
.NOTES
Authors: Patrick Heijmann
.PARAMETER VMhosts
Specify the VMhosts To gather the ports from
.EXAMPLE
PS> get-wwn -VMhosts ESXhost001
.EXAMPLE
PS> Get-Cluster -Name *|get-vmhost|Get-WWN
.EXAMPLE
PS> Get-vmhost *|Get-WWN
#>
Param (
[Parameter(
Valuefrompipeline = $true,
ParameterSetName = "VMhosts",
Mandatory = $true,
HelpMessage = "Enter Host name")]
[String[]]$VMhosts)

process
{foreach ($vmhost in $vmhosts){Write-Host -foregroundcolor green "Server: " $vmhost
$hbas = Get-VMHostHba -vmhost $vmhost -Type FibreChannel
foreach ($hba in $hbas){$wwpn = "{0:x}" -f $hba.PortWorldWideName
Write-Host -foregroundcolor green `t "World Wide Port Name:" $wwpn}
}
}
}

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”

 

Create multiple VM’s by cloning template

Because I needed to create multiple VM’s from a template I decided to have a look into the PowerCLI command for this.  I created a text file with pre-given names, called D:<file>.txt, for each item in this list I create a new VM according to template <template> on <vmhost> and <datastore>.  To put the VM’s in a specific location I use the “-location”. With the option “RunAsync” it fires the commands and goes to the next one instead of waiting for the first job to complete before proceeding to the next one.

foreach ($vm in (GC D:<file>.txt)){

New-VM -name $vm -Location <location> -Template <template>`
-vmhost <vmhost> -Datastore <datastore> -RunAsync
}

Retrieve WWPN from datastore

As our storage admins frequently request the exact disk ID so we know we are talking about the same disk. I found it annoying and hard to gather them from the GUI and copy paste them. So I decided to create a function for this which I called “get-serial” just to easily grab the WWPN.


function Get-serial {
<#
.SYNOPSIS
Retreives the canonical name from a datastore
.DESCRIPTION
Retreive the LUN ID to match with your storage admin
.NOTES
Author: Patrick Heijmann
.EXAMPLE
get-serial "ESXCL001_P01"
.EXAMPLE
get-serial ESXCL001_P01
.EXAMPLE
get-serial -datastore ESXCL001
.EXAMPLE
get-cluster|get-datastore|get-vmhost|get-serial
.PARAMETER Datastore
Specifies the datastore to query
#>
[CmdletBinding()]
param
(
[Parameter(Mandatory=$True,
ValueFromPipeline=$True,
ValueFromPipelineByPropertyName=$True,
HelpMessage='Which datastore would you like to target?')]
[Alias('host')]
[ValidateLength(3,30)]
[string[]]$datastore
)

begin {
Write-Verbose "Starting to find the datastore you entered"
}

process {
$details = Get-Datastore|?{$_.name -eq $Datastore}|?{$_.type -eq "vmfs"}|get-view
if (!$details){
Write-Output "No valid datastore specified";Write-Verbose "Datastore not found enter a valid datastore name"
}
else {
$serial = ($details.info.vmfs.Extent|select diskname).diskname -replace "naa."
Write-Verbose "Done with $datastore and $serial"
$out =" " |select @{N="Datastore";E={($datastore)}}, @{N="Serial";E={($serial)}}
Write-Output $out
}
}
}
1 2 3