[powershell] In PowerShell, how can I test if a variable holds a numeric value?

In PowerShell, how can I test if a variable holds a numeric value?

Currently, I'm trying to do it like this, but it always seems to return false.

add-type -Language CSharpVersion3 @'
    public class Helpers {
        public static bool IsNumeric(object o) {
            return o is byte  || o is short  || o is int  || o is long
                || o is sbyte || o is ushort || o is uint || o is ulong
                || o is float || o is double || o is decimal
                ;
        }
    }
'@

filter isNumeric($InputObject) {
    [Helpers]::IsNumeric($InputObject)
}

PS> 1 | isNumeric
False

This question is related to powershell

The answer is


"-123.456e-789" -match "^\-?(\d+\.?\d*)(e\-?\d+)?$|^0x[0-9a-f]+$"

or

"0xab789" -match "^\-?(\d+\.?\d*)(e\-?\d+)?$|^0x[0-9a-f]+$"

will check for numbers (integers, floats and hex).

Please note that this does not cover the case of commas/dots being used as separators for thousands.


If you want to check if a string has a numeric value, use this code:

$a = "44.4"
$b = "ad"
$rtn = ""
[double]::TryParse($a,[ref]$rtn)
[double]::TryParse($b,[ref]$rtn)

Credits go here


Each numeric type has its own value. See TypeCode enum definition: https://docs.microsoft.com/en-us/dotnet/api/system.typecode?view=netframework-4.8 Based on this info, all your numeric type-values are in the range from 5 to 15. This means, you can write the condition-check like this:

$typeValue = $x.getTypeCode().value__
if ($typeValue -ge 5 -and $typeValue -le 15) {"x has a numeric type!"}

filter isNumeric {
    $_ -is [ValueType]
}

-

1 -is [ValueType]
True
"1" -is [ValueType]
False

-

function isNumeric ($Value) {
    return $Value -is [ValueType]
}

isNumeric 1.23
True
isNumeric 123
True
isNumeric ""
False
isNumeric "asdf123"
False

-

(Invoke-Expression '1.5') -is [ValueType]

You can check whether the variable is a number like this: $val -is [int]

This will work for numeric values, but not if the number is wrapped in quotes:

1 -is [int]
True
"1" -is [int]
False

You can do something like :

$testvar -match '^[0-9]+$'

or

$testvar -match '^\d+$'

Returns True if $testvar is a number.


Testing if a value is numeric or a string representation of a numeric value.

function Test-Number 
{
    Param
    (
        [Parameter(Mandatory=$true,
                   Position=0)]
        [ValidatePattern("^[\d\.]+$")]
        $Number
    )

    $Number -is [ValueType] -or [Double]::TryParse($Number,[ref]$null)
}

Testing if a value is numeric.

function Test-Number 
{
    Param
    (
        [Parameter(Mandatory=$true,
                   Position=0)]
        [ValidatePattern("^[\d\.]+$")]
        $Number
    )

    $Number -is [ValueType]
}

-is and -as operators requires a type you can compare against. If you're not sure what the type might be, try to evaluate the content (partial type list):

(Invoke-Expression '1.5').GetType().Name -match 'byte|short|int32|long|sbyte|ushort|uint32|ulong|float|double|decimal'

Good or bad, it can work against hex values as well (Invoke-Expression '0xA' ...)


If you are testing a string for a numeric value then you can use the a regular expression and the -match comparison. Otherwise Christian's answer is a good solution for type checking.

function Is-Numeric ($Value) {
    return $Value -match "^[\d\.]+$"
}

Is-Numeric 1.23
True
Is-Numeric 123
True
Is-Numeric ""
False
Is-Numeric "asdf123"
False

PS> Add-Type -Assembly Microsoft.VisualBasic
PS> [Microsoft.VisualBasic.Information]::IsNumeric(1.5)
True

http://msdn.microsoft.com/en-us/library/microsoft.visualbasic.information.isnumeric.aspx


I ran into this topic while working on input validation with read-host. If I tried to specify the data type for the variable as part of the read-host command and the user entered something other than that data type then read-host would error out. This is how I got around that and ensured that the user enters the data type I wanted:

do
    {
    try
        {
        [int]$thing = read-host -prompt "Enter a number or else"
        $GotANumber = $true
        }
    catch
        {
        $GotANumber = $false
        }
    }
until
    ($gotanumber)

Thank you all who contributed to this thread and helped me figure out how to test for numeric values. I wanted to post my results for how to handle negative numbers, for those who may also find this thread when searching...

Note: My function requires a string to be passed, due to using Trim().

function IsNumeric($value) {
# This function will test if a string value is numeric
#
# Parameters::
#
#   $value   - String to test
#
   return ($($value.Trim()) -match "^[-]?[0-9.]+$")
}

$itisint=$true
try{
 [int]$vartotest
}catch{
 "error converting to int"
 $itisint=$false
}

this is more universal, because this way you can test also strings (read from a file for example) if they represent number. The other solutions using -is [int] result in false if you would have "123" as string in a variable. This also works on machines with older powershell then 5.1