Posted in: Windows 10, Windows 11, Windows 8 a 8.1, Windows server, Základy PowerShellu

Generování hesel v PowerShellu

Každý správce, který se stará o nějaký identitní systém, potřebuje vymýšlet bezpečná jednorázová hesla. K tomu mu může sloužit například následující kousek PowerShell kódu:

$delka = 10
$specZnaku = 2
Add-Type -AssemblyName System.Web
[System.Web.Security.Membership]::GeneratePassword($delka,$specZnaku)

Verze, která nevyužívá volání .NET:

function Generate-Password
{
param
(
[int] $delka = 12,
[switch] $specZnak
)
$length = $delka
if($specZnak)
{
$charSet = ‚abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789{]+-[*=@:)}$^%;(_!&#?>/|.‘.ToCharArray()
}
else
{
$charSet = ‚abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789‘.ToCharArray()
}
$rng = New-Object System.Security.Cryptography.RNGCryptoServiceProvider
$bytes = New-Object byte
$rng.GetBytes($bytes)
$result = New-Object char
for ($i = 0 ; $i -lt $length ; $i++) {
$result[$i] = $charSet[$bytes[$i]%$charSet.Length]
}
return (-join $result)
}

Posted in: Windows 10, Windows 11, Windows 8 a 8.1, Windows server, Základy PowerShellu

Spuštění PowerShellu pod účtem operačního systému

V rámci balíčku nástrojů SysInternals od Microsoftu je k dispozici nástroj PSEXEC, který umožní spouštět aplikace pod účtem operačního systému. Nejspolehlivější a nejlepší využití je spustit si PowerShell, protože jeho pomocí mohu dělat cokoliv a spouštět cokoliv.
Příkaz bude mít tvar:
psexec -s -i powershell

Stažení a dokumentace PSXEC

Posted in: Windows server

Prověření hesel v AD

Tento článek bych rád věnoval problematice kontrole hesel, které využívají vaši uživatelé v rámci doménové sítě. Jednou věcí je vydefinovat politiku na složitost délku, dobu platnosti hesla a uzamykání stanic, což je naprostý základ každé domény a doporučuji toto nastavení definovat v Default Domain Policy.
Pokud je toto nastavení provedeno správně, značně ztěžuje slovníkový či brute-force útok na heslo uživatele, ale problém je v tom, že lokální AD na rozdíl od Azure AD neumí porovnávat hesla se známími uniklými hesly. Pomocí Azure AD Premuim lze při hybridním scénáři tuto funkcionalitu do lokálního AD nasadit, ale pojďmě se podívat na to, jak si podobný test provés bez cloudu.Tento manuální audit hesel by měli provádět pouze doménový správci, ostatně jsou jediní, kdo to může udělat legitimně. Test nemusíme, ani to nedoporučuji, provádět přímo na serveru Active Directory, co budeme potřebovat je počítač s Windows 10, naprosto ideálně počítač s klientskou verzí systému Windows odpovídající serverové verzi. Například pro Windows server 2012R2 to jsou 8.1, pro Windows server 2012 jsou to 8, pro Windows server 2016 a 2019 jsou to Window 10.Dále budeme potřebovat PowerShell modul od Michaela Grafnettera DSInternals, který leze instalovat normálně z PowerShell galery. Dokumentace je krom PowerShellu dostupná na GitHubu či webu.

Poslední potřebnou věcí jsou databáze uniklých hesel např. have i been pwned (NTLM Hash) nebo čistě textové. Ze stažených archivů exportujeme txt soubor s hesly.

Postup

  1. Ze záloíhy AD si obnovíme co nejnovější verzi ntds.dit a souboru SYSTEM (což je soubor registru ze složky: C:\Windows\System32\config)
  2. Spustíme PowerShell jako správce

V PowerShellu spustíme následující kód pro databázi NTLM Hashů hesel:

$ntdsPath = Read-Host -Prompt "Zadej cestu k ntds.dit"
$systempath = Read-Host -Prompt "Zadej cestu k souboru registru SYSTEM z DC"
$slovnik = Read-Host -Prompt "Zadej cestu k souboru slovníku NTLM hash"
$vystup = Read-Host -Prompt "Zadej umístění výstupního souboru txt"
Import-Module -Name DSInternals
$key = Get-BootKey -SystemHivePath $systempath
Get-ADDBAccount -All -DBPath $ntdsPath -BootKey $key | Test-PasswordQuality -WeakPasswordHashesFile $slovnik | Out-File $vystup -Encoding utf8

Pokud máme zdrojovou databázi (či vlastní list) v plaintextu, použijeme následující příkazy:

$ntdsPath = Read-Host -Prompt "Zadej cestu k ntds.dit"
$systempath = Read-Host -Prompt "Zadej cestu k souboru registru SYSTEM z DC"
$slovnik = Read-Host -Prompt "Zadej cestu k souboru slovníku NTLM hash"
$vystup = Read-Host -Prompt "Zadej umístění výstupního souboru txt"
Import-Module -Name DSInternals
$key = Get-BootKey -SystemHivePath $systempath
Get-ADDBAccount -All -DBPath $ntdsPath -BootKey $key | Test-PasswordQuality -WeakPasswordsFile $slovnik | Out-File $vystup -Encoding utf8

Nyní necháme proces proběhnout (trvá od jednotek minut do řádu hodin dle počtu účtů, velikosti databáze uniklých hesel, toho zda databáze obsahuje plaintextová hesla nebo rovnou hash a rychlosti disku). Po dokončení procesu máme ve výstupním souboru hotovou analýzu.

Posted in: Windows 10, Windows 11, Windows server

Výpis zařízení, která jsou HybridJoin do AAD

Zcela jistě nejsem sám, kdo v dnešní době zpravuje hybridní prostředí a proto se opět podíváme na to, jak si zjisti z AAD nějaké údaje, které se v portálu získávají obtížně či je nelze získat přímo.
Jak mi dá spousta z Vás za pravdu, na stránce se zařízení v portálu AAD se filtruje velmi špatně, takže se hodí PowerShell a právě ten využijeme k tomu, abychom zjistili počet a konkrétní seznam našich zařízení, která jsou joinovaná jak do lokálního AD, tak prostřednictvím např. AAD Connectu do AAD. Informace nám vytáhne následující script:

#kontrola, za máte modul MsolService a pokud ne, tak jeho instalace
if((get-module -Name MsolService) -eq $null) {
Install-Module -Name MsolService -force
import-module MsolService
}else {
import-module AzureAD
}
#připojení k AAD prostřednictvím tenantu Office 365
Connect-MsolService
#vylistování všech zařízení do tabulky
Get-msoldevice -all | Where-Object {$_.DeviceTrustType -eq "Domain Joined"} | select displayname, DeviceOSType, DeviceOsVersion, DeviceTrustType, DeviceTrustLevel, DeviceObjectVersion, ApproximateLastLogonTimestamp | Out-GridView
#stanovení počtu těchto zažízení
(Get-msoldevice -all | Where-Object {$_.DeviceTrustType -eq "Domain Joined"}).count
Posted in: Windows server

Jak přenést či zálohovat role a funkce Windows Serveru?

Dnes si představíme malý PowerShell skript, který Vám pomůže přenést všechny role a funkce z jednoho serveru na druhý. Na takto připraveném serveru je možné následně využít nástrojů pro migraci serveru, které dokáže exportovat a importovat jednotlivé konfigurace různých rolí a funkcí serveru. Základem ovšem zůstává mít instalované stejné role a funkce na starém i novém stroji a to jak vše provést na 2 spuštění sktriptu a přenesené jednoho TXT souboru si ukážeme. Nejprve je potřeba si uložit následující skript:

Function MigraceRoliFunkci
{
    Param(
        [Parameter(Mandatory=$true)]
        [String]$soubor = "C:\Users\Public\features.txt",
        [Parameter(Mandatory=$false)]
        [Switch]$Import
    )
    if($Import)
    {
        $file = Get-Content $soubor;
    	$radek = ($file.Count) - 3;
    	$role = Get-Content E:\funkce.txt -Tail $radek
        foreach ($f in $role)
        {
            Install-WindowsFeature -Name $f -IncludeManagementTools
        }
        Write-Host "Restartujte server co nejdříve!"
	}

     else

     {

	Get-WindowsFeature | Where-Object {$_. installstate -eq "installed"} | select name | Out-File -FilePath $soubor
        
	Write-Host "Vyzvednete si vygenerovany soubor pro import."
    
     }

}

Nyní jej můžeme spustit na starém serveru a následně zavolat funkci například takto:
MigraceRoliFunkci -soubor E:\funkce.txt
Nyní skriprt spustí export seznamu rolí a funkcí za našeho starého serveru na náš disk E do souboru funkce.txt.
Disk E přeneseme na nový server, kde pro zjednodušení bude mít také písmeno E, spustíme náš skript a opět budeme volat funkci:
MigraceRoliFunkci -soubor E:\funkce.txt -Import
Nyní naše funkce provede instalaci všech rolí a funkcí, které nalezne v souboru funkce.csv. Po dokončení instalace máme server připraven k importu nastavení, ale o tom až někdy jindy.

Posted in: Windows 10, Windows 11, Windows server

PowerShell script pro monitoring záloh a obnovu ze zálohy

Write-Host „Práce se zálohou serveru“;
Write-Host „“;
Write-Host „Menu:“ -ForegroundColor Green;
$volba;
Write-Host „1: Aktuální stav běžící zálohy“;
Write-Host „2: Výpis dostupných záloh“;
Write-Host „3: Výpis položek obsažených v záloze“;
Write-Host „4: Obnova souborů a složek do původního umístění“;
Write-Host „5: Obnova souborů a složek do vlastního umístění“;
Write-Host „6: Obnova celé jednotky“;
Write-Host „7: Obnova registru“;
Write-Host „8: Obnova systémového stavu“;
$volba = Read-Host -Prompt „Zadejte číslo své volby“;
function status()
{
Write-Host „Vypisuji stav běžící zálohy“ -ForegroundColor Green;
wbadmin get status
Write-Host „Stav záloh za poseldní týden“ -ForegroundColor Green;
Get-WBJob -Previous 7
}
function dostupne()
{
$cil = Read-Host -Prompt „Zadej cíl zálohy (např.: H:): „;
Write-Host „Vypisuji dostupné zálohy“ -ForegroundColor Green;
wbadmin get versions -backupTarget:$cil
}
function polozky()
{
$ID = Read-Host -Prompt „Zadej ID zálohy (např.: 01/27/2021-15:01): „;
Write-Host „Vypisuji položky zálohy“ -ForegroundColor Green;
wbadmin get items -version:$ID;
}
function souboryP()
{
Write-Host „Obnova soborů a složek“ -ForegroundColor Green;
$slozka = Read-Host -Prompt „Obnovuješ složku? (A/N): „;
$ID = Read-Host -Prompt „Zadej ID zálohy (např.: 01/27/2021-15:01): „;
$polozka = Read-Host -Prompt „Zadej položku k obnově (např.: E\Fotoalbum\MTZ)“;
if($slozka -eq „A“ -or $slozka -eq „a“)
{
wbadmin start recovery -version:$ID -itemType:File -items:$polozka -recursive;
}
else
{
wbadmin start recovery -version:$ID -itemType:File -items:$polozka;
}
}
function souboryS()
{
Write-Host „Obnova soborů a složek“ -ForegroundColor Green;
$slozka = Read-Host -Prompt „Obnovuješ složku? (A/N): „;
$ID = Read-Host -Prompt „Zadej ID zálohy (např.: 01/27/2021-15:01): „;
$polozka = Read-Host -Prompt „Zadej položku k obnově (např.: E\Fotoalbum\MTZ)“;
$cil = Read-Host -Prompt „Zadej cíl obnovy (např.: H\Foto\mtz)“
if($slozka -eq „A“ -or $slozka -eq „a“)
{
wbadmin start recovery -version:$ID -itemType:File -items:$polozka -recursive -recoverytarget:$cil;
}
else
{
wbadmin start recovery -version:$ID -itemType:File -items:$polozka -recoverytarget:$cil;
}
}
function jednotka()
{
Write-Host „Obnova jednotky“ -ForegroundColor Green;
$ID = Read-Host -Prompt „Zadej ID zálohy (např.: 01/27/2021-15:01): „;
$jednotka = Read-Host -Prompt „Zadej identifikátor jednotky (např.: \\?\Volume{cc566d14-44a0-11d9-9d93-806e6f6e6963}\“
wbadmin start recovery -version:$ID -itemType:Volume -items:$jednotka;
}
function registr()
{
Write-Host „Obnova registru přibyde v novější verzi“ -ForegroundColor red;
}
function system()
{
Write-Host „Obnova stavu systému“ -ForegroundColor Green;
$ID = Read-Host -Prompt „Zadej ID zálohy (např.: 01/27/2021-15:01): „;
wbadmin start systemstaterecovery -version:$ID;
}
switch($volba)
{
1{status}
2{dostupne}
3{polozky}
4{souboryP}
5{souboryS}
6{jednotka}
7{registr}
8{system}
default{Write-Host „Chybně zadaná volba, spusť skript znovu!“-ForegroundColor Red}
}

Posted in: Windows 10, Windows 11, Windows 8 a 8.1, Windows server, Základy PowerShellu

Kontrola spuštění PoweShellu v řežimu správce

Při správě serverů není nic vzácného, že PowerShell je potřeba spustit v privilegovaném módu. Určitě všichni správci znají fintu pravého tlačítka na skript a volby Run with PowerShell, ale jak ve sktirptu zkontrolovat, zda byl spuštěn s oprávněním správce? Zkuste následující větvení, které místo pouhých výpisů rolí obohaťte o svůj kód.

if((whoami /priv /fo csv | convertfrom-csv | select "Privilege Name")."Privilege Name" -contains "SeImpersonatePrivilege")
{"admin"}
else
{"user"}

Tento skript využívá toho, že účet správce má dva módy, jeden privilegovaný (obsahuje SID skupiuny Administrators) a jeden běžný (neobsahuje SID skupiny Administrators). Když i správce spustí aplikaci pouhým poklikáním, neběží v privilegovaném módu (až na vyjímky jako je Plánovač, Prohlížeč událostí apod.). Také PowerShell jde pustit v obou režimech a pokud výslovně správce nespustí PowerShell v řežimu správce, má stejná oprávnění jako běžný uživatel. Zobrazit jednotlivá oprávnění daného režimu PowerShellu jde příkazem:

whoami /priv

Více se pak dočtete v dokumentaci Microsoftru v sekci věnované uživatelským účtům.

Posted in: Windows server

Ruční řízení synchronizace Azure AD Connect

Dnes Vám ukáži primitivní skript, kterým je možné zjisti stav synchronizace a případně ručně spustit synchronizaci AD s Azure AD.

<#
    Skript vypíše stav synchronizace Azure ADconnect,
    provede pravidelnou nebo celou synchronizaci.
    Skript musí běžet na PC, kde je instalován Azure ADconnect.
#>
$volba = 0
Write-Host "volba 1: Zjištěnís tavu synchronizace"
Write-Host "volba 2: Spustí synchrnizaci"
Write-Host "volba 3: Spustí úplnou (iniciální) synchronizaci"
switch($volba)
{
    1{Get-ADSyncScheduler}
    2{Start-ADSyncSyncCycle -PolicyType Delta}
    3{Start-ADSyncSyncCycle -PolicyType Initial}
}
Posted in: Windows server

Výpis PC, která si rok neměnila heslo

Jak všichni správci AD ví, i počítače dodržují ze zdvořilosti politiku na změnu hesla. Reálně by to ovšem dělat nemusely, protože heslo počítače má 128 míst, takže jeho prolomení se tím značně komplikuje. Vyjímaje doménových řadičů si ovšem počítače mění heslo v souladu s default domain policy.  Pokud si PC např. rok nezměnil heslo, patrně je vyřazený, nebo opravdu nebyl v dosahu AD. Následující skript vyhledá taková PC a dokáže je smazat, ale musíte si dát pozor na doménové řadiče.

$Date = ((Get-Date).AddDays(-365))
$DC2 = Read-host -promt "Zadejte druhý řád názvu domény: "
$DC1 = Read-host -promt "Zadejte první řád názvu domény: "
#Počítače s více jak ro neměněným heslem​
Get-ADComputer -Filter 'PasswordLastSet -le $Date' -SearchBase "CN=Computers,DC= $DC2,DC=$DC1" -Properties PasswordLastSet | where Enabled -eq $true | FT Name,PasswordLastSet ​
#zakáže PC s rok neměněnýn heslem​
$zakazat = 0​
$zakazat = Read-Host -Prompt "Pro zakázání všech vypsaných účtů zvolte zadejte 1 jinak 0: "​
if($zakazat -eq 1)​
{​
    Disable-ADAccount -Identity (Get-ADComputer -Filter 'PasswordLastSet -le $Date' -Properties PasswordLastSet | where Enabled -eq $true)​
    Write-Host "Počítače byly zakázány"​
}​
else​
{​
    Write-Host "Žádný úet nebyl zakázán"​
}
Posted in: Windows server

Centrální zastavení / spuštění služby Windows Update

Všichni jsme se jako admini setkali se situací, kdy potřebujeme rychle zastavit aktulizace Windows v celé síti, ať z důvodu chybné aktualizace, či z jiného důvodu.
Dnes Vám ukáži, jak aktualizace vypnout pomocí PowerShellu, ale nezapomeňme, že je nutné Windows update po nezbytné době opět zapnout, protože podporované jsou jen plně aktualizované systémy 😉

<#
    
	Skript zastaví službu Windows Update na všech PC v doméně.
    
	Autor nenese žádnou odpovědnost za případné škody, 
	uživatel je povinen před spuštěním se seznámit se skriptem!

    
	Požadavky:
    
	- PowerShell verze 5 a novější
    
	- Admin oprávnění pro všechna PC
    
	- ExcutionPolicy set to bypass

    
	Petrásek Jan
    
	©2020

#>

Invoke-Command -ComputerName (Get-ADComputer -Filter * | select DNSHostName).DNSHostName -ScriptBlock {

	net stop wuauserv;
    sc.exe config wuauserv start=disabled

}

Nyní si uvedeme druhý skript, který aktualizace opět zapne:

<#
    
	Skript zastaví službu Windows Update na všech PC v doméně.
    
	Autor nenese žádnou odpovědnost za případné škody, 
	uživatel je povinen před spuštěním se seznámit se skriptem!

    
	Požadavky:
    
	- PowerShell verze 5 a novější
    
	- Admin oprávnění pro všechna PC
    
	- ExcutionPolicy set to bypass

    
	Petrásek Jan
    
	©2020

#>

Invoke-Command -ComputerName (Get-ADComputer -Filter * -SearchBase "CN=Computers,DC=arpida,DC=local" | select DNSHostName).DNSHostName -ScriptBlock {
	net start wuauserv;
    sc.exe config wuauserv start=auto

}
Back to Top