VMware Cloud Community
faherne_CTI
Enthusiast
Enthusiast
Jump to solution

Identify Users that Placed ESXi Hosts into Maintenance Mode

I want to formalise the ownership of an ESXi host once placed into Maintenance Mode as we have a sprawling global team who manage multiple global vCenters and ESXi clusters.

I currently have:

1. A loop that identifies all hosts across multiple vCenters that have been placed in Maintenance Mode.

2. A command that queries the hostd log of an ESXi host for a line that confirms the host was successfully placed into Maintenance Mode.

3. If an entry in the ESXi host's hostd log isn't found (The ESXi logs persistence problem), then I'd like to give the User a default value of "Unknown", or an empty string.

I'm looking for any assistance possible to either combine the 2 together to output a table along the lines of the following columns:

| vCenter Name| Datcenter Name | Cluster Name | ESXi Host Name | ConnectionState | User Who Placed Host in MM |

1. Code: The Loop that identifies all hosts in Maintenance Mode

Connect-viserver -Server (Get-Content C:\Scripts\vCList.txt) > $null

$report = Foreach($vc in $global:DefaultVIServers){

foreach($dc in Get-Datacenter -Server $vc){

Get-Cluster -Location $dc -Server $vc |

Get-VMHost | Where {$_.ConnectionState -like "Maintenance"} |

        Select @{N='VC';E={$vc.Name}},

            @{N='Datacenter';E={$dc.Name}},

            @{N='Cluster';E={$_.Name}},

            @{N='ConnectionState';E={$_.ConnectionState}}

}

}

$report | Export-Csv C:\Scripts\List-Hosts-in-MM.csv

2. Code: The Hostd log query identifying the user who placed the host in MM

(Get-Log -VMHost (Get-VMHost) hostd).Entries | Where {$_ -like "*enterMaintenanceMode* Status success*"}

Sample Output of above command:

2018-11-07T14:53:59.066Z info hostd[ACGBGH20] [Originator@1236 sub=Vimsvc.TaskManager opID=B26B8B63-00000012-f1-b7-1e63 user=vpxuser:MyDOM\UserA] Task Completed : haTask-ha-host-vim.HostSystem.enterMaintenanceMode-83345579 Status success

0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

Try something like this

Connect-viserver -Server (Get-Content D:\Scripts\vCList.txt) > $null

$report = Foreach ($vc in $global:DefaultVIServers) {

  $mmTab = @{}

  Get-VMHost -Server $vc | % {

   $mmTab.Add($_.Name, $_.ConnectionState)

  }


  $start = (Get-Date).AddDays(-2)

  $mmEvents = Get-VIEvent -Start $start -MaxSamples ([int]::MaxValue) |

   where {$_ -is [VMware.Vim.TaskEvent] -and $_.Info.DescriptionId -eq "HostSystem.enterMaintenanceMode"} |

   Group-Object -Property {$_.Hodst.Name} |

   ForEach-Object -Process {

   $_.Group | Sort-Object -Property CreatedTime |

   ForEach-Object -Process {

   New-Object PSObject -Property @{

   HostName   = $_.Host.Name

   CreatedTime  = $_.CreatedTime

   User   = $_.UserName

   CurrentState = $mmTab[$_.Host.Name]

   }

   }

  }

  $mmNoEvents = $mmTab.GetEnumerator() | where {$mmEvents.HostName -notcontains $_.Name} |

   ForEach-Object -Process {

   New-Object psobject -Property {

  HostName = $_.Name

  CreatedTime = ''

  User = ''

  CurrentState = $_.Value

   }

  }

  $mmEvents + $mmNoEvents

}


$report | Export-Csv D:\Scripts\List-vC-Evts-Hosts-in-MM.csv


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
6 Replies
faherne_CTI
Enthusiast
Enthusiast
Jump to solution

To give more information on the get-Log query:

Example 1: Query a specific ESXI host's Hostd logs for an entry confirming the entry into MM

(Get-Log -VMHost (Get-VMHost MyESXiHost.MyDom.int) hostd).Entries | Where {$_ -like "*enterMaintenanceMode* Status success*"}

Example 2: Query ALL of a vCenter's connected ESXi hosts' Hostd logs for entries confirming the entry into MM

(Get-Log -VMHost (Get-VMHost) hostd).Entries | Where {$_ -like "*enterMaintenanceMode* Status success*"}

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Can't you get that from the Events log?

Something like this for example

Depending how long after the event you scan, you would need to adapt the value on the Start parameter

$esxName = 'MyEsx'

$esx = Get-VMHost -Name $esxName

Get-VIEvent -Entity $esx -Start (Get-Date).AddMinutes(-15) -MaxSamples ([int]::MaxValue) |

  where {$_ -is [VMware.Vim.EnteredMaintenanceModeEvent]} |

  Sort-Object -Property CreatedTime -Descending |

  Select -First 1 -Property CreatedTime, UserName, @{N = 'VMHost'; E = {$_.Host.Name}}


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
faherne_CTI
Enthusiast
Enthusiast
Jump to solution

Hi Luc,

I didn't know about that command, so thanks!!

I modified your script to the following, but I'd like to hear your take on how I can fine-tune the script further.

The following script queries multiple vCenters and pulls the required data:

Connect-viserver -Server (Get-Content D:\Scripts\vCList.txt) > $null

$report = Foreach($vc in $global:DefaultVIServers){

$start = (Get-Date).AddDays(-2)

Get-VIEvent -Start $start -MaxSamples ([int]::MaxValue) |

where {$_ -is [VMware.Vim.TaskEvent] -and $_.Info.DescriptionId -eq "HostSystem.enterMaintenanceMode"} |

Select CreatedTime,@{N="Host";E={$_.Host.Name}},UserName

}

$report | Export-Csv D:\Scripts\List-vC-Evts-Hosts-in-MM.csv

...but there's a gap where the host may have been taken out of Maintenance Mode since the original event. The following lines can output the vCenter hosts that are currently in MM:

Connect-viserver -Server (Get-Content D:\Scripts\vCList_test.txt) > $null

Get-VMHost | Where {$_.ConnectionState -like "Maintenance"} | Select Name | Export-Csv D:\Scripts\Hosts-in-MM.csv

Is there a way of either:

1. Using the lines above to show the current status of the hosts that have event entries logged against MM actions e.g. a column to show that the host is now currently "Connected"?

OR

2. Generating both tables (Table_1 = List of Hosts currently in MM, Table_2 = Hosts with vCenter Events logged for being entered into MM), then joining the 2 tables on hostnames, and joining the data columns? e.g.

Table_1: Columns

| HostName | ConnectionState | 

Table_2: Columns

| HostName | UserName | CreatedTime |

Tables_Joined: Columns

| HostName | ConnectionState | UserName | CreatedTime |

**also take into account that a host may be in MM, but may not have any vCenter Events associated with it (In that scenario I'd like the columns for Username and CreatedTime to be filled with either blank or NULL values.

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Try something like this

Connect-viserver -Server (Get-Content D:\Scripts\vCList.txt) > $null

$report = Foreach ($vc in $global:DefaultVIServers) {

  $mmTab = @{}

  Get-VMHost -Server $vc | % {

   $mmTab.Add($_.Name, $_.ConnectionState)

  }


  $start = (Get-Date).AddDays(-2)

  $mmEvents = Get-VIEvent -Start $start -MaxSamples ([int]::MaxValue) |

   where {$_ -is [VMware.Vim.TaskEvent] -and $_.Info.DescriptionId -eq "HostSystem.enterMaintenanceMode"} |

   Group-Object -Property {$_.Hodst.Name} |

   ForEach-Object -Process {

   $_.Group | Sort-Object -Property CreatedTime |

   ForEach-Object -Process {

   New-Object PSObject -Property @{

   HostName   = $_.Host.Name

   CreatedTime  = $_.CreatedTime

   User   = $_.UserName

   CurrentState = $mmTab[$_.Host.Name]

   }

   }

  }

  $mmNoEvents = $mmTab.GetEnumerator() | where {$mmEvents.HostName -notcontains $_.Name} |

   ForEach-Object -Process {

   New-Object psobject -Property {

  HostName = $_.Name

  CreatedTime = ''

  User = ''

  CurrentState = $_.Value

   }

  }

  $mmEvents + $mmNoEvents

}


$report | Export-Csv D:\Scripts\List-vC-Evts-Hosts-in-MM.csv


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
LucD
Leadership
Leadership
Jump to solution

Did this work for you in the end?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
faherne_CTI
Enthusiast
Enthusiast
Jump to solution

Hi Luc,

The script did work - Thanks a million. Apologies for not updating the thread and assigning the points.

This has always been a big issue for us having tens of thousands hosts and a large global team. How can you tell if a host is in build, in MM for an existing issue, or accidently in MM after an issue has been resolved? identifying the engineer who placed the host in MM is key to quickly getting an answer, and then dispensing the appropriate beat-downs! :smileysilly:

0 Kudos