Powershell Extracting info from Event Log Error

Windows 2008 Server

I get this event Error every now and then and I want to create a script to extract the ip address from this message and place it in a file to build a file of all the ip address from all the messages then I can update my Firewall rule to add the list to the not allowed in my rule.

My code

$DT = [DateTime]::Now.AddDays(-1)

$l = Get-EventLog Application -InstanceId 1035 -after $DT

$l | select-string -inputobject {$_.message} -pattern "Microsoft Exchange is (.)*\.*\.*\.*"  -allmatches | foreach-object {$_.Matches} | foreach-object {$_.Value} | foreach-object {$_.replace("Microsoft Exchange is ", "")} | group-object -property $_ | where-object {$_.count -gt 10} | select-object -property name | format-list | out-file c:\rdpblock.txt get-content -path c:\rdpblock.txt | foreach-object {$_.replace("Name :", "")} | out-file c:\rdpblockcleaned.txt 

get-content -path c:\rdpblockcleaned.txt | select-object -unique | out-file c:\rdpblocknospaces.txt

$c = get-content -path c:\rdpblocknospaces.txt | select-object -skip 1

 

Open in new window



Results

PS C:\util> ./getipfrom1035
Get-EventLog : No matches found
At C:\util\GetIPFrom1035.ps1:3 char:6
+ $l = Get-EventLog Application -InstanceId 1035 -after $DT
+      ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (:) [Get-EventLog], ArgumentException
    + FullyQualifiedErrorId : GetEventLogNoEntriesFound,Microsoft.PowerShell.Commands.GetEventLogCommand

PS C:\util>



The event log message

Log Name:      Application
Source:        MSExchangeTransport
Date:          7/21/2015 6:32:12 PM
Event ID:      1035
Task Category: SmtpReceive
Level:         Warning
Keywords:      Classic
User:          N/A
Computer:      SERV025.FQDN.com
Description:
Inbound authentication failed with error LogonDenied for Receive connector Default SERV025. The authentication mechanism is Ntlm. The source IP address of the client who tried to authenticate to Microsoft Exchange is [193.0.200.134].
Event Xml:
<Event xmlns="http://schemas.microsoft.com/win/2004/08/events/event">
  <System>
    <Provider Name="MSExchangeTransport" />
    <EventID Qualifiers="32772">1035</EventID>
    <Level>3</Level>
    <Task>1</Task>
    <Keywords>0x80000000000000</Keywords>
    <TimeCreated SystemTime="2015-07-21T22:32:12.000000000Z" />
    <EventRecordID>206324</EventRecordID>
    <Channel>Application</Channel>
    <Computer>SERV025.FQDN.com</Computer>
    <Security />
  </System>
  <EventData>
    <Data>LogonDenied</Data>
    <Data>Default SERV025</Data>
    <Data>Ntlm</Data>
    <Data>193.0.200.134</Data>
  </EventData>
</Event>




Also I want to run this command in the script

netsh advfirewall firewall set rule name="Block_IP" new remoteip=38.87.45.44,193.0.200.134        etc   

Open in new window


Need to read the file and create this line


Thoughts.
LVL 23
Thomas GrassiSystems AdministratorAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Justin YeungSenior Systems EngineerCommented:
The error indicate it can't find anything match the instanceID 1035 after $DT.

are you running this remotely or on the box itself?
footechCommented:
From what I've seen, you will get the error when there is an event with a matching ID, but not one that falls within the specified timeframe.  However, you can hide the error by using -errorAction SilentlyContinue.

Since you have Server 2008, I'll advocate using Get-WinEvent with a filter hashtable as it is faster.  See how this bit works for you (should work for a single event).
$l = Get-WinEvent -FilterHashtable @{ LogName = "Application"; id = 1035; StartTime = (Get-Date).AddDays(-1) } -ErrorAction SilentlyContinue
$IP = ([xml]$l.ToXml()).Event.EventData.Data[3]

Open in new window

For more than one event, this should work.
Get-WinEvent -FilterHashtable @{ LogName = "Application"; id = 1035; StartTime = (Get-Date).AddDays(-1) } -ErrorAction SilentlyContinue |
 ForEach { ([xml]$_.ToXml()).Event.EventData.Data[3] }

Open in new window


Besides getting the IP, I don't know where you're going with line 5 of your code, so maybe you can explain what you have in mind.
Justin YeungSenior Systems EngineerCommented:
found the reason.

the time stamp doesn't work after -After parameter

you will need to change to this

$DT = [DateTime]::Now.AddDays(-1).ToshortDateString()
Discover the Answer to Productive IT

Discover app within WatchGuard's Wi-Fi Cloud helps you optimize W-Fi user experience with the most complete set of visibility, troubleshooting, and network health features. Quickly pinpointing network problems will lead to more happy users and most importantly, productive IT.

Thomas GrassiSystems AdministratorAuthor Commented:
Thanks Guys

Made both changes now the job runs

But the output file rdpblock.txt is empty.


My current code.

$DT = [DateTime]::Now.AddDays(-1).ToshortDateString() 

$l = Get-WinEvent -FilterHashtable @{ LogName = "Application"; id = 1035; StartTime = (Get-Date).AddDays(-1) } -ErrorAction SilentlyContinue
$IP = ([xml]$l.ToXml()).Event.EventData.Data[3]


$l | select-string -inputobject {$_.message} -pattern "Microsoft Exchange is (.)*\.*\.*\.*"  -allmatches | foreach-object {$_.Matches} | foreach-object {$_.Value} | foreach-object {$_.replace("Microsoft Exchange is ", "")} | group-object -property $_ | where-object {$_.count -gt 10} | select-object -property name | format-list | out-file c:\rdpblock.txt 

Open in new window




This runs on the server itself not remotely.


Footech

Besides getting the IP, I don't know where you're going with line 5 of your code, so maybe you can explain what you have in mind.

I need to build a file rdpblock.txt to look like this

38.13.85.101
151.11.112.32
192.168.38.100

etc etc etc.

Then lastly build the
netsh advfirewall firewall set rule name="Block_IP" new remoteip=38.87.45.44,193.0.200.134        etc  

which needs to read the rdpblock.txt file to get all the ip addresses.

Hope that explains
footechCommented:
@Justin - I don't think that's right.  I've used a datetime object for the parameter.  One thing I've noticed that may affect the results is that InstanceID and EventID are not always the same thing.
footechCommented:
The pattern in Select-String won't match, so that's one problem.

Your description doesn't quite cover everything.  What's the Group-Object and Where-Object and so forth in there for?  Rather than making (educated) guesses, I'd rather hear it from you.
$IPs = Get-WinEvent -FilterHashtable @{ LogName = "Application"; id = 1035; StartTime = (Get-Date).AddDays(-1) } -ErrorAction SilentlyContinue |
 ForEach { ([xml]$_.ToXml()).Event.EventData.Data[3] } |
 Select -Unique
If ( Test-Path c:\rdpblock.txt )
{
    $read = Get-Content c:\rdpblock.txt
    $IPs += $read
    $IPs = $IPs | Select -Unique
}
$IPs | Out-File c:\rdpblock.txt -Encoding ascii

$netIPs = $IPs -join "," 
netsh advfirewall firewall set rule name="Block_IP" new remoteip=$netIPs

Open in new window

Thomas GrassiSystems AdministratorAuthor Commented:
Footech

the above is working now just one minor problem

the netsh  command failed

The contents of rdpblock.txt are:
193.0.200.13438.87.45.44220.130.108.48

My script is this now
$IPs = Get-WinEvent -FilterHashtable @{ LogName = "Application"; id = 1035; StartTime = (Get-Date).AddDays(-1) } -ErrorAction SilentlyContinue |
 ForEach { ([xml]$_.ToXml()).Event.EventData.Data[3] } |
 Select -Unique
If ( Test-Path c:\rdpblock.txt )
{
    $read = Get-Content c:\rdpblock.txt
    $IPs += $read
    $IPs = $IPs | Select -Unique
}
$IPs | Out-File c:\rdpblock.txt -Encoding ascii

$netIPs = $IPs -join "," 
netsh advfirewall firewall set rule name="Block_IP" new remoteip=$netIPs
netsh advfirewall firewall show rule name="Block_IP"

Open in new window


I ran it and this is the console I also showed what the Firewall rule looks like



PS C:\util> set-psbreakpoint -script c:\util\getipfrom1035.ps1 -variable cn

  ID Script                      Line Command                     Variable                   Action
  -- ------                      ---- -------                     --------                   ------
   0 getipfrom1035.ps1                                            cn


PS C:\util> ./getipfrom1035

A specified IP address or address keyword is not valid.

Usage: set rule
      group=<string> | name=<string>
      [dir=in|out]
      [profile=public|private|domain|any[,...]]
      [program=<program path>]
      [service=service short name|any]
      [localip=any|<IPv4 address>|<IPv6 address>|<subnet>|<range>|<list>]
      [remoteip=any|localsubnet|dns|dhcp|wins|defaultgateway|
         <IPv4 address>|<IPv6 address>|<subnet>|<range>|<list>]
      [localport=0-65535|<port range>[,...]|RPC|RPC-EPMap|IPHTTPS|any]
      [remoteport=0-65535|<port range>[,...]|any]
      [protocol=0-255|icmpv4|icmpv6|icmpv4:type,code|icmpv6:type,code|
         tcp|udp|any]
      new
      [name=<string>]
      [dir=in|out]
      [program=<program path>
      [service=<service short name>|any]
      [action=allow|block|bypass]
      [description=<string>]
      [enable=yes|no]
      [profile=public|private|domain|any[,...]]
      [localip=any|<IPv4 address>|<IPv6 address>|<subnet>|<range>|<list>]
      [remoteip=any|localsubnet|dns|dhcp|wins|defaultgateway|
         <IPv4 address>|<IPv6 address>|<subnet>|<range>|<list>]
      [localport=0-65535|RPC|RPC-EPMap|any[,...]]
      [remoteport=0-65535|any[,...]]
      [protocol=0-255|icmpv4|icmpv6|icmpv4:type,code|icmpv6:type,code|
         tcp|udp|any]
      [interfacetype=wireless|lan|ras|any]
      [rmtcomputergrp=<SDDL string>]
      [rmtusrgrp=<SDDL string>]
      [edge=yes|deferapp|deferuser|no (default=no)]
      [security=authenticate|authenc|authdynenc|notrequired]

Remarks:

      - Sets a new parameter value on an identified rule. The command fails
        if the rule does not exist. To create a rule, use the add command.
      - Values after the new keyword are updated in the rule.  If there are
        no values, or keyword new is missing, no changes are made.
      - A group of rules can only be enabled or disabled.
      - If multiple rules match the criteria, all matching rules will
        be updated.
      - Rule name should be unique and cannot be "all".
      - If a remote computer or user group is specified, security must be
        authenticate, authenc or authdynenc.
      - Setting security to authdynenc allows systems to dynamically
        negotiate the use of encryption for traffic that matches
        a given Windows Firewall rule. Encryption is negotiated based on
        existing connection security rule properties. This option
        enables the ability of a machine to accept the first TCP
        or UDP packet of an inbound IPsec connection as long as
        it is secured, but not encrypted, using IPsec.
        Once the first packet is processed, the server will
        re-negotiate the connection and upgrade it so that
        all subsequent communications are fully encrypted.
      - Authdynenc is valid only when dir=in.
      - If action=bypass, the remote computer group must be specified when dir=in.
      - If service=any, the rule applies only to services.
      - ICMP type or code can be "any".
      - Edge can only be specified for inbound rules.

Examples:

      Change the remote IP address on a rule called "allow80":
      netsh advfirewall firewall set rule name="allow80" new
      remoteip=192.168.0.2

      Enable a group with grouping string "Remote Desktop":
      netsh advfirewall firewall set rule group="remote desktop" new
      enable=yes

      Change the localports on the rule "Allow port range" for udp-
      Set rule name="Allow port range" dir=out protocol=udp localport=5000-5020 action=allow






Rule Name:                            Block_IP
----------------------------------------------------------------------
Enabled:                              Yes
Direction:                            In
Profiles:                             Domain,Private,Public
Grouping:
LocalIP:                              Any
RemoteIP:                             38.87.45.44/32,220.130.108.48/32
Protocol:                             TCP
LocalPort:                            Any
RemotePort:                           25
Edge traversal:                       No
Action:                               Block
Ok.

PS C:\util>


Not sure what $netIPS looks like before it is passed to the command line can we display it to see?
I think it needs comma's between the ip addresses

Thoughts
footechCommented:
Hmm...  There should one IP per line in the rdpblock.txt file.  Easiest fix right now is to edit the file so it is so.  I suppose it could have happened if the file was first created with only a single line - then when it was read in it was just a string type instead of an array of strings.   That would cause the append to happen in way we don't want.
You could modify line 6 so this wouldn't happen again if you started over.
    $read = @(Get-Content c:\rdpblock.txt)

Open in new window


You can write out the contents of a variable at any time during a script.  If you want to do it after a script is ran, then easiest is to run the script in the global scope.
. .\getipfrom1035

Open in new window

Thomas GrassiSystems AdministratorAuthor Commented:
Footech

Yes I agree one ip address per line would be the best
So I changed the file rdpblock.txt to this
193.0.200.134
38.87.45.44
220.130.108.48

Changed Line 6 to
$read = @(Get-Content c:\rdpblock.txt)

New Code is
$IPs = Get-WinEvent -FilterHashtable @{ LogName = "Application"; id = 1035; StartTime = (Get-Date).AddDays(-1) } -ErrorAction SilentlyContinue |
 ForEach { ([xml]$_.ToXml()).Event.EventData.Data[3] } |
 Select -Unique
If ( Test-Path c:\rdpblock.txt )
{
    $read = @(Get-Content c:\rdpblock.txt)
    $IPs += $read
    $IPs = $IPs | Select -Unique
}
$IPs | Out-File c:\rdpblock.txt -Encoding ascii
$netIPs = $IPs -join "," 

netsh advfirewall firewall set rule name="Block_IP" new remoteip=$netIPs
netsh advfirewall firewall show rule name="Block_IP"

Open in new window



Now the RDPBLOACK.TXT file is back to a single line
193.0.200.134193.0.200.13438.87.45.44220.130.108.48

So what do you think is wrong ?

Also I tried
. .\getipfrom1035

Same results and no variables displayed

The RDPBlock.TXT file needs to be corrected first but not sure where to go from here

Thoughts
Thomas GrassiSystems AdministratorAuthor Commented:
Footech

I did this that may help you

PS C:\Util> ls variable:

Name                           Value                                                                          
----                           -----                                                                          
$                              variable:                                                                      
?                              False                                                                          
^                              is                                                                            
args                           {}                                                                            
ConfirmPreference              High                                                                          
ConsoleFileName                                                                                              
CurrentlyExecutingCommand                                                                                    
DebugPreference                SilentlyContinue                                                              
Error                          {The term 'is' is not recognized as the name of a cmdlet, function, script f...
ErrorActionPreference          Continue                                                                      
ErrorView                      NormalView                                                                    
ExecutionContext               System.Management.Automation.EngineIntrinsics                                  
false                          False                                                                          
FormatEnumerationLimit         4                                                                              
HOME                           C:\Users\administrator.mydom                                                    
Host                           System.Management.Automation.Internal.Host.InternalHost                        
input                          System.Collections.ArrayList+ArrayListEnumeratorSimple                        
IPs                            193.0.200.134193.0.200.13438.87.45.44 220.130.108.48                          
LASTEXITCODE                   0                                                                              
MaximumAliasCount              4096                                                                          
MaximumDriveCount              4096                                                                          
MaximumErrorCount              256                                                                            
MaximumFunctionCount           4096                                                                          
MaximumHistoryCount            4096                                                                          
MaximumVariableCount           4096                                                                          
MyInvocation                   System.Management.Automation.InvocationInfo                                    
NestedPromptLevel              0                                                                              
netIPs                         193.0.200.134193.0.200.13438.87.45.44 220.130.108.48                          
null                                                                                                          
OutputEncoding                 System.Text.SBCSCodePageEncoding                                              
PID                            8224                                                                          
profile                        C:\Users\administrator.mydom\Documents\WindowsPowerShell\Microsoft.PowerShellI...
ProgressPreference             Continue                                                                      
PSBoundParameters              {}                                                                            
PSCommandPath                  C:\Util\GetIPFrom1035.ps1                                                      
PSCulture                      en-US                                                                          
PSDefaultParameterValues       {}                                                                            
PSEmailServer                                                                                                
PSHOME                         C:\Windows\System32\WindowsPowerShell\v1.0                                    
psISE                          Microsoft.PowerShell.Host.ISE.ObjectModelRoot                                  
PSScriptRoot                   C:\Util                                                                        
PSSessionApplicationName       wsman                                                                          
PSSessionConfigurationName     http://schemas.microsoft.com/powershell/Microsoft.PowerShell                   
PSSessionOption                System.Management.Automation.Remoting.PSSessionOption                          
PSUICulture                    en-US                                                                          
psUnsupportedConsoleApplica... {wmic, wmic.exe, cmd, cmd.exe...}                                              
PSVersionTable                 {PSVersion, WSManStackVersion, SerializationVersion, CLRVersion...}            
PWD                            C:\Util                                                                        
read                           {193.0.200.13438.87.45.44 220.130.108.48}                                      
ShellId                        Microsoft.PowerShell                                                          
StackTrace                        at System.Management.Automation.CommandDiscovery.LookupCommandInfo(String...
true                           True                                                                          
VerbosePreference              SilentlyContinue                                                              
WarningPreference              Continue                                                                      
WhatIfPreference               False                                                                          


Shows how the IP's are not correctly formatted

HTH
footechCommented:
Ah, I see another possible cause of the same problem.  Change line 1-3
$IPs = @(Get-WinEvent -FilterHashtable @{ LogName = "Application"; id = 1035; StartTime = (Get-Date).AddDays(-1) } -ErrorAction SilentlyContinue |
 ForEach { ([xml]$_.ToXml()).Event.EventData.Data[3] } |
 Select -Unique)

Open in new window


Of course, unless you edit the script to output a variable, it's not going to do it.  Or if you ran it in the global scope, then at the PS prompt you can call the variables as you want after the script ran (your ls variable: command is an example of this).  You know you can just have a command like $IPs right?

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Thomas GrassiSystems AdministratorAuthor Commented:
Footech

You got it, now working.

Can I email the report in PowerShell?

I would like the output of this command in the body of an email
netsh advfirewall firewall show rule name="Block_IP"

Look like this
Rule Name:                            Block_IP
----------------------------------------------------------------------
Enabled:                              Yes
Direction:                            In
Profiles:                             Domain,Private,Public
Grouping:
LocalIP:                              Any
RemoteIP:                             38.87.45.44/32,193.0.200.134/32,220.130.108.48/32
Protocol:                             TCP
LocalPort:                            Any
RemotePort:                           25
Edge traversal:                       No
Action:                               Block
Ok.
 

I can add these two lines for sending email
$PSEmailServer = "serv025.mydomain.net"
PS C:\> Send-MailMessage -From "no-reply@mydomain.net" -To "support@mydomain.net" -Subject "SERV025 Firewall Rule BlockIP Updated" -Body "   XXXXXXXXXXXXXX  "




This works sending email just need way to get the output into the body?


Thoughts?
footechCommented:
How about
$body = netsh advfirewall firewall show rule name="Block_IP" | Out-String
$PSEmailServer = "serv025.mydomain.net"
Send-MailMessage -From "no-reply@mydomain.net" -To "support@mydomain.net" -Subject "SERV025 Firewall Rule BlockIP Updated" -Body $body -smtpserver $PSEmailServer

Open in new window

Thomas GrassiSystems AdministratorAuthor Commented:
Footech we are getting very close to finishing this one Thanks for all the help

The above works when I am connected from my machine to the Server using PowerShell
From my computer I start PowerShell and then issue
Enter-pssession -computername serv025


Then I run this and I get an email sent to my account all good

$body = netsh advfirewall firewall show rule name="Block_IP" | Out-String
$PSEmailServer = "serv025.mydomain.net"
Send-MailMessage -From "no-reply@mydomain.net" -To "support@mydomain.net" -Subject "SERV025 Firewall Rule BlockIP Updated" -Body $body -smtpserver $PSEmailServer

Open in new window



When I run the code above on my Server Windows 2008 R2 running Exchange 2010
The email is never sent.
I even changed the $PSEmailServer = "serv025.mydomain.net"
to $PSEmailServer = "10.2.8.2"  the ip address of SERV025

No luck

Thoughts
footechCommented:
You just keep adding on don't you?  :)

I think you would best be served by asking a new question for the last.  Sounds like Exchange is blocking the email or it's not getting routed correctly.  I no longer deal with on-site Exchange so can't really help.  I also don't see why it would be different in a local session on the Exhange vs. a remote session to that same machine.
Thomas GrassiSystems AdministratorAuthor Commented:
Footech

Yes indeed it works

Chceked the exchange server found event id 1020 going to open new case for that one if needed

Thanks for all your help
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Powershell

From novice to tech pro — start learning today.