簡體   English   中英

如何使用 PowerCLI 獲取與 vCenter 對象關聯的任務?

[英]How do I get the tasks associated with vCenter objects using PowerCLI?

我們在我們的環境中使用 vSphere 6.7。

我正在編寫一個腳本來查找與我們的 vCenter 環境中的特定目標資源關聯的某些任務。 但是, Get-Task僅返回顯示在 HTML5 客戶端的“ Recent Tasks ”視圖中的近期任務。 我可以很好地獲取與資源關聯的事件,例如,我可以獲取與給定數據存儲文件夾關聯的事件,如下所示:

Get-Folder FOLDER_NAME -Type Datastore | Get-VIEvent

但是似乎沒有等效的方法來獲取與這些相同資源關聯的任務。 Get-Task不像Get-VIEvent那樣接受管道輸入,並導致錯誤:

Get-Folder FOLDER_NAME -Type Datastore | Get-Task

Output:

Get-Task: The input object cannot be bound to any parameters for the command either
because the command does not take pipeline input or the input and its properties
do not match any of the parameters that take pipeline input.

Get-Task也不會顯示 HTML5 客戶端的“ Recent Tasks ”視圖中未顯示的任何任務。

檢查 object 似乎沒有提供任何成員讓我看到針對這些資源的任務:

Get-Folder FOLDER_NAME -Type Datastore | Get-Member

Output:

   TypeName: VMware.VimAutomation.ViCore.Impl.V1.DatastoreManagement.DatastoreClusterImpl

Name                             MemberType Definition
----                             ---------- ----------
ConvertToVersion                 Method     T VersionedObjectInterop.ConvertToVersion[T]()
Equals                           Method     bool Equals(System.Object obj)
GetClient                        Method     VMware.VimAutomation.ViCore.Interop.V1.VIAutomation VIObjectCoreInterop.GetClient()
GetHashCode                      Method     int GetHashCode()
GetType                          Method     type GetType()
IsConvertableTo                  Method     bool VersionedObjectInterop.IsConvertableTo(type type)
LockUpdates                      Method     void ExtensionData.LockUpdates()
ToString                         Method     string ToString()
UnlockUpdates                    Method     void ExtensionData.UnlockUpdates()
CapacityGB                       Property   decimal CapacityGB {get;}
ExtensionData                    Property   System.Object ExtensionData {get;}
FreeSpaceGB                      Property   decimal FreeSpaceGB {get;}
Id                               Property   string Id {get;}
IOLatencyThresholdMillisecond    Property   System.Nullable[int] IOLatencyThresholdMillisecond {get;}
IOLoadBalanceEnabled             Property   bool IOLoadBalanceEnabled {get;}
Name                             Property   string Name {get;}
SdrsAutomationLevel              Property   VMware.VimAutomation.ViCore.Types.V1.Cluster.DrsAutomationLevel SdrsAutomationLevel {get;}
SpaceUtilizationThresholdPercent Property   System.Nullable[int] SpaceUtilizationThresholdPercent {get;}
Uid                              Property   string Uid {get;}

不過,這不僅適用於文件夾任務,如果給定資源不在 HTML5 客戶端的“ Recent Tasks ”視圖中,我似乎根本無法枚舉任何任務。 相反,在 HTML5 客戶端中,我可以使用其Monitor選項卡輕松枚舉給定資源上的任務,但這對自動化沒有幫助,除非以編程方式爬過 UI(沒有發生):

文件夾 > 監控 > 任務視圖

如何使用 PowerCLI 查看針對使用 PowerCLI 的特定資源的任務?

Get-VIEvent返回各種東西——幸運的是,包括任務! 您可以通過它們的類型[VMware.Vim.TaskEvent]來查看它們,或者通過檢查只有任務事件具有的info屬性來查看它們。 例如:

$VIEvents = Get-VM $VMName | Get-VIEvent
$VITasks  = $VIEvents | Where Info
$VITasks | Select CreatedTime, FullFormattedMessage

CreatedTime           FullFormattedMessage                 
-----------           --------------------                 
8/19/2021 4:39:22 PM  Task: Remove all snapshots           
8/19/2021 4:38:04 PM  Task: Reconfigure virtual machine    
8/19/2021 3:52:06 PM  Task: Migrate virtual machine        

任務事件的Info屬性中往往存儲了更詳細的信息,但我們必須通過專門選擇該屬性來擴展它:

$VITasks.Info | select QueueTime,Name,EntityName,State

不過,關於實際發生的事情的非常詳細的信息通常存儲在其他事件類型中。 例如,要查看“重新配置虛擬機”任務中發生了什么變化,我需要檢查具有ConfigChanges屬性的事件。

這些也恰好具有非常詳細的結構,其中包含您可以解析的ConfigChangesConfigSpec屬性。 我在這里只使用預先格式化的消息,但您可以使用計算屬性來顯示它們Select就像我獲取 VM 名稱一樣:

Get-VM My-Test-VM1 | Get-VIEvent | Where ConfigChanges | 
  Select -First 1 CreatedTime,@{label='VmName';expr={$_.VM.Name}},FullFormattedMessage |
  Format-List

CreatedTime          : 8/19/2021 4:38:04 PM
VmName               : My-Test-VM1
FullFormattedMessage : Reconfigured My-Test-VM1 on My-Test-Host1 in My-Test-Datacenter1.  
                        Modified:  
                       config.hardware.device(3002).deviceInfo.summary: "ISO (ISO-DATASTORE1) RHEL7.iso" -> "Remote ATAPI"; 
                        Added:  
                        Deleted:  

這些步驟適用於任何事件/任務類型,但您必須進行一些初步挖掘以找到所需數據的存儲位置,以及如何以有用的方式顯示數據。


無論出於何種原因, Get-Task專門設計用於僅獲取:

[...有關當前或最近任務的信息[...]

獲取任務參考

Luc Dekens 寫了一個腳本 function 來解決你的問題。 這是 function 的副本,您可以使用實體參數定位特定資源。

function Get-TaskPlus {
    <#  
    .SYNOPSIS  Returns vSphere Task information   
    .DESCRIPTION The function will return vSphere task info. The
    available parameters allow server-side filtering of the
    results
    .NOTES  Author:  Luc Dekens  
    .PARAMETER Alarm
    When specified the function returns tasks triggered by
    specified alarm
    .PARAMETER Entity
    When specified the function returns tasks for the
    specific vSphere entity
    .PARAMETER Recurse
    Is used with the Entity. The function returns tasks
    for the Entity and all it's children
    .PARAMETER State
    Specify the State of the tasks to be returned. Valid
    values are: error, queued, running and success
    .PARAMETER Start
    The start date of the tasks to retrieve
    .PARAMETER Finish
    The end date of the tasks to retrieve.
    .PARAMETER UserName
    Only return tasks that were started by a specific user
    .PARAMETER MaxSamples
    Specify the maximum number of tasks to return
    .PARAMETER Reverse
    When true, the tasks are returned newest to oldest. The
    default is oldest to newest
    .PARAMETER Server
    The vCenter instance(s) for which the tasks should
    be returned
    .PARAMETER Realtime
    A switch, when true the most recent tasks are also returned.
    .PARAMETER Details
    A switch, when true more task details are returned
    .PARAMETER Keys
    A switch, when true all the keys are returned
    .EXAMPLE
    PS> Get-TaskPlus -Start (Get-Date).AddDays(-1)
    .EXAMPLE
    PS> Get-TaskPlus -Alarm $alarm -Details
    #>
    param(
        [CmdletBinding()]
        [VMware.VimAutomation.ViCore.Impl.V1.Alarm.AlarmDefinitionImpl]$Alarm,
        [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl]$Entity,
        [switch]$Recurse = $false,
        [VMware.Vim.TaskInfoState[]]$State,
        [DateTime]$Start,
        [DateTime]$Finish,
        [string]$UserName,
        [int]$MaxSamples = 100,
        [switch]$Reverse = $true,
        [VMware.VimAutomation.ViCore.Impl.V1.VIServerImpl[]]$Server = $global:DefaultVIServer,
        [switch]$Realtime,
        [switch]$Details,
        [switch]$Keys,
        [int]$WindowSize = 100
    )
    begin {
        function Get-TaskDetails {
            param(
                [VMware.Vim.TaskInfo[]]$Tasks
            )
            begin {
                $psV3 = $PSversionTable.PSVersion.Major -ge 3
            }
            process {
                $tasks | ForEach-Object {
                    if ($psV3) {
                        $object = [ordered]@{ }
                    }
                    else {
                        $object = @{ }
                    }
                    $object.Add("Name", $_.Name)
                    $object.Add("Description", $_.Description.Message)
                    if ($Details) { $object.Add("DescriptionId", $_.DescriptionId) }
                    if ($Details) { $object.Add("Task Created", $_.QueueTime) }
                    $object.Add("Task Started", $_.StartTime)
                    if ($Details) { $object.Add("Task Ended", $_.CompleteTime) }
                    $object.Add("State", $_.State)
                    $object.Add("Result", $_.Result)
                    $object.Add("Entity", $_.EntityName)
                    $object.Add("VIServer", $VIObject.Name)
                    $object.Add("Error", $_.Error.ocalizedMessage)
                    if ($Details) {
                        $object.Add("Cancelled", (& { if ($_.Cancelled) { "Y" }else { "N" } }))
                        $object.Add("Reason", $_.Reason.GetType().Name.Replace("TaskReason", ""))
                        $object.Add("AlarmName", $_.Reason.AlarmName)
                        $object.Add("AlarmEntity", $_.Reason.EntityName)
                        $object.Add("ScheduleName", $_.Reason.Name)
                        $object.Add("User", $_.Reason.UserName)
                    }
                    if ($keys) {
                        $object.Add("Key", $_.Key)
                        $object.Add("ParentKey", $_.ParentTaskKey)
                        $object.Add("RootKey", $_.RootTaskKey)
                    }
                    New-Object PSObject -Property $object
                }
            }
        }
        $filter = New-Object VMware.Vim.TaskFilterSpec
        if ($Alarm) {
            $filter.Alarm = $Alarm.ExtensionData.MoRef
        }
        if ($Entity) {
            $filter.Entity = New-Object VMware.Vim.TaskFilterSpecByEntity
            $filter.Entity.entity = $Entity.ExtensionData.MoRef
            if ($Recurse) {
                $filter.Entity.Recursion = [VMware.Vim.TaskFilterSpecRecursionOption]::all
            }
            else {
                $filter.Entity.Recursion = [VMware.Vim.TaskFilterSpecRecursionOption]::self
            }
        }
        if ($State) {
            $filter.State = $State
        }
        if ($Start -or $Finish) {
            $filter.Time = New-Object VMware.Vim.TaskFilterSpecByTime
            $filter.Time.beginTime = $Start
            $filter.Time.endTime = $Finish
            $filter.Time.timeType = [vmware.vim.taskfilterspectimeoption]::startedTime
        }
        if ($UserName) {
            $userNameFilterSpec = New-Object VMware.Vim.TaskFilterSpecByUserName
            $userNameFilterSpec.UserList = $UserName
            $filter.UserName = $userNameFilterSpec
        }
        $nrTasks = 0
    }
    process {
        foreach ($viObject in $Server) {
            $si = Get-View ServiceInstance -Server $viObject
            $tskMgr = Get-View $si.Content.TaskManager -Server $viObject 
            if ($Realtime -and $tskMgr.recentTask) {
                $tasks = Get-View $tskMgr.recentTask
                $selectNr = [Math]::Min($tasks.Count, $MaxSamples - $nrTasks)
                Get-TaskDetails -Tasks[0..($selectNr - 1)]
                $nrTasks += $selectNr
            }
            $tCollector = Get-View ($tskMgr.CreateCollectorForTasks($filter))
            if ($Reverse) {
                $tCollector.ResetCollector()
                $taskReadOp = $tCollector.ReadPreviousTasks
            }
            else {
                $taskReadOp = $tCollector.ReadNextTasks
            }
            do {
                $tasks = $taskReadOp.Invoke($WindowSize)
                if (!$tasks) { break }
                $selectNr = [Math]::Min($tasks.Count, $MaxSamples - $nrTasks)
                Get-TaskDetails -Tasks $tasks[0..($selectNr - 1)]
                $nrTasks += $selectNr
            }while ($nrTasks -lt $MaxSamples)
            $tCollector.DestroyCollector()
        }
    }
}

更多信息,請訪問https://www.lucd.info/2013/06/01/task-data-mining-an-improved-get-task/#more-4464

@jrmilner 的回答在這里對我有用,但它不允許我從非庫存對象獲取任務,即使我將-Entity的類型更改為[object[]]也是如此。 然而,我確實發布了一個關於從非庫存對象中檢索事件的后續問題,但這次我能夠通過修改另一個 function LucD 寫的解決方案,這是我在繼續研究時發現的。 那么這與這個問題有什么關系呢?

感謝Cpt.Whale ,我了解到任務事件,雖然我獲得了事件並以不同的方式將“小麥與任務”分開,但他們的回答在下面幫助了我。

通過在我對另一個問題的鏈接答案中使用修改后的Get-VIEventPlus ,我可以通過檢查是否在返回的事件上設置Severity來區分任務和事件,因為它們在 HTML5 客戶端中是分開的:

$dsCluster = Get-DatastoreCluster

$tasks = Get-VIEventPlus -Entity $dsCluster | Where-Object { ! $_.Severity }
$events = Get-VIEventPlus -Entity $dsCluster | Where-Object { $_.Severity }

似乎事件將設置嚴重性,而任務則沒有。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM