RayDar
RayDar

Reputation: 3

Check a PowerShell script line against a txt file containing computer names

I need to check the following code against a txt file with computer names, so if the computer name exist in the file, it'll be copied to the shadow group.

$OU="OU=Computers,DC=mylab,DC=local"
$ShadowGroup="CN=SelectPCs,OU=Groups,DC=mylab,DC=local"
Get-ADComputer –SearchBase $OU –SearchScope OneLevel –LDAPFilter "(!memberOf=$ShadowGroup)" | ForEach-Object {Add-ADPrincipalGroupMembership –Identity $_ –MemberOf $ShadowGroup}

I tried a pipe and 'Where', but couldn't make it work:

$OU="OU=Computers,DC=mylab,DC=local"
$ShadowGroup="CN=SelectPCs,OU=Groups,DC=mylab,DC=local"
$PCList = c:\scripts\computernames.txt
Get-ADComputer –SearchBase $OU –SearchScope OneLevel –LDAPFilter "(!memberOf=$ShadowGroup)" **| Where-Object {$_.Name –Match $PCList}** |ForEach-Object {Add-ADPrincipalGroupMembership –Identity $_ –MemberOf $ShadowGroup}

Upvotes: 0

Views: 837

Answers (2)

mklement0
mklement0

Reputation: 437998

I suggest you rewrite your command as follows:

Get-Content c:\scripts\computernames.txt | Get-ADComputer -Property MemberOf | 
   Where-Object { $_.DistinguishedName -match ('^[^,]+,' + $OU + '$') -and 
                  $_.MemberOf -notcontains $ShadowGroup } |         
    ForEach-Object {Add-ADPrincipalGroupMembership –Identity $_ –MemberOf $ShadowGroup}
  • Start with your list of computer names, which Get-ADComputer should be able to identify directly, via the pipeline, implicitly bound to the -Identity parameter.

  • -Property MemberOf ensures that the non-default property MemberOf is included in each return object.

  • The Where-Object call then checks whether the computer is in the right OU ($_.DistinguishedName -match ('^[^,]+,' + $OU + '$') - perhaps you don't even need this, given that you've identified the computers by name[1] ) and whether it's not already a member of $ShadowGroup ($_.MemberOf -notcontains $ShadowGroup).

  • Finally, the Foreach-Object calls adds the matching computers to group $ShadowGroup.


[1] Computers are assumed to have unique names, so using Get-ADComputer with a computer name (which implies parameter -Identity) matches a computer in any OU, so there's generally no need to constrain the matches by OU.
That said, the regex used above is explicitly designed to only match computers located directly in $OU.
If you wanted to match computers in the specified OU and any descendent OU, use $_.DistinguishedName -match (',' + $OU + '$')

Upvotes: 1

Jon Dechiro
Jon Dechiro

Reputation: 1446

It looks like you are trying to match a name with the array of computer names. That would be like asking does 'computer1' contain 'computer1, computer2, computer3' which would be false. But asking if 'computer1, computer2, computer3' contains the string 'computer1' would be true.

In other words, instead of Where-Object {$_.Name -match $PCList} you could do Where-Object {$PCList -match $_.Name}.

Keep in mind though that this would also do partial matches. For example computer1 would match for computer1 and also computer11, computer12, etc.

The better approach would be to loop through the list of computernames in the text file to perform your check and action (as mklement0's answer demonstrates).

Upvotes: 1

Related Questions