PowerShell Multiple -and operators? - powershell

Is there a simpler way to do this? Or does it require me to type out each -and/-notlike for each of the criteria?
Where-Object {$_.DistinguishedName -like "<Enter Domain OU>"} |
Select-Object UserPrincipalName |
Where-Object `
{$_.UserPrincipalName -notlike 'a-*' `
-and $_.UserPrincipalName -notlike 'falkon*' `
-and $_.UserPrincipalName -notlike 'test*' `
-and $_.UserPrincipalName -notlike '*whiteboard*' `
-and $_.UserPrincipalName -notlike '*CSC*' `
-and $_.UserPrincipalName -notlike '*autopilot*'} |
Sort-Object UserPrincipalName

Unfortunately, he can't use -match in an AD filter, but he can use -notlike. The poster can drop the backticks and use operators to continue lines at least. Distinguishedname can't be in an AD filter.
get-aduser -filter "UserPrincipalName -notlike 'a-*' -and
UserPrincipalName -notlike 'falkon*' -and
UserPrincipalName -notlike 'test*' -and
UserPrincipalName -notlike '*whiteboard*' -and
UserPrincipalName -notlike '*CSC*' -and
UserPrincipalName -notlike
'*autopilot*'" -searchbase 'DC=stackoverflow,DC=com' -resultsetsize 1

You can do the following string manipulation to build an LDAP Filter for less verbosity on your script and to leverage Active Directory Filtering capabilities.
Worth mentioning, as more users are under the SearchBase Organizational Unit the faster -Filter / -LDAPFilter becomes compared to Where-Object.
$ou = 'OU=some,OU=ou,DC=some,DC=domain'
$notLike = 'a-*', 'falkon*', 'test*', '*whiteboard*', '*CSC*', '*autopilot*'
$filter = '(&(!userprincipalname={0}))' -f ($notLike -join ')(!userprincipalname=')
$params = #{
SearchBase = $ou
SearchScope = 'OneLevel' # Or SubTree for all child OUs under `$ou`
LDAPFilter = $filter
}
Get-ADUser #params | Sort-Object UserPrincipalName

Related

powershell combine where and or

Im trying to buils a script to exclude users depending on their userprincipalname. I have started with the following script
Get-MsolUser -all | ?{($_.userprincipalname -notlike "*#domain1.com" -or $_.userprincipalname -notlike "*#domain2.com" -or $_.userprincipalname -notlike "*domain3.com")}
The code above does not exclude any users, it just ignores the where statement
BR
Carlos
If for example the suffix is #domain2.com, the two other clauses will still be true (because #domain2.com is still not #domain1.com or #domain3.com), so you'll want to use -and instead of -or:
Get-MsolUser -all | ?{($_.userprincipalname -notlike "*#domain1.com" -and $_.userprincipalname -notlike "*#domain2.com" -and $_.userprincipalname -notlike "*domain3.com")}
Other solution, with a domain list :
$ExcludeDomain=#('domain1.com', 'domain2.com', 'domain3.com')
Get-MsolUser -all | where {($_.userprincipalname -split '#')[1] -notin $ExcludeDomain}

Get user count and actual userdata in a csv file in Powershell

I am trying to get the user count and the actual userinformation through get-aduser but fail miserably.
Get-ADUser -Server $test -Credential $1cred -Filter{enabled -eq $true} | Where-Object { $_.DistinguishedName -notlike '*OU=.Service Accounts,*' -and $_.samaccountname -notlike '*health*' } | Select-object Samaccountname,surname,givenname | Where { $excludedusers -NotContains$_.Samaccountname } | format-list > 'C:\Scripts\Test\enabled_users_and count.csv'
Is the current code. I can add a .count before format-list like this:
(Get-ADUser -Server $test -Credential $1cred -Filter{enabled -eq $true} | Where-Object { $_.DistinguishedName -notlike '*OU=.Service Accounts,*' -and $_.samaccountname -notlike '*health*' } | Select-object Samaccountname,surname,givenname | Where { $excludedusers -NotContains$_.Samaccountname }).count
But I only get the count of the users, as earlier said, I need both.
Extremely thankful for the help.
You need Two different things, Count don't need to be a field in the csv, you can get it by the line count of the final output
You might need the count for the console use, anyway it's not logically right to save it in the final output. (if I understand you right)
You can save it to a variable, then do export or count check...
$Users = Get-ADUser -Server $test -Credential $1cred -Filter{enabled -eq $true} |
Where-Object { $_.DistinguishedName -notlike '*OU=.Service Accounts,*' -and $_.samaccountname -notlike '*health*' } |
Where { $excludedusers -NotContains $_.Samaccountname }
Export:
$Users | Select-object Samaccountname,surname,givenname |
Export-CSV 'C:\Scripts\Test\enabled_users_and count.csv'
Check Count:
$Users.Count

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 iterate through collection in where-object

Forgive me in advance as I may not be defining things correctly here:
I have a script that queries Active Directory for users in a specific OU while excluding a dozen or so OUs within that OU. The script works, but it's kind of messy as I'm declaring 13 variables representing the various OUs and referencing them in where-object. There's also an existing foreach loop as I'm querying more than one domain. I'd like to find a way to reference all the OU's I'm excluding from the query in a single collection or array or whatever and loop through it in my where-object to avoid having to reference 13 variables in the where-object. Can anyone point me in the right direction? (Code below excludes the OU variable defintions)
Existing Code:
(Get-ADForest).domains | foreach {
Get-ADUser -filter {Enabled -eq $True} -properties * -SearchBase "OU=Accounts,$((Get-ADDomain -Server $_).DistinguishedName)" -Server $_ |
where-object {$_.Title -notmatch "Volunteer" -and $_.DistinguishedName -notmatch $excludeOU1 -and $_.DistinguishedName -notmatch $excludeOU1 -and $_.DistinguishedName -notmatch $excludeOU2 -and
$_.DistinguishedName -notmatch $excludeOU3 -and $_.DistinguishedName -notmatch $excludeOU4 -and $_.DistinguishedName -notmatch $excludeOU5 -and $_.DistinguishedName -notmatch $excludeOU6 -and
$_.DistinguishedName -notmatch $excludeOU7 -and $_.DistinguishedName -notmatch $excludeOU8 -and $_.DistinguishedName -notmatch $excludeOU9 -and $_.DistinguishedName -notmatch $excludeOU10 -and
$_.DistinguishedName -notmatch $excludeOU11 -and $_.DistinguishedName -notmatch $excludeOU12 -and $_.DistinguishedName -notmatch $excludeOU13 }
}
Thanks!
You could use a regex to use with notmatch.
[regex]$excluderegex = "^(excludeOU1|excludeOU2|excludeOU3)$"
(Get-ADForest).domains | foreach {
Get-ADUser -filter {Enabled -eq $True} -properties * -SearchBase "OU=Accounts,$((Get-ADDomain -Server $_).DistinguishedName)" -Server $_ |
where-object {$_.Title -notmatch "Volunteer" -and $_.DistinguishedName -notmatch $excluderegex}
}
You can put anything you like inside the Where filter expression:
$excludes = $excludeOU1,$excludeOU2,$excludeOU3,$excludeOU4,$excludeOU5,$excludeOU6,$excludeOU7,$excludeOU8,$excludeOU9,$excludeOU10,$excludeOU11,$excludeOU12,$excludeOU13
Get-ADUser -Filter {Enabled -eq $true} -Properties * -SearchBase "OU=Accounts,$((Get-ADDomain -Server $_).DistinguishedName)" -Server $_ | Where-Object {
$_.Title -notmatch 'Volunteer' -and $(&{
foreach($exclude in $excludes)
{
if($_.DistinguishedName -match $exclude)
{
return $false
}
}
return $true
})
}
You could use the Select-Object cmdlet in your pipeline to add a new "calculated property" to your Get-ADUser data that holds just the OU of the user. The Where-Object call could then simply use a -notin operator.
In my opinion, this would make the code a little more readable. More info here:
Select-Object Calculated Properties
Notin Operator

How can I exclude particular names from Get-ADComputer results?

I want to get all computers in my domain that are enabled, and have 2003 operating system, and the name of the computers do Not contain ' ping , pict , pire '
Here is what I have, but totally failing:
Get-ADComputer -filter {(Enabled -eq $True) -and (OperatingSystem -like "*2003*")} -properties OperatingSystem | where {($_.Name -notlike 'PING*') -or ($_.Name -notlike 'PICT*') -or ($_.Name -notlike 'PIRE*')} | Select Name
You can use the -notlike operator inside the filter, so there is no need for the where statement. See the Get-ADComputer reference on technet.
As well as changing your -or operators to -and as I mentioned, I put all conditions into the filter ending up with this:
Get-ADComputer -filter {
Enabled -eq $True -and
OperatingSystem -like '*2003*' -and
Name -notlike 'PING*' -and
Name -notlike 'PICT*' -and
Name -notlike 'PIRE*'
} | Select Name