Parse log for Phone number and BYE via powershell - parsing

I need to parse phone numbers from a log file (which is a .txt).
I need to find the phone number along with the timestamp and date and then the corresponding terminated request (which is when the caller hangs up) for that phone number. All calls into the system are iniated with DNAME and ended with TERMINATED.
I've used the select-string command but i cant filter the data effectively
the data is as follows :
13/08/2015 08:57:46:849 | L:4831.1[Line:10003<<XXXXXXXXXX]: Updated OutCID:'Conference_Call' and DNName: 'CALLER '
13/08/2015 09:00:42:118 | Leg L:4839.1[Line:10003<<XXXXXXXXXX] is terminated: Cause: BYE from 66.23.190.100:5060
all phone numbers have been replaced by XXXXXXXX for safety.
Does anyone know of a more powerful command to do this?
more data
13/08/2015 08:55:27:554 | Session 1230943 of leg L:4820.1[Line:10003<<180012334545] is confirmed
13/08/2015 08:55:49:766 | Answer to offerer immediateily, other party (L:4820.1[Line:10003<<180012334545]) doesn't support re-invite
13/08/2015 08:55:49:972 | L:4820.1[Line:10003<<18001234545]: Updated OutCID: 'Conference_Call' and DNName: 'Joe Brown '
13/08/2015 08:55:49:972 | L:4820.1[Line:10003<<180012334545]: Target refresh is not possible: Line:10003<<18001334545 doesn't support re-INVITE
13/08/2015 08:55:49:972 | [CM503010]: Call(C:4820): Making route(s) from Line:10003<<18001334545 to <sip:811#127.0.0.1:5060>
13/08/2015 08:55:49:972 | [Flow] Call(C:4820): has built target endpoint: Ivr:811 for call from L:4820.1[Line:10003<<191944345740]
13/08/2015 08:55:49:972 | [CM503004]: Call(C:4820): Route 1: from L:4820.1[Line:10003<<18001233545] to T:Ivr:811#[Dev:sip:811#127.0.0.1:40600;rinstance=19fdaa2fa620113c]
13/08/2015 08:55:49:972 | [CM503027]: Call(C:4820): From: Line:10003<<18001334545 ("Glen Peaks " <sip:180012334545#98.100.70.194:5060>) to T:Ivr:811#[Dev:sip:811#127.0.0.1:40600;rinstance=19fdaa2fa620113c]
13/08/2015 08:55:49:972 | [Flow] Call(C:4820): making call from L:4820.1[Line:10003<<18001233545] to T:Ivr:811#[Dev:sip:811#127.0.0.1:40600;rinstance=19fdaa2fa620113c]
13/08/2015 08:55:50:027 | [CM503025]: Call(C:4820): Calling T:Ivr:811#[Dev:sip:811#127.0.0.1:40600;rinstance=19fdaa2fa620113c] for L:4820.1[Line:10003<<180012334545]
13/08/2015 08:55:50:181 | L:4820.3[Ivr:811] has joined to L:4820.1[Line:10003<<18001234545]
13/08/2015 08:55:50:181 | L:4820.1[Line:10003<<19914345740]: Terminating targets, reason: SIP ;cause=200 ;text="Call completed elsewhere"

Your question is not clear enough, though regarding the TimeStamp and Phone number you can use this:
$Array = #()
$text = cat C:\Test.txt
$TimeStamp = "\d{2}\D\d{2}\D\d{4}\s\d{2}\D\d{2}\D\d{2}\D\d{3}"
$Number = "\d{10}"
foreach ($Line in $text)
{
$Result = "" | Select TimeStamp,Number
$Result.TimeStamp = $Line | select-string -Pattern $TimeStamp -AllMatches | % { $_.Matches } | % { $_.Value }
$result.Number = $Line | select-string -Pattern $Number -AllMatches | % { $_.Matches } | % { $_.Value }
$Array += $Result
}
Please provide more info for the CALLER,Terminated etc. so i can help you find the correct Regex

Related

Is it possible to have F# able to recognize an overlap of DU and use the right one itself?

type GenericResult =
| Ok
| Error of string
type LoginResult =
| Ok
| UserNotFound
| WrongPassword
let check something:GenericResult =
match something with
//| true -> Ok // error:This expression was expected to be of type "GenericREsult" but here has type "LoginResult"
| true -> GenericResult.Ok // I'm forced to specify GenericResult.Ok
| false -> Error "aargg!"
let checkLogin something:LoginResult =
match something with
| true -> Ok // here I don't need to specify the DU because this is defined after
| _ -> WrongPassword
I'd like to use just "Ok" in both the methods, without the need to specify the DU.
I see that in case of clashing of the value the last one is the "predefined".
Ideally I'd like to have a sort of inheritance
to reuse part of a DU in another DU.
For example:
type GenericResult =
| Ok
| Error of string
type LoginResult =
//| GenericResult.Ok
| UserNotFound
| WrongPassword
type SaveResult =
| Created
| Updated
//| GenericResult.Error
let checkLogin something: LoginResult | GenericResult.Ok =
match something with
| true -> Ok
| _ -> WrongPassword
[EDIT]
The real scenario where I feel the need for this feature is this with 3 different results from 3 different logic classes.
There will be in the future more cases so the multiplication of duplicated DU values will increase.
// DUs ordered from the most specific to the most generic
type BalanceUpdateResult =
| Created
| Updated
| InvalidRequest of string
type DeleteResult =
| Ok
| InvalidRequest of string
type Result<'T> =
| Ok of 'T
| NotValid of string
| Error of string
The goal is to have a clean match syntax in the consumer, where the value of the DU will evenctually be used to raise an exception or to return the created value, for example.
// balance update function (result is BalanceUpdateResult):
match result with
| Created -> this.createOkWithStatus 201
| Updated -> this.createOkWithStatus 200
| InvalidRequest error -> this.createErrorForConflict error
// company creation function (result is Result<Company>):
match result with
| Result.Ok newItem ->
context.Logger.Log $"Company created. New Id:{newItem.Id}, Name:{newItem.Name}."
this.createCreated newItem
| NotValid error -> base.createErrorForConflict error
| Error error -> base.createError error
Here, for example, InvalidRequest is not accepted in the second case because it belongs to the wrong DU.
Having to specify the DU everywhere results in a mess like the following example (see the many Result<_>.):
interface ICompanyLogic with
member this.Create(company:Company):Result<Company> =
match normalize company |> validate with
| NotValid msg -> Result<_>.NotValid msg
| Valid validCompany ->
match companyRepository.Exists(validCompany.Name) with
| true -> Result<_>.NotValid($"A company with name \"{validCompany.Name}\" already exists.")
| _ ->
let newCompany = assignNewId validCompany
companyRepository.Create(newCompany)
Result<_>.Ok(newCompany)
member this.Update (company:Company):Result<Company> =
let checkNameExists company =
match companyRepository.GetByName company.Name with
| Some c when c.Id <> company.Id -> NotValid $"A company with name \"{company.Name}\" already exists."
| _ -> Valid company
match normalize company |> validate with
| NotValid msg -> Result<_>.NotValid msg
| Valid c -> match checkNameExists c with
| Valid c -> companyRepository.Update c; Result<_>.Ok c
| NotValid msg -> Result<_>.NotValid msg
I think the best way to achieve what you are trying to do would be to start with a generic Result type that has a type parameter representing the error type:
type Result<'TError> =
| Ok
| Error of 'TError
This allows you to use different types for representing errors, including string, but also another DU to capture more specific error types. You can then define GenericResult and LoginResult as two type aliases:
type LoginError =
| UserNotFound
| WrongPassword
type GenericResult = Result<string>
type LoginResult = Result<LoginError>
To report a login error, you would now use Error WrongPassword to wrap the specific error in the generic Error constructor. The implementation of your two functions looks as follows:
let check something:GenericResult =
match something with
| true -> Ok
| false -> Error "aargg!"
let checkLogin something:LoginResult =
match something with
| true -> Ok
| _ -> Error WrongPassword
Unlike TypeScript union type, F# DU are meant to be composed and not extensible - see Thomas answer for a solution using this approach.
Since F# does not offer a direct solution, you may consider renaming cases like InvalidRequest in order to be more specific and to help differentiate them when reading the code. With these specific names, you can also merge all result types into a big Event DU like what's usually done in an event sourced system:
type Event =
// BalanceUpdateResult
| BalanceCreated
| BalanceUpdated
| BalanceUpdateError of string
// DeleteResult
| DeleteOk
| DeleteError of string
// ...
Ok, as explained by Romain multiple DUs cannot solve my problem.
I decided to use the built-in type Result<'T,'TError>.
It allows me to avoid create many DUs that inevitably will have clash of names, forcing the use the full DU prefix in the code.
I solved the problem that drove me to create custom DUs with the inspiring example from Thomas reply.
(with Result<,>) I have the possibility to have dinstinct Errors or Oks.
(note the Result<unit,_> and the Result<BalanceUpdateRequest,_>)
type ICompanyLogic =
abstract member Create:Company -> Result<Company, string> // CreateResult
abstract member Update:Company -> Result<Company, string> // UpdateResult
abstract member Delete:string -> Result<unit,string> // DeleteResult
type BalanceUpdateResult =
| Created
| Updated
type IBalanceLogic =
abstract member CreateOrUpdate: request:BalanceUpdateRequest -> Result<BalanceUpdateResult, string>
Apart BalanceUpdateResult all the other DUs where replaced buy the Result<'T,'TError>.
I just maintained a couple one for specific tasks:
type CompanyValidation = Valid of Company | NotValid of string
type ValidateResult = Valid | NotValid of string
In the end with this solution:
I don't need to define many DUs
I can customize the Result... within as many values I want (storing a sub-DU in the Ok or Error union case)
I don't need to use prefix or use synonims to avoid clash (code result much cleaner)

value is a function while a set was expected while evaluating 'outputs'

I'm getting the above error when attempting to check a flake; I'm trying to use flake-compat on a non-NixOS system for compatibility with home-manager.
This is the flake that's causing the trace below:
error: value is a function while a set was expected
at /nix/store/l22dazwy8cgxdvndhq45br310nap92x3-source/etc/nixos/flake.nix:167:136:
166|
167| outputs = inputs#{ self, nix, nixpkgs, flake-utils, flake-compat, ... }: with builtins; with nixpkgs.lib; with flake-utils.lib; let
|
^
168|
… while evaluating 'outputs'
at /nix/store/l22dazwy8cgxdvndhq45br310nap92x3-source/etc/nixos/flake.nix:167:15:
166|
167| outputs = inputs#{ self, nix, nixpkgs, flake-utils, flake-compat, ... }: with builtins; with nixpkgs.lib; with flake-utils.lib; let
| ^
168|
… from call site
at «string»:45:21:
44|
45| outputs = flake.outputs (inputs // { self = result; });
| ^
46|
… while evaluating anonymous lambda
at «string»:10:13:
9| builtins.mapAttrs
10| (key: node:
| ^
11| let
… from call site
… while evaluating the attribute 'root'
… while evaluating anonymous lambda
at «string»:2:23:
1|
2| lockFileStr: rootSrc: rootSubdir:
| ^
3|
… from call site
Unfortunately, I cannot provide a minimal reproducible example as I do not know from where in the flake this error is originating.
Turns out, my lib value was actually a function; unfortunately, since nix flakes is still unstable, it didn't quite show where this was happening.

Using KQL 'let' to combine two queries in the same table

I am trying to learn KQL and had a query where I wanted to take 2 values from Windows Event codes 4624 (login) and 4634 (logout) and return them for different scenarios I'm still trying to build.
But primarily I would just like to be able to return the values in a table (print or project?)
let login = SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == '4624'
| project loginTime = TimeGenerated;
let logout = SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == '4634'
| project logoutTime = TimeGenerated;
print login
The error I am getting is "'project' operator: Failed to resolve scalar expression named 'login'"
What I would have hoped to see is:
loginTime | logoutTime
----------------------------------------------
01/02/2021 18:46:30 | 01/02/2021 18:45:45
01/02/2021 18:47:30 | 01/02/2021 18:47:45
01/02/2021 18:48:30 | 01/02/2021 18:48:45
Would a join be better? It is in the same table (SecurityEvent), so I thought it would be possible to do it this way?
The dataset is from the MS provided Azure portal: https://portal.azure.com/#blade/Microsoft_Azure_Monitoring_Logs/DemoLogsBlade
Thanks for the help!
The problem is that "login" is a table type but print is expecting a scalar type.
let login = SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == '4624'
| project loginTime = TimeGenerated;
let logout = SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == '4634'
| project logoutTime = TimeGenerated;
print toscalar (login)
As to the result you are trying to get, I think this might be what you need:
Updated to improve clarity/perf
let login = SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == '4624'
| project TargetLogonId, loginTime = TimeGenerated;
let logout = SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == '4634'
| project TargetLogonId, logoutTime = TimeGenerated;
login
| join kind=leftouter logout on TargetLogonId
| project loginTime, logoutTime
I added some changes that encompass #GenericUser and #Slavik-N suggested and brings out the information that I was looking to calculate:
let login = SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == '4624'
| where AccountType == 'User'
| project Computer,Account ,TargetLogonId, loginTime = TimeGenerated;
let logout = SecurityEvent
| where TimeGenerated > ago(1h)
| where EventID == '4634'
| where AccountType == 'User'
| project Computer,Account,TargetLogonId, logoutTime = TimeGenerated;
login
| join kind=inner logout on TargetLogonId
| project Computer,Account,loginTime, logoutTime, minute = datetime_diff('minute',logoutTime,loginTime)
| where minute >0
| sort by minute desc

.ToString returns System.Object[] in Error

With PowerShell 2.0 if I run the following on a Windows 7 machine:
(Get-WmiObject Win32_NetworkAdapterConfiguration |
Where { $_.IPAddress }
it returns
192.168.83.26
fe80::<IPv6 address>
If I run:
(Get-WmiObject Win32_NetworkAdapterConfiguration |
Where { $_.IPAddress }.ToString()
It returns
System.Object[]
Why? And how can I resolve it?
FYI, I'm actually trying to use .ToString().split('.')[0..2] -join '.' but I'm pretty sure it's the .ToString that's causing the issue
function Get-IPAddress{
(Get-WmiObject Win32_NetworkAdapterConfiguration |
Where { $_.IPAddress } |
Select -Expand IPAddress).split('.')[0..2] -join '.'
}
Get-IPAddress
returns 192.168.10 on PoSh 3. This doesn't seem to work on PoSh 2, and returns the `System.Object[]' that I stated above. The error complains about not having a Method named trim. Others have suggested declaring it as a String, but I've been unable to make it work
Try this:
(Get-WmiObject Win32_NetworkAdapterConfiguration |
? { $_.IPAddress } ).ipaddress | % { ($_ -split '\.')[0..2]}
This:
(Get-WmiObject Win32_NetworkAdapterConfiguration | ? { $_.IPAddress } ).ipaddress
returns always an array of strings also in the case of a single ip address.
The reason it doesnt work is IPAddress property is part of a PropertySet, the console output makes it look like a string but it is not
Not entirely sure what you require for your end result but you can try
(Get-WmiObject Win32_NetworkAdapterConfiguration | %{ $_.IPAddress }) -join " "
As Christian mentioned, the $_.IPAddress property is an array of strings.
Get-WmiObject Win32_NetworkAdapterConfiguration | % {
if($_.IPAddress){
$_.IPAddress[0]
}
}
Using your string manipulation:
$ip = Get-WmiObject Win32_NetworkAdapterConfiguration | % { if($_.IPAddress){$_.IPAddress[0] }}
$ip.ToString().split('.')[0..2] -join '.'
10.15.0
As a one-liner:
(Get-WmiObject Win32_NetworkAdapterConfiguration | % { if($_.IPAddress){$_.IPAddress[0] }}).ToString().split('.')[0..2] -join '.'
toString is causing the problem.
you need to pipe "out-string"
the tostring() gives you the class type to string as defined

How to get a null value when using the head function with an empty list

I have a cypher query like this.
START dep=node:cities(city_code = "JGS"),
arr=node:cities(city_code = "XMN")
MATCH dep-[way:BRANCH2BRANCH_AIRWAY*0..1]->()-->arr
RETURN length(way), transfer.city_code,
extract(w in way: w.min_consume_time) AS consumeTime
The relationship named "way" is a optional one, so the property named "consumeTime" will be a empty list when the relationship "way" not exsit.
The query result is:
| 0 | "JGS" | [] |
| 1 | "SZX" | [3600] |
When I want to use the head function with the property "consumeTime", it return a error "Invalid query: head of empty list".
How can I get a result like this?
| 0 | "JGS" | null |
| 1 | "SZX" | 3600 |
This would be trivial with conditional expressions, which is something I think is important to add to Cypher: https://github.com/neo4j/community/issues/899
Here's a somewhat hacky query using reduce for you that requires 1.9-SNAPSHOT:
START dep=node:cities(city_code = "JGS"),
arr=node:cities(city_code = "XMN")
MATCH dep-[way:BRANCH2BRANCH_AIRWAY*0..1]->()-->arr
WITH length(way) as wayLength,
transfer.city_code as transferCityCode,
extract(w in way: w.min_consume_time) AS consumeTime
WITH wayLength,
transferCityCode,
consumeTime,
// reverse the consumeTime list, so that we can get the head from the end
reduce(acc=[], x in consumeTime: x + acc) reverseConsumeTime
RETURN wayLength,
transferCityCode,
consumeTime,
// return null if empty, else the end of the list
reduce(acc=null, x in reverseConsumeTime: x) as headOrNull;
This query could be improved a fair amount with the following syntax to reverse a collection:
reverse(coll) or conditional expressions to check for an empty list.

Resources