1

Question:

Anyone understand why I'm receiving the following error for my title property in my PSCustomObject inside a foreach? I understand what the error is stating, just confused on the 'why' of it. Everything else works, I'm confused why $_.inputobject returns "Firstname Lastname" just fine in the user property, but can't be used in -filter scriptblock and is unrecognized as an object type in PSCustomObject even though it returns the expected value in the user column.

Error:

Get-ADUser : Property: 'inputobject' not found in object of type: 'System.Management.Automation.PSCustomObject'.

Code:

Compare-Object -ReferenceObject $users.name -DifferenceObject $results.user | foreach {
    $_.sideindicator = $_.sideindicator -replace "<=","No assigned device"
    [PSCustomObject]@{
        user = $_.inputobject
        title = Get-ADUser -Filter {name -like $_.inputobject} -Properties * | % title
        device_status = $_.sideindicator
    }
} 
mklement0
  • 382,024
  • 64
  • 607
  • 775
Nvlddmkm
  • 31
  • 5

1 Answers1

2

First, the standard advice applies:

Second, the solution is to use an expandable (double-quoted) string ("...") instead:

Get-ADUser -Filter "name -eq `"$($_.inputobject)`"" -Properties title

Note: Given that your operand contains no wildcard metacharacters, there's no reason to use -like.

As for the error message:

  • At least historically, only simple, stand-alone variable references - e.g., $_ - were supported in the string that is (ultimately) passed to the [string]-typed -Filter argument, not also expressions, which inlcudes attempts to access a property, e.g. $_.InputObject

  • The error message suggests that the AD provider - now? - does try to evaluate an expression such as $_.InputObject, but - seemingly - only looks for type-native properties, whereas a [pscustomobject] instance's properties are dynamic properties.

  • Perhaps someone can shed more light on this (I don't have access to AD).

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • 1
    Thanks, adding to quote block did the trick. I've had major issues in the past with quote blocks for some more complex filtering, and that error almost made it seem like PS wouldn't have recognized InputObject regardless, so I didn't bother trying xD. Funny enough, I did previously try "$($_.inputobject)" inside the scriptblock and it returned empty, so I figured it wouldn't work in a filter quote block, PS makes my head hurt :). Also I do switch to -eq after I get -like working, I just like to use -like to troubleshoot with * if need be. Thanks again! – Nvlddmkm Oct 02 '22 at 02:52
  • Glad to hear it, @Eric. The problem with using a _script block_ `{ ... }` with `-Filter` is that it is _not_ evaluated like a regular PowerShell script block, because it is (a) converted to a _string_ first and (b) interpreted by the _AD provider_, not PowerShell. And while the syntax supported in such strings is _similar_ to that in PowerShell script blocks, it is both much more limited and exhibits subtle differences in behavior. That is why it is generally preferable to construct the `-Filter` argument _as a(n expandable) string_ to begin with. The linked answer has more information. – mklement0 Oct 02 '22 at 03:00
  • Thanks for the explanation and the link @mklement0. Do you know of any good resources for some of these more nuanced best practices? Some of the intricacies with PS or certain modules isn't very intuitive or standard, and I struggle with finding good articles or lectures on best practice outside of beginner level. I suppose checking MS KBs for specific cmdlet options or arguments is a good start. Thanks again. – Nvlddmkm Oct 02 '22 at 18:23
  • I'm afraid I don't have any recommendations, @Eric, except to say that sites like this one are often a good source of information of what the official docs don't cover. – mklement0 Oct 02 '22 at 18:28