Search code examples
powershellactive-directoryactivedirectorymembership

Add-ADGroupMember can't find an object with identity


I am having trouble trying to solve a simple issue. My script works up to the point of adding the ADComputer to the AD Security Group. I have even tried adjusting the Add-ADGroupMember -Identity $groupName -Members $NameofRandomComputer -verbose but it doesn't work.

I know for a fact that the script does create the groups, it does read the OUs for the computer names and it does randomize successfully. I can even see it trying to add the computers but it fails to find the computer name, which makes no sense. What gives?

Error: Cannot find an object with identity: MissouriWorkstation001 under "DC=domain,DC=com"

$logfile = "results-$((Get-Date).ToString('MM-dd-yyyy_hhmmtt')).log"

Get-Date | Out-File $logfile

$groupnameprefix = 'Test_Create_AD_Group'
$organizationalunitpath = 'OU=Systems,OU=Corp,DC=domain,DC=com'
$grouporganizationalunitpath = 'OU=Groups,OU=Corp,DC=domain,DC=com'
$NumberofComputersPerGroup = '10'
# This is a list of computer names that will be used to generate group names
$Patch_Groups = @(
    '_Group_1',
    '_Group_2',
    '_Group_3',
    '_Group_4'
)

# Get all computers from the specified organizational unit
$computers = $organizationalunitpath |
    ForEach-Object { Get-ADComputer -Filter * -SearchBase $_ } |
    Select-Object -ExpandProperty Name -Verbose

# Create the new group
foreach ($Patch_Group in $Patch_Groups) {
    # Generate the group name by concatenating the prefix and the Patch Group name with spaces removed
    $groupname = $groupnameprefix + $Patch_Group.Replace(' ', '')
    # Create the group using the generated name and the specified organizational unit path
    New-ADGroup -Name $groupName -path $grouporganizationalunitpath -GroupScope Global -verbose

    # Randomly select the specified number of computers and add them to the group
    $randomComputers = $computers | Get-Random -Count $NumberofComputersPerGroup -Verbose
    foreach ($NameofRandomComputer in $randomComputers) {
        try {
            Add-ADGroupMember -Identity $groupName -Members $NameofRandomComputer -verbose
        }
        catch {
            $message = ' A problem occurred trying to add Member '
            $message | Out-File $logfile -Append
            Write-Warning $message
            Write-Warning $_.Exception.Message
            $_.Exception.Message | Out-File $logfile -Append
        }
    }
}

Solution

  • I think the issue stems from the line :

    # Get all computers from the specified organizational unit
    $computers = $organizationalunitpath | ForEach-Object {Get-ADComputer -Filter * -SearchBase $_} | Select -ExpandProperty Name -verbose
    

    however if you check the syntax for Add-ADGroupMember

    https://learn.microsoft.com/en-us/powershell/module/activedirectory/add-adgroupmember?view=windowsserver2022-ps

    you'll see that the expected values for -members are either Distinguished name, GUID (objectGUID), Security identifier (objectSid) or SAM account name (sAMAccountName), not Name.

    So because you specifically selected Name from Get-ADComputer rather than just getting the entire object, it's unable to find the Computer with the supplied value. I'd suggest changing the first line to :

    $computers = $organizationalunitpath | ForEach-Object {Get-ADComputer -Filter * -SearchBase $_}
    

    and then within the for loop leave the Get-ADGroupMember line as :

    try { Add-ADGroupMember -Identity $groupName -Members $NameofRandomComputer -verbose   }
    

    That way you simply pass the entire Computer object via $NameOfRandomComputer to Add-ADGroupMember rather than picking out a single property... in this case the wrong property. I'd argue the only time you need to specifically retrieve the individual property is if you're going to display/record that text somewhere, in which case you can use $NameofRandomComputer.name to reference that property, and the rest of the time let Powershell continue working with complete objects as designed.