Today I want to show you a simple PowerShell script, that can be used to find on which domain machines a user is logged on currently.
Basicaly the script is working like the pslogedon utility, but does not require the remote registry to be enabled on target machines.As usual I’ve uploaded the script to GitHub .
It is required that psexec be placed in the script folder, and if you plan to check all computers in the domain, Active Directory module for PowerShell must be installed on your machine.
Let me describe shortly the logic and parameters of the script.
User – a required parameter, the name of the user we are searching.
Comps – computer names to check, you can set several commas separated names.
Maxthreads – the number of threads, by default 50, but depending on your requirements can be reduced or increased.
Allservers – true/false – the search goes only on machines that have “server” in their names or paths in AD.
If allservers and comps are not specified, then the search goes over all enabled machines in Active Directory.
The logic here, is something like this – first a list of computers is formed, then for each computer the job is created and machine is checked for availability. If it is available, the script tries to connect to the machine with PowerShell remote, if it’s unavailable, then if connects with psexec.
Unfortunately, due to the way the script works, you can’t check yourself, I mean the account that starts the script, because your account will be logged on to every machine. So if you want to check your account, you must run the script with a different account.
At the end, a CSV file is generated showing whether the user is logged on to the machine, not logged on, or an error occurred.
<# .SYNOPSIS Search on which computers in domain user is currently logged on .DESCRIPTION This script searches where specified user currenty loggen on .EXAMPLE #.\loggedon.ps1 -user "someuser" -AllServer $true -threads 100 .PARAMETER user Whom we are searching for. .PARAMETER $comps where a user should be searched. By defalt the search is going on all active domain machines. .PARAMETER maxtheads Set maximum theads, by default - 50. .PARAMETER AllServers Make search through all servers. #> param ( [PARAMETER(Mandatory=$True,Position=0)][String]$user, [PARAMETER(Mandatory=$False,Position=1)][String[]]$comps, [PARAMETER(Mandatory=$False,Position=2)][int]$maxthreads, [PARAMETER(Mandatory=$False,Position=3)][Bool]$AllServers ) import-module activedirectory $sid=get-aduser $user -erroraction stop if ($maxthreads -eq 0){ $maxthreads=50 } if ($comps -eq $null -and $AllServers -ne $True){ $comps=(get-adcomputer -filter {enabled -eq "True"} -erroraction stop).name } if ($AllServers -eq $True){ $comps=(Get-ADComputer -Filter {enabled -eq "True"} -erroraction stop | ?{$_.DistinguishedName -like "*server*"}).name } $csvPath=".\result.csv" $pstoolsPath="$PSScriptRoot\" $total=$comps.count foreach ($comp in $comps){ $job={ $pstoolsPath=$args[2] if (!(test-path "$($pstoolspath)psexec.exe")){ write-host "psexec not found" return } $path="REGISTRY::HKEY_USERS\$($args[1])" if (Test-Connection $args[0] -Count 2){ try { $test=invoke-command -erroraction stop -computername $args[0] { param($path) Test-Path $path } -ArgumentList $path if ($test -eq $True){ $result="true" } elseif ($test -eq $False) { $result="false" } else { $result="powershell error" } } catch{ cd $pstoolsPath $test=(.\psexec.exe -nobanner -accepteula \\$($args[0]) powershell.exe -nologo -NonInteractive -noprofile -command "Test-Path $path") if ($test -eq "True"){ $result="true" } elseif ($test -eq "False") { $result="false" } else { $result="error" } } } else { $result="unavailable" } write-host "$($args[0]);$result" } $maxthreads Start-Job -Name $comp -ScriptBlock $job -argumentlist @($comp,$sid.sid,$pstoolsPath) While (@(Get-Job | Where { $_.State -eq "Running" }).Count -gt $maxthreads) { $completed=((Get-Job | Where { $_.State -ne "Running" }).Count) $percentCompleted=($completed*100/$total) Write-Progress -Activity "Search in progress..." -status "$percentCompleted% Completed" -PercentComplete $percentCompleted Start-Sleep -Seconds 3 } } While (@(Get-Job | Where { $_.State -eq "Running" }).Count -gt 0) { $completed=((Get-Job | Where { $_.State -ne "Running" }).Count) $percentCompleted=($completed*100/$total) Write-Progress -Activity "Search in progress..." -status "$percentCompleted% Completed" -PercentComplete $percentCompleted Start-Sleep -Seconds 3 } $final=get-job | receive-job 6>&1 get-job | remove-job "computer;result" | Out-File $csvPath -Encoding utf8 $final | Out-String | Out-File $csvPath -Encoding utf8 -append
Share the article with your friends in social networks, maybe it will be useful to them.
If the article helped you, you can >>thank the author<<