从作业中返回性能计数器结果

Returning performance counter results from within a job

我有以下脚本 运行 作业中的性能计数器:

$counter = {
  param($TestLength)
  $perfsample = Get-Counter -Counter `
  "\PhysicalDisk(_Total)\% Disk Time",`
  "\Processor(_Total)\% Processor Time",`
  "\Process(_Total)\Working Set",`
  "\Network Interface(*)\Bytes Total/Sec"`
  -SampleInterval 1 -MaxSamples $TestLength -ErrorAction SilentlyContinue

  $perfsample
}

Start-Job -Name GettingCounters -ScriptBlock $counter -ArgumentList $TestLength | Wait-Job

Export-Counter -Path $DestinationFile -FileFormat csv -InputObject (Receive-Job GettingCounters)

当运行上述代码时,出现以下错误:

Export-Counter : Cannot bind parameter 'InputObject'. Cannot convert the "Micro
soft.PowerShell.Commands.GetCounter.PerformanceCounterSampleSet" value of type
"Deserialized.Microsoft.PowerShell.Commands.GetCounter.PerformanceCounterSample
Set" to type "Microsoft.PowerShell.Commands.GetCounter.PerformanceCounterSample
Set".

我知道这是因为输出被序列化了,所以是否可以 return 反序列化输出?

不幸的是,所有类型都不是可序列化的。为什么不导出作业内部?

$counter = {
  param($TestLength, $DestinationFile)
  $perfsample = Get-Counter -Counter `
  "\PhysicalDisk(_Total)\% Disk Time",`
  "\Processor(_Total)\% Processor Time",`
  "\Process(_Total)\Working Set",`
  "\Network Interface(*)\Bytes Total/Sec"`
  -SampleInterval 1 -MaxSamples $TestLength -ErrorAction SilentlyContinue

  $perfsample | Export-Counter -Path $DestinationFile -FileFormat csv
}

Start-Job -Name GettingCounters -ScriptBlock $counter -ArgumentList $TestLength, $DestinationFile | Wait-Job

作为替代方案,您可以使用 运行spaces 而不是作业,因为它们不需要对象序列化并且通常更快(至少当您使用 RunspacePool 来 运行 多个线程时并行)。不过,还有几行可以使用它:

$DestinationFile = ".\Desktop\test.csv"
$TestLength = 10

$counter = {
  param($TestLength)
  $perfsample = Get-Counter -Counter `
  "\PhysicalDisk(_Total)\% Disk Time",`
  "\Processor(_Total)\% Processor Time",`
  "\Process(_Total)\Working Set",`
  "\Network Interface(*)\Bytes Total/Sec"`
  -SampleInterval 1 -MaxSamples $TestLength -ErrorAction SilentlyContinue

  $perfsample
}

$Powershell = [powershell]::Create()
$Powershell.AddScript($counter)
$Powershell.AddParameter("TestLength",$TestLength)
$job = $Powershell.BeginInvoke()

#Get results
$result = $Powershell.EndInvoke($job)
$result | Export-Counter -Path $DestinationFile -FileFormat csv

#Cleanup
$Powershell.Dispose()
$Powershell = $null
$job = $null