Get-ADUser with multiple filters & variables - powershell

I'm trying to get AD users into a variable using multiple filters. However one of the filters has variables in it & I can't get it to work... I have searched for similar issues & tried applying those but nothing seems to work.
$FilterBase = "department"
$Filter = "IT"
$ADusers = Get-ADUser -ResultSetSize $null -SearchBase "OU=Users,DC=mydomain,DC=com" -Properties * -Filter {(Enabled -eq $True) -and ($FilterBase -like $Filter) -and (cn -notlike ""SMB_*"")} |
Select-Object distinguishedName |
Sort-Object distinguishedName
I'm trying to fill $ADusers with all enabled users whose commonname doesn't start with "SMB_" (don't ask) & where the department is IT. I used -like to prevent issues if the values in AD would have different casings (uppercase, lowercase, mixed case, ...).
The reason that I'm using variables for this is because in the end the script will be dynamic. At some point $FilterBase is going to be "company" instead of "department" and $Filter is going to be "HR" instead of "IT" etc...
But I just can't seem to get it to work:
Get-ADUser : Error parsing query: '(Enabled -eq $True) -and ($FilterBase -like $Filter) -and (cn -notlike ""SMB_*"")' Error Message: 'syntax error' at position: '74'.
At line:4 char:12
I have tried using quotes around the variables like "$Filter", "$($Filter)", ' $Filter ' but alas. And I know it's not best practice to use variables in Filter but I can't think of any other way to accomplish this.
Any suggestions?

the error has the key to the answer. I'm sure I'll find this again and use it myself because I look this up every year or so...
Error parsing query: '(Enabled -eq $True)...'
In this case the filter needs a simple string 'True' which the variable $True does equal.
Two options will work, either
Enabled -eq 'True'
or
Enabled -eq '$True'
but
Enabled -eq $True
will not.
This should work
Replaced the braces with double quotes so inside them the variables still parse
Put single quotes around all strings and variables that resolve into strings
'$True'
'$Filter'
'SMB_*'
$FilterBase = "department"
$Filter = "IT"
$ADusers = Get-ADUser -ResultSetSize $null -SearchBase "OU=Users,DC=mydomain,DC=com" -Properties CN -Filter "(Enabled -eq '$True') -and ('$FilterBase' -like '$Filter') -and (CN -notlike 'SMB_*')" |
Select-Object distinguishedName |
Sort-Object distinguishedName
Important to note the above syntax highlighting will make the sample above look wrong because it misses the tokens like $FilterBase and $Filter when there are inside single quotes inside double quotes. Remember that single quotes are just apostrophes when inside double quotes, therefore the tokens should be colored differently and not look like strings.
> "('$FilterBase' -like '$Filter')"
('department' -like 'IT')
Paste a sample like above and see what it resolves to - best way to figure it out.

its just simply syntax error.
$enabled = 'Enabled'
$EnabledTrueOrFalse = $true
$SN = 'Surname'
$surname = "Doe"
$OU = "OU=Users,DC=mydomain,DC=com"
Get-ADuser -filter{$enabled -eq $EnabledTrueOrFalse -and $SN -eq $surname} -SearchBase $OU -Properties * | Select-Object distinguishedName | Sort-Object distinguishedName
read more about it here

Thanks for the tips guys. I couldn't get it to work with multiple filters so I moved some filters to the where clause.
My current (working) code is now:
$FilterBase = "department"
$Filter = "IT"
$ADusers = Get-ADUser -ResultSetSize $null -SearchBase "OU=Users,DC=mydomain,DC=com" -Properties * -Filter "$FilterBase -like `"$Filter`"" |
Where {$_.Enabled -eq $True -and $_.CN -notlike "SMB_*"} |
Select-Object distinguishedName |
Sort-Object distinguishedName

Related

I am trying to add members to a AD group based on a value in the "title" attribute

I am trying to add members to a AD group based on a value in the "title" attribute. I have about 30 different tiles i want to use. Is there a way to write the command witout 30 "OR" statements?
Thanks
Get-ADuser -filter {(title -eq "SECSCH") -or (title -eq "SEC12") -or (title -eq
"LTOSEC") -or (title -eq "LTO12")} | %{Add-ADGroupMember "SDK test print color"
$_.SamAccountName}
Also, for another group I would like All "custod" in title except at location "85c" and "42c" Below is where i am at.
Get-ADuser -filter {(title -eq "custod") -and (locationNumber -ne "85c") -or (title -eq
"custod") -and (locationNumber -ne "42c")} | %{Add-ADGroupMember "SDK test print
convert" $_.SamAccountName}
For your first issue you can create an array which contains your titles and browse it.
Example :
$Titles = "SECSCH","SEC12","LTOSEC","LTO12"
foreach($Title in $Titles){
Get-ADuser -filter {title -eq $Title} | %{Add-ADGroupMember "SDK test print color" $_.SamAccountName}
}
The -Members parameter can take an array of ADPrincipal objects so what you can do instead of using so many 'OR's in the Filter is using a Where-Object clause afterwards.
This will allow you to use operators like -contains or -match
$titles = "SECSCH","SEC12","LTOSEC","LTO12" # your 30+ titles here
$users = Get-ADUser -Filter * -Properties Title | Where-Object { $titles -contains $_.Title }
Add-ADGroupMember -Identity "SDK test print color" -Members $users
As for your second code change the Filter to below
$filter = "Title -eq 'custod' -and (locationNumber -ne '85c' -and locationNumber -ne '42c')"
$users = Get-ADUser -Filter $filter -Properties Title, locationNumber
Add-ADGroupMember -Identity "SDK test print convert" -Members $users
Note: the property locationNumber is AFAIK not a standard attribute in AD. Is that a custom property in your organization or do you perhaps mean something else like Division or EmployeeNumber ?
I provided a different answer to the first at the other place it was asked, using -Ldapfilter, but I feel #Onyx's answer here is probably more intuitive if you're not so comfortable with that. It's efficient in that you're only getting the objects you need, not grabbing every account out of AD and throwing away most of them.
To be honest, doing -Filter 'title -like "*"' would be better than nothing if you MUST use a Where clause.
For the second question (as described in the comments), the same applies with maybe building an LDAPfilter or #Onyx's method of creating an array for your customlocations and doing a Foreach through those.
Or again, at the very least, do -Filter '(employeeType -ne "student") -and (CustomLocation -like "*")' before the Where.

Why are variables not working with Get-Aduser in powershell?

Looking for a little explanation as to why this isn't working and what I might be doing wrong. Any Help would be great!
Expected Results :
BSMITH
Get-Aduser -filter {(givenname -eq "Bob") -and (surname -eq "Smith"))} | select-object SamAccountName
Result :
BSMITH
Works Fine. Good to go
Expected Result :
BSMITH
$textbox_FirstName = "Bob"
$textbox_LastName = "Smith"
Get-Aduser -filter {(givenname -eq "$textbox_FirstName.text") -and (surname -eq "$textbox_LastName.text")} | select-object SamAccountName
Result : (Blank Nothing)
I have tried givenname -eq "$textbox_FirstName.text" without quotes, without .text, with no quotes at all. Still no results :(
Both variables are of the type string they don't have a .text property, in addition adding double quotes to your variable would expand the variable and concatenate .text:
$textbox_FirstName = "Bob"
"$textbox_FirstName.Text" => Bob.Text
Any of these options should give you the output you expect:
Get-Aduser -Filter {GivenName -eq $textbox_FirstName -and Surname -eq $textbox_LastName}
Get-Aduser -Filter "GivenName -eq '$textbox_FirstName' -and Surname -eq '$textbox_LastName'"
Get-Aduser -LDAPFilter "(&(GivenName=$textbox_FirstName)(Surname=$textbox_LastName))"

Powershell Filter ADgroups the right way

Hi im trying to Filter AD-Groups by a string i defined in a variable:
$groupname="string"
Get-ADGroup -filter {GroupCategory -eq "security" -and Name -like ($sgroup_name+"*")}
How do i do this the right way?
String expansion doesn't work well with the -Filter parameter when passing it a script block - use a string filter instead:
$groupname = "string"
Get-ADGroup -Filter "GroupCategory -eq 'security' -and Name -like '${groupname}*'"

How do I input the SamAccountName from get-aduser?

I've been scrambling around looking for examples of how -inputobject is used, and I cannot seem to find any. I've never touched powershell before, but when I recently started this job, and was told that this is a script we used, I couldn't help but start messing around with it! Pipes are fascinating, but I can't seem to get past this latest issue I have.
I have this huge list of data that comes out when looking up users in AD, and I was wondering if I could also snag the SamAccountName from the same code block!
$User = Get-ADUser -Filter "EmployeeID -eq '$NameID' -or SamAccountName -eq '$NameID' -or DisplayName -eq '$NameID' -or UserPrincipalName -eq '$NameID'" -Properties
Enabled,LockedOut,Mail,Created,passwordlastset,Description,PasswordExpired,LastLogonDate,EmployeeID,DisplayName,"msRTCSIP-UserEnabled",
"msDS-UserPasswordExpiryTimeComputed","extensionAttribute7",telephonenumber,targetaddress,distinguishedName |
Select-Object #{Expression={$_.Name};Label='User Name';},
#{Expression={$_.UserPrincipalName};Label='Logon Name';},
#{Expression={$_.DisplayName};Label='Display Name';},
#{Expression={$_.Created};Label='Date Created';},
#{Expression={$_.SamAccountName};Label='SamAccountName';} -InputObject $Name,
Description,
Enabled,
#{Expression={$_.LockedOut};Label='Locked';},
#{Expression={$_.Mail}; Label='Email Address';},
#{Expression={$_.passwordlastset};Label='PW Last Reset';},
#{Expression={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")};Label='Password Expiry';},
#{Expression={$_.LastLogonDate};Label='Last Logon';},
#{Expression={$_.PasswordExpired};Label='Password Expired';},
#{Expression={$_.extensionAttribute7};Label='Contract Expires On';},
#{Expression={$_.EmployeeID};Label='Employee ID';},
#{Expression={$_."msRTCSIP-UserEnabled"};Label='Skype Enabled';},
#{Expression={$_.telephonenumber};Label='Phone Number';},
#{Expression={$_.targetaddress};Label='Email Forwarded To';},
#{Expression={$_.distinguishedName};Label='Distinguished Name';} | Select-Object SamAccountName -InputObject $Name | Format-list | Out-String
The above is what I use to get most of the interesting information to display nicely in the script, but going forward, I have to call it again with my limited knowledge to simply input a user's SamAccountName into a $Name var(To gather their managers and the like.) It looks something like this:
$Name = (getad-user -Filter "EmployeeID -eq '$NameID' -or SamAccountName -eq '$NameID' -or DisplayName -eq '$NameID' -or UserPrincipalName -eq '$NameID'").SamAccountName
I was just wondering if I could compress it all down into one Get-ADUser, and what the best practice that would be!
Thanks in advance all
You have a pretty convoluted way to get what you want. To minimize the number of Get-ADUser calls just use a variable. You already assign a variable in the beginning but for whatever reason you "trash" the object.
Within your code Select-Object SamAccountName -InputObject $Name doesn't seem to make sense. You never show what you assign to $Name and with what you do before it, it look strange. As such I removed it in the below code.
$user = Get-ADUser -Filter "EmployeeID -eq '$NameID' -or SamAccountName -eq '$NameID' -or DisplayName -eq '$NameID' -or UserPrincipalName -eq '$NameID'" -Properties
Enabled,LockedOut,Mail,Created,passwordlastset,Description,PasswordExpired,LastLogonDate,EmployeeID,DisplayName,"msRTCSIP-UserEnabled",
"msDS-UserPasswordExpiryTimeComputed","extensionAttribute7",telephonenumber,targetaddress,distinguishedName
$niceDisplay = $user |
Select-Object #{Expression={$_.Name};Label='User Name';},
#{Expression={$_.UserPrincipalName};Label='Logon Name';},
#{Expression={$_.DisplayName};Label='Display Name';},
#{Expression={$_.Created};Label='Date Created';},
#{Expression={$_.SamAccountName};Label='SamAccountName';} -InputObject $Name,
Description,
Enabled,
#{Expression={$_.LockedOut};Label='Locked';},
#{Expression={$_.Mail}; Label='Email Address';},
#{Expression={$_.passwordlastset};Label='PW Last Reset';},
#{Expression={[datetime]::FromFileTime($_."msDS-UserPasswordExpiryTimeComputed")};Label='Password Expiry';},
#{Expression={$_.LastLogonDate};Label='Last Logon';},
#{Expression={$_.PasswordExpired};Label='Password Expired';},
#{Expression={$_.extensionAttribute7};Label='Contract Expires On';},
#{Expression={$_.EmployeeID};Label='Employee ID';},
#{Expression={$_."msRTCSIP-UserEnabled"};Label='Skype Enabled';},
#{Expression={$_.telephonenumber};Label='Phone Number';},
#{Expression={$_.targetaddress};Label='Email Forwarded To';},
#{Expression={$_.distinguishedName};Label='Distinguished Name';} | Format-list | Out-String
$name = $User.SamAccountName
The best practise would be to turn any piece of code into a resuable function and then combine multiple functions into modules. Since you are beginning with powershell you could start with a simple function like this:
Function Get-ADUserInfo {
param([string]$NameID)
Get-ADUser -Filter "SamAccountName -eq '$NameID'" -Properties Enabled,LockedOut,Mail,Created,passwordlastset,Description,PasswordExpired,LastLogonDate,EmployeeID,DisplayName,Manager,"msRTCSIP-UserEnabled","msDS-UserPasswordExpiryTimeComputed","extensionAttribute7",telephonenumber,targetaddress,distinguishedName |
Select-Object #{Expression={$_.Name};Label='User Name'},
SamAccountName
}
# call the function with different nameid values like so
$Name = Get-ADUserInfo -NameID someuser1
$Name = Get-ADUserInfo -NameID someuser2
managers info
Get-ADuser -Identity $Name.Manager
Inputobject as the name suggests is used to pass an object as an input to a function. The property samaccountname is already present in the output so there is no need to do anything else other than to just specify it as shown in the code above.
also why choose to display "Name" as "user name"? wouldn't it be easier to format the headers in excel?
Here are some links that could be helpful:
functions
https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_functions?view=powershell-5.1

Filter displayname for parentheses error

My script won't send any information to my .txt file except the headers. I want to find any display names that may contain (), /, _ and so forth. Am I not able to use * symbol to mean that I want any display name filtered that contains a "(" anywhere in the name?
#Grab some AD attributes for the specific user ID
$userid = Get-ADUser -filter {displayname -like '*(' -or displayname -like '*_' -or displayname -like '*/'} -SearchBase "OU=Corporate,DC=we,DC=dirsrv,DC=com" -Properties name, displayname, description, manager
Trying to make it show up in my txt file but still new to powershell
#Grab some AD attributes for the specific user ID
$userids = Get-ADUser -Properties name, displayname, description, manager -filter {displayname -like '*(*' -or displayname -like '*_*' -or displayname -like '*/*'}
#THIS IS THE FOREACH I'M TRYING TO MAKE WORK
foreach ($userid in $userids)
{
$ID = Get-AdUser ($userid.displayname) -Properties displayname
$userid = $ID.displayname
}
foreach ($userid in $userids)
{
#manager missing
if ($userid.Manager -eq $null) {
$owner = "MISSING"
$ownerid = "MISSING"
$ownername = "MISSING"
} else {
#grab the manager's name, surname, and department
$owner = Get-ADUser ($userid.Manager) -Properties GivenName, Surname
$ownerid = $owner.Name
$ownername = $owner.Surname + "." + $owner.GivenName
}
}
What I'm making so far. Not having good luck tho lol
When you use the -like operator like you are, you are looking for strings that end in (,_, etc. Instead you need to surround the character you are looking for with wildcards:
{displayname -like '*(*' -or displayname -like '*_(*' -or displayname -like '*/*'}
Alternatively, for a more succinct query, you could use a regular expression:
{displayname -match '[\(\)\\_]'}
Note that since (,), and \ are special regular expression characters, you have to escape them with \.
WOW so if I input the code
Get-AdUser -Properties displayname -filter {displayname -like '*(*'} | Select displayname
Then it will give me all the listings I need of the displayname..... note to self!
Now to connect it with my code :P