Powershell: Help with script

Parity123
Parity123 used Ask the Experts™
on
Hello,

I am not sure how to exclude a set of users in my query,

The following line works
get-aduser -filter * -properties * | where {$_.name -notlike 'sam*'} | select name

If I want to exclude about 10 users how to do this.  For instance: -notlike 'sam*', 'john*','kim*','lev*'  etc

Please assist.
Comment
Watch Question

Do more with

Expert Office
EXPERT OFFICE® is a registered trademark of EXPERTS EXCHANGE®
Steven CarnahanAssistant Vice President\Network Manager

Commented:
One option is you can use the -and option like:

get-aduser -filter * -properties * | {$._UserName -notlike "user1" -and $_.UserName -notlike "*user2"}
What happens if you try:

Get-AdUser -Filter 'name -nolike "sam*" '

Open in new window

You would be better off with a -notmatch.
(get-aduser -filter * | where {$_.name -notmatch "^(SP |SQL |Mich|CRM |Mike)"}).Name

Open in new window

Also, it's a generally bad practice to use the -Propeties wildcard.  You're not using all those properties so why bring them across the wire?  And Name is in the default parameter set.

One last thing, in the future please pick a more descriptive thread title.  The generic "help" isn't very helpful for the folks who are skimming the list looking for things they can answer, or for delivered answers later.
Python 3 Fundamentals

This course will teach participants about installing and configuring Python, syntax, importing, statements, types, strings, booleans, files, lists, tuples, comprehensions, functions, and classes.

Qlemo"Batchelor", Developer and EE Topic Advisor
Top Expert 2015

Commented:
Do you need something more dynamic, or it's a "fixed" list.

Author

Commented:
It is going to be a fixed list. The number of items could vary. The list could expand from 10 to 15 elements etc.
You might try the following.
$arrUsers = @("sam", "john", "kim", "lev")
get-aduser -filter * -properties * | where {$_.name -notmatch ('(' + [string]::Join(')|(', $arrUsers) + ')')} | select name

Open in new window

Steven CarnahanAssistant Vice President\Network Manager

Commented:
Based on your wanting to check for just first names (SAM* in your example)Perhaps you want to use -notcontain instead of -notmatch  OR givenName instead of name and then you won't need the "*".

Perhaps create a adlist.csv file of the names you want to skip so that you can modify the list at anytime.

Then:

$users = Import-Csv - Path C:\scripts\adlist.csv
foreach ($user in $users) {
get-aduser -filter * | where {$_.GivenName -notcontains $user}

Open in new window

Qlemo"Batchelor", Developer and EE Topic Advisor
Top Expert 2015
Commented:
zalazar's code is similar to what I had in mind, and would prefer myself (though slightly simplified):
$arrUsers = @("sam", "john", "kim", "lev")
get-aduser -filter * -properties * | ? { $_.name -notmatch ($arrUsers -join '|') } | select name

Open in new window

pony10us' code is not recommended, as you would execute the get-aduser for each individual user, but getting all users each time. A costly operation.
Steven CarnahanAssistant Vice President\Network Manager

Commented:
Qlemo,

Thank you for pointing that out.  I was not thinking so much about the "cost" as much as using GivenName (first name) as opposed to name (full name?) which would require the wild card character (*) that you and zalazar both omitted. By omitting the wild card character, and using -notmatch, you are looking for exact math where using -notcontain in your code would look for the string anywhere in the name field. Using GivenName would only be looking at the first name field so you wouldn't need the wild card character here either unless you didn't want to use the full first name.

Also, I was looking at the ability to use an external csv file for the names to be omitted so it could easily be edited without having to go into the code all the time.  

Overall I appreciate your pointing out that my code is not the most efficient, especially for a larger organization with many users to look at.
OK, you are confusing a few things.
-Match/-NotMatch doesn't use simple wildcards like -Like.  It uses RegEx which is much more powerful, but it can also be confusing to folks that haven't used it before.
You have also confused the operator -Contains/-NotContains with the method .Contains().  The former verifies membership in a collection.  The latter verifies a string within a string.  It's an unfortunate overloading of terms that confuses a lot of people.
Qlemo"Batchelor", Developer and EE Topic Advisor
Top Expert 2015

Commented:
To be precise, the -notmatch approach is less restrictive here - we are not enforcing the names to be the first to come, but they might be located anywhere ('Akim' would be a match to 'kim', for example). But enforcing that is part of the RegEx feature set.
But "^Kim" would force it to match the beginning of the string, which is how I had setup my example above.
Steven CarnahanAssistant Vice President\Network Manager

Commented:
First I must admit that I am still learning PS so I appreciate very much these corrections in my thinking.

Next I still have one concern here. How would you account for the following:

kim smith
kimmy jones
Kimberly smith

You only want to exclude kim smith.  If you use -notmatch kim wouldn't it exclude all three based on Qelmo's description: 'Akim' would be a match to 'kim'
It is like any other RegEx.  You can make it as tight or as loose as you want.

(get-aduser -filter * | where {$_.name -notmatch "^(Kim |SQL |Mich|CRM |Mike)"}).Name

Open in new window

In this case Kim Smith (that is, Kim starting at the beginning of the string and followed by a literal space) will not show up in the results.  Whereas kimmy jones and Kimberly Smith will.

PowerShell and RegEx is an unbeatable combination when it comes to text manipulation.
Qlemo"Batchelor", Developer and EE Topic Advisor
Top Expert 2015

Commented:
Bob, but neither zalazar nor I did include the ^ ;-). And that is what I referred to.

pony, you would exclude all three if asking for "kim" only. If you want to exclude "kim smith" only, you have to search for exactly that, of course: -notmatch '^(kim smith|jessy james|the waltons)$' requires an exact match to exclude.
Steven CarnahanAssistant Vice President\Network Manager

Commented:
Qlemo, just when I thought I was getting it you through that out.  :)  

So bringing it back to if you want to eliminate anyone with the first name of kim wouldn't it be better to use givenname instead of name?

On the other hand, if you want to eliminate a specific user, say 'kim smith' but not 'kim jones', then you would use name and have to put the full name in the array.
Qlemo"Batchelor", Developer and EE Topic Advisor
Top Expert 2015

Commented:
Whether to use the given name or the full name or the display name or the samAccountName or the philosophical name depends on the situation, and so there is no correct answer to that. But if I want to search for the first part of the name, which shall be the given name (not necessarily so), then yes, of course I would use givenname for matching.
Did you see that there was a space after Kim.  That is significant.  It is literal.  It is part of the matching criteria.
Steven CarnahanAssistant Vice President\Network Manager

Commented:
Thanks guys. As usual I learned some valuable information myself.  :)

Author

Commented:
Thank you all.

Do more with

Expert Office
Submit tech questions to Ask the Experts™ at any time to receive solutions, advice, and new ideas from leading industry professionals.

Start 7-Day Free Trial