I'm working on a script that will build a new group if it doesn't exist. I'm using Get-ADGroup to make sure the group doesn't exist using the following command:
$group = get-adgroup $groupName -ErrorAction:SilentlyContinue -WarningAction:SilentlyContinue
But when I do I get the following error (I removed any domain specific data from the error):
Get-ADGroup : Cannot find an object with identity: '*group name*' under: '*domain*'.
At U:\Scripts\Windows\Create-FolderAccessGroup.ps1:23 char:24
+ $group = get-adgroup <<<< $groupName -ErrorAction:SilentlyContinue -WarningAction:SilentlyContinue
+ CategoryInfo : ObjectNotFound: (y:ADGroup) [Get-ADGroup], ADIdentityNot
FoundException
+ FullyQualifiedErrorId : Cannot find an object with identity: '' under: ''.,Microsoft.ActiveDirectory.Management.Commands.GetADGroup
I assumed setting ErrorAction and WarningAction to SilentlyContinue would keep this error from being displayed but it hasn't.
I find that this works best:
$Group = Get-ADGroup -Filter {SamAccountName -eq $GroupName}
If the filter returns no results, then $Group is simply set to $null and no error message is generated. Also, since a SAM account name must be unique in Active Directory, there is no risk of $Group being set to an array of more than one object.
I find that using -Filter to get the group rather than -Identity works really well when checking for the existence of groups (or users) in If statements. For example:
If (Get-ADGroup -Filter {SamAccountName -eq $GroupName})
{
Add-ADGroupMember -Identity $GroupName -Members $ListOfUserSamAccountNames
}
Else
{
Write-Warning "Users could not be added to $GroupName because $GroupName
does not exist in Active Directory."
}
I find that is a lot easier to deal with logically (if the group exists, add the users; if not, display a message) than mjolinor's suggestion of try/catch with using the Get-ADGroup cmdlet with the -Identity parameter. Consider the try/catch method of doing the same as above, using the -Identity parameter:
Try
{
Get-ADGroup -Identity $GroupName
Add-ADGroupMember -Identity $GroupName -Members $ListOfUserSamAccountNames
}
Catch
{
Write-Warning "Users could not be added to $GroupName because $GroupName
does not exist in Active Directory."
}
You see if any of the commands in the try block throws a terminating error. If one does, it means the group doesn't exist and will move on and process the command(s) in the catch block. It will work, but I don't think try/catch here flows as well, logically, in comparison to if/else.
Don't get me wrong, mjolinor is a PowerShell genius. It's just that in this case I don't think his solution is the best one.
try {get-adgroup <groupname>}
catch {
<make new group>
}
#mjolinor gives the good answer, but I think some explanation can also help.
Windows PowerShell provides two mechanisms for reporting errors: one mechanism for terminating errors and another mechanism for non-terminating errors.
Internal CmdLets code can call a ThrowTerminatingError method when an error occurs that does not or should not allow the cmdlet to continue to process its input objects. The script writter can them use exception to catch these error.
Internal CmdLets code can call a WriteError method to report non-terminating errors when the cmdlet can continue processing the input objects. The script writer can then use -ErrorAction option to hide the messages.
I realize this is old, but I also had this problem and solved it like this:
If (Get-ADObject -Filter {objectClass -eq "Group -and samAccountName -eq "groupname"}) { //do stuff// }
Related
Following situation: You have ForeignSecurityPrincipals in your AD Groups. But Remove-ADGroupMember cannot remove them, since it does not support removing "ForeignSecurityPrincipal". Using the DOMAIN\SamAccountName Method is not available as well, since that old domain does not exist any more. On top you are not allowed to use external modules since that company does not want external modules.
I needed this functionality today for a mass-cleanup job, as written without needing extra modules, and without having the old AD available since it was already killed. Found nothing, so I developed this solution and share it.
You have to get the DOMAINSID first, which should be simple. My example uses -Server since the "adminforest" is not the same as the forest of the groups to be modified. It searches all groups from the given OU, selects all groups with members matching the DOMAINSID, and then removes each member matching the DOMAINSID from those groups.
Don't forget to set $WhatIf=$false, else it runs in "we test only" mode.
$Groups = Get-ADGroup -Server other.domain.local -Filter * -SearchBase "OU=Groups,OU=SubOU,OU=Subsidary,DC=OTHER,DC=DOMAIN,DC=LOCAL" -Properties *
$GroupsWithForeignMembers = #($Groups.Where({$_.member -like "*S-1-5-21-2631234548-991234592-3812345124*"}))
$WhatIf=$true
foreach ($Group in $GroupsWithForeignMembers) {
$MemberForeign= #((Get-ADGroup -Server bk.bwl.net -Identity $Group.SamAccountName -Properties member).member.Where({$_ -like "*S-1-5-21-2631234548-991234592-3812345124*"}))
foreach ($Member in $MemberForeign) {
"Removing $Member from $($Group.SamAccountName)" | Tee-Object -Append "GROUPS-cleanup.log"
Set-ADObject -Server other.domain.local -Identity $Group -Remove #{member=$Member} -Verbose -WhatIf:$WhatIf
}
}
When I'm holding a variable and passing it to a commandlet I am getting inconsistent results. Maybe I am just plain using variables in powershell incorrectly? If there were a way to see exactly the line of code my Visual Studio Code was sending at runtime that would be helpful.
My code returns a $null object when executing those first two filters. I've confirmed that $username actually does contain the string "userLoginName" but it doesn't seem to pass to the Get-ADUser commandlet correctly.
PS C:\> $username = "userLoginName"
PS C:\> Get-ADUser -Filter {SAMAccountName -eq "$($username)"}
PS C:\> Get-ADUser -Filter {SAMAccountName -eq "$username"}
PS C:\> Get-ADUser -Filter {SAMAccountName -eq "userLoginName"}
Why is it that only the third -filter command runs successfully? The first two return $null, not a UserNotFound kind of exception or anything. What am I doing wrong here? Do I just have no concept of how to use variables in powershell (yes)? Sorry for being a noob, but thank you for your time.
See this post. The AD calls' -Filter parameter doesn't like taking in string variables as part of a ScriptBlock for some reason (you can read the post more for more info). But passing -Filter as a String should work.
Get-ADUser -Filter "SAMAccountName -eq '$username'"
Alternatively, if you're just wanting to lookup an AD user with the SAMAccountName, you can just do Get-ADUser -Identity $username. That's probably easier. The benefit (or sometimes the consequence) of using the -Filter parameter is that, like you discovered, it won't throw an exception if a user is not found. If you use the -Identity parameter, it WILL throw an exception if a user is not found.
I am trying to utilize Powershell to get the computer name it’s currently running on and then add that computer to a security group and I’m stuck.
Forcing myself to learn Powershell better and got this from a co-worker but not sure how to edit it for my needs. This script will be used to run after a certain package has been installed to grant access. Here is what I have so far:
param(
[string[]]$mname,
[string[]]$gname
)
foreach($m in $mname.split(','))
{
$mobj = get-adcomputer $m
foreach($g in $gname.split(','))
{
Add-ADGroupMember "GROUP_NAME" -Members $mobj
}
}
ERROR:
You cannot call a method on a null-valued expression.
At C:\Scripts\Add-MachineToCollectionGroup.ps1:6 char:15
+ foreach($m in $mname.split(','))
Just add your groupname at the top, also if you aren't running Powershell 5 you may need to change Add-ADGroupMember $groupobj -Members $computerobj to be Add-ADGroupMember $groupobj -Member $computerobj I think they changed that.
Also add -whatif to the end of the last line to test it (It'll tell you what it would have done without the whatif).
Oh also you will need to run this from an account that has AD access to add the machine to the group and the computer must have the activedirectory module installed.
$Groupname = "ENTER GROUP NAME HERE"
$computerobj = Get-ADComputer $env:COMPUTERNAME
$groupobj = Get-ADGroup $Groupname
Add-ADGroupMember $groupobj -Members $computerobj -WhatIf
I'm building a script to automate AD deployments for customers. We have a prepared list of users and groups in CSV files. The groups are organized in a file with the following format. Keep in mind that I'm using the same CSV file to create the AD groups (which happens in a previous step).
Name,Description,Members
GroupName,GroupDescription,"user1,user2,user3"
The code I'm using to add the users to the groups is below:
$groups = Import-CSV -Path $groupCSVPath
$groups | % { Add-ADGroupMember -Identity $_.Name -Members $_.Members }
This results in an error: Get-ADUser : Cannot find an object with identity: 'user1,user2,user3'.
If I attempt the following, it works:
Add-ADGroupMember -Identity "GroupName" -Members user1,user2,user3
The error appears to reference the Get-ADUser command, which does not accept arrays as inputs. However, the Add-ADGroupMember command does. Why am I getting the Get-ADUser error when using the Add-ADGroupMember command and how can I get it to accept an array of values for the AD Username?
Tricky one. The problem turned out to be that the $_.members parameter is being passed to the Add-ADGroupMember cmdlet as a single string rather than an array of separate values, because of the way Import-CSV works. Get-Help Add-ADGroupMember shows that the members parameter expects an array, not a string.
This should work, I've tested it:
$groups | % { Add-ADGroupMember -Identity $_.Name -Members $_.members.split(',') }
I'm working on a simple script that should add a contact to a distribution group depending of the week of the year. My bug is that my script can add objectclass:User but when I try with a contact GUID the script give me that error:
Add-ADGroupMember : Cannot find an object with identity: '123dd2345-12f0-542b-c3e6-5774bac431aa' under: 'DC=MY,DC=DOMAIN'.
At line:1 char:25
+ get-adgroup $ADGroup | Add-ADGroupMember -members $zvar.ObjectGUID
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (123dd2345-12f0-542b-c3e6-5774bac431aa:ADPrincipal) [Add-ADGroupMember], ADIdentityNotFoundException
+ FullyQualifiedErrorId : SetADGroupMember.ValidateMembersParameter,Microsoft.ActiveDirectory.Management.Commands.AddADGroupMember
The part of the script that I use is looking like that:
$zvar = get-adobject -filter {displayname -eq "Valentine, John (CELL)" } #this is my contact displayname that is put in a variable with necessary properties
get-adgroup "Dist - Support group" | Add-ADGroupMember -members $zvar.ObjectGUID #this is my Distribution group, whatever the properties I put to my contact object I get the error message above i.e. $zvar.name, $zvar.distinguishedname, etc
If I replace the value "Valentine, John (CELL)" by the ObjectClass:user "Valentine,John" the command will succeed without error.
Am I using the command correctly ?
I could probably use the Quest-module but I'd like to avoid using a third party.
Thanks in advance
Came across this problem as well today: You cannot add an AD Object of class "objectClass=contact" to a group using the Add-ADGroupMember cmdlet.
However, the members of a an AD group are simply stored in the multivalued property "member", and every *-ADObject and related command supports the -Add, -Replace, -Clear and -Replace parameters.
Thus, this works to add a single user:
Set-ADGroup -Identity "GroupName" -Add #{'member'=$contact.DistinguishedName};
And this removes the user:
Set-ADGroup -Identity "GroupName" -Remove #{'member'=$contact.DistinguishedName};
As #mjolinor comment, the exchange cmdlet would be the solution, but I don't have what it need to use it. So I will use Quest-cmdlet. With that it's working.