Powershell: How to pull Event Viewer message and time - powershell

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!

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

Export-Csv MIM FIM PowerShell Issue

I was asked to retrieve a .csv list with all users that registered to the FIM portal. I did some searching until I stumbled accross this script:
set-variable -name URI -value "http://localhost:5725/resourcemanagementservice' " -option constant
set-variable -name CSV -value "RegistredResetPassUsers.csv" -option constant
clear
If(#(Get-PSSnapin | Where-Object {$_.Name -eq "FIMAutomation"} ).count -eq 0) {Add-PSSnapin FIMAutomation}
$WFDFilter = "/WorkflowDefinition[DisplayName='Password Reset AuthN Workflow']"
$curObjectWFD = export-fimconfig -uri $URI –onlyBaseResources -customconfig ($WFDFilter) -ErrorVariable Err -ErrorAction SilentlyContinue
$WFDObjectID = (($curObjectWFD.ResourceManagementObject.ResourceManagementAttributes | Where-Object {$_.AttributeName -eq "ObjectID"}).value).split(":")[2]
$Filter = "/Person[AuthNWFRegistered = '$WFDObjectID']"
$curObject = export-fimconfig -uri $URI –onlyBaseResources -customconfig ($Filter) -ErrorVariable Err -ErrorAction SilentlyContinue
[array]$users = $null
foreach($Object in $curObject)
{
$ResetPass = New-Object PSObject
$UserDisplayName = (($Object.ResourceManagementObject.ResourceManagementAttributes | Where-Object {$_.AttributeName -eq "DisplayName"}).Value)
$ResetPass | Add-Member NoteProperty "DisplayName" $UserDisplayName
$Users += $ResetPass
}
$users | export-csv -path $CSV
The script works without errors except that the actual list that it exports only contains my display name. I've been trying to figure out why its not exporting the complete list of all users and only shows my name, but I haven't been able to figure it out so I was wondering if any one could help me shed some light into this issue.
Thanks again for any help you guys can provide!
No experience with this snapin/product, but seeing as the code fundamentally works (it returns your object) this could be a permissions issue. You may not be able to read the other user objects, so they're not being exposed to you.
If you can view them in a UI console of some kind, then check for separate permissions related to API actions, and ensure you have access that way.
Another course of action may be to run the code line by line and see what results you receive from each line, to make sure you get what you're expecting.
Try replacing:
[array]$users = $null
With:
$users = #()
This is likely due to permission setup.
By default you have a permissions to see your own attributes.
There is likely some Management Policy Rule setup so user accounts in a specific Set can read AuthNWFRegistered attribute of other users to support for troubleshooting and customer support.
You will need to use one of the options:
Add the account used for this script into the Set that delegates out this Read permission already
or
Create a separate MPR for this particular reporting (this is what I would recommend) that Grants permissions for a specific user account to read AuthNWFRegistered attribute.
Also make sure there is really only one Workflow that is associated with user registration. If there are multiple, you'd want to target Set with all register Workflows in your XPath filter instead of particular Workflow name.
On a separate note - while FIMAutomation is sometimes necessary snapin to use with standard tooling, for your custom work I strongly suggest to use Lithnet's LithnetRMA PowerShell module (https://github.com/lithnet/resourcemanagement-powershell).
You will be much more productive with it and most of the operations will be without boilerplate code FIMAutomation needs. This will be your code using LithnetRMA.
Set-ResourceManagementClient -BaseAddress 'http://localhost:5725/resourcemanagementservice'
$scope = Search-Resources -XPath "/Person[AuthNWFRegistered = /WorkflowDefinition[DisplayName='Password Reset AuthN Workflow']]" -ExpectedObjectType Person
$scope | select DisplayName | Export-Csv 'RegistredResetPassUsers.csv' -Encoding Unicode

retrieve computer names admin account logged on through AD

How would retrieve computer names and their IP addresses in Active Directory which are logged into by an admin account?
I can retrieve local admin accounts with my script below:
function get-localadministrators {
param ([string]$computername=$env:computername)
$computername = $computername.toupper()
$ADMINS = get-wmiobject -computername $computername -query "select * from win32_groupuser where GroupComponent=""Win32_Group.Domain='$computername',Name='administrators'""" | % {$_.partcomponent}
foreach ($ADMIN in $ADMINS) {
$admin = $admin.replace("$computernamerootcimv2:Win32_UserAccount.Domain=","") # trims the results for a user
$admin = $admin.replace("$computernamerootcimv2:Win32_Group.Domain=","") # trims the results for a group
$admin = $admin.replace('",Name="',"")
$admin = $admin.REPLACE("""","")#strips the last "
$objOutput = New-Object PSObject -Property #{
Machinename = $computername
Fullname = ($admin)
DomainName =$admin.split("")[0]
UserName = $admin.split("")[1]
}#end object
$objreport+=#($objoutput)
}#end for
return $objreport
}#end function
but what I want is to return all instances of Administrator logged on to Computers. Is this possible or is there anything that would return similar results?
You are not going to be able to do this with AD alone.
How many computers are we talking here? Nevertheless, i would make use of the eventlog. Each logon-event is stored and has the SID of the user that logs on (or triggers the event). Event 7001 (logon) is what you are looking for.
You could retrieve these events in een XML format. This XML contains the SID of the user that has triggered the event. You can either use a .NET translation function to convert it into a SamAccountName OR you can just retrieve all SID's from AD and compare them that way (so maybe make use of a hasbtable).
I have written a script some time ago that uses a lot of these techniques.
It was meant to see when a user has logged on and off AND locked and unlocked their computer. You can find a blog-post about it here:
https://cookiecrumbles.github.io/GetLogonEventViewer/
That blogpost also references the github where you can find the script i made.
With some tweaking, you could make it into a tool that you need.

Powershell -get-eventdata

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.

How can i filter Windows Events retrieve with an XPATH where a certain value is a substring of the value?

Windows Events have an ability to filter by XPATH (which is a fast search). I have sucessfully using the PowerSHell Cmdlet Get-WinEvent filtered where a specific value is a specific value as shown below
$qry = "*[(EventData/Data[#Name='TaskName'] ='\Microsoft\Windows\Diagnosis\Scheduled') ]"
Get-WinEvent -LogName Microsoft-Windows-TaskScheduler/Operational -FilterXPath $qry -ErrorAction SilentlyContinue -MaxEvents 3
However i don't really want to filter by a specfic task name but a substring of it, a start-with of contains or something.. for instance in the above scenario i want to do "startswith" \Microsoft\Windows\Diagnosis . However all the different techniques i've tried, that seem like standard XPATH 1.0 syntax such as
$qry = "*[starts-with(EventData/Data[#Name='TaskName'] ,'\Microsoft\Windows\Diagnosis') ]"
give an error
Get-WinEvent : The specified query is invalid
Try the contains function:
$x = [xml] '<root><books><book title="Foo" /></books></root>'
$x.SelectSingleNode('//book[contains(#title, oo)]')
Reference for xpath string functions: http://msdn.microsoft.com/en-us/library/ms256180.aspx
Your's may look like:
"*[EventData[contains(Data,'\Microsoft\Windows\Diagnosis\Scheduled')]]"