0

I am in the process of writing a script that takes the output from the sysinternals command: psloggedon.exe and outputs the computer name and what users are signed in.

I currently have the script producing the following possibilities depending upon what output is given by each computer when queried.

DOMAIN\computer-name01
DOMAIN\user-name

DOMAIN\computer-name02
DOMAIN\user-name
DOMAIN\user-name

DOMAIN\computer-name03
Error connecting

DOMAIN\computer-name04
No user is signed in

Each chunk of data will always have a computer name followed by either the list of users signed in, an error, or a message saying that no one is signed in.

I would like to assign the data to a custom object so that I can output it to a CSV. As I understand this is the best way to generate a proper CSV.

Where I am getting confused with the custom object is how do I deal with a situation where the incoming data is changing in amount? So for instance, I may have a computer that has 4 people signed into it. I also don't understand how I can create the column headers. Most of the examples I have found the data that is being fed into the custom object already has it's own column headers or properties.

I am looking to output the data so that it looks something like below

DOMAIN\computer-name, DOMAIN\user-name, DOMAIN\user-name
DOMAIN\computer-name, Error Message
DOMAIN\computer-name, No one signed in

The column header over the computer name would be "Computer Name" and the header of the signed in user/error message/no one signed in would be "Status".

Microsoft has this pretty well documented it seems: https://technet.microsoft.com/en-us/library/ff730946.aspx

In this example I don't understand where "$objBatter.Name" comes from. How does the script know the property or column header from the input? Does the data being inputted already have that defined?

Sorry for being so confusing, I am having a hard time wrapping my brain around it so explaining it is hard.

Here is what I have tried. But basically the custom object just outputs the properties/column headers (sorry I am not really sure what this is called). The rest is blank.

$Computers = @(
,"computer-name01"
)

Foreach ( $Computer in $Computers)
{
    $loggedon = $null
    If ( Test-Connection -ComputerName $Computer -Quiet -Count 1 )
    {
        $loggedon = (PsLoggedon.exe -x -l \\$Computer | Where-Object { ($_ -like "*DOMAIN\*" -or $_ -like "*No one*" -or $_ -like "*$Computer\*" -or $_ -like "*Error opening*")}).trim()

        if ( $loggedon -like "*Error Opening*" )
        {
            Write-Output "Error occurred while attempting to connect. This computer is online."
            Continue
        } else {

            $loggedon = ,"$Computer" + $loggedon

            $colComputerAndUser = @()

            foreach ($item in $loggedon)
            {
                $ObjComputerAndUser = New-Object System.Object
                $ObjComputerAndUser | Add-Member -Type NoteProperty -Name Computer -Value $item.Computer
                $ObjComputerAndUser | Add-Member -Type NoteProperty -Name User -Value $item.User
                $colComputerAndUser += $ObjComputerAndUser
            }

            $colComputerAndUser
        }
    }
 }

UPDATE 01

I attempted to use the code you provided. It worked as intended, but I get a strange behavior if a computer returns more than just one person signed in. Inside the custom object, the computer will be displayed multiple times.

$Computers = @(
,"computer01"
,"computer02"
)

$colComputerAndUser = @()

Foreach ( $Computer in $Computers)
{
    $loggedon = $null
    If ( Test-Connection -ComputerName $Computer -Quiet -Count 1 )
    {
        $loggedon = (PsLoggedon.exe -x -l \\$Computer | Where-Object { ($_ -like "*DOMAIN\*" -or $_ -like "*No one*" -or $_ -like "*$Computer\*" -or $_ -like "*Error opening*")}).trim()
        $loggedon = [string]$loggedon
        $ObjComputerAndUser = New-Object PSObject
        $ObjComputerAndUser | Add-Member -Type NoteProperty -Name Computer -Value $Computer
        $ObjComputerAndUser | Add-Member -Type NoteProperty -Name User -Value $loggedon
        $colComputerAndUser += $ObjComputerAndUser     
    }

    $colComputerAndUser
}

Computer User
-------- ----
computer01 DOMAIN\user01 DOMAIN\user02
computer01 DOMAIN\user01 DOMAIN\user02
computer02 DOMAIN\user03

Update 02

Sample 01 out from the PsLoggedon.exe - unedited

PsLoggedon v1.35 - See who's logged on  
Copyright (C) 2000-2016 Mark Russinovich  
Sysinternals - www.sysinternals.com  

Users logged on locally:  
        DOMAIN\user.name01  
        DOMAIN\user.name02

Sample 02 out from the PsLoggedon.exe - unedited

PsLoggedon v1.35 - See who's logged on  
Copyright (C) 2000-2016 Mark Russinovich  
Sysinternals - www.sysinternals.com  

Users logged on locally:  
        LOCALMACHINE\local.user01
        LOCALMACHINE\local.user04
        DOMAIN\user.name15  
        DOMAIN\user.name17

UPDATE 03 This code was actually working, but I had placed the out in the wrong part of the code.

$Computers = @(
,"computer01"
,"computer02"
,"computer03"
,"computer04"
,"computer05"
)

$colComputerAndUser = @()

Foreach ( $Computer in $Computers)
{
    $loggedon = $null
    If ( Test-Connection -ComputerName $Computer -Quiet -Count 1 )
    {
        $loggedon = (PsLoggedon.exe -x -l \\$Computer | Where-Object { ($_ -like "*DOMAIN\*" -or $_ -like "*No one*" -or $_ -like "*$Computer\*" -or $_ -like "*Error opening*")}).trim()
        $loggedon = [string]$loggedon
        $ObjComputerAndUser = New-Object PSObject
        $ObjComputerAndUser | Add-Member -Type NoteProperty -Name Computer -Value $Computer
        $ObjComputerAndUser | Add-Member -Type NoteProperty -Name User -Value $loggedon
        $colComputerAndUser += $ObjComputerAndUser     
    }
}
$colComputerAndUser

Where this code is different is where the final $colComputerNameUser is placed. originally I had it contained within the foreach loop, which caused the output to duplicate. It now comes after the loop, and the output is working correctly.

1 Answer 1

1

Make an object with two properties: ComputerName, Users. Concatenate all of the values after the ComputerName into a string and assign the string to the Users attribute.

$Computers = @(,"computername")

Foreach ($Computer in $Computers)
{
$loggedon = $null
if (Test-Connection -ComputerName $Computer -Quiet -Count 1){
    $loggedon = (.\PsLoggedon.exe -x -l \\$Computer)

    if ($loggedon -like "*Error Opening*"){
        Write-Output "Error occurred while attempting to connect. This computer is online."
        Continue
    } else {
        $loggedon = ,"$Computer" + $loggedon

        $colComputerAndUser = @()

        $UserString = ""
        for($Cnt = 9;$Cnt -lt $loggedon.Count;$Cnt++)
        {
            $UserString += ($loggedon[$Cnt]).Trim() + "`n"
        }
        $ObjComputerAndUser = New-Object System.Object
        $ObjComputerAndUser | Add-Member -Type NoteProperty -Name Computer -Value $Computer
        $ObjComputerAndUser | Add-Member -Type NoteProperty -Name User -Value $UserString
        $colComputerAndUser += $ObjComputerAndUser
     }
   }
 }
$colComputerAndUser | format-table -wrap

Not my most elegant work, but it works. I don't like hard-coding the start of the array count to 9. I tried to split on the colon but it just split on each `n in the output from PsLoggedon. I might try to refine this later. I also tried a global regex to match on [regex]'(?[^\])\(?.*)' but that didn't work out either. I got the results out, but couldn't enumerate the results.

Sign up to request clarification or add additional context in comments.

5 Comments

I tried implementing what you suggested. It works, except that I get repeating output if a computer returns more then one user. I suspect that I have missed a detail. I am not entirely sure what you mean by concatenating all values after ComputerName. Do you mean putting them all into on variable? Or just making sure all the values are on a single line? Sorry for my ignorance, this is far more advanced then what I am used to.
Can you post sample output from PsLoggedon.exe?
Under UPDATE 02 I have added some unedited output from the PsLoggedon.exe (with the exception of actual domain). I believe the duplicate in the custom object is possible coming from the fact that some computers may return more than one user. There is something strange going on when we add the values to the object.
Sorry for late reply. I very much appreciate the update you provided. I tried out the code. It appears to work, except that if there is more then one computer in the $Computers variable, only the last computer appears to get put into $colComputerAndUser. Not sure why at this point. I will need to dig into why this is happening.
So it turns out that your original code actually works great. It was my mistake. I had the $colComputerAndUser contained within the foreach loop. This is why the output was getting screwed up. So your original code worked great! Thank you very much.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.