I'm writing the below function in PowerShell and on execution an error is generated:
Get-ADUser : Error parsing query: 'EmployeeId -eq ' Error Message: 'syntax error' at position
: '12'.
At line:14 char:16
The function is below.
Function UpdateGroupMembership ($Members, $Group, $err) {
$Members | ForEach-Object {
$EID = $_.ID
$filter = [scriptblock]::Create("EmployeeId -eq $EID")
If ((Get-ADUser -Filter $filter) -like "")
{$err += "`n"+"User: "+$_."First Name"+" "+$_."Last Name"+" was not found in "+$_."District"+"<br>"}
Else
{$alias += Get-ADUser -Filter $filter}
}
$alias | ForEach-Object {
Add-ADGroupMember -Identity $Group -Members $_.SamAccountName
}
}
UpdateGroupMembership ($atl, $atlGroup, $atlerr)
Any advice would be highly appreciated! Just learning PowerShell...so please go easy on me!
Hard to say exactly how your code works since you don't show us any input but the following is the first major issue
Function Parameters
UpdateGroupMembership ($atl, $atlGroup, $atlerr)
Functions are not methods. When you call your function like that you are sending all arguments as an array to the parameter $Members
. The call has to look like this.
UpdateGroupMembership $atl, $atlGroup, $atlerr
That If
Block
((Get-ADUser -Filter $filter) -like "")
Not sure what you are trying to accomplish but -like
is usually used for string comparisons. Get-ADUser
would return an object array or $null
. Are you testing to see if it is empty or null?
If(Get-ADUser -Filter $filter){
}
The above would only be true if data was returned.
About $err
Are you trying to pass back information through that variable? Function be default pass information by value so you populating $err
would have no use outside the function.
I think some understanding of and functions and parameters, as well as error handling is in order here. You leave out some info so I am going to assume that $atl
is an array of objects, and that those objects each have (at least) the properties 'ID', 'First Name', and 'Last Name'. I assume that $atlGroup
is a string being the name of the group you want to add the users defined in those objects to. I also assume that $atlerr
is probably nothing, but that you want it to be populated with errors should they happen.
This really comes down to what Matt said in his answer. You are calling your function incorrectly. You are passing an array of objects as the first parameter (the 'Members' parameter). So here's the flow of the function as you have it...
$Members = @($atl, $atlGroup, $atlErr)
$Group = $null
$Err = $null
$Members
then gets passed to a ForEach loop, so it passes it's first item, which is an array of objects. It passes the entire array of $atl
on to the ForEach loop, so that loop now goes:
$EID = $atl.ID
Well, here we have a problem. $atl is an array, it doesn't have a property of 'ID' like all of the objects it contains. So it returns $null
, so...
$EID = $null
$filter = [scriptblock]::Create("EmployeeId -eq $EID")
Ok, so now $filter
is a scriptblock that looks like {EmployeeId -eq $null}
, which as a scriptblock goes is just fine. The problem is that when it is passed to the Get-ADUser cmdlet as the argument for the -Filter
parameter that parameter expects you to provide something in the format of:
Property Operator Value
You're looking at the EmployeeID property, and using the -eq
operator. That property is a string, so it expects you to provide a string to compare it to. You don't do that, so it throws an error.
Now you were hoping to catch those errors with your If/Else statement, but son you're simply re-creating the wheel with that. PowerShell already has Try/Catch blocks, and here's how they work. If you Try
an action that causes the script to stop, instead of stopping it moves to the Catch
scriptblock and executes that.
So to simplify what you were doing we could Try
to get the ad user, and pipe that directly into add-adprincipalgroupmembership
(this cmdlet accepts piped in user objects, and lets you define the name of the group to add them to as opposed to the cmdlet that you used which accepted piped group objects and lets you define what users to add to the group). Then in the Catch
block we output your error which should only happen when the process in the Try
block fails. Now you just assign the output of the function to whatever you want to store your errors in. It ends up looking something like this:
Function UpdateGroupMembership{
Param(
[object[]]$Members,
[String]$Group
)
ForEach($User in $Members){
Try{
Get-ADUser -Filter {EmployeeId -eq "$($User.ID)"} | Add-ADPrincipalGroupMembership -MemberOf $Group
}
Catch{
"User: {0} {1} was not found." -f $User."First Name",$User."Last Name"
}
}
}
$atlErr = UpdateGroupMembership $atl $atlGroup
Matt's answer really does answer your question, I just wanted to offer some guidance on how exactly the process was working and why you got the errors, and give some advise on how you could have better written the function so you have something to take with you going forward. I up-voted Matt's answer, it does answer the question, I just thought some additional context and help on fixing the issue would be in order to help out a newbie. We've all been there at some point.
Edit: I should also mention that I think creating a function to process groups of things like this is a mistake. You would be better served making it process one thing, and accepting piped input or putting it in a ForEach loop. But that's just my opinion, take it or leave it.
Function UpdateGroupMembership { Param( [object[]]$Members, [String]$Group ) ForEach($User in $Members){ Try{ $filter = $($User.ID) Get-ADUser -Filter {EmployeeId -eq $filter} | Add-ADPrincipalGroupMembership -MemberOf $Group } Catch{ "User: {0} {1} was not found in {2}." -f $User."First Name",$User."Last Name", $User.District } } } $atlErr = UpdateGroupMembership $atl $atlGroup
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.