cja777
asked on
Event log monitoring with PowerShell
I'm trying to use PowerShell to monitor event log ID 528 in the security log. My script works ok but I am trying to add a few parameters and am a bit of a newbie to scripting in general.
First off, I'd like to add a date/time stamp to my Outfile so that it isn't over written each time the script is run.
Secondly, I need to add the "Souce Network Addrees" Parameter from Event ID 528 to the output. I tried adding "Source Network Address" to my script but come back with a null output. Event 528 looks like this:
Successful Logon:
User Name: User
Domain: My Domain
Logon ID: (0x0,0x90BEF452)
Logon Type: 10
Logon Process: User32
Authentication Package: Negotiate
Workstation Name: COMPUTER NAME
Logon GUID: {ea0d7ccb-e029-9d9d-96f0-0 7be3d66f5d d}
Caller User Name: COMP$
Caller Domain: My Domain
Caller Logon ID: (0x0,0x3E7)
Caller Process ID: 7456
Transited Services: -
Source Network Address: 192.168.1.5
Source Port: 3390
Lastly, I need to know what parameters to add to run the script for the current day rather than for the newest 10000 events,
This is the script I currently have written.
$events = Get-EventLog -ComputerName "COMPUTER" -LogName "Security" -newest 10000 | Where {$_.eventid -eq 528 -AND $_.Source -eq "Security" }
foreach ( $event in $events ) {
if (($event.message | Select-String "Logon Type: 2")){
"LogonType 2 (Interactive Login );"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";"+$event.SourceNetworkAd dress | out-file logins.txt
}
if (($event.message | Select-String "Logon Type: 3")){
"LogonType 3 (Network Login ) ;"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";"+$event.SourceNetworkAd dress | out-file logins.txt
}
if (($event.message | Select-String "Logon Type: 4")){
"LogonType 4 (Batch Login ) ;"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";"+$event.SourceNetworkAd dress | out-file logins.txt
}
if (($event.message | Select-String "Logon Type: 5")){
"LogonType 5 (Service Login ) ;"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";"+$event.SourceNetworkAd dress | out-file logins.txt
}
if (($event.message | Select-String "Logon Type: 7")){
"LogonType 7 (Computer Unlocked );"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";"+$event.SourceNetworkAd dress | out-file logins.txt
}
if (($event.message | Select-String "Logon Type: 8")){
"LogonType 8 (Network Cleartext Login );"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";"+$event.SourceNetworkAd dress | out-file logins.txt
}
if (($event.message | Select-String "Logon Type: 9")){
"LogonType 9 (NewCredentials ) ;"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";"+$event.SourceNetworkAd dress | out-file logins.txt
}
if (($event.message | Select-String "Logon Type: 10")){
"LogonType 10 (RDP Login ) ;"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";"+$event.SourceNetworkAd dress | out-file logins.txt
}
if (($event.message | Select-String "Logon Type: 11")){
"LogonType 11 (Cached Credentials Login );"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";"+$event.SourceNetworkAd dress | out-file logins.txt
}
}
First off, I'd like to add a date/time stamp to my Outfile so that it isn't over written each time the script is run.
Secondly, I need to add the "Souce Network Addrees" Parameter from Event ID 528 to the output. I tried adding "Source Network Address" to my script but come back with a null output. Event 528 looks like this:
Successful Logon:
User Name: User
Domain: My Domain
Logon ID: (0x0,0x90BEF452)
Logon Type: 10
Logon Process: User32
Authentication Package: Negotiate
Workstation Name: COMPUTER NAME
Logon GUID: {ea0d7ccb-e029-9d9d-96f0-0
Caller User Name: COMP$
Caller Domain: My Domain
Caller Logon ID: (0x0,0x3E7)
Caller Process ID: 7456
Transited Services: -
Source Network Address: 192.168.1.5
Source Port: 3390
Lastly, I need to know what parameters to add to run the script for the current day rather than for the newest 10000 events,
This is the script I currently have written.
$events = Get-EventLog -ComputerName "COMPUTER" -LogName "Security" -newest 10000 | Where {$_.eventid -eq 528 -AND $_.Source -eq "Security" }
foreach ( $event in $events ) {
if (($event.message | Select-String "Logon Type: 2")){
"LogonType 2 (Interactive Login );"+ $event.TimeGenerated.DateT
}
if (($event.message | Select-String "Logon Type: 3")){
"LogonType 3 (Network Login ) ;"+ $event.TimeGenerated.DateT
}
if (($event.message | Select-String "Logon Type: 4")){
"LogonType 4 (Batch Login ) ;"+ $event.TimeGenerated.DateT
}
if (($event.message | Select-String "Logon Type: 5")){
"LogonType 5 (Service Login ) ;"+ $event.TimeGenerated.DateT
}
if (($event.message | Select-String "Logon Type: 7")){
"LogonType 7 (Computer Unlocked );"+ $event.TimeGenerated.DateT
}
if (($event.message | Select-String "Logon Type: 8")){
"LogonType 8 (Network Cleartext Login );"+ $event.TimeGenerated.DateT
}
if (($event.message | Select-String "Logon Type: 9")){
"LogonType 9 (NewCredentials ) ;"+ $event.TimeGenerated.DateT
}
if (($event.message | Select-String "Logon Type: 10")){
"LogonType 10 (RDP Login ) ;"+ $event.TimeGenerated.DateT
}
if (($event.message | Select-String "Logon Type: 11")){
"LogonType 11 (Cached Credentials Login );"+ $event.TimeGenerated.DateT
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Just wanted to provide a quick update. I was able to get the log to give me the information I wanted, I just had it include the whole message instead of just the source address.
I changed the script to try to have it generated based on the day. I'd also like to have it generate with a timestamp in the file name since it will need to run 2-3 times per day against certain machines. Here is the updated script and output:
$events = Get-EventLog -ComputerName "Computer" -LogName "Security" | Where {$_.eventid -eq 528 -AND $_.Source -eq "Security"-and $_.timeGenerated -ge ((get-date).adddays(0).dat e) }
$LogDate = get-date -uformat "%y-%m-%d" # GET DATE AND FORMAT IT
$LogFileName = logins_$LogDate.txt # CREATE NAME FOR LOG FILE
outfile $LogFileName #CREATE AN EMPTY FILE
foreach ( $event in $events ) {
if (($event.message | Select-String "Logon Type: 2")){
"LogonType 2 (Interactive Login );"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";" +$event.message | Out-File $LogFileName
}
if (($event.message | Select-String "Logon Type: 3")){
"LogonType 3 (Network Login ) ;"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";" +$event.message | Out-File $LogFileName
}
if (($event.message | Select-String "Logon Type: 4")){
"LogonType 4 (Batch Login ) ;"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";" +$event.message | Out-File $LogFileName
}
if (($event.message | Select-String "Logon Type: 5")){
"LogonType 5 (Service Login ) ;"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";" +$event.message | Out-File $LogFileName
}
if (($event.message | Select-String "Logon Type: 7")){
"LogonType 7 (Computer Unlocked );"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";" +$event.message | Out-File $LogFileName
}
if (($event.message | Select-String "Logon Type: 8")){
"LogonType 8 (Network Cleartext Login );"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";" +$event.message | Out-File $LogFileName
}
if (($event.message | Select-String "Logon Type: 9")){
"LogonType 9 (NewCredentials ) ;"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";" +$event.message | Out-File $LogFileName
}
if (($event.message | Select-String "Logon Type: 10")){
"LogonType 10 (RDP Login ) ;"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";" +$event.message | Out-File $LogFileName
}
if (($event.message | Select-String "Logon Type: 11")){
"LogonType 11 (Cached Credentials Login );"+ $event.TimeGenerated.DateT ime + ";" +$event.UserName + ";" +$event.message | Out-File $LogFileName
}
}
The ouput I get now is
Out-File : Cannot bind argument to parameter 'FilePath' because it is null.
At C:\temp\logins.1.ps1:22 char:125
+ "LogonType 5 (Service Login ) ;"+ $event.TimeGenerated.DateT ime +
";" +$event.UserName + ";" +$event.message | Out-File <<<< $LogFileName
+ CategoryInfo : InvalidData: (:) [Out-File], ParameterBindingVal
idationException
+ FullyQualifiedErrorId : ParameterArgumentValidatio nErrorNull NotAllowed ,M
icrosoft.PowerShell.Comman ds.OutFile Command
Out-File : Cannot bind argument to parameter 'FilePath' because it is null.
At C:\temp\logins.1.ps1:19 char:125
+ "LogonType 4 (Batch Login ) ;"+ $event.TimeGenerated.DateT ime +
";" +$event.UserName + ";" +$event.message | Out-File <<<< $LogFileName
+ CategoryInfo : InvalidData: (:) [Out-File], ParameterBindingVal
idationException
+ FullyQualifiedErrorId : ParameterArgumentValidatio nErrorNull NotAllowed ,M
icrosoft.PowerShell.Comman ds.OutFile Command
I changed the script to try to have it generated based on the day. I'd also like to have it generate with a timestamp in the file name since it will need to run 2-3 times per day against certain machines. Here is the updated script and output:
$events = Get-EventLog -ComputerName "Computer" -LogName "Security" | Where {$_.eventid -eq 528 -AND $_.Source -eq "Security"-and $_.timeGenerated -ge ((get-date).adddays(0).dat
$LogDate = get-date -uformat "%y-%m-%d" # GET DATE AND FORMAT IT
$LogFileName = logins_$LogDate.txt # CREATE NAME FOR LOG FILE
outfile $LogFileName #CREATE AN EMPTY FILE
foreach ( $event in $events ) {
if (($event.message | Select-String "Logon Type: 2")){
"LogonType 2 (Interactive Login );"+ $event.TimeGenerated.DateT
}
if (($event.message | Select-String "Logon Type: 3")){
"LogonType 3 (Network Login ) ;"+ $event.TimeGenerated.DateT
}
if (($event.message | Select-String "Logon Type: 4")){
"LogonType 4 (Batch Login ) ;"+ $event.TimeGenerated.DateT
}
if (($event.message | Select-String "Logon Type: 5")){
"LogonType 5 (Service Login ) ;"+ $event.TimeGenerated.DateT
}
if (($event.message | Select-String "Logon Type: 7")){
"LogonType 7 (Computer Unlocked );"+ $event.TimeGenerated.DateT
}
if (($event.message | Select-String "Logon Type: 8")){
"LogonType 8 (Network Cleartext Login );"+ $event.TimeGenerated.DateT
}
if (($event.message | Select-String "Logon Type: 9")){
"LogonType 9 (NewCredentials ) ;"+ $event.TimeGenerated.DateT
}
if (($event.message | Select-String "Logon Type: 10")){
"LogonType 10 (RDP Login ) ;"+ $event.TimeGenerated.DateT
}
if (($event.message | Select-String "Logon Type: 11")){
"LogonType 11 (Cached Credentials Login );"+ $event.TimeGenerated.DateT
}
}
The ouput I get now is
Out-File : Cannot bind argument to parameter 'FilePath' because it is null.
At C:\temp\logins.1.ps1:22 char:125
+ "LogonType 5 (Service Login ) ;"+ $event.TimeGenerated.DateT
";" +$event.UserName + ";" +$event.message | Out-File <<<< $LogFileName
+ CategoryInfo : InvalidData: (:) [Out-File], ParameterBindingVal
idationException
+ FullyQualifiedErrorId : ParameterArgumentValidatio
icrosoft.PowerShell.Comman
Out-File : Cannot bind argument to parameter 'FilePath' because it is null.
At C:\temp\logins.1.ps1:19 char:125
+ "LogonType 4 (Batch Login ) ;"+ $event.TimeGenerated.DateT
";" +$event.UserName + ";" +$event.message | Out-File <<<< $LogFileName
+ CategoryInfo : InvalidData: (:) [Out-File], ParameterBindingVal
idationException
+ FullyQualifiedErrorId : ParameterArgumentValidatio
icrosoft.PowerShell.Comman
ASKER
I got the script to do what I wanted as far as creating a log file, is it possible to e-mail this file after it's created?
try the following powershell function , will will require a smtp server to relay the message
##############################################################
Function SendEmail
{
Param (
[string]$EmailToAddress = "xxx@xxx.com",
[string]$Emailsubject = "Test",
[string]$EmailBody = "This is the body" ,
[string]$attachment = "",
[string]$EmailCcAddress = (""),
[string]$EmailFromAddress = "from@mydomain.net",
[string]$EmailSmtpServer = "192.192.192.192"
)
if ( ($EmailtoAddress -eq "/?") -or ($EmailtoAddress -eq "-?") -or ($EmailtoAddress -eq "-help") -or ($EmailtoAddress -eq "-h") )
{
#cls
write-host "Help for SendEmail Function"
""
""
Write-host -f GReen "---------------------------"
""
""
write-host -nonewline ' Usage : '
write-host -nonewline -f yellow 'SendEmail '
write-host -nonewline ' "EmailToAddress" "Subject" "Body Text" "Attachment Filename" " CC addresses" "From Address" '
''
""
""
'EG >> sendemail "user@domain.com" "Test" "Check out my body text " "c:\report.xml" "" "sysadmin@mydomain.com" '
""
break
}
#######################################
# Create from/to addresses
#######################################
$from = New-Object System.Net.Mail.MailAddress $EmailFromAddress
$to = New-Object System.Net.Mail.MailAddress $EmailToAddress
#######################################
# Create Message
#######################################
$message = new-object System.Net.Mail.MailMessage $from, $to
$message.Subject = $Emailsubject
$message.Body = $EmailBody
if ($attachment -ne "") {$message.Attachments.Add($attachment) }
#######################################
#add the CC Addresses
#######################################
if ($EmailCcAddress -ne "") { foreach ($CCAddress in $EmailCcAddress) {$message.Cc.Add($CCAddress)} }
#######################################
# create SMTP Client
#######################################
$client = new-object system.net.mail.smtpclient $EmailSmtpServer
$client.Send($message)
#######################
} # end Function
#######################
#######################################
# Example usage
#######################################
# sendemail "testuser@domain.com" "test" "" "" "" "sysadmin@mydomain.com"
ASKER
When specifying the file name to e-mail can I add a variable to it so that it e-mails the log file generated for that day. For instance if I put
"C:\temp\Event528_$((get-d ate).toStr ing('MM-dd -yyyy"
as my attachment file name it would pull the one for today's date. Sorry am new to scripting if this is a super obvious question.
"C:\temp\Event528_$((get-d
as my attachment file name it would pull the one for today's date. Sorry am new to scripting if this is a super obvious question.
i got error here ?
Get-EventLog : Requested registry access is not allowed.
At line:1 char:22
+ $event = Get-EventLog <<<< -LogName "Security" -newest 1 | Where {$_.eventid -eq 528 -AND $_.Source -eq "Security" }
+ CategoryInfo : NotSpecified: (:) [Get-EventLog], SecurityException
+ FullyQualifiedErrorId : System.Security.SecurityException,Microsoft.PowerShell.Commands.GetEventLogCommand
Get-Member : No object has been specified to the get-member cmdlet.
At line:2 char:20
+ $event | get-member <<<<
+ CategoryInfo : CloseError: (:) [Get-Member], InvalidOperationException
+ FullyQualifiedErrorId : NoObjectInGetMember,Microsoft.PowerShell.Commands.GetMemberCommand
ASKER
Thank you very much for the help with the script. When I run:
$event = Get-EventLog -ComputerName "COMPUTER" -LogName "Security" -newest 1000 | Where {$_.eventid -eq 528 -AND $_.Source -eq "Security" }
$event | get-member
I get back
Get-Member : No object has been specified to the get-member cmdlet.
At C:\temp\login3.ps1:2 char:20
+ $event | get-member <<<<
+ CategoryInfo : CloseError: (:) [Get-Member], InvalidOperationEx
ception
+ FullyQualifiedErrorId : NoObjectInGetMember,Micros
s.GetMemberCommand
Also when I run the full script as copied with the correct computer name I get the output of:
The term 'logins_$LogDate.txt' is not recognized as the name of a cmdlet, funct
ion, script file, or operable program. Check the spelling of the name, or if a
path was included, verify that the path is correct and try again.
At C:\temp\logins2.ps1:3 char:36
+ $LogFileName = logins_$LogDate.txt <<<< # CREATE NAME FOR LOG FIL
E
+ CategoryInfo : ObjectNotFound: (logins_$LogDate.txt:Strin
CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Out-File : Cannot bind argument to parameter 'FilePath' because it is null.
At C:\temp\logins2.ps1:4 char:9
+ out-file <<<< $LogFileName #CREATE AN EMPTY FILE
+ CategoryInfo : InvalidData: (:) [Out-File], ParameterBindingVal
idationException
+ FullyQualifiedErrorId : ParameterArgumentValidatio
icrosoft.PowerShell.Comman