brittonv
brittonv

Reputation: 813

How to tell if a number is within a range in PowerShell

I need a way to start services on a server if the hostname value is between 500-549.

If it is not in that range then other services will be started.

I know how to do it all except identify if the number is a value between 500-549 so servernames containing values up to 499 and from 550-999 will have other services started.

So for example, the desired result would be:

server 500 start service A
server 530 start service b
server 660 start service A

Upvotes: 15

Views: 57312

Answers (4)

Underflow
Underflow

Reputation: 61

If you do this a lot, here is a function to cut down on typing and mistakes:

function Test-Range
{
    <#
    .SYNOPSIS
        Takes three integers: Value being tested, Low end of range, High end of range
        If the Value is the same as Low or High it returns True
    #>
    [CmdletBinding()]
    param(
        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0
        )]
        [Int] $Value,
        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 1
        )]
        [Int] $Low,
        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 2
        )]
        [Int] $High
    )
    return (($Value -ge $Low) -and ($Value -le $High ))
}

To execute the function do one of the following:

if (Test-Range 1 2 3) # This will return false
if (Test-Range -Value 1 -Low 2 -High 3) # This will return false

Or if you prefer a slightly more readable version but a few more keys

function Test-Range
{
    <#
    .SYNOPSIS
        Takes three integers: Value being tested, Low end of range, High end of range
        If the Value is the same as Low or High it returns True
    #>
    [CmdletBinding()]
    param(
        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 0
        )]
        [Int] $Value,
        [Parameter(
            Mandatory = $true,
            ValueFromPipelineByPropertyName = $true,
            Position = 1
        )]
        [array] $Range
    )
    return (($Value -ge $Range[0]) -and ($Value -le $Range[1] ))
}

This would be called like so:

if (Test-Range 1 (2, 3)) # This will return false
if (Test-Range -Value 1 -Range (1, 3)) # This will return True

Upvotes: 0

oɔɯǝɹ
oɔɯǝɹ

Reputation: 7625

As a reply to both answers; code clarity and performance both matter, so I did some testing. As with all benchmarking, your results may differ; I just did this as a quick test..

Solution 1

(($value -ge $lower) -and ($value -le $upper))

Solution 2

$value -In $lower .. $upper

Test

$value = 200
$lower = 1

for ($upper = $lower; $upper -le 10000000; $upper += $upper) {
    $a = Measure-Command { (($value -ge $lower) -and ($value -le $upper)) } | Select -ExpandProperty Ticks
    $b = Measure-Command { ($value -in $lower .. $upper) } | Select -ExpandProperty Ticks
    "$value; $lower; $upper; $a; $b"
}

Results:

Enter image description here

When plotted (in Excel), I got the following graph:

Enter image description here

Conclusion

For small ranges, there is no big difference between solutions. However, since the performance penalty for larger ranges does occur (measurable starting at 256 elements), and you may not have influence on the size of the range, and ranges may vary per environment, I would recommend using solution 1. This also counts (especially) when you don't control the size of the range.

Upvotes: 24

nixda
nixda

Reputation: 2697

Use the -In operator and define a range with ..

$a = 200
$a -In 100..300

As a bonus: This works too. Here, PowerShell silently converts a string to an integer

$a = "200"
$a -In 100..300

Output for both examples is

True

Upvotes: 34

Keith Hill
Keith Hill

Reputation: 201662

If the server name is really just a number then:

$num = [int]$serverName
if ($num -ge 500 -and $num -le 549) {
    ... do one thing
}
else  {
    ... do another
}

Upvotes: 22

Related Questions