Author Posts

October 6, 2017 at 3:02 pm

Hi guys,

I'm trying to modify a script I found here, to be based on the AD Groups a user account is a member of. This is what I've got, but I don't think it's returning the group membership correctly:

[CmdletBinding()]
param (
[string]$SiteCode,
[string]$SiteServer,
[string]$Domain
)

$ResourceName = $env:computername
$Prefix = "A."
$Suffix = ".i"

$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment

$PrimaryUsers = (Get-WmiObject -ComputerName $SiteServer -Class SMS_UserMachineRelationship -Namespace root\SMS\Site_$SiteCode -Filter "ResourceName='$ResourceName' and IsActive='1' and Types='1'").UniqueUserName.replace("$Domain\","")
    if ($PrimaryUsers -ne $null) {        
        foreach ($PrimaryUser in $PrimaryUsers){
           "primary user: " + $primaryuser
           $ADObjectDN = ([ADSISEARCHER]"samaccountname=$PrimaryUser").Findone().Properties.distinguishedname
           "ADObjectDN: " + $ADObjectDN
           $AllGroups =([ADSISEARCHER]"member:1.2.840.113556.1.4.1941:=$ADObjectDN").FindAll()
}
}
"AllGroups: " + $AllGroups

$DescList = $AllGroups.Path `
| Where { ($_ -replace '^LDAP://CN=([^,]+).+$','$1').StartsWith($Prefix) -and ($_ -replace '^LDAP://CN=([^,]+).+$','$1').EndsWith($Suffix) } `
| Foreach { ([ADSI]"$_").Description }
$AppCount = 1  
$DescList | Foreach { $tsenv.Value("COALESCEDAPPS" + ($AppCount++).ToString("00")) = "$_" }
"DescList: " + $DescList

Thanks,
Gregor

October 6, 2017 at 4:37 pm

Where is this script running from? If it's from the client you're trying to install, I doubt it will have access to your SCCM Server because the build process runs SYSTEM account and I don't think you'll have your SCCM infra that wide open.

October 6, 2017 at 8:19 pm

OK, let me try to explain what I'm seeing.

When I run the script, my line 27 is returning the following full output:

    AllGroups: LDAP://CN=Remote Desktop Users,CN=Builtin,DC=corp,DC=contoso,DC=com LDAP://CN=TestUserGroup,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com LDAP://CN=Marketing,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com LDAP://CN=Local-Client-RDPAccess,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com LDAP://CN=A.7Zip.I,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com LDAP://CN=A.BeyondCompare.I,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com

Line 27 in my script is the one I've underlined:

[CmdletBinding()]
param (
[string]$SiteCode,
[string]$SiteServer,
[string]$Domain
)

$ResourceName = $env:computername
$Prefix = "A."
$Suffix = ".i"

$tsenv = New-Object -COMObject Microsoft.SMS.TSEnvironment

$PrimaryUsers = (Get-WmiObject -ComputerName $SiteServer -Class SMS_UserMachineRelationship -Namespace root\SMS\Site_$SiteCode -Filter "ResourceName='$ResourceName' and IsActive='1' and Types='1'").UniqueUserName.replace("$Domain\","")
    if ($PrimaryUsers -ne $null) {        
        foreach ($PrimaryUser in $PrimaryUsers){
           "primary user: " + $primaryuser
           $ADObjectDN = ([ADSISEARCHER]"samaccountname=$PrimaryUser").Findone().Properties.distinguishedname
           "ADObjectDN: " + $ADObjectDN
           $AllGroups =([ADSISEARCHER]"member:1.2.840.113556.1.4.1941:=$ADObjectDN").FindAll()
}
}
    "AllGroups: " + $AllGroups.Path
$DescList = $AllGroups.Path ` | Where { ($_ -replace '^LDAP://CN=([^,]+).+$','$1').StartsWith($Prefix) -and ($_ -replace '^LDAP://CN=([^,]+).+$','$1').EndsWith($Suffix) } ` | Foreach { ([ADSI]"$_").Description } $AppCount = 1 $DescList | Foreach { $tsenv.Value("COALESCEDAPPS" + ($AppCount++).ToString("00")) = "$_" } "DescList: " + $DescList

What I want to do, is strip away all of the data in the output from $AllGroups.Path and only return the data between the 'LDAP://CN=A.' and the '.I,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com'

So in the output example I provided above, I need this line:

$DescList | Foreach { $tsenv.Value("COALESCEDAPPS" + ($AppCount++).ToString("00")) = "$_" } 

to return:

7Zip
BeyondCompare

Instead of the full output I showed above underlined.

I believe the issue lies with this (regex?) line in the code (which is line 30 at my end):

Where { ($_ -replace '^LDAP://CN=([^,]+).+$','$1').StartsWith($Prefix) -and ($_ -replace '^LDAP://CN=([^,]+).+$','$1').EndsWith($Suffix) }

If someone can help me reformat that expression, I think that will work for me.

Many thanks,
Greg.

October 6, 2017 at 8:21 pm

Just to be clear, the item I see as line 27 in my code, is showing as line 24 in the example I posted:

"AllGroups: " + $AllGroups.Path

Thanks,
Greg.

October 8, 2017 at 12:12 pm

SCCM notwithstanding...

That is a lot of code just to get ADGroups for a user. When you coudl just use the Get-ADPrincipalGroupMembership cmdlet

ForEach ($TargetUser in (Get-ADUser -Filter * -Properties *))
{
"`n" + "-"*12 + " Showing group membership for " + $TargetUser.SamAccountName
Get-ADPrincipalGroupMembership -Identity $TargetUser.SamAccountName | Select Name
}

October 8, 2017 at 2:39 pm

Your regex should be like this: "LDAP://CN=A\..+\.I,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com" (this is a great tool to designing and testing RegEx: http://www.ultrapico.com/expresso.htm)

then you can just use Where-Object:

$AllGroups = @(
  "LDAP://CN=Remote Desktop Users,CN=Builtin,DC=corp,DC=contoso,DC=com"
  "LDAP://CN=TestUserGroup,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com"
  "LDAP://CN=Marketing,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com"
  "LDAP://CN=Local-Client-RDPAccess,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com"
  "LDAP://CN=A.7Zip.I,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com"
  "LDAP://CN=A.BeyondCompare.I,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com"
)

$AllGroups | Where-Object {$_ -Match "LDAP://CN=A\..+\.I,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com"}

Or whatever method you prefer:

$AllGroups = @(
  "LDAP://CN=Remote Desktop Users,CN=Builtin,DC=corp,DC=contoso,DC=com"
  "LDAP://CN=TestUserGroup,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com"
  "LDAP://CN=Marketing,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com"
  "LDAP://CN=Local-Client-RDPAccess,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com"
  "LDAP://CN=A.7Zip.I,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com"
  "LDAP://CN=A.BeyondCompare.I,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com"
)

ForEach($Group In $AllGroups)
{
  If([System.Text.RegularExpressions.Regex]::IsMatch($Group,"LDAP://CN=A\..+\.I,OU=GROUPS,OU=CORP,DC=corp,DC=contoso,DC=com"))
  {
    $Group
  }
}

to process it. Not sure if this is what you were looking for