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 |