7

Context: We are making an API to get a list of all VMs and the filter it, using if loops, to return only VMs with name starting only with the values in $MachineList.

The list of servers is split in 2:

  • set 1: srv-a-1, srv-a-2, srv-b-1, srv-b-2, srv-c-1, srv-c-2, etc.
  • set 2: tst-a-1, tst-a-2, tst-b-1, tst-b-2, tst-c-1, tst-c-2, etc.

This is the script:

$EnvironmentList = "Environments-4" -or "Environments-5" -or "Environments-41" -or "Environments-61"
$MachineList = "srv-a*" -or "srv-b*" -or "srv-c*" -or "srv-d*" -or "srv-e*" -or "srv-f*" -or "srv-g*" -or "srv-h*" -or" srv-i*" -or "srv-j*" -or "srv-k*" -or "srv-l*"

function CheckService {
    $MachinesRequest = (Invoke-WebRequest -Method Get -Headers @{"X-system-ApiKey"="Hashed-API-Key-Value"} -URI https://url-to-site.local/api/machines/all).Content | ConvertFrom-Json
    foreach ($Machine in $MachinesRequest) {
        if ($EnvironmentList -contains $Machine.EnvironmentIds) {
            if ($MachineList -contains $Machine.Name) {
                $Machine.Name
            }
        }
    }
}

CheckService

We're trying to return just the items which match the values in the machine list however this is returning the full list of machines (both srv* and tst*).

2 Answers 2

10

First and foremost, $MachineList = "srv-a*" -or "srv-b*" -or ... won't do what you apparently think it does. It's a boolean expression that evaluates to $true, because PowerShell interprets non-empty strings as $true in a boolean context. If you need to define a list of values, define a list of values:

$MachineList = "srv-a*", "srv-b*", ...

Also, the -contains operator does exact matches (meaning it checks if any of the values in the array is equal to the reference value). For wildcard matches you need a nested Where-Object filter

$MachineList = "srv-a*", "srv-b*", "srv-c*", ...
...
if ($MachineList | Where-Object {$Machine.Name -like $_}) {
    ...
}

A better approach in this scenario would be a regular expression match, though, e.g.:

$pattern = '^srv-[a-l]'
...
if ($Machine.Name -match $pattern) {
    ...
}
Sign up to request clarification or add additional context in comments.

2 Comments

Why is using a regular expression a better approach in your oppinion?
@Ravior Performance reasons. Doing a series of comparison operations generally takes longer than a single comparison operation.
0

use -eq for an exact match. use -match or -contains for a partial string match

$my_list='manager','coordinator','engineer', 'project engineer',
$retval=$False
if ($dd_and_pm -eq "engineer")
{
    $retval=$True
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.