Home > Back-end >  Powershell match similar entries in an array
Powershell match similar entries in an array

Time:08-20

I've written myself a script to check for vm-folders in vmware vcenter that dont match the corresponding vmname. There are a few automatically deployed VMs which i need to exclude from this check. Those VMs are always similarly named, but with an incremented number at the end. I've declared an array $Vmstoginrore containing strings of them and i'm trying to match my $VmName with this array but it does not work. Ive also tried it with like but i cannot seem to get this to work.

$Vmstoignore=@( "Guest Introspection","Trend Micro Deep Security")
$VmName = "Guest Introspection (4)"

    if ($Vmstoignore-match $VmName ){
        Write-Output "does match"
    }
    else {
        Write-Output "doesn't match"
    }

CodePudding user response:

  • As of v7.2.x, PowerShell offers no comparison operators that accept an array of comparison values (only the input operand - the LHS - is allowed to be an array).

  • However, sine the -match operator is regex-based, you can use a single regex with an alternation (|) to match multiple patterns.

    • Note that the regex pattern to match against must be the RHS (right-hand side) operand of -match (e.g. 'foo' -match '^f' - in your question, the operands are mistakenly reversed).

The following code shows how to construct the regex programmatically from the given, literal array elements (VM name prefixes):

# VM name prefixes to match.
$Vmstoignore = @("Guest Introspection", "Trend Micro Deep Security")

# Construct a regex with alternation (|) from the array, requiring
# the elements to match at the *start* (^) of the input string.
# The resulting regex is:
#    ^Guest\ Introspection|^Trend\ Micro\ Deep\ Security
$regex = $Vmstoignore.ForEach({ '^'   [regex]::Escape($_) }) -join '|'

# Sample input name.
$VmName = "Guest Introspection (4)"

# Now match the input name against the regex:
# -> $true
$VmName -match $regex

Note:

  • You may alternatively construct the regex directly as a string, in which case you need to manually \-escape any regex metacharacters, such as . (no escaping is required with your sample array):

    $regex = '^Guest Introspection|^Trend Micro Deep Security'
    
  • Note that [regex]::Escape() escapes (spaces) as \ , even though spaces aren't metacharacters. However, if the x (IgnorePatternWhiteSpace) regex option is in effect (e.g. by placing (?x) at the start of the regex), spaces that are a meaningful part of the pattern do require this escaping. In the absence of this option (it is off by default), escaping spaces is not necessary.

  • For a detailed explanation of the regex and the ability to interact with it, see this regex101.com page.

  • Related