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
לינק להורדת הסקריפט.
אם יש לכם שאלות או הערות, אשמח לענות.
מיכאל.