How to save all ip addresses connected to the network in a text file - powershell

I would like to create an alert software for employees without outsourcing for security reasons. I found a way to send alerts from cmd with msg command, I didn't test this code but I generated it from Microsoft site, if there is any error please let me know
msg #allip.txt "test"
For IP list, I found a solution using arp -a using cmd but I have to clear the extra info in the file like this, the problem is that if I leave the extra info in the text the code doesn't work
Interface: 192.168.1.140 --- 0x3
Internet Address Physical Address Type
192.168.1.1 00-00-00-00-00-00 dynamic
192.168.1.61 00-00-00-00-00-00 dynamic
192.168.1.255 00-00-00-00-00-00 static
...
Is there a way to save only the internet address table

To extract all the cached IP addresses - which is what arp.exe /a reports - use the following:
Note: Judging by the linked docs, these cached addresses, stored along with their "their resolved Ethernet or Token Ring physical addresses", with a separate table maintained for each network adapter, are the IP addresses the computer at hand has actively talked to in the current OS session, which is not the same as the complete set of computers connected to the network.
To scan an entire subnet for reachable IP addresses, consider a third-party function such as Ping-Subnet.
((arp /a) -match '^\s+\d').ForEach({ (-split $_)[0] })
To save to a file, say ips.txt, append > ips.txt or | Set-Content ips.txt.
Note:
In Windows PowerShell, you'll get different character encodings by these file-saving methods (UTF-16 LE ("Unicode") for > / ANSI for Set-Content)
In PowerShell (Core) 7+, you'll get BOM-less UTF-8 files by (consistent) default.
Use Set-Content's -Encoding parameter to control the encoding explicitly.
Explanation:
-match '^\s+\d' filters the array of lines output by arp /a to include only those starting with (^) at least one (+) whitespace char. (\), followed by a decimal digit (\d) - this limits the output lines to the lines showing cache-table entries.
.ForEach() executes a script block ({ ... }) for each matching line.
The unary form of -split, the string splitting operator, splits each matching line into an array of fields by whitespace, and index [0] returns the first such field.

Related

How to send hexadecimal commands to a monitor over a Serial Port with PowerShell

Okay this is a bit of a weird one but due to my complete lack of knowledge on how to use Serial Ports or PowerShell i couldn't think of anywhere else to go.
What I'm trying to do is send basic commands to a monitor that has a RS232 port on it that can be used to control the properties of the monitor, i.e. Brightness, Contrast, Backlight etc.
I'm attempting to use PowerShell to do this for testing purposes. I can create the $port in PowerShell and assign it to the relevant COM# that the monitor is connected to but I'm at a loss as to how to actually send the command to it as it must be Hexadecimal for the controller on the monitor to understand it.
The monitor is capable of returning an acknowledgement using the same Hex layout but I'm unable to find a way of showing that response on the Powershell console.
This is what I have been able to get so far.
PS C:\Users\Kingdel> [System.IO.Ports.SerialPort]::getportnames()
COM1
COM2
COM3
COM4
COM5
COM6
PS C:\Users\Kingdel> $port= new-Object System.IO.Ports.SerialPort COM1,9600,None,8,one
PS C:\Users\Kingdel> $port.open()
PS C:\Users\Kingdel> $port.WriteLine("0xA6,0x01,0x00,0x00,0x00,0x03,0x01,0x31,0x94")
PS C:\Users\Kingdel>
Anyone able to point me in the right direction as to how I can send this command to the monitor and to view the returned acknowledgement.
I am open to trying different terminals, I have tried PuTTy and Termite and neither of them were successful as far as I can tell.
That's a really good question. Maybe I can help with this.
The SerialPort.WriteLine() method takes in a string to write to the output buffer, so using this, you're essentially sending an argument of strings.
To send something over to the [System.IO.Ports.SerialPort] object, you need to use SerialPort.Write() with a Byte[] argument. The Write() method can take in a number of bytes to the serial port using data from a buffer.
You also need to send it three arguments which are buffer Byte[], offset Int32, and a count Int32. So in your case, you can do the following:
[Byte[]] $hex = 0xA6,0x01,0x00,0x00,0x00,0x03,0x01,0x31,0x94
$port.Write($hex, 0, $hex.Count)
The buffer argument is the array that contains the data to write to the port, offset is the zero-based byte offset in the buffer array at which to begin copying the bytes to the port, and the count is the number of bytes to write.

Script to parse FROM email address from many text files

I have a collection of 338 .log files. These are just basic text files and no two files have the same file name (but all file names start with "rrm-"). Here is an example of the data they contain:
Receiving message #1 : OK (4480 bytes)
From: <djerry#domain.com>
Subject: 2-303-468-02
Message-ID: <PRODVAPP21XvCsLCXPI0035acee#prod.domain.com>
Forwarding to "Some User" <someuser#somedomain.com> : OK
I need a script that will open each file one at a time, parse only the "From:" lines (could be 10, could be 1000s) to extract only the email address between the < and > characters, and write the output to a single text file, one email address per line. The rest of the data I don't care about. I also don't care about validating the email addresses. The resulting text file would look like this:
djerry#domain.com
bob#domain.com
tom#blah.com
jerry#yada.com
I'm not a programmer, I only know how to break things when I try. I don't even know what software / utility I would need to use for this. I'm using a Windows 10 computer. So maybe a Powershell script? Sorry for such a n00b question, I really hate feeling stupid for not knowing how to or being able to google for a simple solution. Appreciate any help!
Try the following:
Select-String -Pattern '^From: .*?<(.+?)>' -Path rrm-* |
ForEach-Object { $_.Matches.Groups[1].Value } > output.txt
^From: .*?<(.+?)> is a regex (regular expression) that finds lines that start with From: and captures what follows between < and >.
The .*? part is to account for an (optional) actual name preceding the <...>-enclosed email address, as is common; e.g, "Dana Jerry" <djerry#domain.com>. Thanks, TheMadTechnician
$_.Matches.Groups[1].Value retrieves what was captured.
> output.txt saves the results to a file.

Why doesn't this bor and bnot expression give the expected result in Powershell?

why doesn't this bor bnot give the expected result in powershell?
To find the last address in an ipv6 subnet one needs to do a "binary or" and a "binary not" operation.
The article I'm reading (https://www.codeproject.com/Articles/660429/Subnetting-with-IPv6-Part-1-2) describes it like this:
(2001:db8:1234::) | ~(ffff:ffff:ffff::) = 2001:db8:1234:ffff:ffff:ffff:ffff:ffff
Where | is a "binary or" and
~ is a "binary not"
In powershell however, I try it like:
$mask = 0xffffffff
$someOctet = 0x0000
"{0:x4}" -f ($someOctet -bor -bnot ($mask) )
and I get 0000 instead of ffff
Why is this?
The tutorial is doing a -not of the entire subnet mask, so ff00 inverts to 00ff and similar for longer Fs and 0s; you aren't doing that, so you don't get the same results.
The fully expanded calculation that you show is doing this:
1. (2001:0db8:1234:0000:0000:0000:0000:0000) | ~(ffff:ffff:ffff:0000:0000:0000:0000:0000)
2. (2001:0db8:1234:0000:0000:0000:0000:0000) | (0000:0000:0000:ffff:ffff:ffff:ffff:ffff)
3. = 2001:db8:1234:ffff:ffff:ffff:ffff:ffff
Note how in step 1. to step 2, the not is inverting the pattern of Fs and 0s, switching the subnet mask around, and switching it around between the bit where the prefix ends and the bit where the host part begins.
Then step 3 or takes only the set bits from the left to keep those numbers the same (neither zero'd nor ffff'd), and all the set bits from the right (to ffff those, maxing them to the max IP address within that prefix).
In other words, it makes no sense to do this "an octet at a time". This is a whole IP address (or whole prefix) + whole subnet mask operation.
Where the tutorial says:
& (AND), | (OR), ~ (NOT or bit INVERTER): We will use these three bitwise operators in our calculations. I think everybody is familiar -at least from university digital logic courses- and knows how they operate. I will not explain the details here again. You can search for 'bitwise operators' for further information.
If you aren't very familiar with what they do, it would be worth studying that more, before trying to apply them to IP subnetting. Because you are basically asking why 0 or (not 1) is 0 and the answer is because that's how Boolean logic "or" and "not" work.
Edit for your comment
[math]::pow(2,128) is a lot bigger than [decimal]::maxvalue, so I don't think Decimal will do.
I don't know what a recommended way to do it is, but I imagine if you really wanted to do it all within PowerShell with -not you'd have to process it with [bigint] (e.g. [bigint]::Parse('20010db8123400000000000000000000', 'hex')).
But more likely, you'd do something more long-winded like:
# parse the address and mask into IP address objects
# which saves you having to expand the short version to
$ip = [ipaddress]::Parse('fe80::1')
$mask = [ipaddress]::Parse('ffff::')
# Convert them into byte arrays, then convert those into BitArrays
$ipBits = [System.Collections.BitArray]::new($ip.GetAddressBytes())
$maskBits = [System.Collections.BitArray]::new($mask.GetAddressBytes())
# ip OR (NOT mask) calculation using BitArray's own methods
$result = $ipBits.Or($maskBits.Not())
# long-winded way to get the resulting BitArray back to an IP
# via a byte array
$byteTemp = [byte[]]::new(16)
$result.CopyTo($byteTemp, 0)
$maxIP = [ipaddress]::new($byteTemp)
$maxIP.IPAddressToString
# fe80:ffff:ffff:ffff:ffff:ffff:ffff:ffff

Should I remove all dots before the # sign in emails

In a web based+REST api system, I want people to enter their email address along a password they choose to authenticate to my service (pretty common practice, nothing new),
My question is, is it ok if I lower case them and remove any dot (.) before the # sign?
To make it even more clear, "ali#example.com" and "a.li#ExamPle.Com" will be the same user.
So part of this question will be, are there email services out there that are sensitive to dots in your email and you will not receive your email if they are send to the dot less version? Gmail ignores the dots as far as I know.
According to RFC 3696, the period is a valid email character:
Contemporary email addresses consist of a "local part" separated from a "domain part" (a fully-qualified domain name) by an at-sign ("#").
[…]
Without quotes, local-parts may consist of any combination of
alphabetic characters, digits, or any of the special characters
! # $ % & ' * + - / = ? ^ _ ` . { | } ~
period (".") may also appear, but may not be used to start or end
the local part, nor may two or more consecutive periods appear.
Edit: To provide some more information, it looks like Exchange doesn't ignore the period in email addresses (firstname.lastname#myprovider.com worked, whereas firstnamelastname#myprovider.com resulted in a Delivery Status Notification (Failure)).

What are these lines of log-parsing Perl doing and how can I come up with something that might work?

This problem comes under the context of pop-before-smtp / Postfix / Dovecot, but if I knew Perl string parsing, I could come up with an answer myself. However, I'm so lost I don't even know the precise question. To wit:
We've been using Postfix for a LONG time now and are kind of hooked on it. Now we need to "move into the modern era" and let people SEND email from our SMTP server(s) even when they're outside our network. So, tasked with this job, I've found pop-before-smtp.
You can find it here.
So, I've got it all configured but it fails in testing. I've troubleshot it using the directions here, and determined that the Perl that's trying to parse the log appears to be incorrect. We're using Dovecot as our IMAP / POP server, and there are three choices given in the configuration file. Here is an excerpt from the config file showing the three sets:
# For Dovecot POP3/IMAP when using syslog.
#$pat = '^[LOGTIME] \S+ (?:dovecot: )?(?:imap|pop3)-login: ' .
# 'Login: .*? (?:\[|rip=)[:f]*(\d+\.\d+\.\d+\.\d+)[],]';
#$out_pat = '^[LOGTIME] \S+ (?:dovecot: )?(?:imap|pop3)-login: ' .
# 'Disconnected.*? (?:\[|rip=)[:f]*(\d+\.\d+\.\d+\.\d+)[],]';
# For Dovecot POP3/IMAP when it does its own logging.
##$logtime_pat = '(\d\d\d\d-\d+-\d+ \d+:\d+:\d+)';
#$pat = '^dovecot: [LOGTIME] Info: (?:imap|pop3)-login: ' .
# 'Login: .+? rip=[:f]*(\d+\.\d+\.\d+\.\d+),';
#$out_pat = '^dovecot: [LOGTIME] Info: (?:imap|pop3)-login: ' .
# 'Disconnected.*? rip=[:f]*(\d+\.\d+\.\d+\.\d+),';
# For older Dovecot POP3/IMAP when it does its own logging.
#$pat = '^(?:imap|pop3)-login: [LOGTIME] Info: ' .
# 'Login: \S+ \[[:f]*(\d+\.\d+\.\d+\.\d+)\]';
#$out_pat = '^(?:imap|pop3)-login: [LOGTIME] Info: ' .
# 'Disconnected.*? \[[:f]*(\d+\.\d+\.\d+\.\d+)\]';
One is supposed to uncomment the ones that apply, however, none of them work.
I surmise that 'pat' is the pattern for login, and out-pat is the pattern for logging out or otherwise disconnecting.
The actual log record format is clearly different than any of these three, but they're close. Here are an example pair:
Mar 11 17:53:55 imap-login: Info: Login: user=<username>, method=PLAIN, rip=208.54.4.205, lip=192.168.1.1, TLS
Mar 11 17:59:10 IMAP(username): Info: Disconnected: Logged out bytes=352/43743
When using POP, 'imap-login' is replaced by 'pop-login', and on log-out, 'POP' replaces 'IMAP' - why the changes in capitalization I can't say!
Importand data are: The timestamp, the username, and, when logging in, the "remote" ip ("rip").
Given enough time, I may be able to piece together something that works, but since I don't actually know Perl, this is kind of tough. Please help me write new rules to parse the logging output used with our Dovecot package.
The (:?.. portion of a Perl regular expression asks for clustering but not capturing; this allows entire groups to be matched or ignored as as group without influencing the capture group numbers; all the lines capture exactly one field, the IP to allow. (Which is a little odd, I might have expected both username and IP, but this might be easier in the long run.)
# For Dovecot POP3/IMAP when using syslog.
$pat = '^[LOGTIME] \S+ (?:imap|pop3)-login: Info: ' .
'Login: .*? (?:\[|rip=)[:f]*(\d+\.\d+\.\d+\.\d+)[],]';
# not necessary? see comment header START OF PATTERNS
# $out_pat = '^[LOGTIME] \S+ (?:IMAP|POP3)\(\S+\): Info: ' .
# 'Disconnected.*';
I've removed the dovecot pieces since they weren't in your input. I added the Info: to both lines. I've modified the $out_pat to use IMAP(username) instead of the no-longer-there imap-login from the original. (The use of \S+ will break if usernames have spaces. Since this assumption was made elsewhere in the file, I hope it's fine.)
Since there is no longer any IP address to capture for the logout line, it is probably best to not define $out_pat -- the START OF PATTERNS comment block includes the phrase If the entry of your choice also provides $out_pat, you should uncomment that variable as well, which allows us to keep track of users who are still connected to the server (e.g. Thunderbird caches open IMAP connections).
I haven't tested this but I have good feelings about it.