Reputation: 259
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-nameDOMAIN\computer-name02
DOMAIN\user-name
DOMAIN\user-nameDOMAIN\computer-name03
Error connectingDOMAIN\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.
Upvotes: 0
Views: 1659
Reputation: 594
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.
Upvotes: 1