Scott Ferguson
Scott Ferguson

Reputation: 3

PowerShell ConvertFrom-Csv

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

Answers (3)

TheMadTechnician
TheMadTechnician

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

mjsqu
mjsqu

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:

Access the USERNAME in the loop

When you need the username inside the loop, use $user.USERNAME

Get a list of strings rather than objects

Replace line 4 with:

$users = $((quser) -replace '\s{2,}', ',' | ConvertFrom-Csv | Select-Object USERNAME).USERNAME

Upvotes: 1

brkscllns
brkscllns

Reputation: 21

On line 4, try using:

$users = ((quser) -replace '\s{2,}', ',' | ConvertFrom-Csv | Select-Object USERNAME).username

Upvotes: 1

Related Questions