Powershell -get-eventdata - powershell

I am trying to create a script that pulls failed log on attempts for certain events in the past 24 hours but I cant figure out how to pull the account information out. User is Null all the time so info is blank BUT when I look in the general tab I can see "Account Information".
I would like to pull and add what it shows in the XML view under "event data" which is TargetUserName. How can I get this done? What I have so far works fine but I need the username info and what my script pulls is always blank.
System - windows server 2008 R2
Log I am pulling from is security log with event ID's 4625,4768,4771,4772 for the past 24 hours.
My code:
get-eventlog Security 4625,4768,4771,4772 -after ((get-date).addDays(-1))| export-csv

I think you'll have to change this around because each event has different messages, but if I try to fail a login, I can get the username from event 4776 like this:
# Get the most recent event 4776
$event = Get-EventLog -LogName Security -InstanceId 4776 -newest 1
# Pull the "Logon Account: testuser" text from the event log message
$usernameMatch = $event.Message -match 'Logon Account:\s+(?<account>.*)'
# Use the magic variable $matches which gets created by -match
if ($usernameMatch) {
write-output "Someone tried to logon as the user $matches['account']"
}
Otherwise, I think you can get the XML message using this:
$event = Get-WinEvent -FilterHashtable #{id=4776} -LogName Security -maxevent 1
$event.ToXML()

#Peter-core appears to know how to accomplish this without needing to parse and search the message body and without converting to XML.
Use the following to find that the extended fields (part of template?) for each event:
(Get-WinEvent -ListProvider Microsoft-Windows-Security-Auditing).Events|Where-object{#(4625,4768,4771,4772) -contains $_.Id}
Use get-winevent to get the events, you can use xpath to filter data more quick (only return events you are interested in to start with), or you can filter them after they return using where-object. Xpath is better option for larger number of devices, eventlogs, or events, but I hate trying to write one.
Get-WinEvent -log Security|Where-object{$_.TimeCreated -gt ((get-date).addDays(-1)) -and #(4625,4768,4771,4772) -contains $_.Id}
From there you can try and implemnt what #Peter-Core wrote. I can't make it work for myself, but the coding looks sound.

Related

Security Group changes - Task

I'm currently auditing security events 4728 and 4729 via powershell in order to check group policy changes in a specific domain controller.
The main idea is to check anomalies between a default AD group policy(a "given configuration", for the company group) and the one that changed(from the new snapshot) at the end of the week.
How could I spot differences beetween these two outputs?
I'd use Get-WinEvent -LogName Security, but we can discuss it.
For Changes I refer to these https://learn.microsoft.com/en-us/windows/security/threat-protection/auditing/audit-security-group-management
(4728,4729 for instance)
I'm looking for a situation like this: an administrator add a user to a security group because the latter has to access a specific file for a short period of time.
Then the admin somehow forgets to restore the original user's configuration policy.
This generates an anomaly, considering the default AD Group Policy.
I have to spot this change from the output.
Now I've wrapped up my rudimentary explination, is there anything you can think of to help with my problem?
Thanks in advance
The basic command you're looking for would be like this:
$StartDate = (Get-Date).AddDays(-1)
Get-WinEvent -FilterHashtable #{ LogName='Security'; Id=4728, 4729; StartTime=$StartDate }
In a script it would be something like this:
$StartDate = (Get-Date).AddDays(-1)
$Results = Get-WinEvent -FilterHashtable #{ LogName='Security'; Id=4728, 4729; StartTime=$StartDate }
if ( $Results )
{
# Send e-mail or something here
}
If you want more complex queries you might format it differently.
$DaysInThePast = 1
$Hash = #{
LogName = 'Security'
Id = 4728, 4729
StartTime = (Get-Date).AddDays(-$DaysInThePast)
}
Get-WinEvent -FilterHashtable $Hash

Powershell: How to pull Event Viewer message and time

I am trying to pull users out of the logoff events within security.
Using the below code I can pull the usernames but I am not sure how to modify it to pull the time from the event log as well?
Many thanks
$events = get-eventlog -logname Security -instanceid 4634 -Newest 5
foreach ($ev in $events) {
$me = $ev.Message -match "(Account Name:).*"
if ($me) {
$matches[0]
}
}
I'm not exactly sure what you are attempting to do. However, Get-EventLog is deprecated in favor of Get-WinEvent which is faster and has much better filtering options, and example may look something like this:
$FilterHash = #{
LogName = 'Security'
Id = 4624
}
Get-WinEvent -FilterHashtable $FilterHash -MaxEvents 5 |
ForEach-Object{
If($_.Properties[1].Value -eq $me) {
Write-Host "Account Name : ($_.Properties[1].Value)"
}
}
The -FilterHashtable parameter is the most popular, but there are also -FilterXPath and -FilterXML params you can look at in the documentation.
Important: In my case, I didn't have 4634 events. The property value and array position can be determined by looking at the XML view of a given log entry in Event Viewer. Just look under then and count the array indices from 0.
Another way to do that is to just isolate a single entry and echo the properties to the screen, and again just count to get the right index number. This is important because different info may be in different positions in different events etc.
Get-WinEvent is really robust. I strongly recommend taking a look at the documentation!

Setting a DateTime to $null/empty using PowerShell and the SCSM cmdlets

I'm currently trying to sync additional attributes from the AD (Active Directory) for user objects in SCSM (System Center Service Manager) using a PowerShell script.
The extension I wrote for this, includes an attribute for the expiration date of a AD user account (DateTime value, named DateTimeAttribute in the example) if the user account doesn't expire it should be empty/null.
Using Import-SCSMInstance, which should be similar to a CSV import, it kind of works by passing "null" for the field. The problem is that Import-SCSMInstance seems to be quite unreliable and it doesn't offer any kind of information of why it works or doesn't work. Using Update-SCSMClassInstance seems to work a lot better but I can't figure out a way to clear the field using this and even using [DateTime]::MinValue will result in an error, stating that it's an invalid value.
So would anyone have an idea on how to clear the value using Update-SCSMClassInstance or figure out why Import-SCSMInstance might or might not work?
A simple example for this could look like the following:
$server = "<ServerName>"
$extensionGuid = "<GUID>"
Import-Module 'C:\Program Files\System Center 2012 R2\Service Manager\Powershell\System.Center.Service.Manager.psd1'
New-SCManagementGroupConnection -ComputerName $server
$extensionClass = Get-SCSMClass -Id $extensionGuid
$scsmUserObject = Get-SCSMClassInstance -Class $extensionClass -Filter 'UserName -eq "<User>"'
# Error
$scsmUserObject.DateTimeAttribute = ""
# Works but fails on Update-SCSMClassInstance
$scsmUserObject.DateTimeAttribute = $null
$scsmUserObject.DateTimeAttribute = [DateTime]::MinValue
# Works
$scsmUserObject.DateTimeAttribute = "01-01-1970"
Update-SCSMClassInstance -Instance $scsmUserObject
It seems that you can't clear a date once it's filled. When you write $null, it sets the date to 1-1-0001 01:00:00, which is an invalid date causing the update-scsmclassinstance to fail.
What we have set as a user's AD property when we don't want something to expire, is 2999-12-31 (yyyy-MM-dd). Perhaps this could help, although it's not directly what you asked for...
Also, you can use the pipeline to update a property in SCSM:
Get-SCSMClassInstance -Class $extensionClass -Filter 'UserName -eq "<User>"' | % {$_.DateTimeAttribute = <date>; $_} | update-scsmclassinstance
It doesn't look like it's currently possible to clear custom date attributes using the PowerShell cmdlets.

'GET-EVENTLOG' creating a full object list, then being filtered ? - is there quicker way?

The following Powershell script fetches all the System Error Events occuring today only - it works:
Get-EventLog System -After ([datetime]::Today) | Where-Object { $_.EntryType -eq "Error" }
But it can take several seconds to run : I suspect this is because the first'Get-EventLog' cmdlet is generating the complete list of all events first; then the 'Where-Object' cmdlet trims down that list.
Is a way of passing in the 'where-object' filter as an argument to the 'Get-EventLog' so that it could test each object as it fetches them ?
I am speculating that such a mechanism would be quicker to run, since the 'Get-EventLog' wouldn't have to maintain the full list of objects that are passed to the subsequent 'Where-Object' ?
But I'm just guessing here.
Also: this isn't such a big deal - it's just a point of interest/understanding on my part.
Get-EventLog System -After ([datetime]::Today) -EntryType Error
Yes, you can specify this parameter in the original command.

Using WMI to get printer logs

I'm trying to use WMI to get printer system logs from several servers. A week ago I made the following code which for some reason only works sometimes:
wmic /node:<servername> NTEvent WHERE "logfile='System' AND SourceName='Print' AND TimeGenerated > '20130219'" get EventCode,TimeGenerated,Message
This line of code sometimes will work, but the majority of the time I'm getting the following error whenever I've tried running it to get logs:
ERROR:
Code = 0x80020009
Description = Exception occurred.
Facility = Dispatch
I was wondering if anyone may know why this is occurring and if there would be a better method to rewrite my code. I've considered using the get-wmiobject cmdlet, however I'm not sure how to filter and get the same logs that I'm trying to get.
There are two ways to do this. Neither uses Get-WMIObject.
Option 1: Get the whole event log, then filter.
Get-EventLog -LogName System -Source Print|where-object{$_.timeGenerated -gt (get-date "2013-02-19")}|select-object eventid, timegenerated,message | Export-csv -path r:\log.csv -notypeinfo;
Option 2: Filter at the source
Get-WinEvent -FilterHashtable #{logname='system';source='print';StartTime=(get-date "2013-02-19").date;}|select-object id,timecreated,message;
Best practice is to filter as close to the source of the data as possible (Filter Left, Format Right), which would be option 2 in this case.