A jelszavas házirendek a legjobbak 😀 Néha azonban fiókok kijelentkezéséhez vezetnek, amikor valaki elfelejt kijelentkezni egy munkamenetből valahol a hálózaton. Ez lehet a TS munkamenet, amit negyedévente egyszer használnak jelentésre, vagy talán ismered az érzést, amikor RDP-vel belépsz egy szerverre, és csak azt látod, hogy azt 2 másik rendszergazda zárta le, akik elfelejtettek kijelentkezni, amikor elmentek. (Ki, mert ez soha nem történik meg… mindannyian PowerShell-t használunk…) Mindegy, ez volt nekem keresni egy felhasználói munkamenetet valahol a hálózaton. A legrosszabb az, amikor a saját jelszavam lejár. Utálom, amikor a fiókom végül le van zárva. Ezért szabállyá tettem, hogy csak az összes szervert ellenőrzöm, mielőtt jelszót változtatok. Többféleképpen lehet ezt megtenni, de természetesen én inkább a PowerShell útvonalat választom.
Keresés
Az eredetileg általam használt módszer a TechNet galériából
Röviden: Get-WmiObject -Class Win32_process
Ez alapvetően megtalálja az összes egyedi felhasználó által a gépen futó folyamatot. Ez király, mert mindent megtalál, még a szolgáltatásként futó dolgokat is, de nem vagyok meggyőződve arról, hogy ez a leghatékonyabb módszer.
A google-t böngészve rengeteg kreatív módszert találtam arra, hogy ellenőrizzük, ki van bejelentkezve a dobozunkra.
peetersonline.nl/2008/11/oneliner-get-logged-on-users-with-powershell/ adta az ötletet, hogy a Win32_LoggedOnUser-t ellenőrizzük, ami nyilvánvalónak tűnik.
Ez remekül néz ki, és úgy tűnik, hogy a Get-CimInstance-el is működik, bár a kimenet egy kicsit más.
learn-powershell.net/…/Quick-hit-find-currently-logged-on-users/ egy kicsit régimódibb megközelítést vett, ami valahogy tetszik, mert egy kicsit durva, és arra kényszerít, hogy játsszak a sablon alapú elemzésemmel.
Nem vagyok benne biztos, hogy melyik módszer a gyorsabb, ezért miért nem próbálod meg mindhármat egy modulban megvalósítani és kipróbálni.
Vázlatkészítés
Mindig jó ötlet azzal kezdeni, hogy készítesz egy vázlatot arról, hogy mit akarsz elérni.
Pseudo code:Get-ActiveUser -ComputerName -Method Wanted output:Username ComputerName-------- ------------TestUser1 Svr3TestUser3 Svr3DonaldDuck Client2
Most már megvan minden információm, amire szükségem van a GitHub tároló beállításához.
github.com/mrhvid/Get-ActiveUser
Code
Először is az engem érdeklő paraméterek a ComputerName és a Method.
Param ( # Computer name, IP, Hostname ] $ComputerName, # Choose method, WMI, CIM or Query $Method )
Már van 3 lehetséges Methods a fejemben, így a ValidateSet-et a 3 lehetőséggel állítom be. Így később nem kell aggódnom ezen a bemeneten.
Process { switch ($Method) { 'WMI' { } 'CIM' { } 'Query' { } } }
A függvényem Process részében egyszerűen egy kapcsolót használok a 3 különböző Metódushoz, amit a Parameterben engedélyeztem.
Most ez egy alapvető kitöltés.
WMI
A régi megoldásom egyszerű és jól működik.
$WMI = Get-WmiObject -Class Win32_Process -ComputerName $ComputerName -ErrorAction Stop$ProcessUsers = $WMI.getowner().user | Select-Object -Unique
De most, hogy megtaláltam a Win32_LoggedOnUser-t, rossznak tűnik, hogy így csinálom. Nézzük meg helyette az új ötletet.
Ez mind a megfelelő adat, de úgy tűnik, hogy string formátumban van, így egy kis manipulációt kell végeznem. Ezt millióféleképpen meg lehet csinálni.
function Get-MyLoggedOnUsers { param($Computer) Get-WmiObject Win32_LoggedOnUser -ComputerName $Computer | Select Antecedent -Unique | %{"{0}{1}" -f $_.Antecedent.ToString().Split('"'), $_.Antecedent.ToString().Split('"')} }
Peter fent említett egysorosa nekem nem tűnt túl olvasóbarátnak, ami egy egysorosnál rendben van, de szeretném, ha egy kicsit olvashatóbb lenne, ha lehetséges.
$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)}
Ez jónak tűnik 🙂 Elmentem a kimenetet a $ActiveUsers változóba, és ugyanezt teszem a CIM és a Query esetében is.
CIM
Próbáljuk meg a CIM-mel.
Ez sokkal strukturáltabbnak tűnik.
A CIM végül egy könnyen érthető egysoros lesz 😀
$ActiveUsers = (Get-CimInstance Win32_LoggedOnUser -ComputerName $ComputerName).antecedent.name | Select-Object -Unique
Query
A jó öreg Query-t használva.exe nagyon hasznosnak találtam a korábban tárgyalt sablon alapú elemzést.
$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
Most már csak a felhasználókat kell szépen formázni és kimeneti formában kiadni. Tiszta objektumokat akarok a ComputerName és a UserName adatokkal.
# Create nice output format$UsersComputersToOutput = @()foreach($User in $ActiveUsers) { $UsersComputersToOutput += New-Object psobject -Property @{ ComputerName=$ComputerName; UserName=$User } }}# output data$UsersComputersToOutput
Tesztelés
Most van egy problémám. Ezt nem tudom tesztelni, mivel nem áll rendelkezésemre egy csomó teszt szerver. Minden tesztelésemet a saját Windows 10-es boxom ellen végeztem. Úgy tűnik, hogy a lekérdezés sokkal gyorsabb helyben fut, de a WMI/CIM talán teljesebb képet ad arról, hogy milyen szolgáltatások futnak.
Van egy csomó szabványos szolgáltatásfiókom, amit jó lenne eltávolítani a kimenetből. Szintén ahhoz, hogy ez hasznos legyen, sok gépen szeretnénk futtatni.
A Get-ActiveUser és a Start-Multithread kombinálása a múlt heti bejegyzésből úgy tűnik, hogy a tervezett módon működik.
Start-Multithread -Script { param($C) Get-ActiveUser -ComputerName $C -Method Query } -ComputerName ::1,Localhost | Out-GridView
A fentiek átvezetése az Out-GridView-ba proberbly az én személyes kedvenc módszerem arra, hogy valami igazán hasznosat érjünk el.
Most már minden adatunk szépen kereshető módon van, és nagyon könnyű ellenőrizni, hogy a felhasználó be van-e jelentkezve egy random gépen. Ez is egy egyszerű módja annak, hogy ellenőrizzük a hálózaton lévő rouge felhasználókat.
Közzététel és visszajelzés
A kódot a PowerShellGalériában tettem közzé.
Kérem, segítsen nekem azzal, hogy teszteli nekem. Szeretném tudni, hogy ez működik-e a való világban 🙂
# To install Get-ActiveUserInstall-Module Get-ActiveUser#To install Start-MultithreadInstall-Module Start-Multithread
Ennek működnie kell, ha a WMF 5+ telepítve van, és a Windows 10 alapból működik.