2

I have a script that builds a PSCustomObject with properties based on output from a DOS command. The array builds correctly and I can inspect it by dumping it to the screen output. However, when I try to get a list of elements by property name, it gives me zero output. Example below:

$computers = @("computer1","computer2","computer3")
ForEach ($computer in $computers) {
    quser /server:$computer | Select-Object -Skip 1 | ForEach-Object {
    $CurrentLine = $_.Trim() -Replace '\s+',' ' -Split '\s'
    $HashProps = @{
        UserName = $CurrentLine[0]
        ComputerName = $computer
        timestamp = $timestamp
    }
$tempUserList = @(New-Object -TypeName PSCustomObject -Property $HashProps | Select-Object -Property UserName,Id,State,IdleTime,LogonTime,ComputerName | % { $_ -replace '","', ','} | % { $_ -replace "^`"",''} | % { $_ -replace "`"$",''})
$userList += $tempUserList
}
$serverCount = $userList | % { $_.UserName | where ($_.ComputerName -eq $computer) }
Write-Host "Server $computer has" $serverCount.Count "Users Logged On."

}

The Output from this code is:

Server computer1 has 0 Users Logged On.
Server computer2 has 0 Users Logged On.
Server computer3 has 0 Users Logged On.

If I add a $userList to the script after the loop has completed, I get the following output:

@{UserName=user1; Id=2; State=Active; IdleTime=0; LogonTime=7/28/2016 7:43 AM; ComputerName=computer1}
@{UserName=user2; Id=3; State=Active; IdleTime=1:13; LogonTime=7/28/2016 11:31 AM; ComputerName=computer2}
@{UserName=user3; Id=4; State=Active; IdleTime=24692+13:29; LogonTime=7/28/2016 11:15 AM; ComputerName=computer3}

How can I get the script to recognize the ComputerName property and give a correct count of logons?

McKenning
  • 230
  • 1
  • 3
  • 10

1 Answers1

3

I would do it more like this (presuming I've read your logic correctly):

foreach ($computer in $computers) {
  $list = @()
  $quser = quser /server:$computer | Select-Object -Skip 1
  foreach ($q in $quser) {

    $item = New-Object -TypeName PSObject
    $item | Add-Member -MemberType NoteProperty -Name ComputerName -Value $computer
    $item | Add-Member -MemberType NoteProperty -Name UserName -Value $q.Trim().Replace('\s+',' ').Split(' ')[0]
    $item | Add-Member -MemberType NoteProperty -Name TimeStamp -Value (Get-Date)

    $list += $item
  }
  $count = ($list | Where-Object -FilterScript { $_.ComputerName -eq $computer }).Count
  Write-Output "Server $computer has $count users logged on"
}
DarkMoon
  • 1,039
  • 15
  • 30
  • This worked, however there is a typo in the code. The $count = line has an extra ')'. It should be: $count = ($list | Where-Object -FilterScript { $_.ComputerName -eq $computer }).Count – McKenning Sep 08 '16 at 14:12
  • Sorry, answer has been updated. Glad it helped. – DarkMoon Sep 08 '16 at 20:16
  • Hmm, re-reading that code now, it has a lot of overhead that's not needed in and of itself. All you need is the number of lines returned from quser (other than the header) for each computer in the list, right? So take out $list = @(), the whole foreach section, and the $count after it, and then replace "...has $count users..." with "...has $($q.Count) users...", and that should do it. You're not actually using the custom object, so why bother to create and populate it? – DarkMoon Sep 09 '16 at 05:59
  • In the context of the original question, I understand why the custom object wouldn't be necessary, but this is actually a transcribed code snippet. In the actual script, the object is used to report the logged on users and how long they've been connected. – McKenning Sep 09 '16 at 13:54
  • 1
    Yeah, OK, had a feeling that might be the case, which is why I didn't edit the answer directly. ;-) – DarkMoon Sep 09 '16 at 22:30