powershell get specific row from a body - powershell

i'm getting some problem to get a specific row from a powershell body. HR team send email to us, a logic app get the body of email and pass it to a script that disable the user.
The body is like this:
Hi,
the following user have to be dismiss:
#mail: user1#mycompany.com
#mail: user2#mycompany.com
#mail: user2#mycompany.com
Bye
hr team
hrteam#mycompany.com
i would like to get only the specific row:
#mail: user1#mycompany.com
#mail: user2#mycompany.com
#mail: user2#mycompany.com
to do this i did a trick with following code:
$Body
$SplitBody = $Body.split("").split(" ").Split("#")
$objetbody = $SplitBody.Replace(" ","").Trim()
and i got following result:
Hi,
the
following
user
have
to
be
dismiss:
mail:
user1#mycompany.com
mail:
user2#mycompany.com
mail:
user2#mycompany.com
Bye
hr
team
hrteam#mycompany.com
after that i pass $objetbody into a foreach and loop all row(at the end of this foreach is put a break becouse it can disable HR mail). The flow work if HR sent only 1 mail to disable.
My question is there is a way to got that specific row that contains the mails?
Thanks

Here is a one-liner to output all email addresses using the .NET RegEx class:
[RegEx]::Matches( $body, '(?<=#mail:\s*)\S+' ).Value
The same can be achieved using Select-String:
($body | Select-String '(?<=#mail:\s*)\S+' -AllMatches).Matches.Value
RegEx breakdown:
(?<= ... starts a positive look behind pattern, meaning that the sub string we search for must be preceded by the given pattern, but this pattern won't be included in the result
#mail:\s* ... literal "#mail:" followed by optional whitespace
) ... ends the look behind pattern
\S+ ... any sequence of non-whitespace characters -> the email address
I kept the email address pattern simple, because correctly matching email addresses using RegEx can be hard. Anyway you propably want to do validation as a separate step so you can report invalid addresses. This can be done much simpler using the .NET MailAddress class:
$mailAddresses = [RegEx]::Matches( $body, '(?<=#mail:\s*)\S+' ).Value
foreach( $adr in $mailAddresses) {
try {
[System.Net.Mail.MailAddress]::new( $adr )
} catch {
# The MailAddress constructor throws FormatException for invalid address
Write-Error "Invalid mail address: '$adr'"
}
}

You could use a loop in addition to the -match operator and the use of the automatic variable $Matches:
foreach($line in $Body)
{
if($line -match '^#mail: (.*#.*\.[\w\d]+)')
{
$Matches[1]
}
}
From the example above, $Matches[1] would return the values for the matched capturing group:
user1#mycompany.com
user2#mycompany.com
user2#mycompany.com
If you want to keep #mail: use $Matches[0] instead.

Related

PHPmailer: Exclude input field from foreach loop

I am happily running a contact form using https://github.com/PHPMailer/PHPMailer and recently added https://friendlycaptcha.com to minimize the amount of spam sent by bots through that form. I love the sleek implementation with no user interaction. The captcha is activated once you click the first input field in the form and auto-solves.
Unfortunately the captcha's solution (hidden input field) adds an enormous string to the e-mail that I would like to exclude.
How do I tell the foreach loop not to include the frc-captcha-solution in the mail that's composed?
private function compose_mail($post)
{
$content = "The following message has been received via contact form:\n\n";
foreach($post as $name=>$value)
{
$content .= ucwords($name).": \t";
$content .= "$value\n\n";
}
$this->mailer->Body = $content;
}
This is the input field in the form that is generated and yields the long string.
<input name="frc-captcha-solution" class="frc-captcha-solution" type="hidden" value=".UNSTARTED">
An example of what I get is:
name: Joe
e-mail: joe#miller.com
address: 100 street
ZIP: 10100
place: City
phone: 0123456789
msg: This is a test message
Frc-captcha-solution: f5e6874becd6758f456b78f6f1726e1d.YadsJVSp+/j0pyBNAQwtjQAAAAAAAAAA+eFoDacaj3c=.AAAAAJZoAQABAAAAQ5YAAAIAAADCJAUAAwAAAF9IAQAEAAAAj5cEAAUAAACwkQMABgAAAFcaAAAHAAAAfvIEAAgAAADvUwIACQAAAK/MAQAKAAAAm+MBAAsAAACU6AAADAAAAJZUAAANAAAA/dAEAA4AAABrSwEADwAAAC7mAAAQAAAAXFoDABEAAAD4UAEAEgAAACMEAAATAAAA3xcCABQAAABBHwMAFQAAAE6LAQAWAAAA1mwAABcAAAAmwwAAGAAAACIZBwAZAAAA6p4AABoAAADovwIAGwAAAFE/AAAcAAAA+d8BAB0AAACQ8gAAHgAAAO1fAgAfAAAAbtwCACAAAAA7EgEAIQAAABmWAQAiAAAA/ysAACMAAAAx0wIAJAAAAJsyBAAlAAAA6acBACYAAACATwAAJwAAAM/wBQAoAAAATLYJACkAAABT1AIAKgAAAMWWAwArAAAAzIAGACwAAAA3fwAA.AgAA
There are many ways to do that, but one is to skip that name when it appears in your loop:
private function compose_mail($post)
{
$content = "The following message has been received via contact form:\n\n";
foreach($post as $name => $value) {
if ($name !== 'frc-captcha-solution') {
$content .= ucwords($name).": \t";
$content .= "$value\n\n";
}
}
$this->mailer->Body = $content;
}

How to insert PowerShell variables into a string block

Quick question, i'm trying to insert a variable into a string json body block like below, but when i perform a rest api call by passing the json body into the invoke-webrequest function, the variable is actually not getting inserted. In the alert software i'm using i just see the message as 'The following host $($scrapperHost) is not running!!'
#variable
$myHost = $Env:Computername
#variable prints the correct hostname
#string json body
$jsonBody = #'
{
"message": "The following host $($myHost) is not running!!"}
}
There are several ways you can insert variables into strings / Here Strings.
For your specific example, instead of using #' '# you can use #" "#, and you can insert the variable without the $ at the beginning:
#variable
$myHost = $Env:Computername
#variable prints the correct hostname
#string json body
$jsonBody = #"
{
"message": "The following host ${myHost} is not running!!"}
}
"#
This would also work fine, always using #" "#:
"message": "The following host $myHost is not running!!"
Or:
# This is very useful when you want to insert a property of your variable
"message": "The following host $($myHost) is not running!!"`
Another example:
$jsonBody = #'
{{
"message": "The following host {0} is not running!!"
}}
'# -f $myHost
Notice I'm using double {{ }} because you need to escape, basically you're telling Powershell you want a literal curly brace instead of using the curly brace as a special character.
There are a lot more examples you can use to insert variables into strings, check out this post by Kevin Marquette: https://powershellexplained.com/2017-01-13-powershell-variable-substitution-in-strings/

Null valued expression

foreach ($OldAccount in $forwarderarray) {
$OldAccount.ForwardingAddress = $OldAccount.ForwardingAddress.substring(0,1).toupper()+$OldAccount.ForwardingAddress.substring(1).tolower()
$Separatorforwarderaddress = $OldAccount.UserPrincipalName.IndexOf("#") # This section truncates the SMTP address to the firstname.surname to remove the #
$LeftPartforwarderaddress = $OldAccount.UserPrincipalName.Substring(0, $Separatorforwarderaddress)
$RightPartforwarderaddress = $OldAccount.UserPrincipalName.Substring($Separatorforwarderaddress + 2)
$SeparatorOwnerAddress = $OldAccount.ForwardingAddress.IndexOf(".") # This section truncates the SMTP address to the firstname.surname to remove the #
$LeftPartOwnerAddress = $OldAccount.ForwardingAddress.Substring(0, $SeparatorOwnerAddress)$RightPartOwnerAddress =
$OldAccount.ForwardingAddress.Substring($SeparatorOwnerAddress + 2)
What is strange is the write host displays the value expected
But when I try to SMTP
Send-MailMessage -to $OldAccount.ForwardingAddress
I ge:
You cannot call a method on a null-valued expression
Can someone please help? What I am trying to achieve is to take out the email address for display purposes and to make the name start with a capital letter.
So why does this display the correct information
Write-Host "Sending message, to:"$OldAccount.ForwardingAddress

ReCaptcha Implementation in Perl

To implement recaptcha in my website.
One option is google API . But for that i need to signup with domain name to get API key.
Is there any other way we can do it ?
You don't necessarily need a domain name to sign up, per se.
They have a concept of a "global key" where one single domain key would be used on several domains. When signing up, select the "Enable this key on all domains (global key)" option, and use a unique identifier (domainkey.abhilasha.com) and this will be fine, you can use the key from any domain in the end.
One way: add this code to your perl file that is called by an html form:
Simplified of course
my #field_names=qw(name branch email g-recaptcha-response);
foreach $field_name (#field_names)
{
if (defined param("$field_name"))
{
$FIELD{$field_name} = param("$field_name");
}
}
$captcha=$FIELD{'g-recaptcha-response'};
use LWP::Simple;
$secretKey = "put your key here";
$ip = remote_host;
#Remove # rem to test submitted variables are present
#print "secret= $secretKey";
#print " and response= $captcha";
#print " and remoteip= $ip";
$URL = "https://www.google.com/recaptcha/api/siteverify?secret=".$secretKey."&response=".$captcha."&remoteip=".$ip;
$contents = get $URL or die;
# contents variable takes the form of: "success": true, "challenge_ts": "2016-11-21T16:02:41Z", "hostname": "www.mydomain.org.uk"
use Data::Dumper qw(Dumper);
# Split contents variable by comma:
my ($success, $challenge_time, $hostname) = split /,/, $contents;
# Split success variable by colon:
my ($success_title, $success_value) = split /:/, $success;
#strip whitespace:
$success_value =~ s/^\s+//;
if ($success_value eq "true")
{
print "it worked";
}else{
print "it did not";
}
If you are just trying to block spam, I prefer the honeypot captcha approach: http://haacked.com/archive/2007/09/10/honeypot-captcha.aspx
Put an input field on your form that should be left blank, then hide it with CSS (preferably in an external CSS file). A robot will find it and will put spam in it but humans wont see it.
In your form validation script, check the length of the field, if it contains any characters, do not process the form submission.

Sending email to multiple recipients

I've moved some old code from an old unix box to our new unix box, and I'm having some difficulty with a perl script sending email to multiple recipients. It works on the old box.
Old box perl: version 5.004_04 built for PA-RISC2.0
New box perl: v5.8.8 built for IA64.ARCHREV_0-thread-multi-LP64
Here's the basics of the script (stripped-down):
use Net::SMTP::Multipart;
$to = "sam\#bogus.com tom\#foo.com";
$smtp = Net::SMTP::Multipart->new($smtpserver);
$smtp->Header(To => $to,
From => "junk\#junk.com",
Subj => "This is a test.");
$smtp->Text("Hello, world!\n");
$smtp->End();
This works if I change it to $to = "justOneEmail\#address.com", but if I have two or more email addresses (separated by spaces), it no longer works. I don't get an error message, but no message shows up.
Any ideas why?
Do it like this:
use Net::SMTP::Multipart;
$to1 = "sam\#bogus.com";
$to2 = 'tom#foo.com';
$smtp = Net::SMTP::Multipart->new($smtpserver);
$smtp->Header(To => [ $to1, $to2, 'another_email#server.com' ],
From => "junk\#junk.com",
Subj => "This is a test.");
$smtp->Text("Hello, world!\n");
$smtp->End();
Notice that if you use double-quotes, you should escape the # in the email addresses, or perl may try to interpret it as an array interpolation.
Instead of separating the email addresses with spaces, use a comma with no intervening spaces. This works for me..
Declare an array and put all the email id's like
#MailTo = ('mail1#demomail.com', 'mail2#demomail.com', ...., 'mailn#demomail.com')
Now use the Net::SMTP module to send out the emails
$smtp->to(#MailTo);