Seznam uživatelů přihlášených k vašim počítačům

Zásady hesel jsou nejlepší 😀 Někdy však vedou k odhlášení účtu, když se někdo zapomene odhlásit z relace někde v síti. Může to být relace TS, kterou používají jednou za čtvrt roku pro hlášení, nebo možná znáte ten pocit, když se přes RDP dostanete na server, abyste zjistili, že je zamčený dvěma dalšími administrátory, kteří se při odchodu zapomněli odhlásit. (Mimo, protože tohle se nikdy nestává… všichni používáme PowerShell…) Každopádně mě to donutilo hledat uživatelskou relaci někde v síti. Nejhorší je, když mi vyprší vlastní heslo. Nesnáším, když můj účet skončí zablokovaný. Proto jsem si zavedl pravidlo, že před změnou hesla prostě zkontroluji všechny servery. Existuje více způsobů, jak to udělat, ale já se samozřejmě přikláním k cestě PowerShellu.

Vyhledávání

Původně jsem použil metodu z galerie TechNet

V krátkosti: Get-WmiObject -Class Win32_process

To v podstatě najde všechny unikátní uživatelské procesy běžící na počítači. Je to super, protože to najde všechno, i věci běžící jako služba, ale nejsem přesvědčen, že je to nejefektivnější způsob.

Podle googlu jsem našel spoustu kreativních způsobů, jak zkontrolovat, kdo je přihlášen na vašem boxu.

peetersonline.nl/2008/11/oneliner-get-logged-on-users-with-powershell/ mi vnukl nápad zkontrolovat Win32_LoggedOnUser, což se zdá být samozřejmé.

2015-08-28 (1)

To vypadá skvěle a zdá se, že to funguje i s Get-CimInstance, i když výstup je trochu jiný.

2015-08-28

learn-powershell.net/…/Quick-hit-find-currently-logged-on-users/ zvolil trochu staromódnější přístup, který se mi docela líbí, protože je trochu drsný a nutí mě hrát si s parsováním na základě šablon.

2015-08-28 (2)

Nejsem si úplně jistý, která metoda je rychlejší, tak proč nezkusit implementovat všechny tři v modulu a vyzkoušet to.

Sketching

Vždy je dobré začít tím, že si uděláte náčrt toho, čeho se snažíte dosáhnout.

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

Teď mám všechny informace, které potřebuji k nastavení úložiště GitHub.

github.com/mrhvid/Get-ActiveUser

Kód

Především mě zajímají parametry ComputerName a Method.

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

Už mám v hlavě 3 možné Methods, takže nastavím ValidateSet s těmito 3 možnostmi. Pak se nemusím později starat o toto zadání.

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

V části funkce Process jednoduše použiji přepínač pro 3 různé metody, které jsem povolil v Parametru.

Teď je to základní vyplňování prázdných políček.

WMI

Moje staré řešení je jednoduché a funguje dobře.

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

2015-08-28 (3)

Ale teď, když jsem našel Win32_LoggedOnUser, se mi zdá, že je špatně to dělat tímto způsobem. Podívejme se místo toho na nový nápad.

2015-08-28 (4)

gwmi-Wmi32_LoggedOnUser_gm

To jsou všechno správné údaje, ale zdá se, že jsou ve formátu řetězce, takže s nimi budu muset trochu manipulovat. Dá se to udělat milionem způsobů.

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

Petrův výše zmíněný jednořádkový text mi nepřišel příliš čtenářsky přívětivý, což u jednořádkového textu nevadí, ale rád bych, aby byl pokud možno trochu čitelnější.

$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)

To vypadá správně 🙂 Výstup uložím do proměnné $ActiveUsers a totéž udělám pro CIM a Query.

CIM

Zkusíme to s CIM.

2015-08-28 (6)

Tohle vypadá mnohem strukturovaněji.

2015-08-28 (7)

CIM skončí jako snadno pochopitelná jednohubka 😀

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

Query

Použijeme starý dobrý Query.exe se mi velmi osvědčilo dříve probírané parsování na základě šablon.

$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

Teď už jen potřebuji pěkně naformátovat a vypsat uživatele. Chci čisté objekty s ComputerName a UserName.

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

Testování

Teď mám problém. Nemohu to otestovat, protože nemám k dispozici hromadu testovacích serverů. Veškeré testování jsem prováděl proti vlastnímu boxu s Windows 10. Zdá se, že dotaz je mnohem rychlejší při lokálním spuštění, ale WMI/CIM by mohl poskytnout úplnější přehled o tom, jaké služby jsou spuštěny.

get-activeuser_wmi_highlight

Mám spuštěno několik standardních účtů služeb, které by bylo dobré z výstupu odstranit. Také aby to bylo užitečné, budeme to chtít spustit proti mnoha počítačům.

get-activeuser_query

Kombinace Get-ActiveUser se Start-Multithread z minulého týdne se zdá, že funguje, jak má.

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

Přepojení výše uvedeného do Out-GridView je pravděpodobně můj osobní oblíbený způsob, jak dosáhnout něčeho opravdu užitečného.

get-activeuser_query_out-gridview

Teď máme všechna data pěkně pohromadě a je opravdu snadné zkontrolovat, zda je uživatel přihlášen na nějakém náhodném stroji. Je to také snadný způsob, jak zkontrolovat, zda se v síti nenachází nepovolaní uživatelé.

Publikování a zpětná vazba

Kód je zveřejněn na PowerShellGallery.

Prosím, pomozte mi tím, že mi ho otestujete. Rád bych věděl, jestli to funguje v reálném světě 🙂

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

Mělo by to fungovat, když máte nainstalovaný WMF 5+ a na Windows 10 out of the box.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna.