Basically, I am trying to write some code that will run off of a scheduled task any time the event ID 4725 is triggered. This specific event states that a particular user had their AD account disabled (Windows Server 2016).
What I need to do is take the username from this event ID and output it as a variable #UserName to be used in the restmethod URI.
# Variables
$params = @{"action"="move";"destination"="/Shared/IT/Archived User Data/"}
$json = $params|ConvertTo-Json
$eventRecordId = 4725
$eventChannel = "Security"
# Gets the latest "disabled user account" event log and outputs the disabled user's name to a variable called $UserName
Get-EventLog –Log Security -InstanceId 4725 -Newest 1 | $UserName = ?{Group-Object -Property "TargetUserName"}
Echo $UserName
# Calls the Egnyte API to move the disabled user's home folder to the archive folder
Invoke-RestMethod `
-Method Post `
-body $json `
-Uri 'https://xxxxxx.egnyte.com/pubapi/v1/fs/private/"$UserName"' `
-Headers @{Authorization = "Bearer xxxxxxxxxxxxxxxxxxxxxxx"
Contenttype = "application/json"}
Expected results: Take the username from the target-username field in the security event-log ID 4725, output it to variable "#UserName", and then input it into the rest-method API.
Actual results: The variable is not being created.
OK Lets take a look at this Event 4725 template
(Get-WinEvent -ListProvider * -ErrorAction Ignore).Events |
Where-Object {$_.Id -eq 4725} |
select * |
Format-List
We can see there is a TargetUserName
<data name="TargetUserName" inType="win:UnicodeString" outType="xs:string"/>
So lets parse that Message into XML, Get-EventLog returns a type System.Diagnostics.EventLogEntry
So first we need to change that object into a System.Diagnostics.Eventing.Reader.EventLogRecord so we can convert to XML
We can ether Make a new call using Get-WinEvent which will return the type System.Diagnostics.Eventing.Reader.EventLogRecord which has a method for turning data into XML
Or We can get the Index from the current record and call Get-WinEvent looking for the EventRecordID.
Below is a function i wrote that will parse the message field and make a new psobject with property ParsedMessage
function Parse-WindowsEvents(){
param(
[Parameter(Position=1, ValueFromPipeline)]
#[System.Diagnostics.Eventing.Reader.EventRecord[]]$Events
[object[]]$Events
)
process{
$ArrayList = New-Object System.Collections.ArrayList
$Events | %{
$EventObj = $_
$EventObjFullName = $_.GetType().FullName
if($EventObjFullName -like "System.Diagnostics.EventLogEntry"){
$EventObj = Get-WinEvent -LogName security -FilterXPath "*[System[EventRecordID=$($_.get_Index())]]"
}elseif($EventObjFullName -like "System.Diagnostics.Eventing.Reader.EventLogRecord"){
}else{
throw "Not An Event System.Diagnostics.Eventing.Reader.EventLogRecord or System.Diagnostics.EventLogEntry"
}
$PsObject = New-Object psobject
$EventObj.psobject.properties | %{
$PsObject | Add-Member -MemberType NoteProperty -Name $_.Name -Value $_.Value
}
$XML = [xml]$EventObj.toXml()
$PsObject2 = New-Object psobject
$XML.Event.EventData.Data | %{
$PsObject2 | Add-Member -MemberType NoteProperty -Name $_.Name -Value $_."#text"
}
$PsObject | Add-Member -MemberType NoteProperty -Name ParsedMessage -Value $PsObject2
$ArrayList.add($PsObject) | out-null
}
return $ArrayList
}
}
$Username = Get-EventLog –Log Security -InstanceId 4725 -Newest 1 | Parse-WindowsEvents | select -ExpandProperty ParsedMessage | select TargetUserName
$Username.TargetUserName
#or
$Username = (Get-EventLog –Log Security -InstanceId 4725 -Newest 1 | Parse-WindowsEvents | select -ExpandProperty ParsedMessage).TargetUserName
$Username