Powershell script to search text file and output multiple lines in order - powershell

My source file has multiple serial interfaces. I want to simply output each serial line "Serial0/2/0:0" and then the following drops, aborts, etc. on the next lines in the output file under each Serial interface. So far I have this:
get-childitem show-int.log | select-string -pattern drops | foreach {$_.line}
And simply run it with > todays-date. I am a network engineer so forgive how bad I am at ps. I've tried google and putting the many items in quotes but nothing works to my satisfaction.
Serial0/2/0:0 is up, line protocol is up
Hardware is DSX1
MTU 1500 bytes, BW 1536 Kbit/sec, DLY 20000 usec,
reliability 255/255, txload 33/255, rxload 133/255
Encapsulation PPP, LCP Open, multilink Open
Link is a member of Multilink bundle Multilink1, loopback not set
Keepalive set (10 sec)
Last input 00:00:00, output 00:00:00, output hang never
Last clearing of "show interface" counters 1d18h
Input queue: 0/75/0/0 (size/max/drops/flushes); Total output drops:
381
Queueing strategy: fifo
Output queue: 0/40 (size/max)
5 minute input rate 805000 bits/sec, 188 packets/sec
5 minute output rate 200000 bits/sec, 153 packets/sec
8320454 packets input, 2999426407 bytes, 0 no buffer
Received 0 broadcasts (0 IP multicasts)
22 runts, 0 giants, 0 throttles
30 input errors, 29 CRC, 0 frame, 1 overrun, 0 ignored, 0 abort
7629921 packets output, 1268811436 bytes, 0 underruns
0 output errors, 0 collisions, 4294967295 interface resets
0 unknown protocol drops
0 output buffer failures, 0 output buffers swapped out
7 carrier transitions

Not precise, but easy:
Get-Content show-int.log | select-string 'Serial0/2/0:0' -Context 0,10

Related

Pymodbus reading holding and input registers : IllegalAddress

I am trying with the interactive version of pymodbus (pip install pymodbus[repl]) to access a modbus device (UPS).
I had accessed it by using mbpoll tool, so the communication and device are both working.
I guess I am having problems to figure out what are the "right" parameters that match the equivalent mbpoll.
From documentation, I am trying to access the values starting at 30405 (page 864 liebert-intellislot-modbus-rtu-reference-guide-SL-28170_0.pdf) what I understand as holding registers as the function is 30xxx:
pg 864 - Vertiv™ | Liebert® IntelliSlot Modbus/BACnet Reference Guide
Table 3.118 Liebert® GXT5—Input and Holding (continued)
Data Label Input Holding # of Reg Scale Notes/Units
System Input Frequency 30405 — 1 10 Uint16
System Input Power Factor L1 30406 — 1 100 Uint16
System Input Power Factor L2 30407 — 1 100 Uint16
System Input Power Factor L3 30408 — 1 100 Uint16
System Input Max Voltage L1-N 30409 — 1 10 Uint16
System Input Min Voltage L1-N 30410 — 1 10 Uint16
System Input Max Voltage L2-N 30411 — 1 10 Uint16
System Input Min Voltage L2-N 30412 — 1 10 Uint16
System Input Max Voltage L3-N 30413 — 1 10 Uint16
Using the mbpool it returns values as expected:
mbpoll -r 396 -t 3 -c 125 -1 -q 192.168.160.1 | \grep -v "65535 (-1)"
-- Polling slave 1...
[396]: 2162
[402]: 7
[405]: 599
[406]: 53
[409]: 2279
[410]: 2048
[415]: 230
[416]: 27
[417]: 60
[418]: 1
[419]: 0
[420]: 190
[431]: 2163
[434]: 599
[435]: 230
[446]: 2
[447]: 0
[448]: 1
[449]: 0
[450]: 1
[451]: 0
[452]: 14446
...
Then I fired /usr/local/bin/pymodbus.console tcp --host 192.168.160.1 --port 502 and at prompt I've tried several combinations of client.read_holding_registers only to get the "message": "IllegalAddress" for all trials below (and others, varying count, unit, addresses, etc):
client.read_holding_registers address=30396 count=10 unit=1
client.read_holding_registers address=396 count=10 unit=1
client.read_holding_registers address=30396 count=10 unit=0
client.read_holding_registers address=396 count=10 unit=0
The complete return of one of theses client.read is:
> client.read_holding_registers address=396 count=10 unit=0
{
"original_function_code": "3 (0x3)",
"error_function_code": "131 (0x83)",
"exception code": 2,
"message": "IllegalAddress"
}
Since it is returning valid values from mbpoll, I suspect I am doing something wrong with the parameters of client.read_holding_registers, but I can't figure out where is the problem.
Both access are from the same machine, at the same time, running opensuse tumbleweed.
Accessing as root or normal user does not make any difference.
I appreciate any hints to deal with the register address with pymodbus module.
As per the comments the mbpoll command line options can cause some confusion:
-t 3:int16 16-bit input register data type with signed int display
-t 4 16-bit output (holding) register data type (default)
This is confusing because the modbus command to read an input register is 4 and for holding registers its 3 (so the reverse of the mbpoll arguments). This is mentioned in an issue.
So the command you need will be client.read_input_registers address=395 count=10 (as per the comments there is also an issue with register numbering - the "Modbus: When 40001 Really Means 1, or 0 Really Means 1 " section in this article explains this well).

readtable and invalid variable names

I have a script that converts a simulation data file that has variable names like force(1), velocity(2), etc. I have a script that converts the data file to CSV file and up to Matlab 2016b, I was able to import that CSV file to Workspace as a table by using 'readtable'. Readtable would issue a warning that says Matlab modifies those invalid variable names, but still import successfully by replacing the parentheses with underscores: a very minimum amount of modification.
Now with 2017b, readtable doesn't do what it used to do and the imported table variables have completely arbitrary names such as var1, var2, and such: a significant amount of modification.
How can I force readtable modify the variable names like it used to do? Here's a snap shot of the CSV file and it's the "S_Out_DE10(1)" variable name causing the havoc.
I can't use the GUI because I actually bring in multiple files and create table variables in a batch.
I open the CSV file, Cntr+S or Save button, say 'OK' when asked to keep the same format, and 'No' to the same question when closing the file; all without touching a single cell.
Here is a text format of some of the data:
TIME S_Out_DE10(1) Vph x_ehsv mA_ehsv
0 0 0 0 0
0.001 0 0 0 0
0.002 0 0 0 0
0.003 0 0 0 0
0.004 0 0 0 0
Now, the funny thing is if you copy/past the above and "save" it into a CSV file, that "saving" again makes it work.
Instead of using a CSV file with headers (for which it is not designed), you can use xlsread to directly read your Excel files instead.

powershell Get-DhcpServerv4FreeIPAddress from end of range

We use reservations starting from the end of our DHCP scopes for printers.
Get-DHCPServerv4FreeIpAddress starts from the beginning. Is there anyway to make it start from the end to the beginning?
If you know how large the scope is (and how many addresses were already used) you could potentially do this (for example if the scope is 253 addresses):
Get-DHCPServerv4FreeIpAddress -numaddresses 253 | Select -Last 1

Sending complex, multi-line command via plink to Cisco Router =Unexplained behavior

I'm trying to get the below part of the code done in a relatively condensed fashion (to plug in to a much bigger script). I don't have any problems sending multiple commands this way. However, there's something that's causing the multi-line command to eventually choke. Syntax for Cisco comnmands appear to be correct. I'm not sure if I'm running into some kind of character limit or if I need to escape specific characters in $showintstatusCommands, but nothing I tried seems to work.
This code:
$BGPInterface = "GigabitEthernet0/2"
$showintstatusCommands = "`nterminal length 0`nsho int $BGPInterface | include reliability|errors`nsho log | include $Date.*LINK-3-UPDOWN.*$BGPInterface`nexit"
($Response = $showintstatusCommands | C:\Windows\plink.exe -ssh -2 -l $Credential.GetNetworkCredential().username -pw $($Credential.GetNetworkCredential().password) $DeviceName -batch) 2>$null | out-null
produces the below when I reveal the contents of the variables. $ShowIntstatusCommands appears to be correct when it echoes locally. Notice, the end of the 3rd line is cut off (number 2 character is missing at the end). Also the subsequent line is some weird residual of the previous line, which starts with $nclude.
PS C:\Users\MKANET\Desktop\test> $Response
CISCO-ROUTER#
CISCO-ROUTER#terminal length 0
CISCO-ROUTER#sho int GigabitEthernet0/2 | include reliability|errors
reliability 255/255, txload 1/255, rxload 1/255
0 input errors, 0 CRC, 0 frame, 0 overrun, 0 ignored
0 output errors, 0 collisions, 3 interface resets
CISCO-ROUTER#sho log | include Jul 17.*LINK-3-UPDOWN.*GigabitEthernet0/
$nclude Jul 17.*LINK-3-UPDOWN.*GigabitEthernet0/2
CISCO-ROUTER#
CISCO-ROUTER#exit
PS C:\Users\MKANET\Desktop\test> $showintstatusCommands
terminal length 0
sho int GigabitEthernet0/2 | include reliability|errors
sho log | include Jul 17.*LINK-3-UPDOWN.*GigabitEthernet0/2
exit
When you write to a variable in a non-global scope (like script or function scope), PowerShell will not modify any higher level scoped variables of the same name. IOW $Response = 'foo' will create a local copy of the $Response variable and assign 'foo' to it. If your intent is to modify the global variable $Response then change the line to $global:Response = ... What you see in $global:Response is residual, probably from previous tinkerings.
I finally verified that the same behavior was happening on all the remote devices if I typed in the command below manually. The line get's jumbled up if too many characters were used.
I changed:
sho log | include $Date.*LINK-3-UPDOWN.*$BGPInterface
to the below command (removing just a couple of characters); and, it worked fine. It looks like it was a Cisco IOS CLI limit.
sho log | include $Date.*LINK-3-UPDO.*$BGPInterface

How to read SNMP OID Output (bits) (hrPrinterDetectedErrorState)

I have a quick question. Its most likely user error so I apologize before I begin.
I’m trying to setup threshold for a device so that it will alert us when one of our printers is in a certain state. (Jammed, out of toner, no paper etc) I’ve found the specific oid that handles this. (1.3.6.1.2.1.25.3.5.1.2.1) The specific oid is called hrPrinterDetectedErrorState under the HOST-RESOURCE-MIB. I’ve verified that I can see the oid via SNMPWALK. My problem is interpreting the data its spitting out. What i'm reading in the MIB and what i'm seeing via SNMPWALK are different.
Here is the description of oid from the MIB:
"This object represents any error conditions detected
by the printer. The error conditions are encoded as
bits in an octet string, with the following
definitions:
Condition Bit #
lowPaper 0
noPaper 1
lowToner 2
noToner 3
doorOpen 4
jammed 5
offline 6
serviceRequested 7
inputTrayMissing 8
outputTrayMissing 9
markerSupplyMissing 10
outputNearFull 11
outputFull 12
inputTrayEmpty 13
overduePreventMaint 14
Bits are numbered starting with the most significant
bit of the first byte being bit 0, the least
significant bit of the first byte being bit 7, the
most significant bit of the second byte being bit 8,
and so on. A one bit encodes that the condition was
detected, while a zero bit encodes that the condition
was not detected.
This object is useful for alerting an operator to
specific warning or error conditions that may occur,
especially those requiring human intervention."
The odd part is that SNMPWALK says the oid is a Hex-String while the MIB specifies that it should be a Octet-String. Are the two different? Do I need to convert the data that is output by SNMPWALK somehow to get it to match up with what the MIB is saying?
To test everything, I put the printer into several different “States.” I then ran an SNMPWALK on the device to see what the oid output. Here are the results. As you will see, these results don’t match up to what the MIB specifies.
Case 1: Opened the toner door
Expected Output based on MIB: 4
SNMP Output: 08
Case 2: Removed Toner & Closed the door
Expected Output based on MIB: 1
SNMP Output: 10
Case 3: Placed 1 sheet of paper and printed a 2 page document. The printer ran out of paper.
Expected Output based on MIB: 0 or 1
SNMP Output: #
I’m confused at the output. I just need to know how to read the oid so I can setup thresholds so that when it sees, for example, a 08 it performs a certain action.
Thanks for your help!
You are reading this wrong. The data you receive back should actually be interpreted as a bit array and every bit is its own value for the specific alarm in your case
Expected Output based on MIB: 4
SNMP Output: 08
You actually get back the output:
00001000 00000000
The first byte here covers those values
lowPaper 0
noPaper 1
lowToner 2
noToner 3
doorOpen 4
jammed 5
offline 6
serviceRequested 7
So lowPaper is bit 0, noPaper is bit 1, lowToner is bit 2, etc. And doorOpen is bit 4 and as you can see that bit is set, indicating that the door is open.
EDIT:
This is very dependent on the device and implementation. To know how to parse it right involves a lot of trial and error (at least from my experience). As an example if you get back the message 9104, this could be either be
91 and 04 are separate so you first translate 91 to binary from hex and then the
same thing with 04
91: 10010001
04: 00000100
Which would mean low paper, noToner, service requested and inputTrayEmpty. This looks like the most likely way this works.
If you only get one byte back this then means you should only look for alarms in the first 8 bits. As a example of things you need to look out for: If the only alarm present is doorOpen you could be getting back only 08 but it would actually be 0008 where the first 2 hex chars are actually the second part of the alarms but aren't shown because they are none present. So in your case you actually first have to switch the bytes (if there are 4) parse the first two and the second two on their own and then you get the actual result.
As I said there is no real standard here from what i have seen and you have to just work with it until you are sure you know how the data is sent and how to parse it.
Powershell function to interpret the hrPrinterDetectedErrorState octetstring. (I feel like there's some more often used way to do this?) I've been using this module, but it doesn't even resolve hostnames to ip addresses.
The data property returned is just a string not an octetstring type. None of the printers are snmp v3.
https://www.powershellgallery.com/packages/SNMP/1.0.0.1
A single byte would have to be padded with a zero. Most of the time only one byte is sent. The bytes are in the, I think confusing, order that it's documented in. Converting two bytes to an integer results in a different order (depending on big endian or little endian order).
function snmpmessage {
param($data)
[flags()] Enum hrPrinterDetectedErrorState
{
# more common group
LowPaper = 0x0080
NoPaper = 0x0040
LowToner = 0x0020
NoToner = 0x0010
DoorOpen = 0x0008
Jammed = 0x0004
Offline = 0x0002
ServiceRequested = 0x0001
InputTrayMissing = 0x8000
OutputTrayMissing = 0x4000
MarkerSupplyMissing = 0x2000
OutputNearFull = 0x1000
OutputFull = 0x0800
InputTrayEmpty = 0x0400
OverduePreventMaint = 0x0200
}
$bytes = [byte[]][char[]]$data
if ($bytes.count -eq 1) { $bytes = $bytes[0],0 } # pad 0
$code = [bitconverter]::ToUInt16($bytes, ($startIndex=0))
[hrPrinterDetectedErrorState]$code
}
snmpmessage -join [char[]](1,4)
ServiceRequested, InputTrayEmpty
snmpmessage '#' # 0x40
NoPaper
Or:
$hrPrinterDetectedErrorState = '1.3.6.1.2.1.25.3.5.1.2.1'
$hostname = 'myprinter01'
$ip = (Resolve-DnsName $hostname).ipaddress
$result = Get-SnmpData -ip $ip -oid $hrPrinterDetectedErrorState -v v1
snmpmessage $result.data
LowToner
# ?
# $octetstring = [Lextm.SharpSnmpLib.OctetString]::new($result.data)