[PowerShell] User ophalen met al zijn (sub)groepen

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 13:48
Ik ben bezig met een Powershell script om het aantal ingelogde users te tellen in onze VDI omgeving.
Onze gebruikers komen uit meerdere landen, zijn verdeeld in meerdere groepen en subgroepen, maar loggen allemaal in via dezelfde webportal.

Op 1 van onze Desktop Delivery Controllers hebben we de Citrix Powershell SDK geinstalleerd om een lijst op te halen met de users die momenteel zijn ingelogd. Ik wil namelijk een script wat elk uur logt hoeveel users er per groep ingelogd zijn. Dit script word later gebruikt om een betalingsverdeling te maken.

Het probleem is alleen dat de users niet direct lid zijn van de groep waar ik op wil tellen.
Even het AD plaatje:

NL-VDI-Billing is de hoofdgroep
Daarin zitten meerdere subgroepen zoals NL-VDI-Bedrijf1, NL-VDI-Bedrijf2, NL-VDI-Bedrijf3.

Het belangrijkste probleem is dat de users niet direct lid zijn van de Bedrijf's groep, maar dat er daar nog een x aantal groepen tussen kan zitten. Dit aantal is niet bij elke user evenveel. Dit heeft te maken met de verdeling van groepen binnen een land.

Als Powershell script heb ik al het volgende:

PowerShell:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
clear
#Set-ExecutionPolicy RemoteSigned
# Author: Thijs Cramer
# Add-PSSnapin XdCommands

#Get Citrix Users
$ddcAddress = "localhost"
$xdsessions = get-xdsession -adminaddress $ddcAddress

#Output total sessioncount
Write-Host "Total Session Count: " $xdsessions.count

#Root domain
$ldapAddress = "LDAP://*****"
$username = "****"
$password = "****"

#LDAP/AD Connection
$ldapConnection = New-Object DirectoryServices.DirectoryEntry $ldapAddress, $username, $password

#Check Connection
if ($ldapConnection -ne $null)
{
    Write-Host "Connected to Code1"
}
else
{
    Write-Host "Connection to Code1 Failed"
    Exit
}
    

#Search Object
$ldapSearcher = New-Object DirectoryServices.DirectorySearcher $ldapConnection

#Set the billing group
$billingGroupName = "ggNLYEHVVDS1-VDI-Billing"
$ldapSearcher.Filter = "(cn=$billingGroupName)"
$billingGroup = $ldapSearcher.FindOne()

#Check Billingroup
if ($billinGroup -eq $null) 
{ 
    Write-Host "Billing group found." }
else 
{ 
    Write-Host "Billing group NOT found." 
    pause 10
    Exit 
}

#Get Subgroups
$billingMembers = $billingGroup.Properties["member"]

Write-Host "Billing members: " $billingMembers.Count

#Declare CompanyDictionary
$billingCounters = @{}

#Read users file
foreach ($session in $xdsessions)
{
    $fulluser = [regex]::Split( $session, " " )[0]
    $user = [regex]::Split($fulluser, "\\")[1]
    
    $ldapSearcher.PageSize = 1000
    $ldapSearcher.SearchScope = "Subtree"
    $ldapSearcher.Filter = "(cn=$user)"
    
    $result = $ldapSearcher.findall()

    if ($result -eq $null)
    {
        Write-Host "User " $user "not found"
    }
    else
    {
        $vdiGroupFound = $FALSE
        
        #Loop thru user groups
        $rawGroups = $result[0].Properties['memberof']
        ForEach ($rawgroup in $rawGroups)
        {            
            $group = [regex]::Split($rawgroup, ",")[0]
            
            #Loop thru BillingGroups
            ForEach ($rawBillingMember in $billingMembers)
            {
                $billingMember = [regex]::Split($rawBillingMember, ",")[0]
                
                #Check if group is billinggroup
                if ($group -eq $billingMember)
                {
                    $vdiGroupFound = $TRUE
                    
                    
                    #Add counter
                    if ($billingCounters.Contains($group))
                    {
                        $count = $billingCounters.Get_Item($group)
                        $count = $count + 1
                        $billingCounters.Set_Item($group, $count)
                    }
                    else
                    {
                        $billingCounters.Add($group, 1)
                    }
                }
            }
        }
        
        if ($vdiGroupFound -eq $FALSE)
        {
            #Write-Host "Error with user: " $user
        }
    }
}

foreach ($company in $billingCounters.Keys)
{
    Write-Host $company ": " $billingCounters[$company]
}


Resultaat:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
Total Session Count:  444
Connected to Code1
Billing group found.
Billing members:  32
CN=ggNLYEHVVDS1-VDI-Users-Oxyme :  2
CN=ggNLYEHVVDS1-VDI-Users-ServiceAccounts :  2
CN=ggNLYEHVVDS1-VDI-Users-20100409-LI-CEVA :  1
CN=ggNLYEHVVDS1-VDI-Users-20100201-CL-DHLDreux :  5
CN=ggNLYEHVVDS1-VDI-Users-CIAN :  1
CN=ggNLYEHVVDS1-VDI-Users-20101028-LI-Legendre Project :  1
CN=ggNLYEHVVDS1-VDI-Users-20100201-CF-PartnersAIS :  1
CN=ggNLYEHVVDS1-VDI-Users-20100429-ITI-TSystems :  4
CN=ggNLYEHVVDS1-VDI-Users-20100201-CF-CustomerValueGroup :  1
CN=ggNLYEHVVDS1-VDI-Evaluation-20100201-HE-CustomerServiceGSS :  1
CN=ggNLYEHVVDS1-VDI-Evaluation-20101015-HE-CONTACTEL :  3
CN=ggNLYEHVVDS1-VDI-Users-20100201-HE-ITSecurityIsrael :  1
CN=ggNLYEHVVDS1-VDI-Users-IPS :  10
CN=ggNLYEHVVDS1-VDI-Users-20100201-ITA-Satyam :  16


Zoals je ziet gaat het ophalen van alle data al prima. Het querien van LDAP werkt ook prima.

Het belangrijkste probleem wat ik nu heb, is dat ik niet alle subgroepen direct zie van de gebruiker.
Nou snap ik, dat ik niet per resultaat wat ik krijg in de ['memberof'] lijst moet gaan kijken of het een groep is, en die weer gaan ophalen. Want dan word het logaritmisch traag.

Het (gemiddelde) aantal gelijktijdig ingelogde gebruikers ligt tussen de 600 en 700. Als ik van elke gebruiker AL zijn groepen recursief moet gaan ophalen, word het een nogal zwaar script.

Weet iemand een manier om zonder al te veel omslachtigheden alle groepen op te halen waar een gebruiker lid van is?

Even niets...


Acties:
  • 0 Henk 'm!

  • Question Mark
  • Registratie: Mei 2003
  • Laatst online: 13:11

Question Mark

Moderator SSC/WOS

F7 - Nee - Ja

Is onderstaand niet veel handiger?

Logging User Access in a XenDesktop Environment

MCSE NT4/2K/2K3, MCTS, MCITP, CCA, CCEA, CCEE, CCIA, CCNA, CCDA, CCNP, CCDP, VCP, CEH + zwemdiploma A & B


Acties:
  • 0 Henk 'm!

  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 13:48
Nee helaas, dit doet namelijk niet wat wij willen.
Wij willen graag per gebruikersgroep een overzicht. Met de informatie die die tool opslaat moeten we nog steeds in de Active Directory duiken om te kijken in welke groep de desbetreffende persoon zit.

Even niets...


Acties:
  • 0 Henk 'm!

  • Question Mark
  • Registratie: Mei 2003
  • Laatst online: 13:11

Question Mark

Moderator SSC/WOS

F7 - Nee - Ja

FireDrunk schreef op maandag 06 december 2010 @ 11:03:
Met de informatie die die tool opslaat moeten we nog steeds in de Active Directory duiken om te kijken in welke groep de desbetreffende persoon zit.
Klopt, maar dat zou je dan wellicht 's nachts kunnen (laten) uitvoeren. Dat wil zeggen, je kunt uit de database exact halen welke users, op welke dag, hoelang verbonden waren. Dan zou je 's nachts een batch kunnen draaien die deze info en de billinggroepen verzameld en output maakt naar één rapport.

Dat gaat aardig wat load schelen op je vdi-omgeving.

MCSE NT4/2K/2K3, MCTS, MCITP, CCA, CCEA, CCEE, CCIA, CCNA, CCDA, CCNP, CCDP, VCP, CEH + zwemdiploma A & B


Acties:
  • 0 Henk 'm!

  • FireDrunk
  • Registratie: November 2002
  • Laatst online: 13:48
De load van het script maakt me niet zo heel veel uit, vooral de tijd dat het loopt, en de load die het genereerd op de Domain Controllers. Want het script zelf word niet op de Clients uitgevoerd, maar op de Provisioning server...

Even niets...