How to send hexadecimal commands to a monitor over a Serial Port with PowerShell - 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.

Related

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

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.

Powershell: Get the current time with w32tm

My task is to get the current time with the w32time service from a Windows 2016 Server, and compare it to the time showed on this server. What I find online about this service is synchronising, and doing more complicated stuff, but I simply need the "official" time in the simplest form, so I can compare the two, and check if there is more than a few seconds of difference between the two.
I can get some useful info with
w32tm /stripchart /computer:time.windows.com /samples:1 /dataonly
Which output has the line
09:59:38, +00.1323527s
Is this the difference between the NTP server and my server? Is there a more straightforward way to achieve what I intend to do, or should I just crop this line out the output, and use it?
According to this the +00.1323527 value you see is the actual offset between local time and the target computer time. If you’re seeing differences in the 0.00* range for actual offset, you can be highly confident that you have the correct system time. Anything with less than a second offset is reasonably good as well.
You can strip the time difference out like:
$currentTime, $timeDifference = (& w32tm /stripchart /computer:time.windows.com /samples:1 /dataonly)[-1].Trim("s") -split ',\s*'
$timeDifference
# or if you rather have a numeric value than a string, cast it to Double:
[double]$timeDifference

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

Not able to read anything from serial using pyserial

I have written a python script to communicate to my RS232 device,
after execution i am able to write to terminal but i am not getting any output.If i open my teraterm i am able to see cmnd passed thru pyserial(with out any output print).
code :
import serial
port = "COM1"
baud = 115200
ser = serial.Serial(port, baud, timeout=1)
if ser.isOpen():
print(ser.name + ' is open...')
cmd = input("Enter command or 'exit':")
if cmd == 'exit':
ser.close()
exit()
else:
ser.write(cmd.encode()+b'\r\n')
out = ser.read()
print('Receiving...'+out.decode())
following is the output from console :
COM1 is open...
Enter command or 'exit':ls
Receiving...l
Receiving...l
This is what I'd expect from your program. The default value for read()'s size parameter is 1. This means that one byte will be read.
If the other end echoes your input 'ls', the first byte will be an 'l'.
Try the readline() method (don't forget to add a timeout, or it might block forever). Or handle the protocol some other way, by repeatedly calling read(), for example.

Returning data from .Net EXE to Powershell

I have a powershell script that calls an executable to do some data crunching and the script needs to retrieve the results from by the executable file. Wondering what options I have on plate for this inter process communication
Can I have the executable file directly return a string array or an object (I don't think this is possible)?
Volatile variable that the exe file sets and the powershell script reads from?
Spawn a temporary .Net remoting server within the executable and have the powershell ping that server to get the results
You could just spit out the results from the EXE to stdout in XML or CSV format and have PowerShell slurp it up with either a cast to [xml] or ConvertFrom-Csv.
That the executable is written in .NET makes no difference: it will be a separate process and therefore only the mechanisms for passing data from one process to another (without specific support in both) are available:
The return value from the exe: an integer.
Standard output from the exe: a string (usually divided into separate lines by splitting on newlines and thus treated as an array).
(Theoretically standard error could also be used, but that would be abusing it for no additional functionality.)
The standard output approach is easiest: in the exe use Console.WriteLine (which is a shortcut to Console.Out.WriteLine) and then parse the strings in PowerShell:
MyExe | Foreach-Object {
# Do something with $_ which will be a string
}
Obviously any data format that can be encoded into strings can be used. Also the calling script could accumulate the whole output into a single value and process it all at once.