Reputation: 3
So Here is my code. Essentially this code will be used by a domain admin to run on our terminal server. I lists all of the currently logged in users, and check their individual group membership and then counts members. Easy Peasy.
99% of this works as expected but I am not a code guru by far. I'm having problems getting a proper list of names from Line 4 which uses quser. If I switch to using Line 5 as text the code works as expected.
I can't for the life of me get the output from line 4 into a format I can use in the rest of the code.
Import-Module ActiveDirectory
$calgary = 0
$edmonton = 0
$users = (quser) -replace '\s{2,}', ',' | ConvertFrom-Csv | Select-Object USERNAME
$usersold = "Thomas", "Scott", "jeremy"
$groups = 'Domain Admins'
foreach ($user in $users) {
foreach ($group in $groups) {
$members = Get-ADGroupMember -Identity $group -Recursive | Select -ExpandProperty SamAccountName
If ($members -contains $user) {
$calgary = $calgary + 1
Write-Host "$user is a member of $group"
Write-Host "$group has $calgary logged in users"
} Else {
Write-Host "$user is not a member of $group"
}
}
}
Upvotes: 0
Views: 422
Reputation: 36322
I think a better way to get a list of logged on users is to use Get-CimInstance
to gather the sessions, filter for LogonType 3 (remote logon), and then get the users associated with those logon IDs. Then, since it looks like you want to be able to check multiple groups, I would get the members for each group, and just note if each user is a member of each group. At the end I would output a table of all sessions, including which groups each user is a member of, and how many users each group has logged on.
$LoggedOn = gcim Win32_LoggedOnUser
$GroupNames = 'pkiadmins'
$Groups = @{}
$GroupNames | ForEach-Object { $Groups.Add($_,(Get-ADGroupMember -Identity $_ -Recursive | Select -Expand SamAccountName)) }
$Sessions = gcim Win32_LogonSession -PipelineVariable Session|?{$_.LogonType -eq 3}|%{
$SesUser = $LoggedOn|?{$_.Dependent.LogonId -eq $Session.LogonId}
$SessionOut = [PSCustomObject]@{
Domain = $SesUser.Antecedent.Domain
User = $SesUser.Antecedent.Name
}
ForEach($Group in $GroupNames){
Add-Member -InputObject $SessionOut -NotePropertyName $Group -NotePropertyValue ($SessionOut.User -in $Groups[$Group])
}
If($SessionOut.User -notmatch '\$$'){$SessionOut} #skip computer accounts
}
$Sessions|FT -Auto
ForEach($Group in $GroupNames){
"Group '{0}' has {1} logged in user(s)" -f $Group,([array]($Sessions|?{$_.$Group})).Count
}
Upvotes: 0
Reputation: 5452
$users.GetType()
returns an Array of elements of type PSCustomObject
, so this is an object with properties, rather than just a list of strings.
When you do ($user in $users)
then each $user
is an object with the USERNAME
property. So you have two options:
When you need the username inside the loop, use $user.USERNAME
Replace line 4 with:
$users = $((quser) -replace '\s{2,}', ',' | ConvertFrom-Csv | Select-Object USERNAME).USERNAME
Upvotes: 1
Reputation: 21
On line 4, try using:
$users = ((quser) -replace '\s{2,}', ',' | ConvertFrom-Csv | Select-Object USERNAME).username
Upvotes: 1