PSSYSAdm.psm1

#Region '.\Public\Disable-CompromisedUser.ps1' 0
<#
.SYNOPSIS
Disable compromised user
 
.DESCRIPTION
Disable compromised users
 
.PARAMETER Identity
One or more user(s) to disable
 
.PARAMETER FileName
File with a list of users to disable. txt with one name by line
 
.PARAMETER OU
One or more OU(s) in which we want to disable all users
 
.PARAMETER Check
Only check if the users passed in parameter, whatever the way (Identity, Filename or OU), are disable
 
.EXAMPLE
Disable-CompromisedUser -Identity "User1"
 
Disable the user account : User1
 
.EXAMPLE
Disable-CompromisedUser -Identity "User1" -Check
 
Check if user account User1 is disable
 
.EXAMPLE
Disable-CompromisedUser -Identity "User1","User2","User3"
 
Disable users account : User1, User2 and User3
 
.EXAMPLE
Disable-CompromisedUser -Identity "User1","User2","User3" -Check
 
Check if users account User1, User2 and User3 are disable
 
.EXAMPLE
Disable-CompromisedUser -FileName "c:\temp\CompromisedUser.txt"
 
File template CompromisedUser.txt :
User1
User2
User3
 
Disable users account : User1, User2 and User3
 
.EXAMPLE
Disable-CompromisedUser -FileName "c:\temp\CompromisedUser.txt" -Check
 
File template CompromisedUser.txt :
User1
User2
User3
 
Check if users account User1, User2 and User3 are disable
 
.EXAMPLE
Disable-CompromisedUser -OU "OU=OU1,DC=contoso,DC=com"
 
Disable all users present in OU1
 
.EXAMPLE
Disable-CompromisedUser -OU "OU=OU1,DC=contoso,DC=com" -Check
 
Check if all users present in OU1 are disable
 
.EXAMPLE
Disable-CompromisedUser -OU "OU=OU1,DC=contoso,DC=com","OU=OU2,DC=contoso,DC=com"
 
Disable all users present in OU1 and OU2
 
.EXAMPLE
Disable-CompromisedUser -OU "OU=OU1,DC=contoso,DC=com","OU=OU2,DC=contoso,DC=com" -check
 
Check if all users present in OU1 and OU2 are disable
 
.NOTES
General notes
#>

function Disable-CompromisedUser
{
    [CmdletBinding(DefaultParameterSetName = "ByUser")]
    param (
        [Parameter(
            ParameterSetName = "ByUser",
            HelpMessage = 'One or more user(s) to disable'
        )]
        [System.String[]]$Identity,
        [Parameter(
            ParameterSetName = "ByFileName",
            HelpMessage = 'File with a list of users to disable. txt with one name by line'
        )]
        [System.String]$FileName,
        [Parameter(
            ParameterSetName = "ByOu",
            HelpMessage = 'One or more OU(s) in which we want to disable all users'
        )]
        [System.String[]]$OU,
        [Parameter(
            HelpMessage = 'Only check if the users passed in parameter, whatever the way (Identity, Filename or OU), are disable'
        )]
        [Switch]$Check
    )

    begin
    {

        $LogFile = "$env:temp\DisableCompromisedUser-$((get-date).ToString("yyyyMMddTHHmmss")).log"
        if (Test-Path -Path $LogFile)
        {
            Remove-Item -Path $LogFile -Force
        }
        Write-Verbose ('[{0:O}] Log File {1}' -f (get-date),$LogFile)
        Write-Verbose ('[{0:O}] Retrieve AD User Account ' -f (get-date))
        $Users = @()

        switch ($PSCmdlet.ParameterSetName)
        {
            ByUser
            {
                Add-content $Logfile -value ('[{0:O}] Retrieve AD User Account by user list ' -f (get-date))
                foreach ($User in $Identity)
                {
                    try
                    {
                        $Users += Get-ADUser -Identity $User -Properties SamAccountName,DisplayName,Enabled -ErrorAction Continue | Select-Object SamAccountName,DisplayName,Enabled
                        Write-Verbose ('[{0:O}] User {1} found ' -f (get-date),$User)
                        Add-content $Logfile -value ('[{0:O}] User {1} found ' -f (get-date),$User)
                    }
                    catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException]
                    {
                        Write-Verbose ('[{0:O}] user {1} not found' -f (get-date), $User)
                        Add-content $Logfile -value (('[{0:O}] user {1} not found' -f (get-date), $User))
                    }
                }
            }
            ByFileName
            {
                Add-content $Logfile -value ('[{0:O}] [INFO] Retrieve AD User Account by filename ' -f (get-date))
                foreach ($User in (Get-Content -Path $FileName))
                {
                    try
                    {
                        $Users += Get-ADUser -Identity $User -Properties SamAccountName,DisplayName,Enabled -ErrorAction Continue | Select-Object SamAccountName,DisplayName,Enabled
                        Write-Verbose ('[{0:O}] [INFO] [FOUND] user {1} ' -f (get-date),$User)
                        Add-content $Logfile -value ('[{0:O}] [INFO] [FOUND] user {1} ' -f (get-date),$User)
                    }
                    catch [Microsoft.ActiveDirectory.Management.ADIdentityNotFoundException]
                    {
                        Write-Verbose ('[{0:O}] [ERROR] [NOTFOUND] user {1} ' -f (get-date), $User)
                        Add-content $Logfile -value (('[{0:O}] [ERROR] [NOTFOUND] user {1}' -f (get-date), $User))
                    }
                }
            }
            ByOu
            {
                Add-content $Logfile -value ('[{0:O}] [INFO] Retrieve AD User Account by OU list ' -f (get-date))
                foreach ($Organ in $OU)
                {
                    Write-Verbose ('[{0:O}] [INFO] Retrieve all users from OU {1}' -f (get-date), $Organ)
                    Add-content $Logfile -value (('[{0:O}] [INFO] Retrieve all users from OU {1}' -f (get-date), $Organ))
                    $Users += Get-ADUser -Filter * -SearchBase $Organ -Properties SamAccountName,DisplayName,Enabled | Select-Object SamAccountName,DisplayName,Enabled
                }
            }
        }

        Write-Verbose ('[{0:O}] [INFO] {1} AD user account found ' -f (get-date), $Users.Count)
        Add-content $Logfile -value (('[{0:O}] [INFO] {1} AD user account found ' -f (get-date), $Users.Count))
    }

    process
    {

        foreach ($user in $Users)
        {
            if ($Check)
            {
                Write-Verbose (('[{0:O}] [INFO] Check state for user {1} ' -f (get-date), $User.SamAccountName))
                Add-content $Logfile -value (('[{0:O}] [INFO] Check state for user {1} [{2}]' -f (get-date), $User.SamAccountName,$user.DisplayName))
                if ($user.Enabled -eq "True")
                {
                    Write-Verbose (('[{0:O}] [INFO] [ENABLE] user {1} ' -f (get-date), $User.SamAccountName))
                    Add-content $Logfile -value (('[{0:O}] [ENABLE] user {1} [{2}] ' -f (get-date), $User.SamAccountName,$user.DisplayName))
                } else
                {
                    Write-Verbose (('[{0:O}] [INFO] [DISABLE] user {1}' -f (get-date), $User.SamAccountName))
                    Add-content $Logfile -value (('[{0:O}] [DISABLE] user {1} [{2}] ' -f (get-date), $User.SamAccountName,$User.DisplayName))
                }
            } else
            {
                Write-Verbose ('[{0:O}] [INFO] Disable AD Account {1} ' -f (get-date), $User.SamAccountName)
                Disable-ADAccount -Identity $user.SamAccountName -WhatIf -Confirm:$false
                Add-content $Logfile -value (('[{0:O}] [INFO] {1} [{2}] AD account disabled ' -f (get-date), $User.SamAccountName,$User.DisplayName))
            }
        }
    }

    end
    {

    }
}
#EndRegion '.\Public\Disable-CompromisedUser.ps1' 206
#Region '.\Public\Find-UserLockoutsInformation.ps1' 0
Function Find-UserLockoutsInformation
{
    [CmdletBinding(
        DefaultParameterSetName = 'All'
    )]
    param (
        [Parameter(
            ValueFromPipeline = $true,
            ParameterSetName = 'ByUser'
        )]
        [System.String]$Identity,
        [System.String]$DC = (Get-ADDomain).PDCEmulator,
        # Specifies the user account credentials to use when performing this task.
        [Parameter()]
        [ValidateNotNull()]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $Credential = [System.Management.Automation.PSCredential]::Empty
    )
    Begin
    {
        Write-Verbose ('[{0:O}] Searching EventID : 4740 on Server : {1} ' -f (get-date), $DC)
        $WinEventArguments = @{
            ComputerName    = $DC
            FilterHashtable = @{LogName = 'Security'; Id = 4740 }
        }

        if ($PSBoundParameters.ContainsKey('Credential'))
        {
            $WinEventArguments['Credential'] = $Credential
        }
        try {
            $LockedOutEvents = Get-WinEvent @WinEventArguments -ErrorAction Stop | Sort-Object -Property TimeCreated -Descending
        }
        catch {
            if ($Error[-1].Exception.Message -like "*elevated user rights*") {
                throw ('[{0:O}] You need an admin account. Please provide with the -Credential parameter' -f (get-date))
            }
        }

        if ($LockedOutEvents) {
            Write-Verbose ('[{0:O}] {1} event found' -f (get-date), $LockedOutEvents.Count)
        } else {
            throw ('[{0:O}] No event found' -f (get-date))
        }
    }

    Process
    {
        switch ($PSCmdlet.ParameterSetName)
        {
            ByUser
            {
                Write-Verbose ('[{0:O}] Searching information for user : {1}' -f (get-date), $Identity)
                $UserInfo = Get-ADUser -Identity $Identity
                Foreach ($Event in $LockedOutEvents)
                {
                    If ($Event | Where-Object { $_.Properties[2].value -match $UserInfo.SID.Value })
                    {

                        $Event | Select-Object -Property @(
                            @{Label = 'User'; Expression = { $_.Properties[0].Value } }
                            @{Label = 'DomainController'; Expression = { $_.MachineName } }
                            @{Label = 'EventId'; Expression = { $_.Id } }
                            @{Label = 'LockoutTimeStamp'; Expression = { $_.TimeCreated } }
                            @{Label = 'Message'; Expression = { $_.Message -split "`r" | Select-Object -First 1 } }
                            @{Label = 'LockoutSource'; Expression = { $_.Properties[1].Value } }
                        )
                    }
                }
            }
            All
            {
                Write-Verbose ('[{0:O}] Searching information for all user(s) ' -f (get-date))
                Foreach ($Event in $LockedOutEvents)
                {

                    $Event | Select-Object -Property @(
                        @{Label = 'User'; Expression = { $_.Properties[0].Value } }
                        @{Label = 'DomainController'; Expression = { $_.MachineName } }
                        @{Label = 'EventId'; Expression = { $_.Id } }
                        @{Label = 'LockoutTimeStamp'; Expression = { $_.TimeCreated } }
                        @{Label = 'Message'; Expression = { $_.Message -split "`r" | Select-Object -First 1 } }
                        @{Label = 'LockoutSource'; Expression = { $_.Properties[1].Value } }
                    )
                }
            }
        }
    }
    End
    {
    }

}
#EndRegion '.\Public\Find-UserLockoutsInformation.ps1' 95
#Region '.\Public\Get-UserLockoutReason.ps1' 0
function Get-UserLockoutReason
{
    [CmdletBinding(
        DefaultParameterSetName = 'All'
    )]
    param (
        [System.String]$Computer,
        [Parameter(
            ValueFromPipeline = $true,
            ParameterSetName = 'ByUser'
        )]
        [System.String]$Identity,
        # Specifies the user account credentials to use when performing this task.
        [Parameter()]
        [ValidateNotNull()]
        [System.Management.Automation.PSCredential]
        [System.Management.Automation.Credential()]
        $Credential = [System.Management.Automation.PSCredential]::Empty
    )

    begin
    {
        $LogonInfo = Import-PSFPowerShellDataFile -Path $PSScriptRoot/PSSYSAdm.psd1
        Write-Verbose ('[{0:O}] Searching EventID : 4625 on Computer : {1} ' -f (get-date), $Computer)

        $WinEventArguments = @{
            ComputerName    = $Computer
            FilterHashtable = @{LogName = 'Security'; Id = 4625 }
        }

        if ($PSBoundParameters.ContainsKey('Credential'))
        {
            $WinEventArguments['Credential'] = $Credential
        }

        $lockoutEvents = $null
        Write-Verbose ('[{0:O}] Test if computer : {1} is alive ' -f (get-date), $Computer)
        if (Test-Connection -ComputerName $Computer -Quiet -Count 2)
        {
            try
            {
                $lockoutEvents = Get-WinEvent @WinEventArguments -ErrorAction Stop
            }
            catch
            {
                if ($_.Exception.Message -match "No events were found that match the specified selection criteria")
                {
                    Write-Verbose ('[{0:O}] No logs found' -f (get-date))
                }
                if ($Error[-1].Exception.Message -like "*elevated user rights*")
                {
                    throw ('[{0:O}] You need an admin account. Please provide with the -Credential parameter' -f (get-date))
                }
            }
        }
        else
        {
            throw ('[{0:O}] computer {1} is not alive' -f (get-date), $Computer)
        }

        if ($lockoutEvents)
        {
            Write-Verbose ('[{0:O}] {1} event found' -f (get-date), $lockoutEvents.Count)
        }
        else
        {
            throw ('[{0:O}] No event found' -f (get-date))
        }
    }

    process
    {

        $ResultEvents = @()
        switch ($PSCmdlet.ParameterSetName)
        {
            All
            {
                Write-Verbose ('[{0:O}] Searching information for all user(s) ' -f (get-date))
                Foreach ($Event in $lockoutEvents)
                {
                    $eventXML = [xml]$event.ToXml()
                    # Building output based on advanced properties
                    $ResultEvents += @{
                        LockedUserName   = $eventXML.Event.EventData.Data[5].'#text'
                        LogonType        = $LogonInfo.PrivateData.LogonType."$($eventXML.Event.EventData.Data[10].'#text')"
                        LogonProcessName = $eventXML.Event.EventData.Data[11].'#text'
                        ProcessName      = $eventXML.Event.EventData.Data[18].'#text'
                        FailureReason    = $LogonInfo.PrivateData.FailureReason."$($eventXML.Event.EventData.Data[8].'#text')"
                        FailureStatus    = $LogonInfo.PrivateData.FailureType."$($eventXML.Event.EventData.Data[7].'#text')"
                        FailureSubStatus = $LogonInfo.PrivateData.FailureType."$($eventXML.Event.EventData.Data[9].'#text')"
                    }
                }
            }
            ByUser
            {
                Write-Verbose ('[{0:O}] Searching information for user : {1}' -f (get-date), $Identity)
                Foreach ($Event in $lockoutEvents)
                {
                    $eventXML = [xml]$event.ToXml()
                    If ($Event | Where-Object { $eventXML.Event.EventData.Data[5].'#text' -match $Identity })
                    {

                        # Building output based on advanced properties
                        $ResultEvents += @{
                            LockedUserName   = $eventXML.Event.EventData.Data[5].'#text'
                            LogonType        = $LogonInfo.PrivateData.LogonType.($eventXML.Event.EventData.Data[10].'#text')
                            LogonProcessName = $eventXML.Event.EventData.Data[11].'#text'
                            ProcessName      = $eventXML.Event.EventData.Data[18].'#text'
                            FailureReason    = $LogonInfo.PrivateData.FailureReason."$($eventXML.Event.EventData.Data[8].'#text')"
                            FailureStatus    = $LogonInfo.PrivateData.FailureType."$($eventXML.Event.EventData.Data[7].'#text')"
                            FailureSubStatus = $LogonInfo.PrivateData.FailureType."$($eventXML.Event.EventData.Data[9].'#text')"
                        }
                    }

                }

            }
        }


    }

    end
    {
        return $ResultEvents
    }
}
#EndRegion '.\Public\Get-UserLockoutReason.ps1' 129