Function Throw-EmptyDiscovery
{
param($SourceId, $ManagedEntityId)
$oDiscoveryData = $g_API.CreateDiscoveryData(0, $SourceId, $ManagedEntityId)
Log-Event $FAILURE_EVENT_ID $EVENT_TYPE_WARNING "Exiting with empty discovery data" $TRACE_INFO
$oDiscoveryData
If($traceLevel -eq $TRACE_DEBUG)
{
#just for debug proposes when launched from command line does nothing when run inside OpsMgr Agent
$g_API.Return($oDiscoveryData)
}
}
Function Throw-KeepDiscoveryInfo
{
param($SourceId, $ManagedEntityId)
$oDiscoveryData = $g_API.CreateDiscoveryData(0,$SourceId,$ManagedEntityId)
#Instead of Snapshot discovery, submit Incremental discovery data
$oDiscoveryData.IsSnapshot = $false
Log-Event $FAILURE_EVENT_ID $EVENT_TYPE_WARNING "Exiting with null non snapshot discovery data" $TRACE_INFO
$oDiscoveryData
If($traceLevel -eq $TRACE_DEBUG)
{
#just for debug proposes when launched from command line does nothing when run inside OpsMgr Agent
$g_API.Return($oDiscoveryData)
}
}
#endregion
Function Process-VM
{
param($measure)
$bag = $g_api.CreatePropertyBag()
$bag.AddValue('VMId',$measure.VMId.ToString())
$bag.AddValue('Type','VM')
$bag.AddValue('AvgCPU', (NullZero $measure.AverageProcessorUsage))
$bag.AddValue('AvgMemory',(NullZero $measure.AverageMemoryUsage))
$bag.AddValue('MaxMemory',(NullZero $measure.MaximumMemoryUsage))
$bag.AddValue('DiskAllocation',(NullZero $measure.TotalDiskAllocation))
$bag.AddValue('NormalizedIOPS',(NullZero $measure.AggregatedAverageNormalizedIOPS))
$bag.AddValue('AvgDiskLatency',(NullZero $measure.AggregatedAverageLatency))
#the following metrics are an absolute value so if collected they need to be collected in delta
$bag.AddValue('DiskDataRead',(NullZero $measure.AggregatedDiskDataRead))
$bag.AddValue('DiskDataWritten',(NullZero $measure.AggregatedDiskDataWritten))
#try to transform in Avg, but sometime the metering time is null
if($measure.MeteringDuration) {
$DataPerSecSignificant=1
$DiskDataReadPerSec = (NullZero $measure.AggregatedDiskDataRead) / $measure.MeteringDuration.TotalSeconds
$DiskDataWrittendPerSec = (NullZero $measure.AggregatedDiskDataWritten) / $measure.MeteringDuration.TotalSeconds
}
else {
$DataPerSecSignificant=0
$DiskDataReadPerSec = 0
$DiskDataWrittenPerSec = 0
}
$bag.AddValue('DiskDataWrittenPerSec',(NullZero $DiskDataWrittendPerSec))
$bag.AddValue('DiskDataReadPerSec',(NullZero $DiskDataReadPerSec))
$bag.AddValue('DiskDataPerSecSignificant',$DataPerSecSignificant)
#now return aggregated Network Data if any
$outboundTraffic = ($measure.NetworkMeteredTrafficReport | where {$_.Direction -ieq 'Outbound'} | Measure-Object -Property TotalTraffic -Sum).Sum
$inboundTraffic = ($measure.NetworkMeteredTrafficReport | where {$_.Direction -ieq 'Inbound'} | Measure-Object -Property TotalTraffic -Sum).Sum
$bag.AddValue("OutboundTraffic",(NullZero $outboundTraffic))
$bag.AddValue("InboundTraffic",(NullZero $inboundTraffic))
#try to transform in Avg, but sometime the metering time is null
if($measure.MeteringDuration) {
$DataPerSecSignificant=1
$OutboundPerSec = (NullZero $outboundTraffic) / $measure.MeteringDuration.TotalSeconds
$InboundPerSec = (NullZero $inboundTraffic) / $measure.MeteringDuration.TotalSeconds
}
else {
Log-Event $START_EVENT_ID $EVENT_TYPE_INFO ("$($measure.VMName) doesn't report Metering Duration. Some Perf counters will be missing.") $TRACE_VERBOSE
$DataPerSecSignificant=0
$OutboundPerSec = 0
$InboundPerSec = 0
}
$bag.AddValue("OutboundTrafficPerSec",(NullZero $OutboundPerSec))
$bag.AddValue("InboundTrafficPerSec",(NullZero $InboundPerSec))
$bag.AddValue("TrafficPerSecSignificant",$DataPerSecSignificant)
#now we can return the data
$bag
#now return the disk data if we have any
foreach($disk in $measure.HardDiskMetrics) {
$bag = $g_api.CreatePropertyBag()
$diskId = $disk.VirtualHardDisk.Id
$bag.AddValue('VMId',$measure.VMId.ToString())
$bag.AddValue('DiskId',$diskId)
$bag.AddValue('Type','Disk')
$bag.AddValue("NormalizedIOPS",(NullZero $disk.AverageNormalizedIOPS))
$bag.AddValue("AvgDiskLatency",(NullZero $disk.AverageLatency))
$bag.AddValue("DiskDataRead",(NullZero $disk.DataRead))
$bag.AddValue("DiskDataWritten",(NullZero $disk.DataWritten))
#try to transform in Avg, but sometime the metering time is null
if($measure.MeteringDuration) {
$DataPerSecSignificant=1
$DiskDataReadPerSec = (NullZero $disk.DataRead) / $measure.MeteringDuration.TotalSeconds
$DiskDataWrittendPerSec = (NullZero $disk.DataWritten) / $measure.MeteringDuration.TotalSeconds
}
else {
$DataPerSecSignificant=0
$DiskDataReadPerSec = 0
$DiskDataWrittenPerSec = 0
}
$bag.AddValue("DiskDataWrittenPerSec",(NullZero $DiskDataWrittendPerSec))
$bag.AddValue("DiskDataReadPerSec",(NullZero $DiskDataReadPerSec))
$bag.AddValue("DiskDataPerSecSignificant",$DataPerSecSignificant)
$bag
}
#end reset the statistics
#Reset-VMResourceMetering -VMName $measure.VMName
Log-Event $START_EVENT_ID $EVENT_TYPE_INFO ("$($measure.VMName) has been processed") $TRACE_VERBOSE
}
#Start by setting up API object.
$P_TraceLevel = $TRACE_VERBOSE
$g_Api = New-Object -comObject 'MOM.ScriptAPI'
$g_RegistryStatePath = "HKLM:\" + $g_API.GetScriptStateKeyPath($SCRIPT_NAME)
if ($VMGuid -ine 'ignore') { #here we're in atask targeted at a specific VM
$measure = Get-VM | where {$_.VMId -ieq $VMGuid -and $_.ResourceMeteringEnabled -eq $true} | Measure-VM
if($measure) {Process-VM $measure}
exit;
}