Dnes jsme zjistily že před 2 dny pan Opršálek prozradil heslo lokálního administrátora a nyní heslo zná i naše uklízečka!
Bude tedy potřeba na všech 55-ti počítačích změnit co nejrychleji heslo a případně odstranit z počítačů cizopasné účty. Vzhledem k tomu že nechceme aby jsme měli na pracovních stanicích instalovaný Fortnite musíme jednat rychle. To znamená PowerShell 🙂 Kdo by to taky obíhal že.
Časy kdy PowerShell sám o sobě neměl žádné příkazy pro správu lokálních uživatelských účtů a hesel je již naštěstí pár let za námi.
Pokud si hodíte “Get-Help New-LocalUser” do powershellské konzole, velmi rychle zjistíte že příkazu New-LocalUser chybí pro nás zásadní parametr a to je: -ComputerName.
A tento parametr nemá žádný z příkazů pro práci s lokálními účty! Co to pro nás znamená? Ne nebudeme muset obíhat všech 55 PC. Ano budeme muset příkazy spustit na všech 55 PC lokálně.
Máme pár dalších možností jako:
- Enter–PSSession o které jsem se zmínil již na začátku ve vstupu do Powershellu že je to vlastně 1:1 spojení se vzdáleným PC a které musíme pro ukončení opustit příkazem Exit–PSSession.
- Nebo rozkopírovat skript do každého počítače ve firmě a po té ho centrálně jiným skriptem spouštět.
Myslím ale že obojí je pro naše použití dost krkolomné a složité.
Naštěstí má PowerShell jeden super CmdLet a to: Invoke-Command. Super je v tom že má parametr -ComputerName a jeho hlavní funkce je spuštění krátkého kódu(nejen Powershel ale třeba i CMD)
Takže pokud spustíme kód:
Invoke-Command -ComputerName pocitac045 -ScriptBlock {Get-LocalUser|FT}
tak ihned vidíme v tabulce jaké máme na počítači “pocitac045” lokální účty.
Pokud nemáme zrovna doménového administrátora tak si přidáme parametr práv spuštění:
Invoke-Command -ComputerName pocitac045 -ScriptBlock {Get-LocalUser|FT} -Credential Domain01\Admin01
Nyní už můžeme vše spustit z vlastní židle. A co teda spustíme?
No, jelikož víme že náš lokální administrátor jménem “instalator” již není cizí ani uklízečkám tak ho jednoduše smažeme z počítačů firmy. Určitě však doporučuji jako první operaci -> vytvořit nového lokálního administrátora. Pokud by vám počítač nějakým nedopatřením vypadl z domény, než tam vytvoříte nového, tak by jste měli velký problém.
$heslo = Read-Host -AsSecureString # vstup z klávesnice Invoke-Command -ComputerName SFPI05 -ScriptBlock {New-LocalUser -Name "instaler" –Password $heslo | Add-LocalGroupMember -Group "Administrators"} #přidání do administrators
A teprve nyní až nám již výše použitý příkaz Get-LocalUser ukáže že tam opravdu nový účet je, tak můžeme mazat:
Invoke-Command -ComputerName pocitac033 -ScriptBlock {Remove-LocalUser -Name "instalator"}
Samozřejmě je nesmysl ručně psát Get-LocalUser na každém PC pro kontrolu existence nového Admin účtu.
Stačí jednoduchá podmínka v předchozím mazacím scriptu:
$oldAdmin = "instalator" $newAdmin = "instaler" if(Get-LocalUser|Where Name -EQ $newAdmin) { Remove-LocalUser -Name $oldAdmin Write-Host "účet smazán"; } else { Write-Host "účet není, nic nemažu"; }
Nyní teda máme dva bloky kódu. Jeden nám vytvoří nový účet lokálního admina a druhý blok zkontroluje jestli je nový admin opravdu vytvořen a následně smaže starého. Mohli by jsme z těchto bloků udělat jeden script ale proč? Jsou to dvě různé operace a třeba se hodí je mít i samostatně 🙂
Takže máme dvě jádra skriptu které po spuštění udělá sice to co potřebujeme ale jen na jednom PC a my přece nebudeme klikat 55x. Stále to ještě není moc automatické.
Opět použijeme cyklus foreach na textový soubor který si nazveme newAdmin.txt
$computername = Get-Content 'C:\X\newAdmin.txt' foreach ($computer in $computername)
a opět musíme mít přehled kde to máme změněné a kde ne protože PC může být z nějakého důvodu vypnuté. K tomu se nám hodí hlášení do konzole Write-Host o stavu operace.
IF (Test-Connection -BufferSize 32 -Count 1 -ComputerName $computer -Quiet) {Je ON} Else {Je OFF}
A výsledný první skript je na světě:
cls $computername = Get-Content 'C:\X\newAdmin.txt' foreach ($computer in $computername) { IF (Test-Connection -BufferSize 32 -Count 1 -ComputerName $computer -Quiet) { Invoke-Command -ComputerName $computer -ScriptBlock {New-LocalUser -Name "instaler" -Password (ConvertTo-SecureString "MyPassword123" -AsPlainText) | Add-LocalGroupMember -Group "Administrators"} Write-Host "***** PC $computer vše OK ******************" } ELSE{Write-Host "***** PC $computer není online *************" } }
Všiměte si co musíme udělat pro to aby jsme mohli heslo do kódu napsat: (ConvertTo-SecureString “MyPassword123” -AsPlainText) je to proto že heslo se neukládá jako textový řetězec ale jako objekt “SecureString”.
Dalo by se to ještě udělat tak že skript se na heslo zeptá při spuštění:
$heslo = Read-Host -AsSecureString New-LocalUser –Name "installer" –Password $heslo | Add-LocalGroupMember -Group "Administrators"
Ale nemám rád když po mě skript něco chce i když jen jednou na 55 PC 🙂
A nyní už jen skoro stejný kód na kontrolu plus mazání starého admina. Jen se zde hodí mít samostatný seznam firemních PC třeba v delAdmin.txt aby jsme mohli hotové PC odmazávat.:
cls $computername = Get-Content 'C:\X\delAdmin.txt' foreach ($computer in $computername) { IF (Test-Connection -BufferSize 32 -Count 1 -ComputerName $computer -Quiet) { $command = {$oldAdmin = "instalator"; $newAdmin = "instaler"; if(Get-LocalUser|Where Name -EQ $newAdmin) # tady je kontrola existence nového admina {Remove-LocalUser -Name $oldAdmin; # zde dochází k výmazu Write-Host "účet smazán"} else{Write-Host "účet tam není nic nemažu"}} #když není new admin nic se nemaže! Invoke-Command -ComputerName $computer -ScriptBlock $command Write-Host "***** PC $computer vše OK ******************" } ELSE{Write-Host "***** PC $computer není online *************" } }
Jen si všimněte proměnné $command ve které je uložen celý kód který se provede na každém vzdáleném PC. Není to nutné ale je to přehlednější.