Filtering Search-ADAccount - powershell

I am wondering if there is a way to filter this:
Search-ADAccount -AccountInactive -DateTime ((get-date).adddays(-90))
-Usersonly
By adding pipeline:
| where-object {($_.samAccountName -notlike "*_ua1") -and ($ _.memberOf -like "*UserAdminL1 *")}
It seems like it freezes and do nothing.
Maybe there is a correct way to do this ?

Search-ADAccount does not return group memberships. If you want to filter on that you could first pipe into Get-AdUser to get the memberOf property. You also are missing the Where-Object portion of your filter and the $ _.memberOf should be $_.memberOf. Compile errors would have been trying to correct that for you so you might just have a copy paste issue with your question.
Search-ADAccount -AccountInactive -DateTime ((get-date).adddays(-90)) -Usersonly |
Get-Aduser -Properties memberof |
Where-Object {($_.samAccountName -notlike "*_ua1") -and ($_.memberOf -like "*UserAdminL1 *")}

Related

Powershell Get-ADComputer filter for multiple operating systems

I am trying to filter/match the operating system from Get-ADComputer and only return computers that have Windows 7 and above:
$computer = Get-ADComputer -properties OperatingSystem | Where-Object {operatingsystem -match "*Windows 7*|*Windows 8*|*Windows 10*"} |
Where-Object {$_.name -like "*-*"} |
Where-Object {$_.name -NotLike "V7-*"} |
Where-Object {$_.name -NotLike "*-NONE"} |
Where-Object {$_.name -NotLike "*-ONCALL"} |
Where-Object {$_.name -NotLike "*-BLACKBAUD"} |
Where-Object {$_.name -NotLike "SC-WIN7-1"} |
Where-Object {$_.name -NotLike "UT-SWCLIENT-01"} |
Select-Object -Expand Name
but when I do that, the debugger asks for a -Filter parameter
I have also tried:
$computer = Get-ADComputer -properties OperatingSystem -filter {(operatingsystem -match "*Windows 7*|*Windows 8*|*Windows 10*")} |
but I get an error:
Get-ADComputer : Error parsing query: '(operatingsystem -match "*Windows 7*|*Windows 8*|*Windows 10*")' Error Message: 'Operator Not supported:
-match' at position: '18'.
So what's the correct/best way to do this?
When you are doing advanced filtering using Where-Object you need to refer to iterator object. Also in your first code example, include -Filter * to get a complete list of all machines. I.e. try running
$computer = Get-ADComputer -properties OperatingSystem -Filter * `
| Where-Object {$_.operatingsystem -match "*Windows 7*|*Windows 8*|*Windows 10*"}
Alternatively you can do simple filtering and exclude the $_ operator like this
Get-Process | where name -like svchost
However, the -match operator does not seem to support this way of filtering.
You can also filtering the returned result when doing the query for all AD computers, like this
Get-ADComputer -Properties OperatingSystem `
-Filter {OperatingSystem -like "*Windows 7*" -or OperatingSystem -like "*Windows 8*"}
See this blog post on what is allowed when doing advanced filtering against Active Directory.
In my opinion, it's worth trying to do as much filtering as possible at the "server" end of the query and only return what you really need. The benefit is that all further processing at your end will be faster since there's less data to process.
You are trying to use multiple filters condition with your Get-AdComputer cmdlet. Instead of using the -match parameter, I would suggest to use -like parameter. I am not sure if Get-AdComputer supports the -match parameter. You can do something like below -
$computer = Get-ADComputer -properties OperatingSystem -filter 'operatingsystem -like "*Windows 7*" -or operatingsystem -like "*Windows 8*" -or operatingsystem -like "*Windows 10*"' |
If you see Get-Help Get-ADComputer -Examples, you can see how the -filter parameter is used.

PowerShell: How to apply multiple filters via where-object cmdlet?

Is there a better way to filter for objects via where-object then to send the data through multiple pipelines?
$clients = Get-ADComputer
-SearchBase "OU=Clients,DC=contoso,DC=com"
-Filter *
-Properties Description,OperatingSystem
$clients | Where OperatingSystem -notlike "*Windows 7*"
| Where OperatingSystem -notlike "*Windows 10*"
Ideal would be a complex filtering mechanism like we can use for the -Filter Parameter. I would have expected to be able to use something like the following...
$Clients | Where {
(OperatingSystem -notlike "Windows 7") -and (OperatingSystem -notlike "Windows 10")
}
$clients | Where OperatingSystem -notlike "*Windows 7*" |
Where OperatingSystem -notlike "*Windows 10*"
Strictly speaking, this should work.
However, the problem you're running in to is that the simplified Where-Object syntax shown above only works in the most simple cases. When you use the full syntax, you must specify the properties using the $_ variable:
$clients | Where-Object {
($_.OperatingSystem -notlike '*Windows 7*') -and ($_.OperatingSystem -notlike '*Windows 10*')
}
However, since you're using Get-ADComputer, you really should be using the -Filter property on that command. It will be much faster, and will be less work for your domain controller, too:
Get-ADComputer -SearchBase "OU=Clients,DC=contoso,DC=com" `
-Filter "(OperatingSystem -notlike '*Windows 7*') -and (OperatingSystem -notlike '*Windows 10*')" `
-Properties Description,OperatingSystem
It is more efficient to filter directly in the query rather than filtering after-the-fact using Where-Object (which retrieves all objects first). Example using the -LDAPFilter parameter:
Get-ADComputer -LDAPFilter "(&(!operatingSystem=Windows 7*)(!operatingSystem=Windows 10*))" -Properties operatingSystem,description
Something like this perhaps?
$DesktopClients=#('Windows 7','Windows 10')
$Clients=$Clients -notmatch ($DesktopClients -join '|')

Powershell to get accounts with passwords older than "$"

I am trying to get a list of accounts with passwords that are older than lets say 90 days but something is not working right and I am not sure why.
Get-ADUser -Filter 'Enabled -eq $True' -Properties PasswordLastSet,samaccountname,passwordlastset | Where-Object {$_.PasswordLastSet -gt ($_.PasswordLastSet).adddays(1)} | select Name,samaccountname,passwordlastset
This is what i got so far but if I run it as is it returns 0 results. I know there are passwords that are older than one day, mine is one of them. Any help is appreciated.
Per your realization in the comments you should compare the PasswordLastSet field to today's date less 90 days as follows:
Get-ADUser -Filter 'Enabled -eq $True' -Properties PasswordLastSet | Where-Object {$_.PasswordLastSet -lt (Get-Date).adddays(-90)} | select Name,SamAccountName,PasswordLastSet
Use -lt for older passwords, or -gt for newer passwords.
You can try this,if you wana export remove #
$DaysAgo=(Get-Date).AddDays(-90)
$params = #{
"filter" = 'Enabled -eq $true -and passwordlastset -lt $DaysAgo'
"Properties" = "Displayname",
"passwordlastset",
"samaccountname"
}
Get-ADUser #params |select displayname,samaccountname,passwordlastset #| export-csv C:\result.csv -nti

Trouble with capturing a group of users

I am trying to get a subset of users. I want to capture a list of groups members but only those who have a canonical name that starts with "contoso.com" Here is the code snippet hopefully someone can help me.
Get-ADGroupMember -Identity $GroupName | where{$_.ObjectClass -eq "User"} | Get-ADUser -Properties CanonicalName | Select CanonicalName | where{$_.CanonicalName -Like "contonso.com"}
Get-ADGroupMember -Identity $group | where{$_.ObjectClass -eq "User"} | Get-ADUser -Properties CanonicalName | where{$_.CanonicalName -match "contoso.com"} | select Canonicalname,name
You need to add a wildcard so that the remaining characters in the CanonicalName will match something in the -like criteria:
...where{$_.CanonicalName -Like "contonso.com*"}
# add a wildcard here ^

Powershell: where {_.Name not in $object}

I'm building a script that lists all Inactive computer accounts. I'd like to exclude a few systems from the results.
I've got a text-file containing all systems to be excluded (one systemname per line). All items are stored in an object with property name "name". So $excluded will contain:
name
----
system1
system2
To list all inactive systems I use the Search-ADAccount cmdlet:
$InactiveComputers = Search-ADAccount -AccountInactive -TimeSpan 90 -ComputersOnly | Where {$_.Enabled -eq $true}
Of course I can loop all results 1 by 1, but is there a simple way to exclude the systems directly from the results? I've got a feeling it's possible with select-object or where-object, but I can't figure out how to compare against the results in an object.
You were basically correct in using this in your title: "where {_.Name not in $object}"
Syntax is a little different. Pipe it to the following
Where { !($_.Name -in $excluded) }
OR
Where { $_.Name -notin $excluded }
Both seem to give the same results in the console. Happy coding!
Note: Tested this on PSv2 and v3.
I ran across this when looking for an answer and figured I would update with these options for others that run into this.
Import the exclude file (as csv) and use the -notcontains operator:
$names = Import-csv exclude.txt | Foreach-Object {$_.Name}
$InactiveComputers = Search-ADAccount -AccountInactive -TimeSpan 90 -ComputersOnly | Where {$_.Enabled -eq $true -and $names -notcontains $_.Name}
I think you can use -notcontains (TechNet article) operator:
$InactiveComputers = Search-ADAccount -AccountInactive -TimeSpan 90 -ComputersOnly | Where {$_.Enabled -eq $true -and $excluded -notcontains $_.name }