Following function is just and example to work with 505 events generated by storport. It will query all disks on local or remote system, and return all latency information together with disks model, location... It does not show progress, therefore you need to be bit patient.

Inspired by [this blogpost](https://blogs.technet.microsoft.com/ashleymcglone/2013/08/28/powershell-get-winevent-xml-madness-getting-details-from-event-logs/)

**Example use:**

Get-DiskPerfReport | Format-Table -Autosize

or

Get-DiskPerfReport -ComputerName "S2D1","S2D2" | Out-GridView -Title DiskPerfReport

![](/Scenarios/S2D%20Tools/Get-DiskPerfReport/Screenshots/output.png)

```PowerShell
<#
.Synopsis
   Function to list 505 events with info.
.DESCRIPTION
   Function to list 505 events and display all info about disks and their latency from 505 event
.EXAMPLE
   Get-DiskPerfReport | Format-Table -Autosize
.EXAMPLE
   Get-DiskPerfReport -ComputerName "S2D1","S2D2" | Out-GridView -Title DiskPerfReport
#>
function Get-DiskPerfReport
{
    Param
    (
        # Parameter ComputerName (can be multiple computer names)
        [Parameter(ValueFromPipelineByPropertyName=$true,
                   Position=0)]
        [array]$ComputerName
    )

        #grab all disks with node info
    if ($ComputerName){
        $disks=Invoke-Command -ComputerName $ComputerName -ScriptBlock {Get-PhysicalDisk}
        #grab all 505 events from all nodes
        $allevents=Invoke-Command -ComputerName $ComputerName -ScriptBlock {
            $events=Get-WinEvent -FilterHashtable @{"ProviderName"="Microsoft-Windows-StorPort";Id=505}
            ForEach ($Event in $Events) {
                # Convert the event to XML
                $eventXML = [xml]$Event.ToXml()
                # create custom object for all values
                for ($i=0; $i -lt $eventXML.Event.EventData.Data.Count; $i++) {            
                    # Append these as object properties            
                    Add-Member -InputObject $Event -MemberType NoteProperty -Force -Name  $eventXML.Event.EventData.Data[$i].name -Value $eventXML.Event.EventData.Data[$i].'#text'
                        
                }
            }
            return $events
        }
    }else{ #if $ComputerName are not specified, grab from local server
        $disks=Get-PhysicalDisk
        $Allevents=Get-WinEvent -FilterHashtable @{"ProviderName"="Microsoft-Windows-StorPort";Id=505}
        ForEach ($Event in $AllEvents) {
            # Convert the event to XML
            $eventXML = [xml]$Event.ToXml()
            # create custom object for all values
            for ($i=0; $i -lt $eventXML.Event.EventData.Data.Count; $i++) {            
                # Append these as object properties            
                Add-Member -InputObject $Event -MemberType NoteProperty -Force -Name  $eventXML.Event.EventData.Data[$i].name -Value $eventXML.Event.EventData.Data[$i].'#text'
            }
        }
    }
 
    #add disk info to events
    foreach ($event in $allevents){
        $disk=$disks | where ObjectID -like "*$($event.ClassDeviceGuid)*" | select -Unique
        Add-Member -InputObject $Event -MemberType NoteProperty -Force -Name FriendlyName -Value $disk.FriendlyName
        Add-Member -InputObject $Event -MemberType NoteProperty -Force -Name SerialNumber -Value $disk.SerialNumber
        Add-Member -InputObject $Event -MemberType NoteProperty -Force -Name MediaType -Value $disk.MediaType
        Add-Member -InputObject $Event -MemberType NoteProperty -Force -Name BusType -Value $disk.BusType
        Add-Member -InputObject $Event -MemberType NoteProperty -Force -Name OperationalStatus -Value $disk.OperationalStatus
        Add-Member -InputObject $Event -MemberType NoteProperty -Force -Name PhysicalLocation -Value $disk.physicallocation
        Add-Member -InputObject $Event -MemberType NoteProperty -Force -Name SlotNumber -Value $disk.slotnumber
    }

    $ReleaseID=Get-ItemPropertyValue -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\' -Name ReleaseID
    if ($ReleaseID -ge 1809){
        return $allevents |select FriendlyName,SerialNumber,MediaType,BusType,OperationalStatus,PhysicalLocation,SlotNumber,TotalIOCount,@{Label="IOSuccessCount(0-256µs)";Expression={$($_.BucketIoSuccess1)}},@{Label="IOSuccessCount(256µs-1ms)";Expression={$($_.BucketIoSuccess2)}},@{Label="IOSuccessCount(1-4ms)";Expression={$($_.BucketIoSuccess3)}},@{Label="IOSuccessCount(4-16ms)";Expression={$($_.BucketIoSuccess4)}},@{Label="IOSuccessCount(16-64ms)";Expression={$($_.BucketIoSuccess5)}},@{Label="IOSuccessCount(64-128ms)";Expression={$($_.BucketIoSuccess6)}},@{Label="IOSuccessCount(128-256ms)";Expression={$($_.BucketIoSuccess7)}},@{Label="IOSuccessCount(256ms-2s)";Expression={$($_.BucketIoSuccess8)}},@{Label="IOSuccessCount(2-6s)";Expression={$($_.BucketIoSuccess9)}},@{Label="IOSuccessCount(6-10s)";Expression={$($_.BucketIoSuccess10)}},@{Label="IOSuccessCount(10-20s)";Expression={$($_.BucketIoSuccess11)}},@{Label="IOSuccessCount(20s+)";Expression={$($_.BucketIoSuccess12)}},TimeCreated,Max*,IoCount*
    }else{
        return $allevents |select FriendlyName,SerialNumber,MediaType,BusType,OperationalStatus,PhysicalLocation,SlotNumber,TotalIOCount,@{Label="IOCount(0-2ms)";Expression={$($_.BucketIoCount1)}},@{Label="IOCount(2-64ms)";Expression={$($_.BucketIoCount2)}},@{Label="IOCount(64ms-2s)";Expression={$($_.BucketIoCount3)}},@{Label="IOCount(2-5s)";Expression={$($_.BucketIoCount4)}},@{Label="IOCount(5s+)";Expression={$($_.BucketIoCount5)}},TimeCreated,Max*,IoCount*
    }
}
 
```