0
votes

I'm having issues with a script in powershell using AD Module.

I know the general rule of thumb as to how AD commands like to receive its queries so I've wrote this script to (what I thought) would fall inline with those guidelines.

$CSV=Import-Csv "c:\temp\deleteduserlist.csv"
foreach ($entry in $CSV)
{
    $filter = "{SamAccountName -like ""$($entry.username)""}"
    Get-ADObject -filter $filter
}

I basically need to be able to query and restore any of the users that have been deleted however it fails with:

Error Message: 'syntax error' at position: '1'

At first I was sending through the filter with single quotations like so:

{SamAccountName -like 'xxx'"}

However I have fixed this now.

One thing that puzzles me is that I can literally show the results of $filter, copy them to Get-ADObject -Filter (paste) manually and it works. Therefore I cannot understand why Powershell does not like it..

Whole Error:

Get-ADObject : Error parsing query: '{SamAccountName -like "xxxx"}' Error M essage: 'syntax error' at position: '1'. At C:\temp\GetDeleted.ps1:5 char:14 + Get-ADObject <<<< -filter $filter + CategoryInfo : ParserError: (:) [Get-ADObject], ADFilterParsing Exception + FullyQualifiedErrorId : Error parsing query: '{SamAccountName -like "xxx "}' Error Message: 'syntax error' at position: '1'.,Microsoft.ActiveD irectory.Management.Commands.GetADObject

1
-Filter is expecting either a string or a ScriptBlock - not a ScriptBlock definition in a string. $filter = {SamAccountName -like "$($entry.username)"} is sufficient, no need for quotes around itMathias R. Jessen
Ah ok does that mean that even making the changes you suggest this is not possible due to what -Filter is expecting to see?CharlesH
Ah ok so if I take away the outer quotes then I get SamAccountName -like "$($entry.username)" which works on the script but of course gives me no results :)CharlesH
No, keep the {} like in my exampleMathias R. Jessen
Sorry yes once I remove the " " and run the script to output $Filter It simply gives me the command back as the result instead of entering the output from the CSV like so: SamAccountName -like "$($entry.username)" SamAccountName -like "$($entry.username)" SamAccountName -like "$($entry.username)" SamAccountName -like "$($entry.username)"CharlesH

1 Answers

1
votes

One way to do it is this

$CSV=Import-Csv "c:\temp\deleteduserlist.csv"
foreach ($entry in $CSV) {
    ## Set username to entry from csv file
    $directory_username = $entry.username

    ## Build search filter before using it, interested in username and deleted objects
    $directory_filter = {(SamAccountName -like $directory_username) -and (Deleted -eq $true)}

    ## Search for ADObject based on filter and deleted objects explicitely included in the search
    $directory_found_object = Get-ADObject -Filter $directory_filter -IncludeDeletedObjects -Properties sAMAccountName, Deleted
    foreach ($directory_object in $directory_found_object) {
        ### Execute required action on each found $directory_object
        ### Perhaps pipe $directory_object | Restore-ADObject with appropriate attribute values for restore
    }
}

$directory_filter can be of course modified to fit your needs better. However one challenge you will be facing still is to decide which of the found objects for given sAMAccountName should be restored. This is because any given objects can be in deleted state multiple times. Perhaps one way to solve for that is to restore object with latest WhenCreated attribute value.

Also I'm not sure what motivation you have to build filter beforehand. It might be useful in case you built in on the fly for different attribute values but it seems not to be the case in your example. So for simplicity it can be also removed and included directly in Get-ADObject call like this

$directory_found_object = Get-ADObject -Filter {(SamAccountName -like $directory_username) -and (Deleted -eq $true)} -IncludeDeletedObjects -Properties sAMAccountName, Deleted