Lista utilizatorilor conectați la mașinile dumneavoastră

Politicile de parole sunt cele mai bune 😀 Uneori, acestea duc la deconectări de conturi atunci când cineva uită să se deconecteze de la o sesiune undeva în rețea. Ar putea fi sesiunea TS pe care o folosesc o dată pe trimestru pentru raportare sau poate cunoașteți sentimentul când faceți RDP la un server doar pentru a descoperi că este blocat de alți 2 administratori care au uitat să se deconecteze când au plecat. (Off pentru că acest lucru nu se întâmplă niciodată… cu toții folosim PowerShell…) Oricum, acest lucru m-a făcut să caut o sesiune de utilizator undeva în rețea. Cel mai rău lucru este atunci când îmi expiră propria parolă. Urăsc când contul meu ajunge să fie blocat. De aceea, mi-am făcut o regulă din a verifica doar toate serverele înainte de a schimba parola. Există mai multe moduri de a face acest lucru, dar, desigur, am tendința de a merge pe calea PowerShell.

Research

Metoda pe care am folosit-o inițial este din galeria TechNet

Prin scurt: Get-WmiObject -Class Win32_process

Aceasta găsește practic toți utilizatorii unici care rulează procese pe mașină. Este mișto pentru că găsește totul, chiar și chestii care rulează ca serviciu, dar nu sunt convins că este cea mai eficientă metodă.

Verificând pe google am găsit o mulțime de metode creative de a verifica cine este logat pe boxa ta.

peetersonline.nl/2008/11/oneliner-get-logged-on-users-with-powershell/ mi-a dat ideea de a verifica Win32_LoggedOnUser, ceea ce pare evident.

2015-08-28 (1)

Aceasta arată grozav și pare să funcționeze și cu Get-CimInstance, deși rezultatul este puțin diferit.

2015-08-28

learn-powershell.net/…/Quick-hit-find-currently-logged-on-users/ a avut o abordare puțin mai old-school, care îmi cam place pentru că este puțin mai dură și mă forțează să mă joc cu parsarea bazată pe șabloane.

2015-08-28 (2)

Nu sunt foarte sigur care metodă este mai rapidă, așa că de ce să nu încercăm să le implementăm pe toate 3 într-un modul și să le testăm.

Schemă

Este întotdeauna o idee bună să începem prin a face o schiță a ceea ce încercăm să realizăm.

Pseudo code:Get-ActiveUser -ComputerName -Method Wanted output:Username ComputerName-------- ------------TestUser1 Svr3TestUser3 Svr3DonaldDuck Client2

Acum am toate informațiile de care am nevoie pentru a configura depozitul GitHub.

github.com/mrhvid/Get-ActiveUser

Code

În primul rând parametrii care mă interesează sunt ComputerName și Method.

 Param ( # Computer name, IP, Hostname ] $ComputerName, # Choose method, WMI, CIM or Query $Method )

Am deja în minte 3 metode posibile, așa că am setat ValidateSet cu cele 3 posibilități. Apoi nu trebuie să-mi mai fac griji cu privire la această intrare mai târziu.

 Process { switch ($Method) { 'WMI' { } 'CIM' { } 'Query' { } } }

În partea Process a funcției mele folosesc pur și simplu un comutator pentru cele 3 metode diferite pe care le-am permis în Parametru.

Acum este vorba de completarea de bază a spațiilor libere.

WMI

Soluția mea veche este simplă și funcționează bine.

$WMI = Get-WmiObject -Class Win32_Process -ComputerName $ComputerName -ErrorAction Stop$ProcessUsers = $WMI.getowner().user | Select-Object -Unique

2015-08-28 (3)

Dar acum că am găsit Win32_LoggedOnUser mi se pare greșit să o fac în acest fel. Să ne uităm la noua idee în schimb.

2015-08-28 (4)

gwmi-Wmi32_LoggedOnUser_gm

Acestea sunt toate datele corecte, dar se pare că sunt într-un format de șir de caractere, așa că va trebui să fac o mică manipulare. Acest lucru se poate face într-un milion de feluri.

function Get-MyLoggedOnUsers { param($Computer) Get-WmiObject Win32_LoggedOnUser -ComputerName $Computer | Select Antecedent -Unique | %{"{0}{1}" -f $_.Antecedent.ToString().Split('"'), $_.Antecedent.ToString().Split('"')} }

Linerul de mai sus al lui Peter nu mi s-a părut foarte ușor de citit, ceea ce este în regulă pentru un one-liner, dar aș vrea să fie un pic mai ușor de citit dacă este posibil.

$WMI = (Get-WmiObject Win32_LoggedOnUser).Antecedent$ActiveUsers = @()foreach($User in $WMI) { $StartOfUsername = $User.LastIndexOf('=') + 2 $EndOfUsername = $User.Length - $User.LastIndexOf('=') -3 $ActiveUsers += $User.Substring($StartOfUsername,$EndOfUsername)}

2015-08-28 (5)

Acest lucru pare corect 🙂 Voi salva rezultatul în variabila $ActiveUsers și voi face același lucru pentru CIM și Query.

CIM

Să încercăm cu CIM.

2015-08-28 (6)

Acesta pare mult mai structurat.

2015-08-28 (7)

CIM sfârșește prin a fi un one-liner ușor de înțeles 😀

$ActiveUsers = (Get-CimInstance Win32_LoggedOnUser -ComputerName $ComputerName).antecedent.name | Select-Object -Unique

Query

Utilizând bunul și vechiul Query.exe mi s-a părut foarte utilă parsarea bazată pe șabloane discutată mai devreme.

$Template = @' USERNAME SESSIONNAME ID STATE IDLE TIME LOGON TIME>{USER*:jonas} console 1 Active 1+00:27 24-08-2015 22:22 {USER*:test} 2 Disc 1+00:27 25-08-2015 08:26'@$Query = query.exe user$ActiveUsers = $Query | ConvertFrom-String -TemplateContent $Template | Select-Object -ExpandProperty User

Output

Acum trebuie doar să formatez și să scot utilizatorii într-un mod plăcut. Vreau obiecte curate cu ComputerName și UserName.

# Create nice output format$UsersComputersToOutput = @()foreach($User in $ActiveUsers) { $UsersComputersToOutput += New-Object psobject -Property @{ ComputerName=$ComputerName; UserName=$User } }}# output data$UsersComputersToOutput

Testing

Acum am o problemă. Nu pot testa acest lucru deoarece nu am la dispoziție o grămadă de servere de test. Toate testele mele au fost făcute împotriva propriei mele cutii Windows 10. Se pare că interogarea este mult mai rapidă rulând local, dar WMI/CIM ar putea oferi o imagine mai completă a serviciilor care rulează.

get-activeuser_wmi_highlight

Am o grămadă de conturi de servicii standard care rulează și care ar fi bine să fie eliminate din ieșire. De asemenea, pentru ca acest lucru să fie util, vom dori să îl rulăm pe o mulțime de mașini.

get-activeuser_query

Combinarea Get-ActiveUser cu Start-Multithread din postarea de săptămâna trecută pare să funcționeze așa cum s-a dorit.

Start-Multithread -Script { param($C) Get-ActiveUser -ComputerName $C -Method Query } -ComputerName ::1,Localhost | Out-GridView

Transmiterea celor de mai sus către Out-GridView este probabil modul meu personal preferat de a realiza ceva cu adevărat util.

get-activeuser_query_out-gridview

Acum avem toate datele într-un mod frumos de căutare și este foarte ușor de verificat dacă utilizatorul este logat pe o mașină oarecare. Este, de asemenea, o modalitate ușoară de a verifica dacă există utilizatori roșii în rețeaua dumneavoastră.

Publicare și feedback

Codul este publicat pe PowerShellGallery.

Vă rog să mă ajutați testându-l pentru mine. Mi-ar plăcea să știu dacă acest lucru funcționează în lumea reală 🙂

# To install Get-ActiveUserInstall-Module Get-ActiveUser#To install Start-MultithreadInstall-Module Start-Multithread

Acest lucru ar trebui să funcționeze atunci când aveți WMF 5 + instalat și pe Windows 10 out of the box.

Lasă un răspuns

Adresa ta de email nu va fi publicată.