Author Posts

December 18, 2017 at 11:51 pm

Hi,

I am trying to understand the values returned by "Get-CimInstance -Class Win32_PerfRawData_PerfDisk_LogicalDisk"
Specifcally I need to use AvgDiskSecPerRead and AvgDiskSecPerWrite similar to perfmon.

There seems to be a formular to convert the raw data returned by the wmi/cim class into something usefull: ((N1-N0)/F)/(D1-D0)
Honestly, I have no clue how to use this formula to get some values in milliseconds.

Any suggestions? Thanks!

December 19, 2017 at 1:55 am

There are public articles on the topic and that formula, is how the default display is achieved not what you use to format later.

Have you read the MSDN docs or other WMI docs on these properties and what they mean?
'msdn.microsoft.com/en-us/library/aa394308(v=vs.85).aspx'

AvgDisksecPerRead
Avg. Disk sec/Read is the average time, in seconds, of a read of data from the disk.
AvgDisksecPerRead_Base

AvgDisksecPerWrite
Avg. Disk sec/Write is the average time, in seconds, of a write of data to the disk.
AvgDisksecPerWrite_Base

There are native built-in formatting that PoSH provides...

'blogs.technet.microsoft.com/heyscriptingguy/2013/03/13/use-powershell-and-conditional-formatting-to-format-numbers'

...but you can you normal math to construct your own.

See these articles:

'computerperformance.co.uk/powershell/powershell_perfmon.htm'
'blogs.technet.microsoft.com/heyscriptingguy/2011/07/28/use-performance-counter-sets-and-powershell-to-ease-baselining'

For example, looking at MSDN data, the value is returned as a integer and based on notes from a few years ago.
Performing base math by property and value could look something like this.

AvgDiskSecPerWrite Data type: uint32 Access type:
Read-only Qualifiers:
CookingType ("PERF_AVERAGE_TIMER") , Counter ("AvgDiskSecPerWrite") ,
PerfTimeStamp ("Timestamp_PerfTime") , PerfTimeFreq ("Frequency_PerfTime") ,
Base ("AvgDisksecPerWrite_Base")

Average time, in seconds, of a write operation of data to the disk.

"Displaying AvgDisksecPerRead dataset `n"
Get-WmiObject Win32_PerfRawData_PerfDisk_PhysicalDisk -Filter "Not Name LIKE '_Total'" |
ForEach-Object { $PerfResultRead = ((($_.AvgDisksecPerRead/$_.Frequency_PerfTime)/$_.AvgDisksecPerRead_Base)*1000)
"$_.name : $PerfResultRead"}

\\WS01\root\cimv2:Win32_PerfRawData_PerfDisk_PhysicalDisk.Name="2 E:".name : 0.438804798083772
\\WS01\root\cimv2:Win32_PerfRawData_PerfDisk_PhysicalDisk.Name="3 H:".name : 0.134188784331138
\\WS01\root\cimv2:Win32_PerfRawData_PerfDisk_PhysicalDisk.Name="0 C:".name : 0.962139882477829
\\WS01\root\cimv2:Win32_PerfRawData_PerfDisk_PhysicalDisk.Name="1 D:".name : 0.145717256624343
\\WS01\root\cimv2:Win32_PerfRawData_PerfDisk_PhysicalDisk.Name="4 G:".name : 0.00291737944932275

"Displaying AvgDisksecPerWrite dataset `n"
Get-WmiObject Win32_PerfRawData_PerfDisk_PhysicalDisk -Filter "Not Name LIKE '_Total'" |
ForEach-Object { $PerfResultWrite = ((($_.AvgDisksecPerWrite/$_.Frequency_PerfTime)/$_.AvgDisksecPerWrite_Base)*1000)
"$_.name : $PerfResultWrite"}

\\WS01\root\cimv2:Win32_PerfRawData_PerfDisk_PhysicalDisk.Name="2 E:".name : 0.382004014543939
\\WS01\root\cimv2:Win32_PerfRawData_PerfDisk_PhysicalDisk.Name="3 H:".name : 0.943027217954768
\\WS01\root\cimv2:Win32_PerfRawData_PerfDisk_PhysicalDisk.Name="0 C:".name : 2.0135973250406
\\WS01\root\cimv2:Win32_PerfRawData_PerfDisk_PhysicalDisk.Name="1 D:".name : 2.54080022055718
\\WS01\root\cimv2:Win32_PerfRawData_PerfDisk_PhysicalDisk.Name="4 G:".name : 2.54080022055718

Anyway, I hope this gets you closer to whatever your use case is.
Lastly, the above may be the long way around the cart. So, I'd suggest you take a look at the Get-Counter cmdlet.

Get-Help -Name Get-Counter -Full

Notes regarding Disk Metrics:

Property Name Command
PercentFreeSpace Get-Counter -Counter "\LogicalDisk(*)\% Free Space"
PercentIdleTime Get-Counter -Counter "\LogicalDisk(*)\% Idle Time"
AvgDisksecPerRead Get-Counter -Counter "\LogicalDisk(*)\Avg. Disk sec/Read"
AvgDisksecPerWrite Get-Counter -Counter "\LogicalDisk(*)\Avg. Disk sec/Write"
AvgDiskQueueLength Get-Counter -Counter "\LogicalDisk(*)\Avg. Disk Queue Length"
DiskTransfersPersec Get-Counter -Counter "\LogicalDisk(*)\Disk Transfers/sec"
CacheBytes Get-Counter -Counter "\Memory\Cache Bytes"

December 19, 2017 at 8:05 am

Thanks for your detailed answer and your implementation of the formula is exactly what I needed!

The reason I don't use get-counter but get-ciminstance is that I also collect other performance data (CPU, memory) from the same machines. To speed things up i establish a single cimsession to every machine and use this session to pull the different data points from all targets.

I was always under the impression this would be the way to go or am I wrong here?

December 19, 2017 at 9:08 pm

Wrong about any given approach is really a matter of use case, possibilities and position / opinion.
PoSH is all about doing what can /needs to be done to accomplish a goal. Sometimes, it's really easy and out of the box, other times not so, and other times you really need to get creative, employing several tings to get the result you are after.

Personally, I've not really used PowerShell to get this sort of thing, we have enterprise tools (for Example, MS SCCM/SCOM) that do this.

You can do the Get-Counter thing (even with multiple counters, well, in a loop through effort) with multiple machines of course and the parse only for what you need.

So, it's best to use your own judgement for your environment and use case for what works and is maintainable for the long term.
Sure, in forums, we can make suggestions, but those can / will be clouded by our own experiences and use case scenarios, which may or may not work for you.

I say, put something together, see if it works, and or post back here to see if the forum can shed more light on your effort.