PowerShell automatizácia pre IT helpdesk: Kompletný sprievodca skriptami a nástrojmi (2026)

Praktický sprievodca automatizáciou helpdesk úloh cez PowerShell a Microsoft Graph SDK. Hotové skripty na správu hesiel, poštových schránok, licencií, Teams, onboarding, offboarding a bezpečnostné audity pre Microsoft 365.

Úvod: Prečo je PowerShell nepostrádateľný pre IT helpdesk

Ak pracujete na IT helpdesku, poznáte to — nekonečné resetovanie hesiel, zakladanie účtov, správa poštových schránok. Stále dokola, deň čo deň. A teraz si predstavte, že väčšinu z toho za vás urobí skript.

Presne na to je tu PowerShell. Nie je to žiadna novinka, ale v roku 2026 je to už kompletný ekosystém s modulmi pre Microsoft Graph, Exchange Online, Azure (Entra ID), SharePoint, Teams a kopec ďalších služieb. Prechod zo starého modulu AzureAD na Microsoft Graph PowerShell SDK je v podstate hotový a úprimne — ak ho ešte nepoužívate, je najvyšší čas začať.

Tento článok som napísal ako praktický sprievodca, kde nájdete hotové skripty na automatizáciu najčastejších helpdesk úloh. Či už ste začínajúci technik alebo skúsený admin, niečo užitočné si tu určite nájdete. Tak poďme na to.

Príprava prostredia: Inštalácia a konfigurácia PowerShell modulov

Inštalácia Microsoft Graph PowerShell SDK

Microsoft Graph PowerShell SDK je v roku 2026 primárny modul pre správu Microsoft 365 a Entra ID. Starší AzureAD modul bol oficiálne ukončený, takže všetky nové skripty by mali ísť cez Graph API. Inštalácia je jednoduchá:

# Inštalácia Microsoft Graph PowerShell SDK
Install-Module Microsoft.Graph -Scope CurrentUser

# Overenie inštalácie
Get-InstalledModule Microsoft.Graph

# Pripojenie k Microsoft 365 tenantu
Connect-MgGraph -Scopes "User.ReadWrite.All", "Group.ReadWrite.All", "Directory.ReadWrite.All"

Pri pripojení budete vyzvaní na prihlásenie a udelenie súhlasu s požadovanými oprávneniami. Pre produkčné prostredie odporúčam vytvoriť si aplikačnú registráciu v Entra ID s presne definovanými oprávneniami — princíp najmenších privilégií tu platí dvojnásobne.

Inštalácia Exchange Online Management modulu

Pre správu poštových schránok, distribučných skupín a e-mailových pravidiel potrebujete Exchange Online Management V3:

# Inštalácia Exchange Online Management modulu
Install-Module ExchangeOnlineManagement -Scope CurrentUser

# Pripojenie k Exchange Online
Connect-ExchangeOnline -UserPrincipalName [email protected]

Dôležité: Parameter -Credential pre Connect-ExchangeOnline bol v roku 2025 označený ako deprecated. Vždy používajte moderné metódy autentifikácie — ideálne certifikátovú autentifikáciu pre automatizované skripty. Naozaj, neriešte to cez uložené heslá.

Modul pre Microsoft Teams

# Inštalácia Microsoft Teams modulu
Install-Module MicrosoftTeams -Scope CurrentUser

# Pripojenie k Teams
Connect-MicrosoftTeams

Malá rada na záver tejto sekcie — snažte sa zostať v jednom module počas celej relácie, ak to úloha umožňuje. Prepínanie medzi modulmi vyžaduje opakované pripojenie a zbytočne spomaľuje prácu.

Správa používateľských účtov: Základné helpdesk operácie

Resetovanie hesla používateľa

Resetovanie hesla je klasika. Podľa štatistík tvorí až 20–50 % všetkých tiketov prvej úrovne (a podľa mojich skúseností je to niekedy ešte viac). Automatizácia tohto procesu je preto absolútna priorita:

# Resetovanie hesla pre konkrétneho používateľa
$userId = "[email protected]"
$newPassword = @{
    password = "DocasneHeslo123!"
    forceChangePasswordNextSignIn = $true
}

Update-MgUser -UserId $userId -PasswordProfile $newPassword

Write-Host "Heslo pre $userId bolo úspešne resetované." -ForegroundColor Green

Pre pokročilejšie resetovanie pomocou autentifikačných metód môžete použiť tento prístup:

# Resetovanie hesla cez Authentication Methods API
Connect-MgGraph -Scopes "UserAuthenticationMethod.ReadWrite.All"

$userId = "[email protected]"
$passwordMethodId = "28c10230-6103-485e-b985-444c60001490"

Reset-MgUserAuthenticationMethodPassword -UserId $userId `
    -AuthenticationMethodId $passwordMethodId `
    -NewPassword "NoveDocasneHeslo456!"

Poznámka k oprávneniam: Pre resetovanie hesiel potrebujete rolu Helpdesk Administrator, Password Administrator alebo User Administrator. Aplikačné oprávnenia (bez prihlásenia používateľa) nie sú pre túto operáciu podporované — musíte sa pripojiť v kontexte používateľa s dostatočnými právami.

Odomknutie zablokovaného účtu

Keď sa účet zablokuje kvôli opakovaným neúspešným prihlásením, helpdesk musí konať rýchlo. Toto je jeden z tých prípadov, kde mať pripravený skript šetrí nervy obom stranám:

# Odomknutie účtu v Entra ID
$userId = "[email protected]"

# Nastavenie accountEnabled na true
Update-MgUser -UserId $userId -AccountEnabled:$true

# Overenie stavu účtu
$user = Get-MgUser -UserId $userId -Property DisplayName, AccountEnabled
Write-Host "Účet $($user.DisplayName): Aktívny = $($user.AccountEnabled)"

Hromadné vyhľadávanie informácií o používateľoch

Helpdesk technici často potrebujú rýchlo zistiť, kto je manažér daného používateľa, do akých skupín patrí, aké licencie má. Namiesto preklikávania sa cez admin portál je tu funkcia, ktorá to všetko vytiahne naraz:

# Kompletný profil používateľa pre helpdesk
function Get-HelpdeskUserProfile {
    param(
        [Parameter(Mandatory=$true)]
        [string]$UserPrincipalName
    )

    # Základné informácie
    $user = Get-MgUser -UserId $UserPrincipalName -Property `
        DisplayName, UserPrincipalName, JobTitle, Department, `
        OfficeLocation, AccountEnabled, LastSignInDateTime

    # Priradené licencie
    $licenses = Get-MgUserLicenseDetail -UserId $UserPrincipalName

    # Členstvo v skupinách
    $groups = Get-MgUserMemberOf -UserId $UserPrincipalName

    # Výstup
    Write-Host "=== Profil používateľa ===" -ForegroundColor Cyan
    Write-Host "Meno: $($user.DisplayName)"
    Write-Host "E-mail: $($user.UserPrincipalName)"
    Write-Host "Pozícia: $($user.JobTitle)"
    Write-Host "Oddelenie: $($user.Department)"
    Write-Host "Kancelária: $($user.OfficeLocation)"
    Write-Host "Účet aktívny: $($user.AccountEnabled)"
    Write-Host ""
    Write-Host "=== Licencie ===" -ForegroundColor Cyan
    $licenses | ForEach-Object { Write-Host "  - $($_.SkuPartNumber)" }
    Write-Host ""
    Write-Host "=== Skupiny ===" -ForegroundColor Cyan
    $groups | ForEach-Object {
        $group = $_.AdditionalProperties
        Write-Host "  - $($group.displayName)"
    }
}

# Použitie
Get-HelpdeskUserProfile -UserPrincipalName "[email protected]"

Správa poštových schránok v Exchange Online

Kontrola veľkosti poštových schránok a kvót

Používateľ sa sťažuje, že nemôže odosielať e-maily? Jeden z prvých krokov je skontrolovať veľkosť jeho schránky. Možno jednoducho narazil na kvótu (stáva sa to častejšie, než by ste čakali):

# Štatistiky konkrétnej poštovej schránky
$mailbox = "[email protected]"
Get-MailboxStatistics -Identity $mailbox |
    Select-Object DisplayName, TotalItemSize, ItemCount, LastLogonTime |
    Format-List

# Prehľad najväčších schránok v organizácii
Get-Mailbox -ResultSize Unlimited |
    Get-MailboxStatistics |
    Sort-Object TotalItemSize -Descending |
    Select-Object DisplayName, TotalItemSize, ItemCount -First 20 |
    Format-Table -AutoSize

Správa oprávnení k poštovým schránkam

Delegovanie prístupu k schránkam je jednou z najčastejších požiadaviek. Asistentka potrebuje prístup do schránky riaditeľa, tím potrebuje zdieľanú schránku — klasické scenáre:

# Udelenie Full Access oprávnenia
Add-MailboxPermission -Identity "[email protected]" `
    -User "[email protected]" `
    -AccessRights FullAccess `
    -InheritanceType All

# Udelenie Send As oprávnenia
Add-RecipientPermission -Identity "[email protected]" `
    -Trustee "[email protected]" `
    -AccessRights SendAs -Confirm:$false

# Zobrazenie všetkých oprávnení na schránke
Get-MailboxPermission -Identity "[email protected]" |
    Where-Object { $_.User -ne "NT AUTHORITY\SELF" } |
    Select-Object User, AccessRights |
    Format-Table -AutoSize

Nastavenie automatických odpovedí (Out of Office)

Zamestnanec náhle ochorie a nepripojí sa k počítaču. Helpdesk musí nastaviť automatickú odpoveď za neho. Nič zložité, ale keď to robíte päťkrát denne, oceníte mať to v skripte:

# Nastavenie Out of Office odpovede
Set-MailboxAutoReplyConfiguration -Identity "[email protected]" `
    -AutoReplyState Scheduled `
    -StartTime "2026-02-24T08:00:00" `
    -EndTime "2026-02-28T17:00:00" `
    -InternalMessage "Dobrý deň, som momentálne mimo kanceláriu. V prípade naliehavých záležitostí kontaktujte moju kolegyňu [email protected]." `
    -ExternalMessage "Ďakujem za vašu správu. Som momentálne mimo kanceláriu do 28.2.2026. Odpoviem vám po návrate."

# Kontrola aktuálneho stavu automatických odpovedí
Get-MailboxAutoReplyConfiguration -Identity "[email protected]" |
    Select-Object AutoReplyState, StartTime, EndTime, InternalMessage

Report o presmerovaní e-mailov

Neautorizované presmerovania e-mailov môžu byť vážnym bezpečnostným rizikom. Tento skript rýchlo odhalí všetky schránky s aktívnym presmerovaním:

# Vyhľadanie schránok s nastaveným forwardovaním
Get-Mailbox -ResultSize Unlimited |
    Where-Object { $_.ForwardingSmtpAddress -ne $null -or $_.ForwardingAddress -ne $null } |
    Select-Object DisplayName, UserPrincipalName, ForwardingSmtpAddress, ForwardingAddress, DeliverToMailboxAndForward |
    Export-Csv -Path "C:\Reports\email-forwarding-report.csv" -NoTypeInformation -Encoding UTF8

Write-Host "Report bol exportovaný do C:\Reports\email-forwarding-report.csv"

Onboarding a offboarding používateľov

Automatizovaný onboarding nového zamestnanca

Onboarding nového zamestnanca zahŕňa množstvo krokov — vytvorenie účtu, priradenie licencie, pridanie do skupín, nastavenie poštovej schránky. Robiť to manuálne je otrava a hlavne sa pri tom ľahko na niečo zabudne. PowerShell to celé zautomatizuje:

# Funkcia pre onboarding nového zamestnanca
function New-EmployeeOnboarding {
    param(
        [string]$FirstName,
        [string]$LastName,
        [string]$Department,
        [string]$JobTitle,
        [string]$ManagerUPN,
        [string]$LicenseSku = "contoso:ENTERPRISEPACK"
    )

    # Generovanie UPN a hesla
    $displayName = "$FirstName $LastName"
    $mailNickname = ($FirstName.Substring(0,1) + "." + $LastName).ToLower()
    $upn = "[email protected]"
    $tempPassword = "Welcome2026!" + (Get-Random -Maximum 999)

    # Vytvorenie používateľa
    $passwordProfile = @{
        password = $tempPassword
        forceChangePasswordNextSignIn = $true
    }

    $newUser = New-MgUser -DisplayName $displayName `
        -UserPrincipalName $upn `
        -MailNickname $mailNickname `
        -PasswordProfile $passwordProfile `
        -Department $department `
        -JobTitle $jobTitle `
        -UsageLocation "SK" `
        -AccountEnabled:$true

    Write-Host "Účet vytvorený: $upn" -ForegroundColor Green

    # Priradenie licencie
    $license = @{
        AddLicenses = @(
            @{ SkuId = (Get-MgSubscribedSku | Where-Object SkuPartNumber -eq $LicenseSku.Split(":")[1]).SkuId }
        )
        RemoveLicenses = @()
    }
    Set-MgUserLicense -UserId $upn -BodyParameter $license
    Write-Host "Licencia priradená: $LicenseSku" -ForegroundColor Green

    # Nastavenie manažéra
    if ($ManagerUPN) {
        $manager = Get-MgUser -UserId $ManagerUPN
        $managerRef = @{ "@odata.id" = "https://graph.microsoft.com/v1.0/users/$($manager.Id)" }
        Set-MgUserManagerByRef -UserId $upn -BodyParameter $managerRef
        Write-Host "Manažér nastavený: $ManagerUPN" -ForegroundColor Green
    }

    # Výstup s prihlasovacími údajmi
    Write-Host ""
    Write-Host "=== Prihlasovanie údaje ===" -ForegroundColor Yellow
    Write-Host "UPN: $upn"
    Write-Host "Dočasné heslo: $tempPassword"
    Write-Host "Poznámka: Pri prvom prihlásení bude vyžadovaná zmena hesla."

    return $newUser
}

# Použitie
New-EmployeeOnboarding -FirstName "Peter" -LastName "Horváth" `
    -Department "Marketing" -JobTitle "Marketing špecialista" `
    -ManagerUPN "[email protected]"

Automatizovaný offboarding odchádzajúceho zamestnanca

Odchod zamestnanca je z bezpečnostného hľadiska kritický proces. Zabudnúť zablokovať prístup alebo zrušiť relácie môže mať nepríjemné následky. Tu je komplexný offboarding skript, ktorý pokryje všetko podstatné:

# Funkcia pre offboarding zamestnanca
function Start-EmployeeOffboarding {
    param(
        [Parameter(Mandatory=$true)]
        [string]$UserPrincipalName,
        [string]$ForwardTo,
        [switch]$ConvertToShared
    )

    Write-Host "Spúšťam offboarding pre: $UserPrincipalName" -ForegroundColor Yellow

    # 1. Resetovanie hesla (zabránenie prístupu)
    $randomPassword = -join ((65..90) + (97..122) + (48..57) | Get-Random -Count 24 | ForEach-Object {[char]$_})
    Update-MgUser -UserId $UserPrincipalName -PasswordProfile @{
        password = $randomPassword
        forceChangePasswordNextSignIn = $true
    }
    Write-Host "  [1/7] Heslo resetované" -ForegroundColor Green

    # 2. Zablokovanie prihlásenia
    Update-MgUser -UserId $UserPrincipalName -AccountEnabled:$false
    Write-Host "  [2/7] Prihlásenie zablokované" -ForegroundColor Green

    # 3. Zrušenie všetkých aktívnych relácií
    Revoke-MgUserSignInSession -UserId $UserPrincipalName
    Write-Host "  [3/7] Všetky relácie zrušené" -ForegroundColor Green

    # 4. Odstránenie zo všetkých skupín
    $groups = Get-MgUserMemberOf -UserId $UserPrincipalName
    foreach ($group in $groups) {
        try {
            Remove-MgGroupMember -GroupId $group.Id -DirectoryObjectId (Get-MgUser -UserId $UserPrincipalName).Id -ErrorAction SilentlyContinue
        } catch {
            # Niektoré členstvá nemožno odstrániť (dynamické skupiny)
        }
    }
    Write-Host "  [4/7] Odstránený zo skupín" -ForegroundColor Green

    # 5. Nastavenie presmerovania e-mailov (voliteľné)
    if ($ForwardTo) {
        Set-Mailbox -Identity $UserPrincipalName -ForwardingAddress $ForwardTo -DeliverToMailboxAndForward $true
        Write-Host "  [5/7] E-mail presmerovaný na: $ForwardTo" -ForegroundColor Green
    }

    # 6. Nastavenie automatickej odpovede
    Set-MailboxAutoReplyConfiguration -Identity $UserPrincipalName `
        -AutoReplyState Enabled `
        -InternalMessage "Tento zamestnanec už nepracuje v našej organizácii. Prosím, kontaktujte recepciu na [email protected]." `
        -ExternalMessage "Tento zamestnanec už nepracuje v našej organizácii. Prosím, kontaktujte nás na [email protected]."
    Write-Host "  [6/7] Automatická odpoveď nastavená" -ForegroundColor Green

    # 7. Konverzia na zdieľanú schránku (voliteľné)
    if ($ConvertToShared) {
        Set-Mailbox -Identity $UserPrincipalName -Type Shared
        Write-Host "  [7/7] Schránka konvertovaná na zdieľanú" -ForegroundColor Green
    }

    Write-Host ""
    Write-Host "Offboarding dokončený pre: $UserPrincipalName" -ForegroundColor Cyan
}

# Použitie
Start-EmployeeOffboarding -UserPrincipalName "[email protected]" `
    -ForwardTo "[email protected]" `
    -ConvertToShared

Správa Microsoft Teams cez PowerShell

Reporty o tímoch a kanáloch

IT helpdesk pravidelne rieši otázky okolo Teams — kto je vlastníkom tímu, aké kanály existujú, koľko členov tím má. Namiesto manuálneho klikania v admin centre si to vytiahnite skriptom:

# Prehľad všetkých tímov v organizácii
Get-Team | Select-Object DisplayName, GroupId, Visibility, Archived |
    Sort-Object DisplayName |
    Export-Csv -Path "C:\Reports\teams-prehlad.csv" -NoTypeInformation -Encoding UTF8

# Detail konkrétneho tímu s členmi
function Get-TeamDetails {
    param([string]$TeamName)

    $team = Get-Team -DisplayName $TeamName
    if (-not $team) {
        Write-Host "Tím '$TeamName' nebol nájdený." -ForegroundColor Red
        return
    }

    Write-Host "=== Tím: $($team.DisplayName) ===" -ForegroundColor Cyan
    Write-Host "Viditeľnosť: $($team.Visibility)"
    Write-Host "Archivovaný: $($team.Archived)"

    # Členovia
    $members = Get-TeamUser -GroupId $team.GroupId
    Write-Host "`nVlastníci:" -ForegroundColor Yellow
    $members | Where-Object Role -eq "owner" | ForEach-Object { Write-Host "  - $($_.User)" }

    Write-Host "`nČlenovia:" -ForegroundColor Yellow
    $members | Where-Object Role -eq "member" | ForEach-Object { Write-Host "  - $($_.User)" }

    # Kanály
    $channels = Get-TeamChannel -GroupId $team.GroupId
    Write-Host "`nKanály:" -ForegroundColor Yellow
    $channels | ForEach-Object { Write-Host "  - $($_.DisplayName) [$($_.MembershipType)]" }
}

Get-TeamDetails -TeamName "IT Helpdesk"

Identifikácia neaktívnych tímov

Nepoužívané tímy zaberajú zdroje a (čo je horšie) môžu predstavovať bezpečnostné riziko. Tento skript vám pomôže nájsť tímy bez aktivity za posledných 90 dní:

# Vyhľadanie neaktívnych tímov (bez aktivity za posledných 90 dní)
$teams = Get-Team
$inactiveTeams = @()

foreach ($team in $teams) {
    $groupId = $team.GroupId

    # Získanie poslednej aktivity cez Microsoft Graph
    try {
        $activity = Get-MgTeamActivity -TeamId $groupId -Period "D90" -ErrorAction Stop
        if (-not $activity) {
            $inactiveTeams += [PSCustomObject]@{
                TeamName = $team.DisplayName
                GroupId  = $groupId
                Visibility = $team.Visibility
            }
        }
    } catch {
        # Tím bez reportov aktivity
        $inactiveTeams += [PSCustomObject]@{
            TeamName = $team.DisplayName
            GroupId  = $groupId
            Visibility = $team.Visibility
        }
    }
}

Write-Host "Nájdených $($inactiveTeams.Count) neaktívnych tímov:" -ForegroundColor Yellow
$inactiveTeams | Format-Table -AutoSize

Správa licencií: Prehľad a optimalizácia

Report o priradených licenciách

Sledovanie licencií je kritické — jednak kvôli nákladom (Microsoft 365 licencie nie sú lacné), jednak kvôli dodržiavaniu licenčných podmienok. Nasledujúci skript vám dá kompletný prehľad:

# Prehľad všetkých dostupných licencií a ich využitia
Get-MgSubscribedSku | Select-Object SkuPartNumber,
    @{N="Celkom";E={$_.PrepaidUnits.Enabled}},
    @{N="Priradených";E={$_.ConsumedUnits}},
    @{N="Dostupných";E={$_.PrepaidUnits.Enabled - $_.ConsumedUnits}} |
    Format-Table -AutoSize

# Podrobný report: Kto má akú licenciu
$users = Get-MgUser -All -Property DisplayName, UserPrincipalName, AssignedLicenses
$licenseReport = @()

foreach ($user in $users) {
    if ($user.AssignedLicenses.Count -gt 0) {
        foreach ($lic in $user.AssignedLicenses) {
            $skuName = (Get-MgSubscribedSku | Where-Object SkuId -eq $lic.SkuId).SkuPartNumber
            $licenseReport += [PSCustomObject]@{
                Meno = $user.DisplayName
                UPN  = $user.UserPrincipalName
                Licencia = $skuName
            }
        }
    }
}

$licenseReport | Export-Csv -Path "C:\Reports\licencny-report.csv" -NoTypeInformation -Encoding UTF8
Write-Host "Licenčný report exportovaný: $($licenseReport.Count) záznamov"

Identifikácia nevyužitých licencií

Licencie priradené neaktívnym používateľom sú vyhodené peniaze. A verte mi, v organizáciách s niekoľkými stovkami zamestnancov sa to dokáže nazbierať na slušnú sumu. Tento skript pomáha identifikovať plytvanie:

# Používatelia s licenciou, ale bez prihlásenia za 90 dní
$cutoffDate = (Get-Date).AddDays(-90)

$inactiveWithLicense = Get-MgUser -All -Property DisplayName, UserPrincipalName, `
    SignInActivity, AssignedLicenses |
    Where-Object {
        $_.AssignedLicenses.Count -gt 0 -and
        ($_.SignInActivity.LastSignInDateTime -lt $cutoffDate -or
         $_.SignInActivity.LastSignInDateTime -eq $null)
    } |
    Select-Object DisplayName, UserPrincipalName,
        @{N="PoslednePrihlasenie";E={$_.SignInActivity.LastSignInDateTime}},
        @{N="PocetLicencii";E={$_.AssignedLicenses.Count}}

Write-Host "Neaktívni používatelia s licenciami: $($inactiveWithLicense.Count)" -ForegroundColor Yellow
$inactiveWithLicense | Sort-Object PoslednePrihlasenie | Format-Table -AutoSize

Bezpečnostné skripty pre helpdesk

Audit prihlasovacích aktivít

Helpdesk je často prvý kontaktný bod pri podozrení na kompromitovaný účet. Rýchla kontrola prihlasovacích aktivít je v takej chvíli kľúčová — potrebujete vidieť, odkiaľ a kedy sa kto prihlasoval:

# Kontrola posledných prihlásení používateľa
function Get-UserSignInHistory {
    param(
        [Parameter(Mandatory=$true)]
        [string]$UserPrincipalName,
        [int]$Days = 7
    )

    $startDate = (Get-Date).AddDays(-$Days).ToString("yyyy-MM-ddTHH:mm:ssZ")

    $signIns = Get-MgAuditLogSignIn -Filter "userPrincipalName eq '$UserPrincipalName' and createdDateTime ge $startDate" `
        -Top 50 |
        Select-Object CreatedDateTime,
            @{N="Stav";E={$_.Status.ErrorCode}},
            @{N="Aplikacia";E={$_.AppDisplayName}},
            @{N="IP";E={$_.IpAddress}},
            @{N="Mesto";E={$_.Location.City}},
            @{N="Krajina";E={$_.Location.CountryOrRegion}},
            @{N="Zariadenie";E={$_.DeviceDetail.DisplayName}},
            @{N="Prehliadac";E={$_.DeviceDetail.Browser}}

    Write-Host "=== Prihlásenia za posledných $Days dní ===" -ForegroundColor Cyan
    Write-Host "Používateľ: $UserPrincipalName"
    Write-Host "Celkom prihlásení: $($signIns.Count)"

    # Zobrazenie neúspešných prihlásení
    $failed = $signIns | Where-Object Stav -ne 0
    if ($failed.Count -gt 0) {
        Write-Host "`nNeúspešné prihlásenia: $($failed.Count)" -ForegroundColor Red
        $failed | Format-Table CreatedDateTime, IP, Mesto, Krajina, Aplikacia -AutoSize
    }

    # Zobrazenie prihlásení z neobvyklých lokalít
    $signIns | Group-Object Krajina | Sort-Object Count -Descending |
        ForEach-Object { Write-Host "  $($_.Name): $($_.Count) prihlásení" }
}

Get-UserSignInHistory -UserPrincipalName "[email protected]" -Days 14

Kontrola MFA stavu používateľov

Overenie, že všetci používatelia majú nakonfigurované viacfaktorové overenie, je dnes úplný základ. Bez MFA je len otázkou času, kedy dôjde k incidentu:

# Report o MFA registrácii používateľov
$users = Get-MgUser -All -Property DisplayName, UserPrincipalName, AccountEnabled

$mfaReport = @()
foreach ($user in $users) {
    if (-not $user.AccountEnabled) { continue }

    $methods = Get-MgUserAuthenticationMethod -UserId $user.UserPrincipalName

    $mfaReport += [PSCustomObject]@{
        Meno = $user.DisplayName
        UPN  = $user.UserPrincipalName
        PocetMetod = $methods.Count
        MaAuthenticator = ($methods | Where-Object { $_.AdditionalProperties."@odata.type" -like "*microsoftAuthenticator*" }) -ne $null
        MaTelefon = ($methods | Where-Object { $_.AdditionalProperties."@odata.type" -like "*phone*" }) -ne $null
    }
}

# Používatelia bez MFA (iba heslo)
$bezMFA = $mfaReport | Where-Object PocetMetod -le 1
Write-Host "Používatelia bez MFA: $($bezMFA.Count) z $($mfaReport.Count)" -ForegroundColor Red
$bezMFA | Format-Table Meno, UPN -AutoSize

Diagnostické skripty: Riešenie bežných problémov

Kontrola stavu služieb Microsoft 365

Keď viacerí používatelia hlásia rovnaký problém naraz, prvé, čo by ste mali overiť, je či nie je výpadok na strane Microsoftu. Ušetrí vám to hodiny zbytočného troubleshootingu:

# Kontrola stavu Microsoft 365 služieb
Connect-MgGraph -Scopes "ServiceHealth.Read.All"

$healthOverview = Get-MgServiceAnnouncementHealthOverview
$issues = $healthOverview | Where-Object Status -ne "serviceOperational"

if ($issues.Count -eq 0) {
    Write-Host "Všetky služby Microsoft 365 sú funkčné." -ForegroundColor Green
} else {
    Write-Host "Služby s problémami:" -ForegroundColor Red
    $issues | Select-Object Service, Status | Format-Table -AutoSize

    # Detail aktívnych incidentov
    $incidents = Get-MgServiceAnnouncementIssue -Filter "isResolved eq false"
    foreach ($incident in $incidents) {
        Write-Host "`n[$($incident.Service)] $($incident.Title)" -ForegroundColor Yellow
        Write-Host "  Stav: $($incident.Status)"
        Write-Host "  Začiatok: $($incident.StartDateTime)"
    }
}

Diagnostika poštovej schránky

Používateľ neodosiela ani neprijíma e-maily a vy neviete, kde začať? Tento diagnostický skript prejde všetky bežné príčiny — od existencie schránky, cez kvóty, pravidlá doručenej pošty, až po presmerovania:

# Komplexná diagnostika poštovej schránky
function Test-MailboxHealth {
    param([string]$Identity)

    Write-Host "=== Diagnostika: $Identity ===" -ForegroundColor Cyan

    # 1. Existuje schránka?
    $mailbox = Get-Mailbox -Identity $Identity -ErrorAction SilentlyContinue
    if (-not $mailbox) {
        Write-Host "CHYBA: Poštová schránka neexistuje!" -ForegroundColor Red
        return
    }
    Write-Host "[OK] Schránka existuje: $($mailbox.PrimarySmtpAddress)" -ForegroundColor Green

    # 2. Typ schránky
    Write-Host "Typ schránky: $($mailbox.RecipientTypeDetails)"

    # 3. Veľkosť a kvóta
    $stats = Get-MailboxStatistics -Identity $Identity
    $quota = $mailbox.ProhibitSendQuota
    Write-Host "Veľkosť: $($stats.TotalItemSize) / Kvóta: $quota"

    # 4. Aktívne pravidlá doručenej pošty
    $rules = Get-InboxRule -Mailbox $Identity
    if ($rules.Count -gt 0) {
        Write-Host "`nAktívne pravidlá ($($rules.Count)):" -ForegroundColor Yellow
        $rules | ForEach-Object {
            Write-Host "  - $($_.Name): Presun do $($_.MoveToFolder) | Odstrániť: $($_.DeleteMessage)"
        }
    }

    # 5. Presmerovanie
    if ($mailbox.ForwardingSmtpAddress) {
        Write-Host "`nPRESMEROVANIE AKTÍVNE: $($mailbox.ForwardingSmtpAddress)" -ForegroundColor Yellow
    }

    # 6. Automatické odpovede
    $autoReply = Get-MailboxAutoReplyConfiguration -Identity $Identity
    if ($autoReply.AutoReplyState -ne "Disabled") {
        Write-Host "`nAutomatická odpoveď: $($autoReply.AutoReplyState)" -ForegroundColor Yellow
    }

    # 7. Posledné prihlásenie
    Write-Host "`nPosledné prihlásenie: $($stats.LastLogonTime)"
}

Test-MailboxHealth -Identity "[email protected]"

Vytváranie reportov a pravidelná automatizácia

Denný helpdesk report

Automatizovaný denný report je niečo, čo by mal mať každý helpdesk tím. Dáva vám prehľad o stave prostredia ešte predtým, než začnú prichádzať tikety. A úprimne, keď ráno otvoríte report a vidíte, že je všetko v poriadku, začnete deň oveľa lepšie:

# Denný prehľadový report pre helpdesk
function New-DailyHelpdeskReport {
    $reportDate = Get-Date -Format "yyyy-MM-dd"
    $report = @()

    # 1. Zablokované účty
    $lockedAccounts = Get-MgUser -All -Property DisplayName, UserPrincipalName, AccountEnabled |
        Where-Object { -not $_.AccountEnabled }
    $report += "ZABLOKOVANÉ ÚČTY: $($lockedAccounts.Count)"

    # 2. Heslá expirujúce do 7 dní
    $passwordExpiring = Get-MgUser -All -Property DisplayName, UserPrincipalName, PasswordPolicies, LastPasswordChangeDateTime |
        Where-Object {
            $_.LastPasswordChangeDateTime -and
            $_.LastPasswordChangeDateTime.AddDays(90) -lt (Get-Date).AddDays(7) -and
            $_.PasswordPolicies -notcontains "DisablePasswordExpiration"
        }
    $report += "HESLÁ EXPIRUJÚCE DO 7 DNÍ: $($passwordExpiring.Count)"

    # 3. Licencie blízko limitu
    $licensesLow = Get-MgSubscribedSku | Where-Object {
        ($_.PrepaidUnits.Enabled - $_.ConsumedUnits) -lt 5 -and $_.PrepaidUnits.Enabled -gt 0
    }
    $report += "LICENCIE S NÍZKYM ZOSTATKOM: $($licensesLow.Count)"

    # 4. Stav služieb
    $serviceIssues = Get-MgServiceAnnouncementHealthOverview | Where-Object Status -ne "serviceOperational"
    $report += "SLUŽBY S PROBLÉMAMI: $($serviceIssues.Count)"

    # Výstup
    Write-Host "========================================" -ForegroundColor Cyan
    Write-Host "  DENNÝ HELPDESK REPORT - $reportDate" -ForegroundColor Cyan
    Write-Host "========================================" -ForegroundColor Cyan
    $report | ForEach-Object { Write-Host $_ }
    Write-Host "========================================" -ForegroundColor Cyan

    # Export do súboru
    $report | Out-File "C:\Reports\daily-report-$reportDate.txt"
}

New-DailyHelpdeskReport

Automatizácia cez Task Scheduler

Pre pravidelné spúšťanie reportov využite Windows Task Scheduler. Stačí vytvoriť naplánovanú úlohu:

# Vytvorenie naplánovanej úlohy pre denný report
$action = New-ScheduledTaskAction -Execute "PowerShell.exe" `
    -Argument "-ExecutionPolicy Bypass -File C:\Scripts\Daily-Report.ps1"

$trigger = New-ScheduledTaskTrigger -Daily -At "07:00"

$settings = New-ScheduledTaskSettingsSet -StartWhenAvailable `
    -DontStopOnIdleEnd -AllowStartIfOnBatteries

Register-ScheduledTask -TaskName "IT-Helpdesk-DennyReport" `
    -Action $action -Trigger $trigger -Settings $settings `
    -Description "Denný report pre IT helpdesk" `
    -User "SYSTEM"

Pre cloudové prostredie zvážte Azure Automation alebo Power Automate — oba vám umožnia spúšťať skripty bez potreby lokálneho servera, čo je v praxi oveľa pohodlnejšie.

Osvedčené postupy a bezpečnostné odporúčania

Zabezpečenie PowerShell skriptov

Skôr než začnete skripty nasadzovať do produkcie, zapamätajte si niekoľko dôležitých pravidiel:

  • Nikdy neukladajte heslá v plain texte — používajte Azure Key Vault, Windows Credential Manager alebo certifikátovú autentifikáciu. Naozaj, ani „len dočasne".
  • Aplikujte princíp najmenších privilégií — servisné účty by mali mať iba oprávnenia nevyhnutné pre danú úlohu, nič viac.
  • Používajte certifikátovú autentifikáciu pre automatizované skripty namiesto interaktívneho prihlásenia.
  • Zaznamenávajte všetky operácie — každý skript by mal generovať log s časovou značkou a identifikáciou operátora.
  • Vždy testujte v testovacom prostredí pred nasadením do produkcie. Viem, znie to samozrejme, ale koľkokrát som videl, ako sa to preskočilo...
  • Používajte verziovací systém (Git) pre sledovanie zmien v skriptoch.

Šablóna bezpečného skriptu

Tu je základná šablóna s logovaním a spracovaním chýb, ktorú môžete použiť ako východiskový bod pre svoje skripty:

# Šablóna s logovaním a error handlingom
function Invoke-HelpdeskAction {
    param(
        [Parameter(Mandatory=$true)]
        [string]$Action,
        [Parameter(Mandatory=$true)]
        [string]$Target,
        [string]$LogPath = "C:\Logs\helpdesk-actions.log"
    )

    $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
    $operator = $env:USERNAME

    try {
        # Zaznamenanie začiatku akcie
        "$timestamp | $operator | START | $Action | $Target" | Out-File $LogPath -Append

        # Tu vykonajte konkrétnu akciu
        # ...

        "$timestamp | $operator | SUCCESS | $Action | $Target" | Out-File $LogPath -Append
        Write-Host "Akcia úspešne dokončená." -ForegroundColor Green
    }
    catch {
        "$timestamp | $operator | ERROR | $Action | $Target | $($_.Exception.Message)" | Out-File $LogPath -Append
        Write-Host "Chyba: $($_.Exception.Message)" -ForegroundColor Red
        throw
    }
}

Organizácia knižnice skriptov

Keď vám skriptov pribudne (a verte mi, pribudne), oceníte jasnú štruktúru priečinkov. Tu je odporúčaná organizácia:

C:\Scripts\Helpdesk\
├── Modules\
│   ├── HelpdeskTools.psm1        # Zdieľané funkcie
│   └── HelpdeskConfig.psd1       # Konfigurácia
├── UserManagement\
│   ├── Reset-Password.ps1
│   ├── New-Employee.ps1
│   └── Remove-Employee.ps1
├── Exchange\
│   ├── Set-OutOfOffice.ps1
│   ├── Set-MailboxPermissions.ps1
│   └── Get-MailboxReport.ps1
├── Teams\
│   ├── Get-TeamReport.ps1
│   └── Find-InactiveTeams.ps1
├── Reports\
│   ├── Daily-Report.ps1
│   └── License-Audit.ps1
└── Logs\
    └── helpdesk-actions.log

Prechod na Microsoft Graph: Čo potrebujete vedieť v roku 2026

V roku 2026 je migrácia na Microsoft Graph PowerShell SDK už nevyhnutná. Staré moduly Azure AD PowerShell a MSOnline sú definitívne ukončené. Ak ste doteraz odkladali migráciu, teraz je naozaj posledný zvonček. Tu je stručný prehľad najdôležitejších zmien:

  • Get-AzureADUserGet-MgUser
  • Set-AzureADUserPasswordUpdate-MgUser -PasswordProfile
  • Get-AzureADGroupGet-MgGroup
  • Add-AzureADGroupMemberNew-MgGroupMember
  • Get-AzureADUserMembershipGet-MgUserMemberOf

A tu sú kľúčové rozdiely, na ktoré si treba dať pozor:

  • Granulárne oprávnenia: Musíte špecifikovať presné scopes pri pripojení (napr. User.Read.All namiesto globálneho prístupu). Je to viac práce na začiatku, ale z dlhodobého hľadiska je to správny prístup.
  • Stránkovanie: Graph API vracia výsledky po stránkach — použite parameter -All pre získanie všetkých záznamov. Na toto sa zabúda najčastejšie.
  • Konzistentné API: Všetky služby Microsoft 365 sú dostupné cez jedno API, čo v konečnom dôsledku zjednodušuje integráciu.

Záver: Automatizujte, čo sa dá

PowerShell automatizácia nie je len o písaní skriptov — je to o zmene prístupu k práci. Každá úloha, ktorú robíte opakovane, je príležitosťou na automatizáciu. Začnite s tými najčastejšími (resetovanie hesiel, onboarding), postupne pridávajte zložitejšie scenáre a budujte si knižnicu overených skriptov, ktorú môže využívať celý tím.

Kľúčové odporúčania na záver:

  1. Začnite jednoducho — prvé skripty by mali riešiť to, čo vás najviac zdržiava.
  2. Dokumentujte — každý skript by mal mať jasný popis, príklady použitia a zoznam požadovaných oprávnení. Budúce ja vám poďakuje.
  3. Zdieľajte v tíme — uložte skripty do Git repozitára a vytvorte jednoduchú wiki s pokynmi.
  4. Testujte pred nasadením — vždy testujte v testovacom prostredí alebo s parametrom -WhatIf.
  5. Sledujte novinky — Microsoft neustále aktualizuje Graph API a PowerShell moduly, oplatí sa pravidelne kontrolovať aktualizácie.
  6. Automatizujte reporty — pravidelné reporty vám pomôžu odhaliť problémy skôr, než si ich všimnú používatelia.

S týmito nástrojmi a postupmi dokáže aj malý helpdesk tím efektívne spravovať stovky až tisíce používateľov v prostredí Microsoft 365. A to je nakoniec to, o čom dobrý helpdesk je — robiť viac s menej námahou.

O Autorovi Editorial Team

Our team of expert writers and editors.