Salasanakäytännöt ovat parhaita 😀 Joskus ne johtavat kuitenkin tilien uloskirjautumisiin, kun joku unohtaa kirjautua ulos istunnosta jossain verkossa. Se voi olla TS-istunto, jota he käyttävät kerran vuosineljänneksessä raportointiin tai ehkä tiedät sen tunteen, kun siirryt RDP:llä palvelimelle vain huomataksesi, että se on lukittu kahden muun ylläpitäjän toimesta, jotka unohtivat kirjautua ulos lähtiessään. (Pois päältä, koska näin ei koskaan tapahdu… me kaikki käytämme PowerShelliä…) Joka tapauksessa, tämä sai minut etsimään käyttäjäistuntoa jostain verkosta. Pahinta on, kun oma salasanani vanhenee. Inhoan, kun tilini päätyy lukituksi. Siksi otin säännöksi tarkistaa kaikki palvelimet ennen kuin vaihdan salasanan. Tähän on useita tapoja, mutta minulla on tietysti tapana käyttää PowerShell-reittiä.
Tutkimus
Alunperin käyttämäni menetelmä on TechNetin galleriasta
Lyhyesti: Get-WmiObject -Class Win32_process
Tämä periaatteessa löytää kaikki uniikit käyttäjät, jotka suorittavat prosesseja koneella. Tämä on siistiä, koska se löytää kaiken, jopa palveluna toimivan tavaran, mutta en ole vakuuttunut siitä, että se on tehokkain tapa.
Tarkistamalla googlesta löydän paljon luovia tapoja tarkistaa, kuka on kirjautuneena koneellesi.
peetersonline.nl/2008/11/oneliner-get-logged-on-users-with-powershell/ antoi minulle idean tarkastaa Win32_LoggedOnUser, joka vaikuttaa ilmeiseltä.
Tämä näyttää hyvältä ja näyttää toimivan myös Get-CimInstance:n kanssa, vaikka tuloste on hieman erilainen.
learn-powershell.net/…/Quick-hit-find-currently-logged-on-users/ otti hieman vanhanaikaisemman lähestymistavan, josta tavallaan pidän, koska se on hieman karkea ja pakottaa minut leikkimään mallipohjaisella jäsentelylläni.
En ole ihan varma, kumpi menetelmä on nopeampi, joten mikset kokeilisi toteuttaa kaikkia kolmea moduulissa ja testaisi sitä.
Sketching
Aina kannattaa aloittaa tekemällä luonnos siitä, mitä yrität saavuttaa.
Pseudo code:Get-ActiveUser -ComputerName -Method Wanted output:Username ComputerName-------- ------------TestUser1 Svr3TestUser3 Svr3DonaldDuck Client2
Nyt minulla on kaikki tiedot, joita tarvitsen GitHub-tietovaraston perustamiseen.
github.com/mrhvid/Get-ActiveUser
Code
Ensin minua kiinnostavat parametrit ovat ComputerName ja Method.
Param ( # Computer name, IP, Hostname ] $ComputerName, # Choose method, WMI, CIM or Query $Method )
Minulla on jo 3 mahdollista Methodia mielessäni, joten asetan ValidateSet:iin nämä 3 mahdollisuutta. Sitten minun ei tarvitse huolehtia tuosta syötteestä myöhemmin.
Process { switch ($Method) { 'WMI' { } 'CIM' { } 'Query' { } } }
Funktioni Process-osiossa käytän yksinkertaisesti kytkintä 3:lle eri metodille, jotka sallin parametrissa.
Nyt se on perus täyttö tyhjiin.
WMI
Vanha ratkaisuni on yksinkertainen ja toimii hyvin.
$WMI = Get-WmiObject -Class Win32_Process -ComputerName $ComputerName -ErrorAction Stop$ProcessUsers = $WMI.getowner().user | Select-Object -Unique
Mutta nyt kun löysin Win32_LoggedOnUserin, tuntuu väärältä tehdä se näin. Katsotaan sen sijaan uutta ideaa.
Tässä on kaikki oikeat tiedot, mutta ne näyttävät olevan merkkijonomuodossa, joten joudun tekemään hieman manipulointia. Tämän voi tehdä miljoonalla tavalla.
function Get-MyLoggedOnUsers { param($Computer) Get-WmiObject Win32_LoggedOnUser -ComputerName $Computer | Select Antecedent -Unique | %{"{0}{1}" -f $_.Antecedent.ToString().Split('"'), $_.Antecedent.ToString().Split('"')} }
Peterin edellä mainittu one-liner ei vaikuttanut minusta kovin lukijaystävälliseltä, mikä on ihan ok one-lineriksi, mutta haluaisin sen olevan hieman luettavampi, jos mahdollista.
$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)}
Tämä vaikuttaa oikealta 🙂 Tallennan tuotoksen $ActiveUsers-muuttujaan ja teen saman CIM:lle ja Querylle.
CIM
Kokeillaan CIM:llä.
Tämä näyttää paljon strukturoidummalta.
CIM päätyy helposti ymmärrettäväksi one-lineriksi 😀
$ActiveUsers = (Get-CimInstance Win32_LoggedOnUser -ComputerName $ComputerName).antecedent.name | Select-Object -Unique
Query
Käytetään vanhaa kunnon Queryä.exe löysin aiemmin käsitellyn mallipohjaisen jäsennyksen erittäin hyödylliseksi.
$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
Nyt minun on vain muotoiltava ja tulostettava käyttäjät mukavalla tavalla. Haluan puhtaat objektit ComputerName ja UserName.
# Create nice output format$UsersComputersToOutput = @()foreach($User in $ActiveUsers) { $UsersComputersToOutput += New-Object psobject -Property @{ ComputerName=$ComputerName; UserName=$User } }}# output data$UsersComputersToOutput
Testaus
Nyt minulla on ongelma. En voi testata tätä, koska minulla ei ole kasa testipalvelimia käytössäni. Kaikki testaukseni on tehty omaa Windows 10 -laatikkoani vastaan. Näyttää siltä, että kysely on paljon nopeampi paikallisesti suoritettuna, mutta WMI/CIM saattaa antaa täydellisemmän kuvan siitä, mitä palveluita on käynnissä.
Minulla on käynnissä joukko vakiopalvelutilejä, jotka voisi olla kiva poistaa tulosteesta. Lisäksi, jotta tästä olisi hyötyä, haluamme ajaa sen monille koneille.
Viime viikon postauksen Get-ActiveUserin ja Start-Multithreadin yhdistäminen näyttää toimivan tarkoitetulla tavalla.
Start-Multithread -Script { param($C) Get-ActiveUser -ComputerName $C -Method Query } -ComputerName ::1,Localhost | Out-GridView
Edellämainitun putkittaminen Out-GridViewiin on proberbly henkilökohtainen suosikkini saada aikaan jotain todella hyödyllistä.
Nyt meillä on kaikki tiedot mukavasti haettavissa ja on todella helppoa tarkistaa, onko käyttäjä kirjautuneena jollain satunnaisella koneella. Se on myös helppo tapa tarkistaa, onko verkossa rouge-käyttäjiä.
Julkaiseminen ja palaute
Koodi on julkaistu PowerShellGalleriassa.
Auttaisitko minua testaamalla sitä puolestani. Haluaisin tietää, toimiiko tämä oikeassa maailmassa 🙂
# To install Get-ActiveUserInstall-Module Get-ActiveUser#To install Start-MultithreadInstall-Module Start-Multithread
Tämän pitäisi toimia, kun sinulla on WMF 5+ asennettuna ja Windows 10:ssä out of the box.