简体   繁体   中英

How to find all computers a user is logged into

I am trying to run a PowerShell script to find all computers a user is logged into on my domain. I haven't been able to get anything to work. I found the following script which will run without errors, but never produces output. Any thoughts or suggestions?

Add-PSSnapin Quest.ActiveRoles.ADManagement -ErrorAction SilentlyContinue
$ErrorActionPreference = "SilentlyContinue"

# Retrieve Username to search for, error checks to make sure the username
# is not blank and that it exists in Active Directory

Function Get-Username {
    $Global:Username = Read-Host "Enter username you want to search for"
    if ($Username -eq $null) {
        Write-Host "Username cannot be blank, please re-enter username!"
        Get-Username
    }
    $UserCheck = Get-QADUser -SamAccountName $Username
    if ($UserCheck -eq $null) {
        Write-Host "Invalid username, please verify this is the logon id for the account"
        Get-Username
    }
}

get-username

$computers = Get-QADComputer | where {$_.accountisdisabled -eq $false} -searchroot '\\MyDomainName\computers'
foreach ($comp in $computers) {
    $Computer = $comp.Name
    $ping = new-object System.Net.NetworkInformation.Ping
    $Reply = $null
    $Reply = $ping.send($Computer)
    if($Reply.status -like 'Success') {
        #Get explorer.exe processes
        $proc = gwmi win32_process -computer $Computer -Filter "Name = 'explorer.exe'"
        #Search collection of processes for username
            ForEach ($p in $proc) {
                $temp = ($p.GetOwner()).User
                if ($temp -eq $Username) {
                write-host "$Username is logged on $Computer"
                }       
            }
        }
    }

We have to login to the AD server and query the Event ID 4624 , search the user logged on history from all event list. It display only the IP address of source computer. There we can use the command nslookup to find out the host name. To do do this process it required a well written batch file or power shell script to quickly findout the HOSTNAME.

If you don't want to be dependent upon a proprietary Quest.ActiveRoles.ADManagement there is a native PowerShell solution available on PSGallery called Get-ActiveUser .

We can feed our list of computers to that and find any place the user is logged in to.

NOTE: As others have mentioned this will take a very long time to query all the computers on your network. Approximately 15 minutes per 100 PCs. Suggestions to check logs will be faster.

# List-Computers-ByUser.ps1
#
[CmdletBinding()]
param (
    # Search for user
    [Parameter(Mandatory=$false,
    ValueFromPipelineByPropertyName=$true,
    HelpMessage="If you don't pass a name you will be prompted",
    Position=0)]
    [String]
    $UserName,

    # Choose method, WMI, CIM or Query
    [Parameter(Mandatory=$false,
    ValueFromPipelineByPropertyName=$true,
    HelpMessage="Default set to WMI",
    Position=1)]
    [ValidateSet('WMI','CIM','Query')]
    [String]
    $Method = "Query"
)

# Retrieve Username to search for, error checks to make sure the username
# is not blank and that it exists in Active Directory
Function Get-Username([String]$UserName) {
    if ([string]::IsNullOrEmpty($UserName)) {
        $UserName = Read-Host "Enter username you want to search for"
    }

    $UserCheck = Get-ADUser -Identity $Username
    if ($null -eq $UserCheck) {
        Write-Debug "Invalid username, please verify this is the logon id for the account"
        $UserName = Get-Username
    }

    return $UserName
}

$Script:UserName = Get-Username $UserName

Write-Host "Checking for PS Module Get-ActiveUser ..."
if (-not (Get-InstalledModule Get-ActiveUser -ErrorAction silentlycontinue)) {
    Install-Module -Name Get-ActiveUser 
}

[String]$Global:output=@()

Write-Host "Searching for username across all computers in domain. This will take a long time ..."
$adComputers =  Get-ADComputer  -Filter 'enabled -eq "true"' | Select-Object -ExpandProperty Name
Measure-Command {
    $output = $adComputers | ForEach-Object -Parallel {
        $users = Get-ActiveUser -ComputerName $_ -Method $using:Method
        ForEach($activeUser in $users) {
            if($activeUser.UserName -eq $UserName) {
                $output+=$activeUser
                Write-Output $activeUser
            }
        }
    } 
}

# Show results, all computers that user is logged in to
$output

Tested this on Windows 2016 and worked very nice for me in powershell:

$computerName = "."
$wmi = [WMI] ""
get-wmiobject Win32_UserProfile -computername $computerName | foreach-object {
  $userAccount = [WMI] ("\\$computerName\root\cimv2:Win32_SID.SID='{0}'" -f $_.SID)
  $userName = "{0}\{1}" -f $userAccount.ReferencedDomainName,$userAccount.AccountName
  new-object PSObject -property @{
    "Name" = $userName
    "LastUseTime" = $wmi.ConvertToDatetime($_.LastUseTime)
    "Loaded" = $_.Loaded
  }
} | sort-object LastUseTime -descending

I don't do any of that complicated scripting nonsense to find that information. On my domain, users are mapped a P: drive to their network share user folder. If you go the the share server, then open computer management > shared folders > sessions, it shows me a list of open sessions, the username and the computer that user is signed into. Sort by username column, then see the multiple computers the user is signed into.

Expanding on Manas' answer because it was exactly what I needed but doesn't show how to do it - and for my own future reference because it will come up again (:

  1. Login to your AD domain controller.
  2. Open powershell as an administrator so you have access to security logs.
  3. If you know the username name of who you're looking for, run the following command. Note the use of newest to trim the results and make it faster to run, increase as needed.
Get-EventLog -LogName Security -InstanceId 4624 -Newest 9000 | 
    Where {$_.Message -Like "*<username here>*"} | 
    Select -First 1 -ExpandProperty Message

If there's a match, the log's message will have a line containing the Source Network Address which will be an ip address. Copy this.

  1. With the IP address you just copied, run nslookup <ip address> to see the computer name the user logged into.

I have various use cases where I need to know what computer someone uses while we're all working remotely and this is the most straight forward solution, just thought it'd be nice to have it spelled out somewhere. In our case, people have remote access to a single computer so I don't need to produce a comprehensive list of all logon events.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM