Unexpected token '$regex' in expression or statement

Tagged: 

This topic contains 15 replies, has 2 voices, and was last updated by Profile photo of Wei-Yen Tan Wei-Yen Tan 1 year, 5 months ago.

  • Author
    Posts
  • #33128
    Profile photo of Wei-Yen Tan
    Wei-Yen Tan
    Participant

    Hi guys,

    I have been trying to debug this issue with my code.

    What I am trying to do is listed in the comment based help but on this line:

    $a | Select -ExpandProperty samaccountname | Get-Aduser |
    where {"$_.$ADProperty" -$Operator "$regex"

    it says this "Unexpected token '$regex' in expression or statement" in Powershell. I am not quite sure why it is doing this as if I am writing it out in the console:


    $a = get-adgroupmember -identity $ADGroup
    $a | Select -ExpandProperty samaccountname | Get-Aduser | where {$_.givenname -match "^[A-Z]"}

    it does work.

    The full copy of my script is below. Any help most appreciated.

    WY

    function Extract-ADGroupmember
    {
    [CmdletBinding()]
    param
    (
    [Parameter(Mandatory = $true,
    ValueFromPipeline = $true,
    ValueFromPipelineByPropertyName = $true,
    Position = 1)]
    $ADGroup,
    [Parameter(Mandatory = $true,
    Position = 2)]
    [ValidateSet("givenname", "surname")]
    $ADProperty,
    [Parameter(
    Position = 3)]
    $Operator = "match",
    [Parameter(Mandatory = $true,
    Position = 4)]
    $regex
    )
    Import-Module ActiveDirectory
    $a = get-adgroupmember -identity $ADGroup

    $a | Select -ExpandProperty samaccountname | Get-Aduser |
    where {"$_.$ADProperty" -$Operator '$regex'
    }

    }

  • #33130
    Profile photo of Wei-Yen Tan
    Wei-Yen Tan
    Participant

    sorry,

    I have posted twice inadvertently. OP below:

  • #33131
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    The problem is that you're trying to use -$Operator instead of just -match. You can't substitute operators with variables that way. (You've also got double-quotes around $_.$ADProperty and single quotes around $regex, neither of which are likely to work the way you want them to.)

    If you're using PowerShell v3 or later, you can take advantage of Where-Object's new parameter sets and splatting to accomplish something very similar, though:

    $splatOperator = @{ $Operator = $true }
    
    $stuff | Where-Object $ADProperty @splatOperator $regex
    

    If you're stuck supporting PowerShell v2, then you'll have to do a bit more work. I think what I might do in that case is create a script block according to the operator that was passed in. Something like this:

    $scriptBlock = switch ($operator) {
        'match' {
            { $args[0] -match $args[1] }
        }
    
        'like' {
            { $args[0] -like $args[1] }
        }
    
        # etc
    }
    
    $stuff | Where-Object { & $scriptBlock $_.$ADProperty $regex }
    
  • #33133
    Profile photo of Wei-Yen Tan
    Wei-Yen Tan
    Participant

    Hi Dave,

    Thank you very much for the reply. We have a Win2012 R2 management box at the place where we are at...so the first option is on the table with Where-Object parameter sets. I tried to add what you have with the splatting but I got no results when I should have got some results.

    When I ran it through the debugger, the operator splat value didn't contain any values. Is there something that I am missing such as defining

    thank you Dave for your reply.

  • #33134
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    I assigned a value to that hashtable as the first line in my example:

    $splatOperator = @{ $Operator = $true }
    
  • #33135
    Profile photo of Wei-Yen Tan
    Wei-Yen Tan
    Participant

    Ahh ok I get it.

    I understand what you are trying to do, but when I evaluate $splatoperator, Powershell returns the value of the splat as a system.collections.hashtable.

  • #33136
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    That's what it is supposed to be. You splat the hashtable to Where-Object.

  • #33137
    Profile photo of Wei-Yen Tan
    Wei-Yen Tan
    Participant

    Ok....but ithen when powershell is interpreting the hash, shouldnt it show the $operator value?

    For some reason I don't think its getting the operator correctly as I am getting the error:

    ERROR: Where-Object : A positional parameter cannot be found that accepts argument '^[A-D]'.
    Extract-ADGroupmember.ps1 (55, 4): ERROR: At Line: 55 char: 4

    I have the relevant part of the code :

    $a = get-adgroupmember -identity $ADGroup
    $splatOperator = @{ $Operator = $True}
    $a | Select -ExpandProperty samaccountname | Get-Aduser |
    where $ADProperty -@splatOperator $regex

    `

    The only thing that I could see messing it up is the -before the splat.

    Have I done this right? The reason why I put in the "-" is to mimic the command in the console:

    $a = get-adgroupmember -identity Contoso_admin
    $a | Select -ExpandProperty samaccountname | Get-Aduser | where givenname -match "^[A-H]"

    The other possibility is actually doing a full blown parameter set.

  • #33138
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    That extra hyphen is your problem. You just want it to be this:

    where $ADProperty @splatOperator $regex
    

    Read the about_Splatting help file for all the details on how that technique works. 🙂

  • #33139
    Profile photo of Wei-Yen Tan
    Wei-Yen Tan
    Participant

    Ahhh thanks Dave,

    That worked and using the syntax below works and gives the result that I want.
    What was confusing me was seeing the splat with a value of $true. I learn something new everyday!

    Extract-ADGroupmember -ADGroup Contoso_admin -ADProperty givenname -Operator '-match' -regex "^[A-Z]"

    Final code:


    function Extract-ADGroupmember
    {
    [CmdletBinding()]
    param
    (
    [Parameter(Mandatory = $true,
    ValueFromPipeline = $true,
    ValueFromPipelineByPropertyName = $true,
    Position = 1)]
    $ADGroup,
    [Parameter(Mandatory = $true,
    Position = 2)]
    [ValidateSet("givenname", "surname")]
    $ADProperty,
    [Parameter(
    Position = 3)]
    $Operator = "match",
    [Parameter(Mandatory = $true,
    Position = 4)]
    $regex
    )
    Import-Module ActiveDirectory
    $a = get-adgroupmember -identity $ADGroup
    $splatOperator = @{ $Operator = $True}
    $a | Select -ExpandProperty samaccountname | Get-Aduser |
    where $ADProperty @splatOperator $regex

    }

  • #33140
    Profile photo of Wei-Yen Tan
    Wei-Yen Tan
    Participant

    BTW, how are you doing the block of code in your post?

  • #33141
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    You're going to run into some trouble without input validation on that operator parameter. Passing in '-match' won't work, but 'match' should.

  • #33142
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    HTML PRE tags. < PRE > (code) < /PRE > , but without the spaces in the tags.

  • #33143
    Profile photo of Wei-Yen Tan
    Wei-Yen Tan
    Participant

    but match won't make it a operator in the orginal code? It seems to be working if i have the parameter like this.

    		[Parameter(
    				   Position = 3)]
    		$Operator = '-match'
    
    
    
    		
    	
  • #33144
    Profile photo of Dave Wyatt
    Dave Wyatt
    Moderator

    You're getting hung up on the hyphen. That's the syntax for operators (and parameters), but when you're using splatting, you don't need the hyphen. Maybe PowerShell's smart enough to ignore it; dunno, never tried, because that's not how the documentation says it's supposed to work.

  • #33145
    Profile photo of Wei-Yen Tan
    Wei-Yen Tan
    Participant

    Ahhh ok. My apologies Dave, you are right. I checked again without the – and it gave me the desired result. Using the hypen didn't give me the results properly.

    Thanks for correcting my assumptions. Reading through the help about_splatting it wasnt apparent to me of what you said.

    In either case this whole exercise is very fruitful.

You must be logged in to reply to this topic.