Question

I've stumbled across an odd error in a PowerShell script that returns for me the computers in Active Directory in a specific OU (and sub OU's) that are enabled and logged on to within a certain date.

The following snippet does work:

$date = (get-date).AddDays(-100)
Get-ADComputer -Filter {(enabled -eq "true") -and (lastLogonTimestamp -gt  $date)} -Properties lastLogonTimestamp -SearchBase "CN=Computers,DC=some,DC=domain,DC=com"

... however I initially attempted to do this is one line:

Get-ADComputer -Filter {(enabled -eq "true") -and (lastLogonTimestamp -gt  $((get-date).AddDays(-100)))} -Properties lastLogonTimestamp -SearchBase "CN=Computers,DC=some,DC=domain,DC=com"

... but I repeatedly received the error below (which made me try the two line example above):

Get-ADComputer : Cannot process argument because the value of argument "path" is not valid. Change the value of the "path" argument and run the operation again.
At line:1 char:1
+ Get-ADComputer -Filter {(enabled -eq "true") -and (lastLogonTimestamp -gt  $((ge ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [Get-ADComputer], PSArgumentException
    + FullyQualifiedErrorId : ActiveDirectoryCmdlet:System.Management.Automation.PSArgumentException,Microsoft.ActiveDirectory.Management.Commands.GetADComputer

I've run the script on both Windows 8 and Windows Server 2008 R2 - both with PowerShell v3. I assume the Active Directory module installed by the RSAT tools on both OS's may be slightly different versions as well.

Data-wise I have got what I need, but I am stumped as to why the one-liner isn't working. The argument "path" isn't required for either the Get-Date or Get-AdComputer cmdlets, but as something to try I've also made sure my working directory is C:.

I'm interested if anyone may be able to provide some insight in to why this might be - I've used this type of syntax before in non-ActiveDirectory module cmdlets, so I'm inclined to assume that because the query is in the "filter" parameter perhaps this is getting passed incorrectly to the Get-AdComputer cmdlet itself (and is something we all have to live with).

Was it helpful?

Solution

The right-hand side of a filter component must be a value, not an expression.

The solution (as you already found out yourself) is to assign the value produced by the expression to a variable, and use that variable on the right-hand side of the filter:

$date = (get-date).AddDays(-100)
Get-ADComputer -Filter {(enabled -eq "true") -and (lastLogonTimestamp -gt  $date)} ...

OTHER TIPS

Sorry for the very delayed response, I have the same issue on a regular basis and keep having to come back and figure it out, but this is a one liner than will bypass the 'expression/value' syntax requirement of this module. Hopefully it will help some others if not the original poster.

Give this a try.

get-adcomputer -filter "lastlogondate -le '$((get-date).adddays(-14))'"

My understanding is the use of quotes in these places forces the evaluation of the expression in-line and inserts the value before passing the filter expression to the original cmdlet. Someone can correct this explanation as needed.

Tried to do this in one line for ages; as BTag said, you need to use double quotes to specify the filter so that it substitutes the string; I also found you have to use the DateTime ToFileTime method to make sure the DateTime object is sent as an LDAP FileTime tick time format that Get-ADComputer -Filter needs:

Get-ADComputer -Filter "enabled -eq 'true' -and lastLogonTimestamp -gt '$((Get-Date).AddDays(-90).ToFileTime())'" -Properties LastLogonTimeStamp -SearchBase "CN=Computers,DC=some,DC=domain,DC=com"

Enjoy!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top