Link to home
Start Free TrialLog in
Avatar of RichardPWolf
RichardPWolfFlag for United States of America

asked on

adding text to end of string

This would seem to be an easy solution but....

The setup. I'm trying to search offline eventlogs. There are multiple logs of a server just different weeks.
These logs are located on a remote storage location.
I can get the directory using
> $logarchivepath = get-childitem $logarchiveuncpath\ -Recurse | ?{ $_.PSIsContainer } | Sort-Object | Select-Object FullName  

Open in new window

I can get the filenames using
> $filenames = get-childitem $logarchiveuncpath\ -Recurse | Select -exp Name

Open in new window

The result of $logarchivepath is ;
\\jill\it-dept\Docs\Docs\Monthly IT Reports\EventLogBackup\temp\WIN10SERVER-Logs-02031502

Open in new window

>>>>> There are about 20 servers with at least 4 folders each<<<<<<<

The result of $filenames is:
Application.evt
ADAM (VMwareVCMSDS).evt
System.evt
Internet Explorer.evt
Active Directory Web Services.evt
Windows PowerShell.evt
HardwareEvents.evt
Key Management Service.evt
Security.evt

Open in new window

>>>>>>>>>>>Again this list is repeated for each server in the above list.<<<<<<<<<<<<<<<<<<

This is my code;
$log = "Security.evt"
	foreach ($computer in $strcomputer)
	{
        $lpb = 1
	 $computer
        $logarchivepath = get-childitem $logarchiveuncpath\ -Recurse | ?{ $_.PSIsContainer } | Sort-Object | Select-Object FullName 
        $filenames = get-childitem $logarchiveuncpath\ -Recurse | Select -exp Name
        $logarchivepath 
           foreach ($logfile in $logarchivepath)
            { 
            foreach ($filename in $filenames)
                {
 		        $result = Get-Winevent -Path $logfile -Logname "$log" -oldest | where-object {$_.Id -eq 517 -or $_.Id -eq 1102}
                $result
                pause
                }
            }
	$lpa = $lpa + 1
	}

Open in new window

>>> The pause statement is for troubleshooting<<<<<

I'm getting the following error;

Get-WinEvent : Parameter set cannot be resolved using the specified named parameters.
At line:179 char:22
+                  $result = Get-Winevent -Path $logfile -Logname "$log" -oldest | where ...
+                            ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidArgument: (:) [Get-WinEvent], ParameterBindingException
    + FullyQualifiedErrorId : AmbiguousParameterSet,Microsoft.PowerShell.Commands.GetWinEventCommand

I "think" my problem is that I need a trailing "\" in my path statement but not sure. And I've tried just about every conceivable method to add a trailing "\" to the path statement but haven't been successful.

Or is there something else I've missed?
Avatar of aikimark
aikimark
Flag of United States of America image

Have you tried imple concatenation?  
Example:
foldername  +"\"+ filename

Open in new window

Avatar of RichardPWolf

ASKER

Yes...to a point. As I understand the Get-Winevent I use the -path <log location> and then the -logname <eventlog.evt> so I've only tried to get the trailing "\" on the path name.
It's not due to a "\".  When you use the -Path parameter you don't need the -Logname parameter.  Those parameters are members of separate parameter sets.
Ahhhh. Then when using the path statement I would use the full path "plus" the filename. Is that correct?
Yes, the complete path (directory and filename) to the file you want to open.
OK, great. Let me plug that info into my script.

So to summarize I would do the following;
$logarchivepath = "\\remote location"
$log = "security.evt"
$path = $logarchivepath + "\" + $log

Get-Winevent -path $path ...... and more code.
Tried it...Didn't work.
PS C:\Users\rwolf> $file = $logfile + "\" + $log
Method invocation failed because [System.Management.Automation.PSObject] does not contain a method named
'op_Addition'.
At line:1 char:1
+ $file = $logfile + "\" + $log
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (op_Addition:String) [], RuntimeException
    + FullyQualifiedErrorId : MethodNotFound
Changed some code around. I think what's happening is that my variable $logpath (new variable) is not a string.

New code----
$logarchivepath = get-childitem $logarchiveuncpath\ -Recurse | ?{ $_.PSIsContainer } | Sort-Object | Select-Object FullName
        $filenames = get-childitem $logarchiveuncpath\ -Recurse | Select -exp Name
        $logarchivepath
           foreach ($logpath in $logarchivepath)
            {
                $logfile = "$logpath + '\' + $log"
                       $result = Get-Winevent -Path $logfile -oldest | where-object {$_.Id -eq 517 -or $_.Id -eq 1102}
                $result
                pause
               
            }
Sorry I meant to include the error. Note the inclusion of my local drive and user information on the first line. Plus the @{......} around the expanded $logpath.

Get-Winevent : Cannot find path 'C:\Users\rwolf\@{FullName=\jill\it-dept\Docs\Docs\Monthly IT
Reports\EventLogBackup\temp\BABS-Logs-02031501} + '\' + Security.evt' because it does not exist.
At E:\Scripts\WorkInProgress.ps1:178 char:24
+                    $result = Get-Winevent -Path $logfile -oldest | where-object {$_.Id ...
+                              ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : ObjectNotFound: (@{FullName=\\ji... + Security.evt:String) [Get-WinEvent], I
   temNotFoundException
    + FullyQualifiedErrorId : Microsoft.PowerShell.Commands.GetWinEventCommand
I can get close.
Results of previous combining of variables. And yes it was a type mismatch of sorts.

code: $logfile = [string]$logpath + '\' + $log
Results: @{FullName=\\jill\it-dept\Docs\Docs\Monthly IT Reports\EventLogBackup\temp\BABS-Logs-02031501}\Security.evt

Now I need to figure out how to get ride of the extra text @{fullname=  and the "}" between the path and the filename.
I can't tell where $logpath is coming from.  But it's likely an object that has a "fullname" property.  You need $logpath to be a simple object type like a string, not a complex type (an object that can have many properties), or you need to reference the specific property you're interested in.

Why don't you use something like this?
$log = "Security.evt"
get-childitem $logarchiveuncpath\ -Recurse -filter $log | Select -expand fullname | % `
{ Get-Winevent -Path $_ -oldest | where-object {$_.Id -eq 517 -or $_.Id -eq 1102} }

Open in new window

You might be able to optimize the Get-Winevent command by using the -filterhashtable parameter to filter IDs, rather than piping to Where-Object, but that's for later once you get the main functionality working.
Thanks, I'll give that a try.
Sorry for the delay been working on another project.

Code seems to work. I'm testing it now. So far it's looking at my first server and am waiting to see if it looks at all servers. Now to get it into a report.
Again sorry for the delay. Got pulled off of this project to deal with another pressing one "Can you say squeaky wheel?". Anyway was able to work with it a little bit still getting some errors. I'm possible going to look at another method which "might" make searching easier. And that is to convert the log files into XML. I'll get back with the progress.
I may be able to help you, but you'll have to post the code you're running and the errors you're seeing...

I'm doubtful that converting the logs to XML would make things easier, but without knowing more about your situation, I couldn't really say.
Thanks, I'll post the code as soon as possible. I'm out of the office today so I'm not sure if it will happen today.
Well due to a computer crash I've lost all my code for this project (and many others). So I'll be starting all over. Not sure if it's reasonable to keep this question open but for the moment I'll do so. If I can't get back to this soon I'll delete the question.

Thanks.
Richard.
OK, I've been able to work with this and yes it does work but I'm missing something. It appears as it's going through the logs there's no definition between servers. What I will be doing is a formatted html document so I need the computer name. How can I add a display for the computer name? I'm trying to break down what you've posted to where I can get the information I need.

Thanks.
Without knowing what code you're using, I can only provide some general advice.  Save the computer name to a variable.  Get-WinEvent outputs objects, and you'll probably use a Select-Object statement to choose which properties of those objects you want.  So with Select-Object, add a calculated property for the computer name, utilizing the previously mentioned variable as the value.
OK, good idea. I also thought about breaking the get-winevent down into a for each loop and only pass one computer at a time but that comes with it's own problems. I like what you've done it's just that parsing thought about 175 folders takes a long time. As these eventlogs are backed up based on the security log being full I'm looking at 1. only backing up the security log as the all the others overwrite as necessary. and 2. increase the log size to slow down the number of log full events.
If you have many computer names, you'll almost assuredly be using a foreach loop (either the foreach statement or ForEach-Object) to cycle through them.  The name has to come from somewhere, usually a file (or sometimes an AD query) but could be the name of a parent folder.  So depending on where the name comes from your approach can change a bit.
Thanks, If I understand the statement correctly I should be able to substitute the $logarchiveuncpath with the computer specific folders i.e. IT-DEPT-Logs-xxxxxx <-date to work with the specific logs.
Sounds reasonable.   But again, without knowing what code you're using I couldn't say more.  Also I don't know what your folder structure is like, whether logs are all kept on the same server, etc.
OK fair enough. Let me put together what I've got and I'll upload it so you can see.
OK, this is a snippet of the total code but is broken down and works for the most part. I'm not getting any results even though I know Event ID 517 and 1102 are present in the logs.

$logarchiveuncpath = "\\jill\IT-Dept\Docs\Docs\Monthly IT Reports\EventLogBackup\temp"
$log = "Security.evt"

$strComputers = @()
      $strComputers = Get-ADComputer -Filter {OperatingSystem -like "*server*"} -Properties OperatingSystem |
     Select-Object name | Sort-Object name | foreach {$_.Name}



foreach ($computer in $strComputers)
{
   $compname = get-childitem $logarchiveuncpath | sort-object -Property name | Select-String -pattern "$computer"
   $computer
      foreach ($comp in $compname)
      { $comp
       get-childitem "$logarchiveuncpath$comp" -recurse -filter $log | Select -expand fullname | Foreach-object `
          { Get-Winevent -Path $_ -oldest | where-object {$_.Id -eq 517 -or $_.Id -eq 1102} }
      }
    Pause
 
}

I know it's working the folders as this is the results I see (due to printing of certain variables).

BABS

BABS-Logs-02031501
babs-Logs-02061557
babs-Logs-02131527
babs-Logs-02131540
babs-Logs-02201516
babs-Logs-03021533
Press Enter to continue...:

This is the format for the folders for all servers.
I'm not confident about it getting the folders right.  Select-String is more for looking inside text files.  Try this.
foreach ($computer in $strComputers)
{
    $compname = Get-ChildItem $logarchiveuncpath | Where { $_.name -match "$computer" } | Select -ExpandProperty FullName
    $computer
    foreach ($comp in $compname)
    { $comp
        Get-ChildItem $comp -recurse -filter $log | Select -expand fullname | ForEach-Object `
            { Get-Winevent -Path $_ -oldest | where-object {$_.Id -eq 517 -or $_.Id -eq 1102} }
    }
    Pause
}

Open in new window

OK, Thanks.
That works great. Running a test right now to see how it works. Just wish it didn't take so long to work its way through all the folders (there is a LOT of folders). Will let this run tonight and see what it looks like in the morning.
ASKER CERTIFIED SOLUTION
Avatar of footech
footech
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Hmmm. Thanks. I had steered away thinking that using the hash table would be more complicated. I'll try it as the script has ran for 16+ hours and it's still not done with all the folders.
All I can say is WOW. I never thought a search of this magnitude could be done so fast. Probably less than 5 minutes. I didn't even have time to think about timing it. I've still got some cleanup but...... looks like I will be modifying many other scripts that use the winevent cmdlet.

Again thanks.
Richard.