HopelessN00b
HopelessN00b

Reputation: 452

How do I reference an object's property in a Powershell Active Directory cmdlet?

Related to this fantastic answer about how to properly construct a -Filter parameter argument, I'm working on a script that makes heavy use of the Active Directory cmdlets in PowerShell, and am having difficulty constructing filter arguments containing the property of an object variable.

The script basically manages distribution groups by reading in spreadsheet and processing each row as appropriate - creating Active Directory contacts if they don't exist, adding or removing them to the appropriate group and so on.

The spreadsheet is stored in an object array, with each row being treated as an object, with the columns defining the object properties.

For example, the below code takes each row of the imported spreadsheet and attempts to find a matching contact object in Active Directory.

Foreach ($contact in $NOClist)
{
     $contactobject = Get-ADObject -filter ("name -eq `"$contact.name`" -and Objectclass -eq `"contact`"") -SearchBase "$NOCContactPath" -Server $ADServer;
     #... do some more stuff.
}

The problem is that $contact.name is being evaluated literally, so it ends up searching for a contact in Active Directory with a name property that's literally $contact.name. I've tried the other variations in the previously referenced answer, (""$contact.name"", '$contact.name' and "' + $contact.name + '"), but they all either evaluate to the literal $contact.name or throw a syntax error on the . character.

The hacky workaround I've come up with is to assign the object property to a variable and use that instead, such as the below, but that just feels terrible.

Foreach ($contact in $NOClist)
{
    $contactname = $contact.name; 
    $contactobject = Get-ADObject -filter ("name -eq `"$contactname`" -and Objectclass -eq `"contact`"") -SearchBase "$NOCContactPath" -Server $ADServer;
     #... do some more stuff.
}

Is there a way to reference an object property inside the filter argument, or is this workaround of assigning it to a variable and then using the variable really the best approach?

Upvotes: 2

Views: 1939

Answers (2)

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200523

PowerShell does only simple variable expansion in strings, no complex stuff like index or dot-property access. There are several ways to deal with this limitation, e.g.

  • concatenation:

    -Filter ("name -eq '" + $contact.name + "' -and Objectclass -eq 'contact'")
    
  • subexpressions:

    -Filter "name -eq '$($contact.name)' -and Objectclass -eq 'contact'"
    
  • the format operator:

    -Filter ("name -eq '{0}' -and Objectclass -eq 'contact'" -f $contact.name)
    

Note that for the first and third approach you need to put the operation in a grouping expression (i.e. in parentheses), so that the result of that operation is passed to the parameter.

Upvotes: 5

mfinni
mfinni

Reputation: 65

First, are you sure that $contact.name is valid within that that loop? For debug purposes, throw a write-host in there to make sure it's what you think it should be.

But the major thing is that you're using single-quotes around the variable, which blocks variable expansion. It looks like you're trying to escape the double-quotes, not sure if that's possible but if it is, that's not the right way to do it. You should be shooting for this from the link:

Get-ADUser -Filter ('sAMAccountName -eq "' + $SamAc + '"')

Example for me:

PS V:> $contactname = "finn2617"

PS V:> Get-ADuser -filter ('samaccountname -eq "' + $contactname + '"' ) | select name, samaccountname

name samaccountname

---- --------------

Finnigan, Matthew FINN2617

So, for you:

$contactobject = Get-ADObject -filter ('name -eq `"' + $contact.name + " -and Objectclass -eq "contact" ' ) -SearchBase "$NOCContactPath" -Server $ADServer;

Upvotes: 1

Related Questions