Win32_PingStatus

Win32_PingStatus lets you ping one or more computers in parallel. You have to submit the target address(es) via the filter property to make this work.

Win32_PingStatus can ping one or more computers. This works in a highly unusual way: rather than calling a method, you submit the ping parameters as filter.

Win32_PingStatus is very fast and can ping multiple computers in parallel. When you ping too many systems simultaneously, you may run out of resources, though.

Examples

When you query instances of Win32_PingStatus, no instances are returned. In order to use this class, you need to also specify a filter. The filter submits the information needed to perform a ping: at least a computer name (or IP address), and a timeout:

$ComputerName = 'google.com'
$TimeoutMillisec = 2000

Get-CimInstance -ClassName Win32_PingStatus -Filter "Address='$ComputerName' and timeout=$TimeoutMillisec" | Select-Object -Property Address, StatusCode

A status code of 0 indicates success.

Pinging Multiple Computers

To ping more than one computer, it is better to submit multiple computer names rather than repeating the call because WMI supports parallel operations. This pings three computer names:

# ping the specified servers with a given timeout (milliseconds)
$TimeoutMillisec = 1000

Get-CimInstance -ClassName Win32_PingStatus -Filter "(Address='microsoft.com' or Address='r13-c14' or Address='google.com') and timeout=$TimeoutMillisec" | Select-Object -Property Address, StatusCode

Keep in mind that all ping operations occur simultaneously. When you submit too many computers, you may run out of resources.

When a computer name does not exist, StatusCode returns $null. Again, a value of 0 indicates success.

Adding Parameters

It is awkward to construct the filter string for multiple computers. PowerShell can do this for you. Simply implement parameters and turn it into a function Test-OnlineFast:

function Test-OnlineFast
{
    param
    (
        [Parameter(Mandatory)]
        [string[]]
        $ComputerName,
 
        $TimeoutMillisec = 1000
    )
    
    # convert list of computers into a WMI query string
    $query = $ComputerName -join "' or Address='"
 
    Get-CimInstance -ClassName Win32_PingStatus -Filter "(Address='$query') and timeout=$TimeoutMillisec" | Select-Object -Property Address, StatusCode
 }

Now it is very simple to ping many computers using a timeout of your choice:

Test-OnlineFast -ComputerName microsoft.com, google.de

By default, Test-OnlineFast uses a timeout of 1000 milliseconds, so when a machine does not respond, it waits a maximum of 1 second. You can change this timeout via -TimeoutMilliseconds.

The more time you grant, the longer the command will take. You should therefore use a timeout that is as small as possible, while still allowing enough time for responding systems to send a response.

Another time factor to consider is DNS resolution: if DNS resolution is slow, or cannot resolve a name, this adds to the overall time it takes. With IP addresses, this slowdown does not occur.

Range Ping

Here is an example that pings 200 IP addresses and takes just a few seconds:

$ComputerName = 1..255 | ForEach-Object { "10.62.13.$_" }
Test-OnlineFast -ComputerName $ComputerName

Friendly Return Values

Win32_PingStatus returns cryptic numeric return values. By adding a hashtable, your function can translate them to meaningful text:

function Test-OnlineFast
{
    param
    (
        # make parameter pipeline-aware
        [Parameter(Mandatory)]
        [string[]]
        $ComputerName,

        $TimeoutMillisec = 1000
    )

    # hash table with error code to text translation
    $StatusCode_ReturnValue = 
    @{
        0='Success'
        11001='Buffer Too Small'
        11002='Destination Net Unreachable'
        11003='Destination Host Unreachable'
        11004='Destination Protocol Unreachable'
        11005='Destination Port Unreachable'
        11006='No Resources'
        11007='Bad Option'
        11008='Hardware Error'
        11009='Packet Too Big'
        11010='Request Timed Out'
        11011='Bad Request'
        11012='Bad Route'
        11013='TimeToLive Expired Transit'
        11014='TimeToLive Expired Reassembly'
        11015='Parameter Problem'
        11016='Source Quench'
        11017='Option Too Big'
        11018='Bad Destination'
        11032='Negotiating IPSEC'
        11050='General Failure'
    }

    # hash table with calculated property that translates
    # numeric return value into friendly text

    $statusFriendlyText = @{
        # name of column
        Name = 'Status'
        # code to calculate content of column
        Expression = { 
            # take status code and use it as index into
            # the hash table with friendly names
            # make sure the key is of same data type (int)
            $StatusCode_ReturnValue[([int]$_.StatusCode)]
        }
    }

    # calculated property that returns $true when status -eq 0
    $IsOnline = @{
        Name = 'Online'
        Expression = { $_.StatusCode -eq 0 }
    }

    # do DNS resolution when system responds to ping
    $DNSName = @{
        Name = 'DNSName'
        Expression = { if ($_.StatusCode -eq 0) { 
                if ($_.Address -like '*.*.*.*') 
                { [Net.DNS]::GetHostByAddress($_.Address).HostName  } 
                else  
                { [Net.DNS]::GetHostByName($_.Address).HostName  } 
            }
        }
    }

    # convert list of computers into a WMI query string
    $query = $ComputerName -join "' or Address='"

    Get-CimInstance -ClassName Win32_PingStatus -Filter "(Address='$query') and timeout=$TimeoutMillisec" |
    Select-Object -Property Address, $IsOnline, $DNSName, $statusFriendlyText
    
}

When you now ping a network segment, you get back fast results and friendly return values:

$iprange = 1..200 | ForEach-Object { "192.168.8.$_" }
Test-OnlineFast -ComputerName $iprange

The result looks similar to this:


Address       Online DNSName               Status
-------       ------ -------               ------
192.168.8.104   True DELL7390.speedport.ip Success
192.168.8.100   True                       Success
192.168.8.1     True speedport.ip          Success
192.168.8.103   True                       Success
192.168.8.107   True STORAGE2              Success
192.168.8.131   True NPIC69D3F             Success
192.168.8.126   True                       Success
192.168.8.128   True                       Success
192.168.8.77    True                       Success
...

Super-Fast Mass-Ping

You can combine all of the above into a powerful mass ping function Test-OnlineFast: it constructs a filter string that includes all computer names plus the timeout value you want to use, and translates the return values to friendly text:

function Test-OnlineFast
{
  param
  (
    # make parameter pipeline-aware
    [Parameter(Mandatory,ValueFromPipeline)]
    [string[]]
    $ComputerName,

    $TimeoutMillisec = 1000
  )

  begin
  {
    # use this to collect computer names that were sent via pipeline
    [Collections.ArrayList]$bucket = @()
    
    # hash table with error code to text translation
    $StatusCode_ReturnValue = 
    @{
      0='Success'
      11001='Buffer Too Small'
      11002='Destination Net Unreachable'
      11003='Destination Host Unreachable'
      11004='Destination Protocol Unreachable'
      11005='Destination Port Unreachable'
      11006='No Resources'
      11007='Bad Option'
      11008='Hardware Error'
      11009='Packet Too Big'
      11010='Request Timed Out'
      11011='Bad Request'
      11012='Bad Route'
      11013='TimeToLive Expired Transit'
      11014='TimeToLive Expired Reassembly'
      11015='Parameter Problem'
      11016='Source Quench'
      11017='Option Too Big'
      11018='Bad Destination'
      11032='Negotiating IPSEC'
      11050='General Failure'
    }
    
    
    # hash table with calculated property that translates
    # numeric return value into friendly text

    $statusFriendlyText = @{
      # name of column
      Name = 'Status'
      # code to calculate content of column
      Expression = { 
        # take status code and use it as index into
        # the hash table with friendly names
        # make sure the key is of same data type (int)
        if ($_.StatusCode -eq $null) {
        	"N/A"
        }
        else 
        {
        	$StatusCode_ReturnValue[([int]$_.StatusCode)]
        }
      }
    }

    # calculated property that returns $true when status -eq 0
    $IsOnline = @{
      Name = 'Online'
      Expression = { $_.StatusCode -eq 0 }
    }

    # do DNS resolution when system responds to ping
    $DNSName = @{
      Name = 'DNSName'
      Expression = { if ($_.StatusCode -eq 0) { 
          if ($_.Address -like '*.*.*.*') 
          { [Net.DNS]::GetHostByAddress($_.Address).HostName  } 
          else  
          { [Net.DNS]::GetHostByName($_.Address).HostName  } 
        }
      }
    }
  }
    
  process
  {
    # add each computer name to the bucket
    # we either receive a string array via parameter, or 
    # the process block runs multiple times when computer
    # names are piped
    $ComputerName | ForEach-Object {
      $null = $bucket.Add($_)
    }
  }
    
  end
  {
    # convert list of computers into a WMI query string
    $query = $bucket -join "' or Address='"
        
    Get-WmiObject -Class Win32_PingStatus -Filter "(Address='$query') and timeout=$TimeoutMillisec" |
    Select-Object -Property Address, $IsOnline, $DNSName, $statusFriendlyText
  }
}

This is how you use the function:

Test-OnlineFast -ComputerName google.de, powershellmagazine.com, 10.10.10.200, 127.0.0.1

The result looks similar to this:

Address                Online DNSName                Status           
-------                ------ -------                ------           
127.0.0.1                True DESKTOP-7AAMJLF        Success          
google.de                True google.de              Success          
powershellmagazine.com   True powershellmagazine.com Success          
10.10.10.200            False                        Request Timed Out

Pipeline Support

In a last step, you might want to add pipeline support for Test-OnlineFast:

function Test-OnlineFast
{
    param
    (
        # make parameter pipeline-aware
        [Parameter(Mandatory,ValueFromPipeline)]
        [string[]]
        $ComputerName,

        $TimeoutMillisec = 1000
    )

    begin
    {
        # use this to collect computer names that were sent via pipeline
        [Collections.ArrayList]$bucket = @()
    
        # hash table with error code to text translation
        $StatusCode_ReturnValue = 
        @{
            0='Success'
            11001='Buffer Too Small'
            11002='Destination Net Unreachable'
            11003='Destination Host Unreachable'
            11004='Destination Protocol Unreachable'
            11005='Destination Port Unreachable'
            11006='No Resources'
            11007='Bad Option'
            11008='Hardware Error'
            11009='Packet Too Big'
            11010='Request Timed Out'
            11011='Bad Request'
            11012='Bad Route'
            11013='TimeToLive Expired Transit'
            11014='TimeToLive Expired Reassembly'
            11015='Parameter Problem'
            11016='Source Quench'
            11017='Option Too Big'
            11018='Bad Destination'
            11032='Negotiating IPSEC'
            11050='General Failure'
        }
    
    
        # hash table with calculated property that translates
        # numeric return value into friendly text

        $statusFriendlyText = @{
            # name of column
            Name = 'Status'
            # code to calculate content of column
            Expression = { 
                # take status code and use it as index into
                # the hash table with friendly names
                # make sure the key is of same data type (int)
                if ($_.StatusCode -eq $null) {
                    "N/A"
                }
                else 
                {
                    $StatusCode_ReturnValue[([int]$_.StatusCode)]
                }
            }
        }

        # calculated property that returns $true when status -eq 0
        $IsOnline = @{
            Name = 'Online'
            Expression = { $_.StatusCode -eq 0 }
        }

        # do DNS resolution when system responds to ping
        $DNSName = @{
            Name = 'DNSName'
            Expression = { if ($_.StatusCode -eq 0) { 
                    if ($_.Address -like '*.*.*.*') 
                    { [Net.DNS]::GetHostByAddress($_.Address).HostName  } 
                    else  
                    { [Net.DNS]::GetHostByName($_.Address).HostName  } 
                }
            }
        }
    }
    
    process
    {
        # add each computer name to the bucket
        # we either receive a string array via parameter, or 
        # the process block runs multiple times when computer
        # names are piped
        $ComputerName | ForEach-Object {
            $null = $bucket.Add($_)
        }
    }
    
    end
    {
        # convert list of computers into a WMI query string
        $query = $bucket -join "' or Address='"
        
        Get-CimInstance -ClassName Win32_PingStatus -Filter "(Address='$query') and timeout=$TimeoutMillisec" |
        Select-Object -Property Address, $IsOnline, $DNSName, $statusFriendlyText
    }
}

Now you can pipe a list of computer names right into the function:

'microsoft.com','powershell.one','google.com' | Test-OnlineFast -TimeoutMillisec 2000 

The result looks similar to this:

Address        Online DNSName        Status           
-------        ------ -------        ------           
google.com       True google.com     Success          
powershell.one   True powershell.one Success          
microsoft.com   False                Request Timed Out

Remote Access

When you use remoting, you can ping other computers from the location of the remote system. To access remote system(s), use the parameter -ComputerName. The example below pings google.com from the perspective of a server named server123.

$ComputerName = 'google.com'
$TimeoutMillisec = 2000

Get-CimInstance -ClassName Win32_PingStatus -Filter "Address='$ComputerName' and timeout=$TimeoutMillisec" | Select-Object -Property Address, StatusCode -ComputerName server123

The example assumes there is a server named server123 that has remoting enabled, and you have the appropriate permissions to access it.

Learn more about accessing remote computers.

Further Reading

Win32_PingStatus comes with parallel optimization built-in but you can also use .NET classes to do pings and control timeouts. Here is a detailed article.

Often, servers and especially clients do not echo ICMP requests for security reasons. That’s why you may want to use a port test instead. Here is an article that provides you with PowerShell code examples to implement your own port scanner.

Methods

Win32_PingStatus has no methods.

Properties

Win32_PingStatus returns 24 properties:

'Address','BufferSize','NoFragmentation','PrimaryAddressResolutionStatus',
'ProtocolAddress','ProtocolAddressResolved','RecordRoute','ReplyInconsistency','ReplySize',
'ResolveAddressNames','ResponseTime','ResponseTimeToLive','RouteRecord','RouteRecordResolved',
'SourceRoute','SourceRouteType','StatusCode','Timeout','TimeStampRecord','TimeStampRecordAddress',
'TimeStampRecordAddressResolved','TimeStampRoute','TimeToLive','TypeofService'

Unless explicitly marked as WRITEABLE, all properties are read-only.

Address

KEY PROPERTY STRING

Value of the address requested.

The form of the value can be either the computer name (“wxyz1234”), IPv4 address (“192.168.177.124”), or IPv6 address (“2010:836B:4179::836B:4179”).

BufferSize

KEY PROPERTY UINT32

Buffer size sent with the ping command. The default value is 32.

NoFragmentation

KEY PROPERTY BOOL

If $true, “Do not Fragment” is marked on the packets sent. The default is $false, not fragmented.

PrimaryAddressResolutionStatus

UINT32

Status of the address resolution process. If successful, the value is 0 (zero). Any other value indicates an unsuccessful address resolution.

PrimaryAddressResolutionStatus returns a numeric value. To translate it into a meaningful text, use any of the following approaches:

Use Update-Type

Update-Type tells PowerShell how to interpret the property. This command needs to be executed only once per PowerShell session:

Update-TypeData -MemberName PrimaryAddressResolutionStatus -TypeName "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/win32_pingstatus" -MemberType ScriptProperty  -Value {
  Enum EnumPrimaryAddressResolutionStatus
  {
    Success   = 0
  }

  [EnumPrimaryAddressResolutionStatus]($this.PSBase.CimInstanceProperties['PrimaryAddressResolutionStatus'].Value)
} -Force

Get-CimInstance -ClassName Win32_PingStatus -Filter "" | Select-Object -Property Address, BufferSize, NoFragmentation, RecordRoute, ResolveAddressNames, SourceRoute, SourceRouteType, Timeout, TimeStampRoute, TimeToLive, TypeofService, PrimaryAddressResolutionStatus
Use Select-Object

Select-Object supports calculated properties. When you submit a hashtable, PowerShell dynamically calculates the result:

$PrimaryAddressResolutionStatus = @{
  Name = 'PrimaryAddressResolutionStatusText'
  Expression = {
    $value = $_.PrimaryAddressResolutionStatus
    
    switch([int]$value)
      {
        0          {'Success'}
        default    {"$value"}
      }
      
  }  
}

Get-CimInstance -ClassName Win32_PingStatus -Filter "" | Select-Object -Property Address, PrimaryAddressResolutionStatus, $PrimaryAddressResolutionStatus
Use a PowerShell Hashtable

You can use a PowerShell hashtable to decode numeric values. Use a hashtable like this one:

$PrimaryAddressResolutionStatus_map = @{
      0 = 'Success'
}
Use Enum structure

You can cast the raw property values to a new enum type to translate raw numeric values into friendly text. Use an enum like this one:

Enum EnumPrimaryAddressResolutionStatus
{
  Success   = 0
}

ProtocolAddress

STRING MAX 4096 CHAR

Address that the destination used to reply. The default is “”.

ProtocolAddressResolved

STRING MAX 4096 CHAR

Resolved address corresponding to the ProtocolAddress property. The default is “”.

RecordRoute

KEY PROPERTY UINT32

How many hops should be recorded while the packet is in route. The default is 0 (zero).

ReplyInconsistency

BOOL

Inconsistent reply data is reported.

ReplySize

UINT32

Represents the size of the buffer returned.

ResolveAddressNames

KEY PROPERTY BOOL

Command resolves address names of output address values. The default is $false, which indicates no resolution.

ResponseTime

UINT32

Time elapsed to handle the request.

ResponseTimeToLive

UINT32

Time to live from the moment the request is received.

RouteRecord

STRING ARRAY

Record of intermediate hops.

RouteRecordResolved

STRING ARRAY

Resolved address that corresponds to the RouteRecord value.

SourceRoute

KEY PROPERTY STRING

Comma-separated list of valid Source Routes. The default is “”.

SourceRouteType

KEY PROPERTY UINT32

Type of source route option to be used on the host list specified in the SourceRoute property. If a value outside of the ValueMap is specified, then 0 (zero) is assumed. The default is 0 (zero).

SourceRouteType returns a numeric value. To translate it into a meaningful text, use any of the following approaches:

Use Update-Type

Update-Type tells PowerShell how to interpret the property. This command needs to be executed only once per PowerShell session:

Update-TypeData -MemberName SourceRouteType -TypeName "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/win32_pingstatus" -MemberType ScriptProperty  -Value {
  Enum EnumSourceRouteType
  {
    None                    = 0
    Loose_Source_Routing    = 1
    Strict_Source_Routing   = 2
  }

  [EnumSourceRouteType]($this.PSBase.CimInstanceProperties['SourceRouteType'].Value)
} -Force

Get-CimInstance -ClassName Win32_PingStatus -Filter "" | Select-Object -Property Address, BufferSize, NoFragmentation, RecordRoute, ResolveAddressNames, SourceRoute, SourceRouteType, Timeout, TimeStampRoute, TimeToLive, TypeofService, SourceRouteType
Use Select-Object

Select-Object supports calculated properties. When you submit a hashtable, PowerShell dynamically calculates the result:

$SourceRouteType = @{
  Name = 'SourceRouteTypeText'
  Expression = {
    $value = $_.SourceRouteType
    
    switch([int]$value)
      {
        0          {'None'}
        1          {'Loose Source Routing'}
        2          {'Strict Source Routing'}
        default    {"$value"}
      }
      
  }  
}

Get-CimInstance -ClassName Win32_PingStatus -Filter "" | Select-Object -Property Address, SourceRouteType, $SourceRouteType
Use a PowerShell Hashtable

You can use a PowerShell hashtable to decode numeric values. Use a hashtable like this one:

$SourceRouteType_map = @{
      0 = 'None'
      1 = 'Loose Source Routing'
      2 = 'Strict Source Routing'
}
Use Enum structure

You can cast the raw property values to a new enum type to translate raw numeric values into friendly text. Use an enum like this one:

Enum EnumSourceRouteType
{
  None                    = 0
  Loose_Source_Routing    = 1
  Strict_Source_Routing   = 2
}

StatusCode

UINT32

Ping command status codes.

StatusCode returns a numeric value. To translate it into a meaningful text, use any of the following approaches:

Use Update-Type

Update-Type tells PowerShell how to interpret the property. This command needs to be executed only once per PowerShell session:

Update-TypeData -MemberName StatusCode -TypeName "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/win32_pingstatus" -MemberType ScriptProperty  -Value {
  Enum EnumStatusCode
  {
    Success                            = 0
    Buffer_Too_Small                   = 11001
    Destination_Net_Unreachable        = 11002
    Destination_Host_Unreachable       = 11003
    Destination_Protocol_Unreachable   = 11004
    Destination_Port_Unreachable       = 11005
    No_Resources                       = 11006
    Bad_Option                         = 11007
    Hardware_Error                     = 11008
    Packet_Too_Big                     = 11009
    Request_Timed_Out                  = 11010
    Bad_Request                        = 11011
    Bad_Route                          = 11012
    TimeToLive_Expired_Transit         = 11013
    TimeToLive_Expired_Reassembly      = 11014
    Parameter_Problem                  = 11015
    Source_Quench                      = 11016
    Option_Too_Big                     = 11017
    Bad_Destination                    = 11018
    Negotiating_IPSEC                  = 11032
    General_Failure                    = 11050
  }

  [EnumStatusCode]($this.PSBase.CimInstanceProperties['StatusCode'].Value)
} -Force

Get-CimInstance -ClassName Win32_PingStatus -Filter "" | Select-Object -Property Address, BufferSize, NoFragmentation, RecordRoute, ResolveAddressNames, SourceRoute, SourceRouteType, Timeout, TimeStampRoute, TimeToLive, TypeofService, StatusCode
Use Select-Object

Select-Object supports calculated properties. When you submit a hashtable, PowerShell dynamically calculates the result:

$StatusCode = @{
  Name = 'StatusCodeText'
  Expression = {
    $value = $_.StatusCode
    
    switch([int]$value)
      {
        0          {'Success'}
        11001      {'Buffer Too Small'}
        11002      {'Destination Net Unreachable'}
        11003      {'Destination Host Unreachable'}
        11004      {'Destination Protocol Unreachable'}
        11005      {'Destination Port Unreachable'}
        11006      {'No Resources'}
        11007      {'Bad Option'}
        11008      {'Hardware Error'}
        11009      {'Packet Too Big'}
        11010      {'Request Timed Out'}
        11011      {'Bad Request'}
        11012      {'Bad Route'}
        11013      {'TimeToLive Expired Transit'}
        11014      {'TimeToLive Expired Reassembly'}
        11015      {'Parameter Problem'}
        11016      {'Source Quench'}
        11017      {'Option Too Big'}
        11018      {'Bad Destination'}
        11032      {'Negotiating IPSEC'}
        11050      {'General Failure'}
        default    {"$value"}
      }
      
  }  
}

Get-CimInstance -ClassName Win32_PingStatus -Filter "" | Select-Object -Property Address, StatusCode, $StatusCode
Use a PowerShell Hashtable

You can use a PowerShell hashtable to decode numeric values. Use a hashtable like this one:

$StatusCode_map = @{
      0 = 'Success'
  11001 = 'Buffer Too Small'
  11002 = 'Destination Net Unreachable'
  11003 = 'Destination Host Unreachable'
  11004 = 'Destination Protocol Unreachable'
  11005 = 'Destination Port Unreachable'
  11006 = 'No Resources'
  11007 = 'Bad Option'
  11008 = 'Hardware Error'
  11009 = 'Packet Too Big'
  11010 = 'Request Timed Out'
  11011 = 'Bad Request'
  11012 = 'Bad Route'
  11013 = 'TimeToLive Expired Transit'
  11014 = 'TimeToLive Expired Reassembly'
  11015 = 'Parameter Problem'
  11016 = 'Source Quench'
  11017 = 'Option Too Big'
  11018 = 'Bad Destination'
  11032 = 'Negotiating IPSEC'
  11050 = 'General Failure'
}
Use Enum structure

You can cast the raw property values to a new enum type to translate raw numeric values into friendly text. Use an enum like this one:

Enum EnumStatusCode
{
  Success                            = 0
  Buffer_Too_Small                   = 11001
  Destination_Net_Unreachable        = 11002
  Destination_Host_Unreachable       = 11003
  Destination_Protocol_Unreachable   = 11004
  Destination_Port_Unreachable       = 11005
  No_Resources                       = 11006
  Bad_Option                         = 11007
  Hardware_Error                     = 11008
  Packet_Too_Big                     = 11009
  Request_Timed_Out                  = 11010
  Bad_Request                        = 11011
  Bad_Route                          = 11012
  TimeToLive_Expired_Transit         = 11013
  TimeToLive_Expired_Reassembly      = 11014
  Parameter_Problem                  = 11015
  Source_Quench                      = 11016
  Option_Too_Big                     = 11017
  Bad_Destination                    = 11018
  Negotiating_IPSEC                  = 11032
  General_Failure                    = 11050
}

Timeout

KEY PROPERTY UINT32

Time-out value in milliseconds.

If a response is not received in this time, no response is assumed. The default is 1000 milliseconds.

TimeStampRecord

UINT32 ARRAY

Record of time stamps for intermediate hops.

TimeStampRecordAddress

STRING ARRAY

Intermediate hop that corresponds to the TimeStampRecord value.

TimeStampRecordAddressResolved

STRING ARRAY

Resolved address that corresponds to the TimeStampRecordAddress value.

TimeStampRoute

KEY PROPERTY UINT32

How many hops should be recorded with time stamp information while the packet is in route.

A time stamp is the number of milliseconds that have passed since midnight Universal Time (UT).

If the time is not available in milliseconds or cannot be provided with respect to midnight UT, then any time may be inserted as a time stamp, provided the high order bit of the Timestamp property is set to 1 (one) to indicate the use of a nonstandard value. The default is 0 (zero).

TimeToLive

KEY PROPERTY UINT32

Life span of the ping packet in seconds.

The value is treated as an upper limit. All routers must decrement this value by 1 (one). When this value becomes 0 (zero), the packet is dropped by the router.

The default value is 80 seconds. The hops between routers rarely take this amount of time.

TypeofService

KEY PROPERTY UINT32

Type of service that is used. The default value is 0 (zero).

TypeofService returns a numeric value. To translate it into a meaningful text, use any of the following approaches:

Use Update-Type

Update-Type tells PowerShell how to interpret the property. This command needs to be executed only once per PowerShell session:

Update-TypeData -MemberName TypeofService -TypeName "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/win32_pingstatus" -MemberType ScriptProperty  -Value {
  Enum EnumTypeofService
  {
    Normal                 = 0
    Minimize_Cost          = 2
    Maximize_Reliability   = 4
    Maximize_Throughput    = 8
    Minimize_Delay         = 16
  }

  [EnumTypeofService]($this.PSBase.CimInstanceProperties['TypeofService'].Value)
} -Force

Get-CimInstance -ClassName Win32_PingStatus -Filter "" | Select-Object -Property Address, BufferSize, NoFragmentation, RecordRoute, ResolveAddressNames, SourceRoute, SourceRouteType, Timeout, TimeStampRoute, TimeToLive, TypeofService, TypeofService
Use Select-Object

Select-Object supports calculated properties. When you submit a hashtable, PowerShell dynamically calculates the result:

$TypeofService = @{
  Name = 'TypeofServiceText'
  Expression = {
    $value = $_.TypeofService
    
    switch([int]$value)
      {
        0          {'Normal'}
        2          {'Minimize Cost'}
        4          {'Maximize Reliability'}
        8          {'Maximize Throughput'}
        16         {'Minimize Delay'}
        default    {"$value"}
      }
      
  }  
}

Get-CimInstance -ClassName Win32_PingStatus -Filter "" | Select-Object -Property Address, TypeofService, $TypeofService
Use a PowerShell Hashtable

You can use a PowerShell hashtable to decode numeric values. Use a hashtable like this one:

$TypeofService_map = @{
      0 = 'Normal'
      2 = 'Minimize Cost'
      4 = 'Maximize Reliability'
      8 = 'Maximize Throughput'
     16 = 'Minimize Delay'
}
Use Enum structure

You can cast the raw property values to a new enum type to translate raw numeric values into friendly text. Use an enum like this one:

Enum EnumTypeofService
{
  Normal                 = 0
  Minimize_Cost          = 2
  Maximize_Reliability   = 4
  Maximize_Throughput    = 8
  Minimize_Delay         = 16
}

CDXML Definition

You can turn this WMI class and its methods into PowerShell cmdlets by importing below CDXML file (Cmdlet Definition XML) as a module.

Create Win32_PingStatus.cdxml
$folder = "c:\wmi\Win32_PingStatus"
$cdxmlPath = Join-Path -Path $folder -ChildPath "Win32_PingStatus.cdxml"

# create folder if not present:
$exists = Test-Path -Path $folder
if (!$exists) { $null = New-Item -Path $folder -ItemType Directory }

# write file
$content = @'
<?xml version="1.0" encoding="utf-8"?>


<!--
This file is licensed under 'Attribution 4.0 International' license (https://creativecommons.org/licenses/by/4.0/).

You can free of charge use this code in commercial and non-commercial code, and you can freely modify and adjust the code 
as long as you give appropriate credit to the original author Dr. Tobias Weltner.

This material was published and is maintained here: 

https://powershell.one/wmi/root/cimv2/win32_pingstatus#cdxml-definition
-->


<PowerShellMetadata xmlns="http://schemas.microsoft.com/cmdlets-over-objects/2009/11">
  <!--referencing the WMI class this cdxml uses-->
  <Class ClassName="Root/CIMV2\Win32_PingStatus" ClassVersion="2.0">
    <Version>1.0</Version>
    <!--default noun used by Get-cmdlets and when no other noun is specified. By convention, we use the prefix "WMI" and the base name of the WMI class involved. This way, you can easily identify the underlying WMI class.-->
    <DefaultNoun>WmiPingStatus</DefaultNoun>
    <!--define the cmdlets that work with class instances.-->
    <InstanceCmdlets>
      <!--query parameters to select instances. This is typically empty for classes that provide only one instance-->
      <GetCmdletParameters />
      <!--defining additional cmdlets that modifies instance properties-->
    </InstanceCmdlets>
  </Class>
  <!--defining enumerations-->
  <Enums>
    <Enum EnumName="Win32_PingStatus.PrimaryAddressResolutionStatus" UnderlyingType="system.uint32">
      <Value Name="Success" Value="0" />
    </Enum>
    <Enum EnumName="Win32_PingStatus.SourceRouteType" UnderlyingType="system.uint32">
      <Value Name="None" Value="0" />
      <Value Name="Loose_Source_Routing" Value="1" />
      <Value Name="Strict_Source_Routing" Value="2" />
    </Enum>
    <Enum EnumName="Win32_PingStatus.StatusCode" UnderlyingType="system.uint32">
      <Value Name="Success" Value="0" />
      <Value Name="Buffer_Too_Small" Value="11001" />
      <Value Name="Destination_Net_Unreachable" Value="11002" />
      <Value Name="Destination_Host_Unreachable" Value="11003" />
      <Value Name="Destination_Protocol_Unreachable" Value="11004" />
      <Value Name="Destination_Port_Unreachable" Value="11005" />
      <Value Name="No_Resources" Value="11006" />
      <Value Name="Bad_Option" Value="11007" />
      <Value Name="Hardware_Error" Value="11008" />
      <Value Name="Packet_Too_Big" Value="11009" />
      <Value Name="Request_Timed_Out" Value="11010" />
      <Value Name="Bad_Request" Value="11011" />
      <Value Name="Bad_Route" Value="11012" />
      <Value Name="TimeToLive_Expired_Transit" Value="11013" />
      <Value Name="TimeToLive_Expired_Reassembly" Value="11014" />
      <Value Name="Parameter_Problem" Value="11015" />
      <Value Name="Source_Quench" Value="11016" />
      <Value Name="Option_Too_Big" Value="11017" />
      <Value Name="Bad_Destination" Value="11018" />
      <Value Name="Negotiating_IPSEC" Value="11032" />
      <Value Name="General_Failure" Value="11050" />
    </Enum>
    <Enum EnumName="Win32_PingStatus.TypeofService" UnderlyingType="system.uint32">
      <Value Name="Normal" Value="0" />
      <Value Name="Minimize_Cost" Value="2" />
      <Value Name="Maximize_Reliability" Value="4" />
      <Value Name="Maximize_Throughput" Value="8" />
      <Value Name="Minimize_Delay" Value="16" />
    </Enum>
  </Enums>
</PowerShellMetadata>
'@ | Set-Content -LiteralPath $cdxmlPath -Encoding UTF8

# import module
Import-Module -Name $cdxmlPath -Force -Verbose

# list new cmdlets
Get-Command -Module "Win32_PingStatus"

See here for more information on CDXML and CDXML-based PowerShell modules.

Type Extensions for PowerShell

You can automatically improve properties of class instances by using a types.ps1xml file.

Create Win32_PingStatus.Types.ps1xml
$folder = "c:\wmi\Win32_PingStatus"
$typesPath = Join-Path -Path $folder -ChildPath "Win32_PingStatus.Types.ps1xml"

# create folder if not present:
$exists = Test-Path -Path $folder
if (!$exists) { $null = New-Item -Path $folder -ItemType Directory }

# write file
$content = @'
<?xml version="1.0" encoding="utf-8"?>


<!--
This file is licensed under 'Attribution 4.0 International' license (https://creativecommons.org/licenses/by/4.0/).

You can free of charge use this code in commercial and non-commercial code, and you can freely modify and adjust the code 
as long as you give appropriate credit to the original author Dr. Tobias Weltner.

This material was published and is maintained here: 

https://powershell.one/wmi/root/cimv2/win32_pingstatus#typesps1xml-file
-->


<Types>
  <Type>
    <!--@

            Applicable type. This type is produced by Get-CimInstance. 
            To extend instances produced by Get-WmiObject, change the type name to: 

            System.Management.ManagementObject#root/cimv2\Win32_PingStatus

        @-->
    <Name>Microsoft.Management.Infrastructure.CimInstance#Root/CIMV2/Win32_PingStatus</Name>
    <Members>
      <ScriptProperty>
        <Name>PrimaryAddressResolutionStatus</Name>
        <!--casting raw content to a enum. This translates numeric values to friendly text while leaving the original property value untouched:-->
        <GetScriptBlock>[Microsoft.PowerShell.Cmdletization.GeneratedTypes.Win32_PingStatus.PrimaryAddressResolutionStatus]($this.PSBase.CimInstanceProperties['PrimaryAddressResolutionStatus'].Value)</GetScriptBlock>
      </ScriptProperty>
      <ScriptProperty>
        <Name>SourceRouteType</Name>
        <!--casting raw content to a enum. This translates numeric values to friendly text while leaving the original property value untouched:-->
        <GetScriptBlock>[Microsoft.PowerShell.Cmdletization.GeneratedTypes.Win32_PingStatus.SourceRouteType]($this.PSBase.CimInstanceProperties['SourceRouteType'].Value)</GetScriptBlock>
      </ScriptProperty>
      <ScriptProperty>
        <Name>StatusCode</Name>
        <!--casting raw content to a enum. This translates numeric values to friendly text while leaving the original property value untouched:-->
        <GetScriptBlock>[Microsoft.PowerShell.Cmdletization.GeneratedTypes.Win32_PingStatus.StatusCode]($this.PSBase.CimInstanceProperties['StatusCode'].Value)</GetScriptBlock>
      </ScriptProperty>
      <ScriptProperty>
        <Name>TypeofService</Name>
        <!--casting raw content to a enum. This translates numeric values to friendly text while leaving the original property value untouched:-->
        <GetScriptBlock>[Microsoft.PowerShell.Cmdletization.GeneratedTypes.Win32_PingStatus.TypeofService]($this.PSBase.CimInstanceProperties['TypeofService'].Value)</GetScriptBlock>
      </ScriptProperty>
    </Members>
  </Type>
</Types>
'@ | Set-Content -LiteralPath $typesPath -Encoding UTF8

# import type definition
Update-TypeData -PrependPath $typesPath

Note: Win32_PingStatus.Types.ps1xml is using enumerations defined in ClassName.cdxml which are available only when you imported the .cdxml file via Import-Module.

Or, you can manually update the PowerShell type database using Update-TypeData.

View Update-TypeData commands for Win32_PingStatus properties
Update-TypeData -MemberName PrimaryAddressResolutionStatus -TypeName "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/win32_pingstatus" -MemberType ScriptProperty  -Value {
  Enum EnumPrimaryAddressResolutionStatus
  {
    Success   = 0
  }

  [EnumPrimaryAddressResolutionStatus]($this.PSBase.CimInstanceProperties['PrimaryAddressResolutionStatus'].Value)
} -Force

Update-TypeData -MemberName SourceRouteType -TypeName "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/win32_pingstatus" -MemberType ScriptProperty  -Value {
  Enum EnumSourceRouteType
  {
    None                    = 0
    Loose_Source_Routing    = 1
    Strict_Source_Routing   = 2
  }

  [EnumSourceRouteType]($this.PSBase.CimInstanceProperties['SourceRouteType'].Value)
} -Force

Update-TypeData -MemberName StatusCode -TypeName "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/win32_pingstatus" -MemberType ScriptProperty  -Value {
  Enum EnumStatusCode
  {
    Success                            = 0
    Buffer_Too_Small                   = 11001
    Destination_Net_Unreachable        = 11002
    Destination_Host_Unreachable       = 11003
    Destination_Protocol_Unreachable   = 11004
    Destination_Port_Unreachable       = 11005
    No_Resources                       = 11006
    Bad_Option                         = 11007
    Hardware_Error                     = 11008
    Packet_Too_Big                     = 11009
    Request_Timed_Out                  = 11010
    Bad_Request                        = 11011
    Bad_Route                          = 11012
    TimeToLive_Expired_Transit         = 11013
    TimeToLive_Expired_Reassembly      = 11014
    Parameter_Problem                  = 11015
    Source_Quench                      = 11016
    Option_Too_Big                     = 11017
    Bad_Destination                    = 11018
    Negotiating_IPSEC                  = 11032
    General_Failure                    = 11050
  }

  [EnumStatusCode]($this.PSBase.CimInstanceProperties['StatusCode'].Value)
} -Force

Update-TypeData -MemberName TypeofService -TypeName "Microsoft.Management.Infrastructure.CimInstance#root/cimv2/win32_pingstatus" -MemberType ScriptProperty  -Value {
  Enum EnumTypeofService
  {
    Normal                 = 0
    Minimize_Cost          = 2
    Maximize_Reliability   = 4
    Maximize_Throughput    = 8
    Minimize_Delay         = 16
  }

  [EnumTypeofService]($this.PSBase.CimInstanceProperties['TypeofService'].Value)
} -Force

Requirements

To use Win32_PingStatus, the following requirements apply:

PowerShell

Get-CimInstance was introduced with PowerShell Version 3.0, which in turn was introduced on clients with Windows 8 and on servers with Windows Server 2012.

If necessary, update Windows PowerShell to Windows PowerShell 5.1, or install PowerShell 7 side-by-side.

Operating System

Win32_PingStatus was introduced on clients with Windows Vista and on servers with Windows Server 2008.

Namespace

Win32_PingStatus lives in the namespace root/cimv2. This is the default namespace. There is no need to use the -Namespace parameter in Get-CimInstance.

Implementation

Win32_PingStatus is implemented in Wmipicmp.dll and defined in Wmipicmp.mof. Both files are located in the folder C:\Windows\system32\wbem:

explorer $env:windir\system32\wbem
notepad $env:windir\system32\wbem\Wmipicmp.mof