PowerShell - AD users from Primary group plus either of two Secondary groups

1.3k views Asked by At

The script here:

https://gallery.technet.microsoft.com/scriptcenter/Powershell-Get-users-who-b0420fe1

will return results for users that exist in a primary group, plus either of two secondary groups (thanks to OP zperryz for the code). Below is my version of this script so far.

I'd like to add conditions for disabled users, and users that are in a specific "hold" OU. In another script, I've been able to do this like so (obviously a snippet, not the whole script):

| where {$_.Enabled -ne $False} `
| where {$_.DistinguishedName -notlike "*HOLD OU*"} `

I'm just not sure where to "inject" these into the script below. (A future modification would then return more information, like DisplayName, Enabled & DistinguishedName, instead of just the logon.)

If anyone has some advice, I'd greatly appreciate it! Here's the script as it stands today:

$ADgroup1 = "VPN Front Door"
$ADgroup2 = "VPN Full Access"
$ADgroup3 = "VPN Restricted Access"

get-adgroupmember $ADgroup1 `
  | ForEach-Object {if(((GET-ADUSER –Identity $_.SamAccountName –Properties MemberOf `
  | Select-Object MemberOf).MemberOf -replace '^CN=([^,]+).+$','$1') -eq "$ADgroup2" -or "$ADgroup3"){$_.SamAccountName `
  | Out-File -append -filepath C:\Users\3Jake\Desktop\VPN_Users.txt}}

Thank you!

FINAL VERSION, all tarted up with comments:

As-is, this is designed to run in the console, but it should be easy to update to spit out a file if needed.

#  Define Variables
$ADgroup1 = "VPN Front Door"
$ADgroup2 = "VPN Full Access"
$ADgroup3 = "VPN Restricted Access"
$vpnGroups = $ADgroup2, $ADgroup3

#  Collect users in $ADgroup1
#  Also pass user properties forward
$UsersFound = (
  Get-ADGroupMember $ADgroup1 |
  Get-ADUser -Properties MemberOf, Name, SamAccountName, Company |

  #  Ignore disabled users & those in the "On HOLD" OU
  Where {
    $_.Enabled -ne $False -and
    $_.DistinguishedName -notlike '*HOLD OU*'
  } |

  #  Compare users in $ADgroup1 to the ones in $ADgroup2 and $ADgroup3
  select Name, SamAccountName, Company,
         @{n='Groups';e={$_.MemberOf | Get-ADGroup | select -Expand Name}} |
  Where { $groups = @($_.Groups); $vpnGroups | Where { $groups -contains $_ } }
  )

  #  Display count
Write-Host "Total = " $UsersFound.Count

  #  Prompt to show user info
$YN = Read-Host "Show Users? (Y/N)"
if ($YN -eq 'Y')
{
$UsersFound |
select Name, SamAccountName, Company | 
Sort-Object name, company | 
Out-GridView
}
else {exit}
1

There are 1 answers

13
Ansgar Wiechers On BEST ANSWER

First, you should unravel that convoluted if statement. Something like this would be far more readable (and far more maintainable):

$vpnGroups = $ADgroup2, $ADgroup3

Get-ADGroupMember $ADgroup1 | ForEach-Object {
  Get-ADUser -Identity $_.SamAccountName -Properties MemberOf |
    select SamAccountName,
           @{n='Groups';e={$_.MemberOf | Get-ADGroup | select -Expand Name}} |
    ? { $groups = @($_.Groups); $vpnGroups | ? { $groups -contains $_ } } |
    select -Expand SamAccountName |
    Out-File -Append -Filepath 'C:\Users\3Jake\Desktop\VPN_Users.txt'
}

You don't even need the ForEach-Object loop, because Get-ADUser can read directly from the pipeline:

$vpnGroups = $ADgroup2, $ADgroup3

Get-ADGroupMember $ADgroup1 |
  Get-ADUser -Properties MemberOf |
  select SamAccountName,
         @{n='Groups';e={$_.MemberOf | Get-ADGroup | select -Expand Name}} |
  ? { $groups = @($_.Groups); $vpnGroups | ? { $groups -contains $_ } } |
  select -Expand SamAccountName |
  Out-File -Filepath 'C:\Users\3Jake\Desktop\VPN_Users.txt'

With that you can simply insert your additional filter(s) after the Get-ADUser:

Get-ADGroupMember $ADgroup1 |
  Get-ADUser -Properties MemberOf |
  ? {
    $_.Enabled -ne $False -and
    $_.DistinguishedName -notlike '*HOLD OU*'
  } |
  select SamAccountName,
         @{n='Groups';e={$_.MemberOf | Get-ADGroup | select -Expand Name}} |
  ? { $groups = @($_.Groups); $vpnGroups | ? { $groups -contains $_ } } |
  select -Expand SamAccountName |
  Out-File -Filepath 'C:\Users\3Jake\Desktop\VPN_Users.txt'