PowerShell/06advanced14 min

Automatyzacja produkcyjna — wzorce z realnych skryptów ZEUS

Ta lekcja zbiera wszystko w jedno: jak wyglądają realne, produkcyjne probe'y ZEUS — Get-LsnForest, Get-LsnInventory, Get-LsnPerf. To wzorce sprawdzone na środowiskach klientów, gdzie skrypt musi działać bez nadzoru i oddać czysty wynik backendowi.

Kontrakt z backendem: -AsJson na stdout

Backend ZEUS uruchamia probe zdalnie i czyta wyłącznie stdout jako JSON. Dlatego diagnostyka idzie na Write-Verbose/Write-Error, a na stdout trafia tylko jeden obiekt JSON.

[CmdletBinding()]
param(
    [Parameter(Mandatory)][string]$Forest,
    [switch]$AsJson
)
$ErrorActionPreference = "Stop"

try {
    $data = Get-LsnInventoryData -Forest $Forest   # zbiera obiekty
    $out  = [pscustomobject]@{ Ok = $true; Forest = $Forest; Items = $data }
}
catch {
    $out = [pscustomobject]@{ Ok = $false; Error = $_.Exception.Message }
}

if ($AsJson) {
    $out | ConvertTo-Json -Depth 8 -Compress    # JEDYNE wyjście na stdout
} else {
    $out
}

Standard ProfessNet: w trybie -AsJson na stdout pojawia się dokładnie jeden dokument JSON. Żadnych Write-Host, bannerów ani debug printów — zaśmieciłyby strumień, który parsuje backend. Diagnostyka → Write-Verbose.

Paged LDAP — duże forest'y bez timeoutu

Inwentaryzacja dużego forestu zwraca dziesiątki tysięcy obiektów. Pobieramy je stronami (paged search), żeby nie przekroczyć limitu serwera LDAP ani pamięci.

function Invoke-LsnLdapPaged {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)][string]$Filter,
        [int]$PageSize = 1000
    )
    $searcher = [adsisearcher]$Filter
    $searcher.PageSize = $PageSize          # kluczowe — bez tego limit ~1000
    $searcher.PropertiesToLoad.AddRange(@('name', 'dNSHostName', 'operatingSystem'))

    foreach ($entry in $searcher.FindAll()) {
        [pscustomobject]@{
            Name = $entry.Properties['name'][0]
            Dns  = $entry.Properties['dnshostname'][0]
            Os   = $entry.Properties['operatingsystem'][0]
        }
    }
}

Standard ProfessNet: zapytania LDAP zawsze z PageSize (np. 1000). Bez stronicowania serwer AD ucina wyniki na domyślnym limicie, a probe zwraca niekompletne dane — cichy, groźny błąd.

Zdalne zbieranie: Invoke-Command przez WinRM

Performance i dane lokalne zbieramy na docelowych maszynach przez WinRM. Sesję zamykamy w finally, równoległość ograniczamy -ThrottleLimit.

function Get-LsnPerf {
    [CmdletBinding()]
    param(
        [Parameter(Mandatory)][string[]]$ComputerName,
        [Parameter(Mandatory)][pscredential]$Credential,
        [switch]$AsJson
    )
    $ErrorActionPreference = "Stop"

    $results = Invoke-Command `
        -ComputerName $ComputerName `
        -Credential $Credential `
        -ThrottleLimit 16 `
        -ScriptBlock {
            [pscustomobject]@{
                Host = $env:COMPUTERNAME
                Cpu  = (Get-CimInstance Win32_Processor).LoadPercentage
                MemFreeMB = [math]::Round((Get-CimInstance Win32_OperatingSystem).FreePhysicalMemory / 1KB)
            }
        }

    $out = [pscustomobject]@{ Ok = $true; Count = $results.Count; Hosts = $results }
    if ($AsJson) { $out | ConvertTo-Json -Depth 6 -Compress } else { $out }
}

Standard ProfessNet: Invoke-Command z listą hostów uruchamia się równolegle z -ThrottleLimit (domyślnie 32, u nas ograniczamy do ~16, by nie przeciążyć sieci klienta). Poświadczenia zawsze jako [pscredential] — nigdy w skrypcie.

Łączenie wzorców

WzorzecPo co
-AsJson + jeden JSON na stdoutczysty kontrakt z backendem
$ErrorActionPreference = "Stop" + try/catchbłąd jako JSON, nie zawis
Paged LDAP (PageSize)kompletne dane z dużych forestów
Invoke-Command + -ThrottleLimitzdalne zbieranie, kontrola obciążenia
[pscredential] + finallybezpieczeństwo i sprzątanie sesji

Wskazówka: testuj probe lokalnie z -Verbose (zobaczysz przebieg), a w integracji z backendem zawsze przez -AsJson i sprawdź, że ConvertFrom-Json po stronie odbiorcy się powiedzie — to realny test kontraktu.


-AsJson na stdout, stronicowany LDAP i zdalny Invoke-Command z throttlingiem to trzon produkcyjnych probe'ów ZEUS. Złożone razem dają skrypt, który działa bez nadzoru na środowisku klienta i oddaje backendowi czysty, kompletny wynik.