Regular Expression - powershell

I need to extract few values from below string with Powershell Regex.
Request ID = 1234 { andquot;EMOandquot;: andquot;123456-Uandquot;, andquot;Terminated Accountandquot;: andquot;Test Userandquot;, andquot;Descriptionandquot;: andquot;andquot;, andquot;Last Dayandquot;: andquot;2019-06-26andquot;, andquot;Terminated User Mailandquot;: andquot;Test.User#gmail.comandquot; } Location : UK ,London
I Need to get Test.User#gmail.com, Test User and 2019-06-26. Please help me to get powershell regex for getting these values from above string.
Thank you.
I Tried below -
$description = "Request ID = 1234 { andquot;EMOandquot;: andquot;123456-Uandquot;, andquot;Terminated Accountandquot;: andquot;Test Userandquot;, andquot;Descriptionandquot;: andquot;andquot;, andquot;Last Dayandquot;: andquot;2019-06-26andquot;, andquot;Terminated User Mailandquot;: andquot;Test.User#gmail.comandquot; } Location : UK ,London"
$formatdesc = $description -replace ' ?(and)?quot;','"'
$formatdesc
Request ID = 1234 {"EMO":"123456-U","Terminated Account":"Test User","Description":"","Last Day":"2019-06-26","Terminated User Mail":"Test.User#gmail.com" } Location : UK ,London
With above how would I have extract Terminated User Mail, Terminated Account and Last Day the values are not static they are dynamic. Please help.

Break down the pattern logically you are looking to find first. It looks like you are looking for: Test.User#gmail.com Test User - use a simple -match e.g. $Myvariablename = [Your string] -match 'Test.User#gmail.com'
2019-06-26: For a date like this, break it down to its parts so that's 4 digits, a hyphen, 2 digits, a hyphen and then 2 digits so that (quickly and therefore not perfect without testing) comes out to a -match like $Myvariablename = [Your string] -match '^\d{4}-\d{2}-\d{2}'

Related

Split a string based on "|" character in PowerShell

I have a string variable in PowerShell which contains the value:
NFP|8dc3b47a-48eb-4696-abe2-48729beb63c8
I am attempting to get the beginning portion of that string into it's own variable by identifying the index of the "|" character and using a substring function to extract the first portion of the string, in this case "NFP". I am not sure how to escape the "|" so I can use it properly. It doesn't seem to recognize it at all. My latest attempt is as follows:
$PolicyManual = $Item["PolicyManual"]
write-host $PolicyManual #Displays NFP|8dc3b47a-48eb-4696-abe2-48729beb63c8
if ($PolicyManual.Contains([regex]::escape("|"))) {
$PolcyManual = $PolicyManual.Substring(0, $PolicyManual.IndexOf([regex]::escape("|")))
}
I'm sure this is simple, but I can't figure out how to make it work. Can anyone offer assistance to a PowerShell novice?
Thanks.
The problem is that .contains method doesn't know about regex and you are never entering the if condition because of this. When you do [regex]::escape("|"), the method is looking for a literal \|.
Try this instead:
$PolicyManual = "NFP|8dc3b47a-48eb-4696-abe2-48729beb63c8"
if ($PolicyManual.Contains('|')) {
$element0, $element1 = $PolicyManual.Split('|')
$element0 #=> NFP
$element1 #=> 8dc3b47a-48eb-4696-abe2-48729beb63c8
}

PowerShell Switch not working with hyphenation

I'm creating a series of new PSObjects, from a CSV import, and then adding them to $new. I'm using a switch to try and set the value for the "Notes" property, as the object is being created\added, and I've run into something 'hinky'.
When I run this...
$import = Import-Csv c:\somerandom.csv
$new = #()
foreach ($Item in $Import) {
$obj = New-Object PsObject -Property #{
Name = $item.Name
Description = $Item.Description
Quantity = $Item.Quantity
Vendor = $Item.Vendor
SubCategory = "Misc"
Notes = ""
}
switch ($obj.Name) {
"iPod" { $obj.Notes = "Burn with the rest of the Apple garbage"}
"nVidia GTX 780ti" { $obj.Notes = "Steal immediately!" }
default { $obj.Notes= "Sorry man... I have no idea what that is"}
}
$new += $obj
}
... it works as expected. All of the entries from $import, are recreated in $new, with the addition of my "SubCategory" and "Notes" noteproperties (iPod gets burn tag, 780ti slated to be stolen). But when I run with the following as the switch...
switch ($obj.Name) {
'SOFM090-107-01-PF-R' { $obj.Notes = "Burn with the rest of the Apple garbage"}
'M094-107-01-PF-R' { $obj.Notes = "Steal immediately!" }
default { $obj.Notes = "Sorry man... I have no idea what that is"}
}
... It sets all the entries to the 'default' setting on the switch. I tried running the switch with a non-hyphenated name for one entry, and a hyphenated entry for the other, and only the hyphenated version was set properly.
The above code is altered from the actual code, but it properly illustrates what I'm trying to do. I need to add a noteproperty that is based off a list of part numbers, and will fill in the "Notes" entry with a tag of my choosing.
I've tried it with single quotes, double quotes, using the -wildcard and replacing the switch hyphens with *'s, and putting the ` character in before the -'s. Nothing seems to be working.
There's nothing wrong with the code, so the problem must lie in the data. I verified that it works fine with a CSV file that has those exact hyphenated values in the "Name" column.
If the switch doesn't work with the hyphenated names, then the values being imported into the Name property don't match what you have in the switch statement. It's a good idea to always post the data you're working with, or a sample of it, because often that's the source of the problem. Even when it isn't, it helps other people understand what you're trying to accomplish and what your code does. Since we don't have the data, I can suggest a few likely possibilities:
You're manually typing the names into the switch statement, and they look like what's in the CSV, but don't actually match, e.g. you're confusing O with 0 because they look the same in the font you're working with. I'd have suspected something like an en-dash instead of a hyphen, but you say you tried replacing the hyphens with wildcards
You have trailing spaces
You're single-quoting the hyphenated names in the CSV file (Import-Csv only understands double quotes; single quotes would be included in the value).
Here are a couple of things you can try to help identify why the data doesn't match (separately, not both together):
Replace switch ($obj.Name) { with switch -regex ($obj.Name) {
Use the following code to show you exactly what PowerShell is seeing in the Name property for each item and which switch conditions are being executed:
Write-Host -NoNewline "[$($obj.Name)] "
switch ($obj.Name) {
'SOFM090-107-01-PF-R' {Write-Host 'burn'; $obj.Notes = "Burn with the rest of the Apple garbage"}
'M094-107-01-PF-R' {Write-Host 'steal'; $obj.Notes = "Steal immediately!"}
default {Write-Host 'sorry'; $obj.Notes = "Sorry man... I have no idea what that is"}
}
If you post the data, we'll probably be able to tell you exactly why it's not working. But I can pretty much guarantee you that if you're using that code, the problem is that the imported Name values that aren't being matched with the right Notes values are in some way not the same as what you have in the switch conditions.

Finding bad words from large list of email addressess using PHP -Mongodb

I have large list of email addressses from a file. It comes around 1 million email ids. I have list of bad words like spam,junk etc, it consist of 20,000+ bad words.
I need to validate email ids. If bad words is present any where in email id it will be marked as invalid.
For example;
testspam#gmail.com - invalid
newuser#desspam.com - invalid
I would like to know which will be fastest comparison method as array looping will take time.
I tried following methods
//$keyword_list- array of bad words;
//$check_key- the email id which need to validate
$arrays = array_chunk($keyword_list, 2000);
for($i=0;$i<count($arrays);$i++)
{
if (preg_match('/'.implode('|', $arrays[$i]).'/', $check_key, $matches)){
return 1;
}
}
The above method is taking more time when comparing 1 million data.
Next we tried with the following code and this also takes more time
//$contain = bad words separated by '|'
// $str - the email id which need to validate
if(stripos($contain,"|") !== false)
{
$s = preg_split('/[|]+/i',$contain);
$len = sizeof($s);
for($i=0;$i < $len;$i++)
{
if(stripos($str,$s[$i]) !== false)
{
return(true);
}
}
}
if(stripos($str,$contain) !== false)
{
return(true);
}
return(false);
Finally I had tried Mongodb Text Search. It works fast with the following issues
If 'Hell' is the word in my bad list and my email id is like
head#e-hellinglysussex.sch.uk, then the Mongodb Text Search wont matches it.
Here is the code I used;
$ret = $db->command( array("text" =>$section, "search" => $keyword_string, "limit"=>$cnt_finalnonmatch));
where $section = Collection name,
$keyword_string = Comparing keywords string separated by space, for eg "Hell Spam Junk" etc,
$cnt_finalnonmatch = total number of comparing email ids
Please help me to solve this issue.
I am not entirely sure, but I suspect that the problem is that 'Hell' is not equal to 'hell' when you search for text since mongodb is case sensitive.
The solution should be to force all the strings and word to be lowercase (or uppercase)
We have used Mongodb 'like' to solve this issue;
$keywords = $key['keyword']; // Keywords need to compare
$regexObj = new MongoRegex("/".$keywords."/i"); // MongoRegex function declration
$where = array($section => $regexObj); // $section is the collection name
$resultset = $info->find($where);

Need a powershell script to use a parameter to manipulate/read in fields from another csv file

I have and existing PowerShell script (not written by me!) which is designed to use a passed-in parameter (SCOM Alert ID) to then set additional information in the alert, e.g. $alert.CustomField1 = $alert.PrincipleName etc etc.
I am looking to add functionality to this script to be able to add additional 'custom' information which is stored in a separate text/CSV file. The text/CSV file has header line
ServerName,ServiceOwner,Application Tier
so a row in the file would be
MYSERVER.CONTOSO.COM,Joe Bloggs, Tier 1
There will be one unique row for each server in our environment (over 600 rows).
So what I need to do is using the passed-in alert ID. I can use $alert.PrincipleName to find the corresponding row in the text file and pull in the additional details stored in field 2 and 3, i.e. ServiceOwner and ApplicationTier.
This logic holds for the majority of alerts but IF server name is a specific value (e.g. MYSTSERVER.CONTOSO.COM) then instead of using $alert.PrincipleName to match servername in text file, I need to match on another alert property $alert.MonitoringObjectDisplayName. However, the server name in this field is part of a larger string in the format, e.g. User Services Watcher for Pool [MYTARGETSERVER.CONTOSO.COM] - so I need to extract the severname from between the square brackets of the string to then perform the match with the text file.
Hopefully I have explained what I'm trying to do clearly - if not I'm happy to provide further clarification and can also post up the existing PS Script I'm trying to modify if thats any help.
You can react to the server name like this:
$csv = Import-Csv 'C:\path\to\your.csv'
...
if ( $alert.PrincipalName -eq 'MYSTSERVER.CONTOSO.COM' ) {
if ( $alert.MonitoringObjectDisplayName -match '.*\[(.*?)\]' ) {
$targetserver = $matches[1]
}
} else {
$targetserver = $alert.PrincipalName
}
$newdata = $csv | ? { $_.ServerName -eq $targetserver } `
| select ServiceOwner, 'Application Tier'
...
$alert.CustomField2 = $newdata.ServiceOwner
$alert.CustomField3 = $newdata.'Application Tier'
...

Powershell - $var.ToString(x,y) issue

for a user creation scrip in powershell i'm using textbox object to fill the information of the new user (family name, first name)
I return a value like that:
$TextlabelUsername.text = $Textbox1.text.ToString().Substring(0,5)
Which apply on a button click.
But using that methode if one of my string value is less then 5 caracters the script return an error that the string is not enough long.
Is there a way to select 5 or less caracters or an other method to process ?
Try this:
$str = $Textbox1.text.ToString()
$TextlabelUsername.text = $str.Substring(0, [math]::Min(5, $str.Length))
There is nothing wrong with Ansgar Wiecher's method. Here is an alternative though:
$TextLabelUserName.Text = $Textbox1.Text.ToString() -replace '(.{0,5}).*', '$1'