Public/Get-AduserLockoutInfo.ps1
Function Get-AduserLockoutInfo { # .ExternalHelp .\Get-AduserLockoutInfo-help.xml [cmdletbinding(SupportsShouldProcess=$true)] param( [parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Mandatory=$true,HelpMessage="search for lockout events in seconds")] [int]$Timespan ) BEGIN{ Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] Starting: $($MyInvocation.MyCommand)" Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] PSVersion = $($PSVersionTable.PSVersion)" Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] OS = $((Get-CimInstance win32_OperatingSystem).Caption)" Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] User = $($env:userdomain)\$($env:USERNAME)" $id = [System.Security.Principal.WindowsIdentity]::GetCurrent() $IsAdmin = [System.Security.Principal.WindowsPrincipal]::new($id).IsInRole('administrators') Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] Is Admin = $IsAdmin" Import-module ActiveDirectory Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] Enumerating PDC Emulator" $DomainController = Get-ADDomain | Select-Object PDCEmulator $DC = $DomainController.PDCEmulator try{ $Session = New-CimSession -computerName $DC -ErrorAction Stop $OS = Get-CimInstance -CimSession $Session -ClassName Win32_operatingSystem | Select-Object Caption }#TRY Catch{ $ErrorMessage = $_.Exception.Message $ErrorMessage exit }#CATCH Switch -Wildcard($OS.Caption){ "Microsoft Windows Server 2008 R2*" { Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] $($DC) is running $($OS.Caption)" Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] cannot run windows firewall check" Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] TestingPSRemotingStatus on $($DC)" $WSMANStatus = TestPSRemotingStatus -ComputerName $DC $FirewallStatus = $True Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] Cannot Test GPO Settings for $($OS.Caption) on $($DC)" Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] Ensure Audit Account Lockout and Audit User Account Management setting are configured" $ADAudtingEnabled = $True } "Microsoft Windows Server 2012 R2*" { Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] $($DC) is running $($OS.Caption)" $WSMANStatus = TestPSRemotingStatus -ComputerName $DC $FirewallStatus = TestFirewallRuleStatus -ComputerName $DC $ADAudtingEnabled = Get-ADAccountLockoutAuditPolicy -ComputerName $DC } "Microsoft Windows Server 2016*" { Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] $($DC) is running $($OS.Caption)" $WSMANStatus = TestPSRemotingStatus -ComputerName $DC $FirewallStatus = TestFirewallRuleStatus -ComputerName $DC $ADAudtingEnabled = Get-ADAccountLockoutAuditPolicy -ComputerName $DC } Default { Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] $($DC) is running $($OS.Caption) no condtion set" Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] TestingPSRemotingStatus on $($DC)" $WSMANStatus = $True $FirewallStatus = $True $ADAudtingEnabled = $True } }#SWITCH }#BEGIN PROCESS{ if (($FirewallStatus -eq $true) -and ($WSMANStatus -eq $True) -and ($ADAudtingEnabled -eq $true)){ TRY{ if($pscmdlet.ShouldProcess($DC)){ Write-Verbose "[$((get-date).TimeOfDay.ToString()) PROCESS ] Invoking: Examining event logs on $($DC)" $Events = Get-WinEvent -ComputerName $DC -FilterHashtable @{LOGNAME='Security';ID="4740"} -ErrorAction Stop foreach ($event in $Events){ if($event.TimeCreated -ge (Get-Date).AddSeconds(-$Timespan) ){ Write-Verbose "[$((get-date).TimeOfDay.ToString()) PROCESS ] user $($event.Properties[0].value) is locked " $Properties = [PSCustomObject][Ordered]@{ "Username" = $event.Properties[0].value "ReferenceComputer" = $Event.Properties[1].value "LockOutTime" = $event.TimeCreated "Domain" = $Event.Properties[5].value "DC" = $Event.Properties[4].value -replace "\$" } $Properties }#IF }#Foreach }#IF }#TRY Catch [System.Exception] { Write-Verbose "[$((get-date).TimeOfDay.ToString()) PROCESS ] No Account lockout events found on $($DC)." }#CATCH }#IF } END{ Remove-CimSession $Session -ErrorAction SilentlyContinue } }#Function Get-AduserLockoutInfo (MAIN) Function TestPSRemotingStatus { [cmdletbinding()] param( [String]$ComputerName ) try{ $WSMAN = New-PSSession -ComputerName $ComputerName -errorAction Stop if($WSMAN){ Write-Verbose "[$((get-date).TimeOfDay.ToString()) PROCESS ] Powershell Remoting enabled on $($ComputerName)" Remove-PSSession $WSMAN.ID Return $true } } Catch { $ErrorMessage = $_.Exception.Message $ErrorMessage Write-error -message "Powershell remoting test error, enable powershell remoting to continue" exit } }# Function TestPSRemotingStatus Function TestFirewallRuleStatus { [cmdletbinding()] param( [String]$ComputerName ) do{ try{ Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] Testing if RemoteEventLogSvc-In-TCP firewall rule is enabled" $FirewallStatus = Invoke-Command -ComputerName $ComputerName -ScriptBlock {(Get-NetFirewallRule -Name 'RemoteEventLogSvc-In-TCP').Enabled} -AsJob | Wait-Job | Receive-Job -ErrorAction Stop if($($FirewallStatus.value) -eq $false){ Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] Attempting to enable RemoteEventLogSvc-In-TCP on $($ComputerName)" $RemoteJob = Invoke-Command -ComputerName $ComputerName -ScriptBlock {(Enable-NetFirewallRule -Name 'RemoteEventLogSvc-In-TCP')} -AsJob | Wait-Job | Receive-Job -ErrorAction Stop }#IF elseif($($FirewallStatus.value) -eq $true){ Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN ] RemoteEventLogSvc-In-TCP firewall Rule Enabled on $($ComputerName). Test Passed" Return $true $Count = 2 }#ELSEIF }#TRY Catch{ $ErrorMessage = $_.Exception.Message Write-Verbose "[$((get-date).TimeOfDay.ToString()) BEGIN:ERROR ] Error $($FirewallStatus)" write-error -Message $FirewallStatus Write-Error -Message $ErrorMessage write-error -message $RemoteJob exit }#CATCH }while($Count -lt 2) }#Function TestFirewallRuleStatus Function Get-ADAccountLockoutAuditPolicy { [cmdletbinding(SupportsShouldProcess)] param( [parameter(ValueFromPipeline=$true,ValueFromPipelineByPropertyName=$true,Mandatory=$true,HelpMessage="DomainContoller (FQDN)")] [String]$ComputerName ) try{ if($PSCmdlet.ShouldProcess($ComputerName)){ Write-Verbose "[$((get-date).TimeOfDay.ToString()) PROCESS ] Getting domain information" $Domain = $ComputerName.Substring($ComputerName.IndexOf(".") + 1) [xml]$DDCP = Get-GPOReport -name "Default Domain Controllers Policy" -Domain $Domain -Server $ComputerName -ReportType xml -ErrorAction Stop Write-Verbose "[$((get-date).TimeOfDay.ToString()) PROCESS ] Checking Default Domain Controllers Policy for Audit Settings" $AAL = $DDCP.ChildNodes.Computer.Extensiondata.extension.AuditSetting | Where-Object {$_.SubcategoryName -eq "Audit Account Lockout"} | Select-Object SubcategoryName, SettingValue -ErrorAction stop $AUAM = $DDCP.ChildNodes.Computer.Extensiondata.extension.AuditSetting | Where-Object {$_.SubcategoryName -eq "Audit User Account Management"} | Select-Object SubcategoryName, SettingValue -ErrorAction stop if($AAL.SettingValue -eq 3 -and $AUAM.SettingValue -eq 3){ Write-Verbose "[$((get-date).TimeOfDay.ToString()) PROCESS ] Audit Settings enabled. Test Passed" Return $true }#IF else{ Write-Verbose "[$((get-date).TimeOfDay.ToString()) PROCESS ] Audit Settings not configured. enable Audit Account Lockout and Audit User Account Management." Write-host "Audit settings required for ADAccountLockoutInfo not configured $($ComputerName) for $($Domain). Script terminated" -ForegroundColor Yellow Return $false }#Else }#IF }#TRY Catch{ $ErrorMessage = $_.Exception.Message $ErrorMessage }#CATCH }#Function Get-ADAccountLockoutAuditPolicy # SIG # Begin signature block # MIIIWAYJKoZIhvcNAQcCoIIISTCCCEUCAQExCzAJBgUrDgMCGgUAMGkGCisGAQQB # gjcCAQSgWzBZMDQGCisGAQQBgjcCAR4wJgIDAQAABBAfzDtgWUsITrck0sYpfvNR # AgEAAgEAAgEAAgEAAgEAMCEwCQYFKw4DAhoFAAQUaxDVzxaiGXRtaR2dbzCZ0H5f # 02+gggXTMIIFzzCCBLegAwIBAgIKI+alEgAAAAAMTzANBgkqhkiG9w0BAQUFADBA # MRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxFjAUBgoJkiaJk/IsZAEZFgZwZXRlcnMx # DzANBgNVBAMTBlJvb3RDQTAeFw0xNjA1MjUyMjQ5MjVaFw0yMTA1MjQyMjQ5MjVa # MIGIMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwxFjAUBgoJkiaJk/IsZAEZFgZwZXRl # cnMxFzAVBgNVBAsTDlBldGVycyBPYmplY3RzMQ4wDAYDVQQLEwVVc2VyczEUMBIG # A1UECxMLQ29udHJhY3RvcnMxGDAWBgNVBAMTD1NoaWhhbiBQaWV0ZXJzejCCASIw # DQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALqjlVFhz2Jmijj+v6bTi4EiAOJA # Dx9InjUSh3aN06eELeKMRjqc0B33dk04kkq6Rs0dy8vvvrmQlE/Etoqx+GRJiy6K # JC34FLQI85YxHrGNhLM54EZwRHX+iDsXsmZvEQqDaUHRC9QzT77fYVQOe8AxojLh # zilyIHIU2Ec+N0chNX77I5e76K6L6fZa92R7lWz+fbeJm6IJIXSpukGTSFPMvLcg # LnflfnnDBDCsfHecY9ZFPEH8LLs+LzV5ta5w8fVFt1IzqAHmiXWEx70t2n1jqvpx # zx4ykBjKORHaVV8IzfiCrICbGl1/082lcdlO/1GbJaJlicTRzFPtoW47/AECAwEA # AaOCAoAwggJ8MDwGCSsGAQQBgjcVBwQvMC0GJSsGAQQBgjcVCIH7wgPJxmWHoZ0j # hYmgYYPNihR3gqzMRYXVsj8CAWQCAQIwEwYDVR0lBAwwCgYIKwYBBQUHAwMwDgYD # VR0PAQH/BAQDAgeAMBsGCSsGAQQBgjcVCgQOMAwwCgYIKwYBBQUHAwMwHQYDVR0O # BBYEFGyYZLBdWxaiOaYrLW+7v7Vzvy1XMB8GA1UdIwQYMBaAFKJt615sTsvKB+Vm # TET+s9YiUd9lMIHKBgNVHR8EgcIwgb8wgbyggbmggbaGgbNsZGFwOi8vL0NOPVJv # b3RDQSxDTj1QRVRNVUxTRVIwMTYsQ049Q0RQLENOPVB1YmxpYyUyMEtleSUyMFNl # cnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9cGV0ZXJzLERD # PWxvY2FsP2NlcnRpZmljYXRlUmV2b2NhdGlvbkxpc3Q/YmFzZT9vYmplY3RDbGFz # cz1jUkxEaXN0cmlidXRpb25Qb2ludDCBuQYIKwYBBQUHAQEEgawwgakwgaYGCCsG # AQUFBzAChoGZbGRhcDovLy9DTj1Sb290Q0EsQ049QUlBLENOPVB1YmxpYyUyMEtl # eSUyMFNlcnZpY2VzLENOPVNlcnZpY2VzLENOPUNvbmZpZ3VyYXRpb24sREM9cGV0 # ZXJzLERDPWxvY2FsP2NBQ2VydGlmaWNhdGU/YmFzZT9vYmplY3RDbGFzcz1jZXJ0 # aWZpY2F0aW9uQXV0aG9yaXR5MDEGA1UdEQQqMCigJgYKKwYBBAGCNxQCA6AYDBZ2 # LXNwaWV0ZXJAcGV0ZXJzLmxvY2FsMA0GCSqGSIb3DQEBBQUAA4IBAQAYLtV27syc # YJgAMf07HQJSZ39O5AZL7NrxBifKpXGryK5imi1zKOaJCYVY1KDrfu+gCLW2IYuB # TeSjqg2HHgM1p3dgS+uufcPasgBJsYnsFSqlTOnezu2IH87d73YuhlpRfR2r649A # 0QXvwYe4aLgENyy6k9N0bkqMWEFxlShIOVY/adlU+qKOP2sPBUC5p9STJ909IYtQ # mN+3iybKr0HMiECBPBH/HxlVqjtIu7PtqYwEBr3socadSmhHp+HwhB74xJ3coegU # CBeRHMpQNlBuu41fmAGExDunJsaCg87n6Kyx9qMguICj7sjU1IAHuouFuRx6UKac # lRhThY4m3CDxMYIB7zCCAesCAQEwTjBAMRUwEwYKCZImiZPyLGQBGRYFbG9jYWwx # FjAUBgoJkiaJk/IsZAEZFgZwZXRlcnMxDzANBgNVBAMTBlJvb3RDQQIKI+alEgAA # AAAMTzAJBgUrDgMCGgUAoHgwGAYKKwYBBAGCNwIBDDEKMAigAoAAoQKAADAZBgkq # hkiG9w0BCQMxDAYKKwYBBAGCNwIBBDAcBgorBgEEAYI3AgELMQ4wDAYKKwYBBAGC # NwIBFTAjBgkqhkiG9w0BCQQxFgQUPLKZCP125wcI/oRaN3RTsfpPX2MwDQYJKoZI # hvcNAQEBBQAEggEAh0J+61KK1Fzkjsrpx5d6kPYZeCwpanphrWFyYUtR8MRcsaF8 # MW9LII040hI8W9p3pRGtz6MlxrrbjQeQO/HuvSWtQgyehh3vSaLndjQsEiDM52uB # cu3h2teMvtyoSMBy0ASSPxcZymY4hEYm8Pn8M0zrNORQHbMyWWt4uKZfZdV4b2Z2 # nC42qx1vMVe+kpsK4j/HZGFRZwBvBQGVyloF7SrsE9t0GqAW3fCCpYNhxpIcGi+8 # QvU/sjvtSJCByIBtOJEEfS3k9h+Pgq5M5of0yHwbfpaIm0FFAhRuOouVkOmfknMt # LxZsqzM/5O80O+azduSKtDm1bre0EY6oCIak3g== # SIG # End signature block |