[英]How do I get the tasks associated with vCenter objects using PowerCLI?
We are using vSphere 6.7 in our environment.我们在我们的环境中使用 vSphere 6.7。
I am writing a script to look for certain tasks associated with specific target resources in our vCenter environment.我正在编写一个脚本来查找与我们的 vCenter 环境中的特定目标资源关联的某些任务。 However,
Get-Task
only returns recent tasks that show up in the Recent Tasks
view in the HTML5 client.但是,
Get-Task
仅返回显示在 HTML5 客户端的“ Recent Tasks
”视图中的近期任务。 I can get events associated with resources just fine, for example I can get the events associated with a given datastore folder like so:我可以很好地获取与资源关联的事件,例如,我可以获取与给定数据存储文件夹关联的事件,如下所示:
Get-Folder FOLDER_NAME -Type Datastore | Get-VIEvent
But there doesn't seem to be an equivalent way to get tasks associated with those same resources.但是似乎没有等效的方法来获取与这些相同资源关联的任务。
Get-Task
doesn't accept pipeline input in the same way Get-VIEvent
does, and results in an error: Get-Task
不像Get-VIEvent
那样接受管道输入,并导致错误:
Get-Folder FOLDER_NAME -Type Datastore | Get-Task
Output: 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
also doesn't show any tasks that don't show in the Recent Tasks
view of the HTML5 client. Get-Task
也不会显示 HTML5 客户端的“ Recent Tasks
”视图中未显示的任何任务。
Inspecting the object doesn't seem to offer any members that let me see tasks targeting these resources:检查 object 似乎没有提供任何成员让我看到针对这些资源的任务:
Get-Folder FOLDER_NAME -Type Datastore | Get-Member
Output: 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;}
This isn't just for folder tasks, though, I can't seem to enumerate any tasks for a given resource at all if they aren't in the Recent Tasks
view of the HTML5 client.不过,这不仅适用于文件夹任务,如果给定资源不在 HTML5 客户端的“
Recent Tasks
”视图中,我似乎根本无法枚举任何任务。 Conversely, in the HTML5 client, I can easily enumerate tasks on a given resource using its Monitor
tab, but this doesn't help with automation short of crawling through the UI programmatically (not happening):相反,在 HTML5 客户端中,我可以使用其
Monitor
选项卡轻松枚举给定资源上的任务,但这对自动化没有帮助,除非以编程方式爬过 UI(没有发生):
How do I use PowerCLI to see the tasks targeting specific resources using PowerCLI?如何使用 PowerCLI 查看针对使用 PowerCLI 的特定资源的任务?
Get-VIEvent
returns all kinds of stuff - luckily, including tasks! Get-VIEvent
返回各种东西——幸运的是,包括任务! You can see them by their type [VMware.Vim.TaskEvent]
, or by checking for their info
property which only tasks events have.您可以通过它们的类型
[VMware.Vim.TaskEvent]
来查看它们,或者通过检查只有任务事件具有的info
属性来查看它们。 For example:例如:
$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
There is often more detailed information stored in the Info
property of task events, but we have to expand it by selecting that property specifically:任务事件的
Info
属性中往往存储了更详细的信息,但我们必须通过专门选择该属性来扩展它:
$VITasks.Info | select QueueTime,Name,EntityName,State
Highly-detailed information about what actually happened is usually stored in other event types though.不过,关于实际发生的事情的非常详细的信息通常存储在其他事件类型中。 For example, to see what changed in the 'Reconfigure virtual machine' task, I'll need to check for events with a
ConfigChanges
property.例如,要查看“重新配置虚拟机”任务中发生了什么变化,我需要检查具有
ConfigChanges
属性的事件。
These also happen to have a very detailed structure with ConfigChanges
and ConfigSpec
properties that you can parse.这些也恰好具有非常详细的结构,其中包含您可以解析的
ConfigChanges
和ConfigSpec
属性。 I just use the pre-formatted message here, but you can use calculated properties to display them with Select
like I do to get the VM Name:我在这里只使用预先格式化的消息,但您可以使用计算属性来显示它们
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:
These steps work for any event/task type, but you have to do some initial digging to find where the data you need is stored, and how to display it in a helpful way.这些步骤适用于任何事件/任务类型,但您必须进行一些初步挖掘以找到所需数据的存储位置,以及如何以有用的方式显示数据。
For whatever reason, Get-Task
is designed specifically to get only:无论出于何种原因,
Get-Task
专门设计用于仅获取:
[...]information about the current or recent tasks[...]
[...有关当前或最近任务的信息[...]
Luc Dekens wrote a scripted function to tackle your issue. Luc Dekens 写了一个脚本 function 来解决你的问题。 Here's a copy of the function, you can target specific resources with the entity param.
这是 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()
}
}
}
More info at https://www.lucd.info/2013/06/01/task-data-mining-an-improved-get-task/#more-4464更多信息,请访问https://www.lucd.info/2013/06/01/task-data-mining-an-improved-get-task/#more-4464
@jrmilner's answer worked for me here, but it does not let me get tasks from non-inventory objects, even if I change the type of -Entity
to an [object[]]
. @jrmilner 的回答在这里对我有用,但它不允许我从非库存对象获取任务,即使我将
-Entity
的类型更改为[object[]]
也是如此。 However, I did post a follow up question about retrieving events from non-inventory objects, but this time I was able to find a solution by modifying another function LucD wrote which I found as I continued my research.然而,我确实发布了一个关于从非库存对象中检索事件的后续问题,但这次我能够通过修改另一个 function LucD 写的解决方案,这是我在继续研究时发现的。 How is this related to this question then?
那么这与这个问题有什么关系呢?
Thanks to Cpt.Whale , I learned that Tasks are Events, and while I obtain the events and separate the "wheat from the Tasks" in a different way, their answer helped me below.感谢Cpt.Whale ,我了解到任务是事件,虽然我获得了事件并以不同的方式将“小麦与任务”分开,但他们的回答在下面帮助了我。
By using the modified Get-VIEventPlus
in my linked answer to the other question, I can discern between tasks and events as they would be separated in the HTML5 client by checking whether Severity
is set on a returned event like so:通过在我对另一个问题的链接答案中使用修改后的
Get-VIEventPlus
,我可以通过检查是否在返回的事件上设置Severity
来区分任务和事件,因为它们在 HTML5 客户端中是分开的:
$dsCluster = Get-DatastoreCluster
$tasks = Get-VIEventPlus -Entity $dsCluster | Where-Object { ! $_.Severity }
$events = Get-VIEventPlus -Entity $dsCluster | Where-Object { $_.Severity }
It appears that events will have the severity set while tasks do not.似乎事件将设置严重性,而任务则没有。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.