Script: Report Host Profile compliance and answer file status

vCenter לא מספק מסך שבו ניתן לראות Compliance Status של כל הסביבה בבת אחת. בסביבות גדולות ובמיחד בסביבות שיש בהן מספר Host Profiles המשימה של שמירה על סדר הופכת לקשה מאוד.

כתבתי סקריפט ב-PowerCLI שרץ על הסביבה ושומר את הנתונים בקובץ csv.

אחד האתגרים בכתיבה הייתה העובדה שלא ניתן להגיע לחלק גדול מהנתונים בעזרת cmdlets קיימים ולכן נאלצתי לעבוד מול ה-API.

להלן דוגמה לנתונים שהסקריפט מוציא (נאלצתי לפצל לשתי תמונות בגלל הגודל):

וזה הסקריפט עצמו:

# Report Host Profile and Answer File compliance state
# Written by Michael Malizhonak, 2017
# http://virtualization.co.il


#region Functions

# This function returns formatted and adjusted date
function FormatDate ($date_obj)
{
    $local_date_obj = $date_obj.ToLocalTime()
    $formatted_date = $local_date_obj.ToShortDateString() + " " + $local_date_obj.ToShortTimeString()
    
    return $formatted_date
}

# This function returns Answer File status and Last Check time
function CheckAnswerFile ($vmhost)
{
    $AnswerFileStatus = $HostProfileManager.QueryAnswerFileStatus($vmhost.Id)
    
    if ($AnswerFileStatus)
    {
        switch ($AnswerFileStatus[0].Status)
        {
            "valid" {$af_status = "Complete"}
            "invalid" {$af_status = "Incomplete"}
            default {$af_status = FormatString $AnswerFileStatus[0].Status}
        }
        
        $formatted_date = FormatDate $AnswerFileStatus[0].CheckedTime
    }
    else
    {
        $af_status = "Unable to get info"
        $formatted_date = "Unable to get info"
    }
    
    return $af_status, $formatted_date
}

# This function returns formatted string
function FormatString ($string)
{
    $formatted_string = $string.Substring(0,1).ToUpper()+$string.Substring(1).ToLower()
    
    return $formatted_string
}

#endregion

$vcenter_name = "<vCenter name>"
Connect-VIServer $vcenter_name

$vmhosts = Get-VMHost | Sort Name

$file_path = "C:\Host Profile Compliance Report - $vcenter_name.csv"

$report = @()

$index = 1
$num_of_hosts = $vmhosts.Count

$HostProfileManager = Get-View HostProfileManager
$ServiceInstance = Get-View ServiceInstance
$ComplianceManager = Get-View $ServiceInstance.Content.ComplianceManager

foreach ($vmhost in $vmhosts)
{
    $vmhost_name = $vmhost.Name
    Write-Host ""
    Write-Host "Processing host $index of $num_of_hosts - $vmhost_name"
    
    $my_obj = "" | select Name, Cluster, HostProfile, AnswerFileStatus, AnswerFileLastChecked, ComplianceStatus, ComplianceLastChecked, Failures
    
    $my_obj.Name = $vmhost_name
    $my_obj.Cluster = $vmhost.Parent.Name
    
    $AttachedProfile = Get-VMHostProfile -Entity $vmhost
    
    # if host has profile attached to it
    if ($AttachedProfile)
    {
        $my_obj.HostProfile = $AttachedProfile.Name
        
        $af_results = CheckAnswerFile $vmhost
        $my_obj.AnswerFileStatus = $af_results[0]
        $my_obj.AnswerFileLastChecked = $af_results[1]
        
        $ComplianceQuery = $ComplianceManager.QueryComplianceStatus($AttachedProfile.Id, $vmhost.Id)
        
        if ($ComplianceQuery)
        {
            $my_obj.ComplianceStatus = FormatString $ComplianceQuery[0].ComplianceStatus
            $my_obj.ComplianceLastChecked = FormatDate $ComplianceQuery[0].CheckTime
            
            [string] $failures_string = $null
            $failures = @()
            [array] $failures = $ComplianceQuery[0].Failure
            
            if ($failures)
            {
                foreach ($failure in $failures)
                {
                    if (!$failures_string)
                    {
                        $failures_string = $failure.Message.Message
                    }
                    else
                    {
                        $failures_string = $failures_string + "; " + $failure.Message.Message
                    }
                }
                
                $my_obj.Failures = $failures_string
            }
            else
            {
                $my_obj.Failures = "No Failures"
            }
        }
        else
        {
            $my_obj.ComplianceStatus = "Unable to get info"
            $my_obj.ComplianceLastChecked = "Unable to get info"
            
            $my_obj.Failures = "Unable to get info"
        }
    }
    else
    {
        $my_obj.HostProfile = "No Host Profile attached / Unable to get info"
        $my_obj.AnswerFileStatus = "N/A"
        $my_obj.AnswerFileLastChecked = "N/A"
        $my_obj.ComplianceStatus = "N/A"
        $my_obj.ComplianceLastChecked = "N/A"
        $my_obj.Failures = "N/A"
    }
    
    $report += $my_obj
    $index++
}

$report | Export-Csv -NoTypeInformation -Path $file_path

Disconnect-VIServer * -Confirm:$false

לינק להורדת הסקריפט.

אם יש לכם שאלות או הערות, אשמח לענות.

מיכאל.

כתיבת תגובה

האימייל לא יוצג באתר. שדות החובה מסומנים *

*