Need to parse thousands of files for thousands of results - prefer powershell - multithreading

I am getting consistently pinged from our government contract holder to search for IP addresses in our logs. I have three firewalls, 30 plus servers, etc so you can imagine how unwieldy it becomes. To amplify the problem, I have been provided a list of over 1500 IP addresses for which I am to search all log files...
I have all of the logs downloaded and can use powershell to go through them one by one but it takes forever. I need to be able to run the search using multi-thread in Powershell but cannot figure out the logic to do so. Here's my one by one script...
Any help would be appreciated!
$log = (import-csv C:\temp\FWLogs\IPSearch.csv)
$ip = ($log.IP)
ForEach($log in $log){ Get-ChildItem -Recurse -path C:\temp\FWLogs -filter *.log | Select-String $ip -List | Select Path
}

Related

Looking to validate that certain string is present in a text file, send warning if not

I have a process where files containing data are generated in separate locations, saved to a networked location, and merged into a single file.
And the end of the process, I would like to check that all locations are present in that merged file, and notify me if not.
I am having a problem finding a way to identify that a string specific to each location isn't present, to be used in an if statement, but it doesn't seem to be identifying the string correctly?
I have tried :
get-childitem -filter *daily.csv.ready \\x.x.x.x\data\* -recurse | where-object {$_ -notin 'D,KPI,KPI,1,'}
I know it's probably easier to do nothing if it is present, and perform the warning action if not, but I'm curious if this can be done in the reverse.
Thank you,
As Doug Maurer points out, your command does not search through the content of the files output by the Get-ChildItem command, because what that cmdlet emits are System.IO.FileInfo (or, potentially, System.IO.DirectoryInfo) instances containing metadata about the matching files (directories) rather than their content.
In other words: the automatic $_ variable in your Where-Object command refers to an object describing a file rather than its content.
However, you can pipe System.IO.FileInfo instances to the Select-String cmdlet, which indeed searches the input files' content:
Get-ChildItem -Filter *daily.csv.ready \\x.x.x.x\data\* -Recurse |
Where-Object { $_ | Select-String -Quiet -NotMatch 'D,KPI,KPI,1,' }

Find and replace a specific string within a specific file type located in wildcard path

Problem:
Update a specific string within numerous configuration files that are found within the subfolders of a partial path using PowerShell.
Expanded Details:
I have multiple configuration files that need a specific string to be updated; however, I do not know the name of these files and must begin my search from a partial path. I must scan each file for the specific string. Then I must replace the old string with the new string, but I must make sure it saves the file with its original name and in the same location it was found. I must also be able to display the results of the script (number of files affected and their names/path). Lastly, this must all be done in PowerShell.
So far I have come up with the following on my own:
$old = "string1"
$new = "string2"
$configs = Get-ChildItem -Path C:\*\foldername\*.config -Recurse
$configs | %{(Get-Content $_) -Replace $old, $new | Set-Content $_FullName
When I run this, something seems to happen.
If the files are open, they will tell me that they were modified by another program.
However, nothing seems to have changed.
I have attempted various modifications of the below code as well. To my dismay, it only seems to be opening and saving each file rather than actually making the change I want to happen.
$configFiles = GCI -Path C:\*\Somefolder\*.config -Recurse
foreach ($config in $configFiles) {
(GC $config.PSPath) | ForEach-Object {
$_ -Replace "oldString", "newString"
} | Set-Content $config.PSPath)
}
To further exasperate the issue, all of my attempts to perform a simple search against the specified string seems to be posing me issues as well.
Discussing with several others, and based on what have learned via SO... the following code SHOULD return results:
GCI -Path C:\*\Somefolder\*.config -Recurse |
Select-String -Pattern "string" |
Select Name
However, nothing seems to happen. I do not know if I am missing something or if the code itself is wrong...
Some questions I have researched and tried that are similar can be found at the below links:
UPDATE:
It is possible that I am being thwarted by special characters such as
+ and /. For example, my string might be: "s+r/ng"
I have applied the escape character that PowerShell says to use, but it seems this is not helping either.
Replacing a text at specified line number of a file using powershell
Find and replacing strings in multiple files
PowerShell Script to Find and Replace for all Files with a Specific Extension
Powershell to replace text in multiple files stored in many folders
I will continue my research and continue making modifications. I'll be sure to notate anything that get's me to my goal or even a step closer. Thank you all in advance.

How to get name of a USB device that is already mounted?

I'm actually writing a node script that detect if a specific USB is plugged, then it copy it content to Desktop. This is for Windows principally. To do this I manually check if 'E:\' path exists , 'F:\' , etc...
But I need to be sure that devices are the ones that I need. They got specific names, for example:
MTR12345 or MTR23RR5 or MTRTGX23.
And I need to know theses names. I searched for differents nodejs and powershell solutions but no ones fit my needs.
I need to get the name of the device that is mounted at E:\ . I'm totally new to PowerShell and NodeJS as well.
How can I do this ? Thanks for your help.
Sounds like you are just looking for the volume names. The WMI class Win32_logicaldisk would return that for mounted devices. Assuming it was populated of course. In it's simplest form:
Get-WmiObject Win32_logicaldisk | Where-Object{$_.VolumeName -eq "MyUSBKey"}
You have some specific examples and a regex query that you are trying to use to narrow down the results. So if you want to match a regex query:
Get-WmiObject Win32_logicaldisk |
Where-Object{Where-Object{$_.VolumeName -match "MTR[A-Za-z0-9]+"}} |
Select -Expand DeviceID
You could even simplify that if you wanted. Just match volumes that start with "MTR". Not as perfect as the other one but just as simple.
Get-WmiObject Win32_logicaldisk |
Where-Object{Where-Object{$_.VolumeName -match "^MTR"}} |
Select -Expand DeviceID

Windows Script to Find String in Log File

I have IBM Cognos TM1 application running as Services on Windows Server 2008. When I start the Service, TM1 will write a log file named "tm1server.log" on "D:\TM1\log\". TM1 will continously write this log until the service is ready, which normally takes 3 hours until the service is ready. When the service is ready, TM1 will write "TM1 Server is ready" on the log.
I want to make a script that continously check the log file until the string "TM1 Server is ready" is written. When the string found, I want the script to run another script that will send email to me. I have made the script for sending email.
Can anybody help me?
Thanks and regards,
Kris
--edit--
i use findstr command to search the string:
findstr /d:d:\TM1\log\ "TM1 Server is ready" "D:\TM1\log\tm1server.log" >> result.log
but the result.log contains all of the contents of tm1server.log.
On my server, 'TM1 server is ready' is written each time the server starts. So I have many 'TM1 server is ready's in one file.
You could test the last returned 'TM1 server is ready' to see when it happened to see if it happened in the last 5 (or whatever) hours with something like:
PS E:\TM1_Server_Logs> (Get-Date(select-string .\tm1server.log -pattern '(?<timestamp>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}).*TM1 server is ready' | select -expand Matches | foreach {$_.groups["timestamp"].value} | Get-Date -format "yyyy-MM-dd HH:mm:ss" | Select-Object -last 1)).AddHours(-5) -ge (Get-Date).AddHours(-5)
That's a long one-liner, but it should work. If it returns true you could decide what to to next.
You can also try
findstr /C:"your token to find" "C:\targetFile.log"

How can I filter Submitted list by multiple user in Perforce?

How can I filter the "Submitted" view by multiple users in perforce?
I want to just see only a few(4-5?) people in the "Submitted" view.
There is a filter function, but filter doesn't take multiple users.
So, can I specify multiple users in the "Submitted" view at perforce?
You are right, there doesn't seem to be a way to accomplish this in either p4v (the GUI) or p4 (CLI). Your best bet is to pass this as a feature request to the excellent perforce support.
I have created a power shell script that could be helpful.
It filters for a specific user, date and you can chose the last number of entries you want to search within (this accelerates the command return).
The result is shown in a power shell grid window which helps you to sort the result entries.
Please feel free to modify variables for your requirements:
$date1 = Get-Date -UFormat "%Y/%m/%d" #today
#$date1 = "2013/09/11" #other day
$users = "user1|user2|user3"
$title = "Submitted changes on: "+$date1+" and users: "+$users
$maxLines = 100
Write-host -foregroundcolor 'cyan' $title
$out = (p4 changes -t -s submitted -m 512 | select-string -Pattern $users | select-string -Pattern $date1)
$out | Select-Object LineNumber,Line,Matches | Out-GridView -Title $title -PassThru
Ihsan
Ok... Just my two cents:
I wanted to filter the submitted list to avoid changelists from other projects on the same P4 server. I tried to filter by user at first, but no luck, just like you.
But! I finally achieved what I wanted by filtering by file path. That way, only my project is visible. I find this quite usefull, as it will show any activity from someone I didn't expect on my project. It's event better than filtering by name. In ma specific case at least.
It doesn't answer the question directly, but it fix the problem I did face :)
Pipe the output to another filter such as grep. For example,
p4 changes -s submitted | egrep "^[^#]* (tom|dick|harry)#"
You may need to modify the regular expression to suit your output format. The ^[^#]* prevents false positives such as tom# in the summary.

Resources