I can use some help structing/nesting the below powershell code to get the desired outcome.
When I use the command:
Get-ADGroupMember -Identity $groupname |
Get-ADUser -Properties * -Erroraction Ignore |
select @{N='UserName';E={$_.UserPrincipalName}} |
Export-csv $filename -NoTypeInformation
It works as expected and only selects people from the AD group $groupname
, but when I modify the code and try to filter for only NEW accounts based on when the account was created, it's now including user accounts that are NOT in that group
Get-ADGroupMember -Identity $groupname |
Get-ADUser -Filter { whenCreated -ge $when } -Properties * -Erroraction Ignore |
select @{N = 'UserName'; E = { $_.UserPrincipalName } } |
Export-csv $filename -NoTypeInformation
I'm not sure why it is now including all new user accounts in our AD, even some outside of the group $groupname
You cannot use -Filter
while piping in objects. If you are piping in objects Get-ADUser
will assume you want to get them. This boils down to a parameter binding error, however, since you've set the -ErrorAction Ignore
you aren't getting the error feedback that would have said so.
You should have any problem getting AD Users that we know exist by virtue of their group membership. So, I'd question if you really need to ignore errors. That said, Removing -ErrorAction Ignore
will not solve the parameter binding issue. For that, I'm afraid you'll have to resort to post-filtering with a Where{}
clause. For example:
$When = (Get-Date "12/31/2020").ToUniversalTime()
Get-ADGroupMember -Identity $groupname |
Get-ADUser -Properties WhenCreated |
Where-Object{ $_.WhenCreated -ge $when }
Select-Object @{Name = 'UserName'; Expression = { $_.UserPrincipalName } } |
Export-csv $filename -NoTypeInformation
Note: The property is stored in UTC, so by converting the local time we're interested in we should get the correct results.
Note: You do not need to get all the properties. UserPrincipalName is included in the default set. To post-filter you will have to add WhenCreated to the results.
An Aside: Try not to use script blocks for the -Filter
argument. If you look at Get-ADUser help documentation you'll find the parameter is actually string typed. As such specifying a script block requires recasting under the hood and can lead to issues. so, if you were to use the -Filter
parameter in this project or elsewhere just use a regular string, like: -Filter "Name -like '*steve*'"
Another Aside: A [DateTime]
such as returned by Get-Date
cannot be directly used in a -Filter
argument. This likely has to do with If, when, and how cmdlet is manipulating the WhenCreated. The Value of the WhenCreated LDAP attribute is stored more like "20200820040000.Z", so you can adjust to use as the -Filter
or -LDAPFilter
argument respectively like below:
$when = (Get-Date '8/20/20' ).ToUniversaltime().ToString('yyyMMddHHmmss.Z')
Get-ADUser -Filter "WhenCreated -ge '$when'"
Or with -LDAPFilter
Get-ADUser -LDAPFilter "(whencreated>=$when)"
I'll follow-up with documentation on the filter-able properties if I can find it.
Update:
Based on comments from @SantiagoSquarzon, you may not want to use Get-ADGroupMember
at all, as you may be passing non-user objects to Get-ADUser
. Combining up his suggestion, an example may look like:
$when = (Get-Date '8/20/20' ).ToUniversaltime().ToString('yyyMMddHHmmss.Z')
$groupDN = (Get-ADGroup -Identity $groupname).DistinguishedName
Get-ADUser -LDAPFilter "(&(memberOf=$groupDN)(whencreated>=$when))" |
Select-Object @{Name = 'UserName'; Expression = { $_.UserPrincipalName }} |
Export-csv $filename -NoTypeInformation