繁体   English   中英

如何查找用户登录的所有计算机

[英]How to find all computers a user is logged into

我正在尝试运行 PowerShell 脚本来查找用户在我的域中登录的所有计算机。 我无法得到任何工作。 我发现以下脚本可以正常运行,但不会产生 output。 有什么想法或建议吗?

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"
                }       
            }
        }
    }

我们必须登录到 AD 服务器并查询事件 ID 4624 ,从所有事件列表中搜索用户登录历史记录。 它只显示源计算机的 IP 地址。 在那里我们可以使用命令nslookup来找出主机名。 要执行此过程,它需要编写良好的批处理文件或 Power Shell 脚本来快速查找 HOSTNAME。

如果您不想依赖专有的Quest.ActiveRoles.ADManagement有一个本地 PowerShell 解决方案,名为Get-ActiveUser

我们可以将我们的计算机列表提供给它,并找到用户登录的任何地方。

注意:正如其他人提到的,查询网络上的所有计算机需要很长时间。 每 100 台电脑大约需要 15 分钟。 检查日志的建议会更快。

# 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

在 Windows 2016 上对此进行了测试,并且在 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

我不会做任何复杂的脚本废话来查找该信息。 在我的域中,用户将 P: 驱动器映射到他们的网络共享用户文件夹。 如果您转到共享服务器,然后打开计算机管理 > 共享文件夹 > 会话,它会向我显示打开的会话列表、用户名和用户登录的计算机。 按用户名列排序,然后查看用户登录的多台计算机。

扩展 Manas 的答案,因为它正是我所需要的,但没有显示如何去做 - 以及我自己未来的参考,因为它会再次出现(:

  1. 登录到您的 AD 域 controller。
  2. 以管理员身份打开 powershell,以便您可以访问安全日志。
  3. 如果您知道要查找的用户名,请运行以下命令。 请注意使用newest来修剪结果并使其运行更快,根据需要增加。
Get-EventLog -LogName Security -InstanceId 4624 -Newest 9000 | 
    Where {$_.Message -Like "*<username here>*"} | 
    Select -First 1 -ExpandProperty Message

如果匹配,则日志消息将有一行包含Source Network Address ,该地址将是 ip 地址。 复制这个。

  1. 使用刚刚复制的 IP 地址,运行nslookup <ip address>以查看用户登录的计算机名称。

我有各种用例,当我们都在远程工作时,我需要知道某人使用什么计算机,这是最直接的解决方案,只是认为在某个地方说明它会很好。 在我们的例子中,人们可以远程访问一台计算机,因此我不需要生成所有登录事件的完整列表。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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