Powershell and regex to parse config and display interface with ospf configured - powershell

Help please. I want the output to display
interface vlan1 is not configured with ospf
interface vlan3 is configured with ospf
interface vlan7 is configured with ospf
but the output I got when running this script below is
interface vlan1 interface vlan3 interface vlan7 is configured with ospf
$interface = select-string -path c:\doc\config.txt -pattern "interface\vlan\d{1,3} -context 0, 3
$ospf = Select-string -inputobject $interface -pattern "ip ospf message-digest.*" | % {$_.matches.value}
if ($ospf -ne $null)
{
$int = $ interface | select -expandproperty line #don't want to show line#
write-host "$int is configured with ospf"
}
else
{
$int = $ interface | select -expandproperty line #don't want to show line#
Write-host "$int is not configured with ospf"
}
interface Vlan1
no ip address
shutdown
!
interface Vlan3
ip ospf message-digest-key 100 md5 7 aa93naf
!
interface Vlan7
standby 38 preempt
ip ospf message-digest-key 100 md5 7 asf9394

Your approach is IMO overcomplicated,
split the config file into chunks(interfaces) separated by the !,
check each single interface for the ospf string,
select the first line of the current interface and output with the test result.
## Q:\Test\2019\03\08\SO_55056710.ps1
$interfaces = (Get-Content .\config.txt -Raw) -split "!`r?`n"
foreach($interface in $interfaces){
if ($interface -match "ip ospf message-digest"){
$ospf = "is"} else {$ospf = "is not"}
"{0} {1} configured with ospf" -f ($interface -split "`r?`n")[0],$ospf
}
Sample output:
> Q:\Test\2019\03\08\SO_55056710.ps1
interface Vlan1 is not configured with ospf
interface Vlan3 is configured with ospf
interface Vlan7 is configured with ospf

Related

Import a CSV, run port connection, then export to new csv

I have a Sources.csv which has columns "Source," "Host" and "Port" (Source is just the name of the device I'm trying to connect to). My goal is to go line-by-line through this CSV, run a connection test to the IP and Port, then export to a new csv file to include these same columns as well as a new column "Reachable." This is what I have so far, but my csv file is filling up with all sorts of information that doesn't seem to make sense... So I'm curious if anyone can point me in the right direction:
$path = '.\Sources.csv'
$csv = Import-Csv -Path $path
Foreach($line in $csv){
$TCPTest = Test-NetConnection $line.host -Port $line.port
$Test = #{DataSource=$line.source; IP=$line.host; Port=$line.port;
Reachable=$TCPTest.TcpTestSucceeded}
$Test | Export-Csv -Path .\SourceChecks.csv -append
}
Santango's answer works all the way back to PowerShell version 1 (I think).
If you can accept a dependency on PowerShell Version 3 (released in 2012), there is another option:
$sourcesPath = '.\Sources.csv'
$sources = Import-Csv $sourcesPath
$sources | ForEach {
$reachable = Test-NetConnection $_.host -Port $_.port -InformationLevel Quiet
[PSCustomObject]#{
Source = $_.Source
Host = $_.Host
Port = $_.Port
Reachable = $reachable
}
} |
Export-Csv newpathtocsv.csv
You can handle this using calculated properties with Select-Object:
$path = '.\Sources.csv'
Import-Csv -Path $path | Select-Object *, #{
Name = 'Reachable'
Expression = {Test-NetConnection $_.Host -Port $_.Port -InformationLevel Quiet}
} | Export-Csv newpathtocsv.csv -NoTypeInformation
Using -InformationLevel Quiet on Test-NetConnection so the cmdlet returns a boolean:
If you set this parameter to Quiet, the cmdlet returns basic information. For example, for a ping test, this cmdlet returns a Boolean value that indicates whether the attempt to ping a host or port is successful.
You can also add -WarningAction Ignore if you wish to not see the warning messages displayed to the console.
It's worth noting that Test-NetConnection is quite slow if you have many target hosts and ports to test connectivity. If you're looking to speed up this process you can give this function a try. It leverages the async capabilities from the .NET TcpClient Class.
An example, using the following CSV as input:
Host,Port
google.com,80
google.com,8080
cisco.com,80
cisco.com,443
amazon.com,80
amazon.com,389
amazon.com,636
Output would become:
PS /> Import-Csv $path | Test-TCPConnectionAsync -TimeOut 10
Source Destionation Port Success
------ ------------ ---- -------
sourceComputerName google.com 80 True
sourceComputerName cisco.com 443 True
sourceComputerName cisco.com 80 True
sourceComputerName amazon.com 80 True
sourceComputerName google.com 8080 False
sourceComputerName amazon.com 389 False
sourceComputerName amazon.com 636 False

removing words from a line output powershell

I have a powershell command with below output, The command output shows the active NIC adapter and NIC adapter name differ in each machine. But what I am looking here is, in one server active NIC adapter is Local Area Connection and in another one it is Ethernet.This will differ in all VM's
PS C:\> netsh interface ipv4 show interface |where { $_ -match '\sconnected' -and $_ -notmatch 'loopback'}
12 5 1500 connected **Local Area Connection**
PS C:\>
PS C:\> netsh interface ipv4 show interface |where { $_ -match '\sconnected' -and $_ -notmatch 'loopback'}
12 5 1500 connected **Ethernet**
PS C:\>
I want only the adapter name to be captured (eg: Local Area Connection\Ethernet etc).
Can anyone help me modifying the command so that I will get the NIC adapter name without any white space as output?
The output should be like below
Local Area Connection
Ethernet
Ethernet 2
If you are running this on a Windows 8 or Server 2012 or newer operating system you can use the Get-NetAdapter cmdlet instead to get the result you want:
Get-NetAdapter | Where {$_.Status -eq 'Up'} | Select -ExpandProperty Name
On an older OS you could try this, which splits the text for each interface by the word "connected" and it's trailing whitespace using the regex special character \s and then return the second item of that split:
$Interfaces = netsh interface ipv4 show interface | where { $_ -match '\sconnected' -and $_ -notmatch 'loopback'}
$Interfaces | ForEach-Object {
($_ -Split 'connected\s+')[1]
}
Or here is another option that avoids using the -split operator and instead uses a regex lookbehind to match 'connected' followed by 5 spaces in the string before what we want to return:
$Interfaces = netsh interface ipv4 show interface | where { $_ -notmatch 'loopback'}
$Interfaces | ForEach-Object {
[regex]::matches($_, '(?<=connected\s{5})(.*)').value
}

validate IP address entered by user

I am making a script to set the IP, subnet mask, gateway and DNS server address on a localhost. I have a working script but I would like to make sure that the IP addresses entered are numeric characters and within the range 0-255 for each Octet.
Any help would be appreciated.
$IP = Read-Host -Prompt 'Please enter the Static IP Address. Format 192.168.x.x'
$MaskBits = 24 # This means subnet mask = 255.255.255.0
$Gateway = Read-Host -Prompt 'Please enter the defaut gateway IP Address. Format 192.168.x.x'
$Dns = Read-Host -Prompt 'Please enter the DNS IP Address. Format 192.168.x.x'
$IPType = "IPv4"
# Retrieve the network adapter that you want to configure
$adapter = Get-NetAdapter | ? {$_.Status -eq "up"}
# Remove any existing IP, gateway from our ipv4 adapter
If (($adapter | Get-NetIPConfiguration).IPv4Address.IPAddress) {
$adapter | Remove-NetIPAddress -AddressFamily $IPType -Confirm:$false
}
If (($adapter | Get-NetIPConfiguration).Ipv4DefaultGateway) {
$adapter | Remove-NetRoute -AddressFamily $IPType -Confirm:$false
}
# Configure the IP address and default gateway
$adapter | New-NetIPAddress `
-AddressFamily $IPType `
-IPAddress $IP `
-PrefixLength $MaskBits `
-DefaultGateway $Gateway
# Configure the DNS client server IP addresses
$adapter | Set-DnsClientServerAddress -ServerAddresses $DNS
Check this link. You can cast the given string to [ipaddress].
PS C:\Windows\system32> [ipaddress]"192.168.1.1"
Above sample does not produce an error. If you're using an invalid ip address:
PS C:\Windows\system32> [ipaddress]"260.0.0.1"
Cannot convert value "260.0.0.1" to type "System.Net.IPAddress". Error: "An
invalid IP address was specified."
At line:1 char:1
+ [ipaddress]"260.0.0.1"
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastParseTargetInvocation
You'll receive an exception that can be caught.
Here is the aproach that combines the above two answers.
For a basic validation this oneliner could help
[bool]("text" -as [ipaddress])
But user may type something like "100" and it will successfully validate to ip address 0.0.0.100.
That's might be something not what you expect.
So i like to use regex and type validation combined:
function IsValidIPv4Address ($ip) {
return ($ip -match "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$" -and [bool]($ip -as [ipaddress]))
}
Use regular expressions
$ipRegEx="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
if($ip -notmatch $ipRegEx)
{
#error code
}
You can search online about regular expressions and examples for IP. Just keep in mind that powershell is built on top of .NET, therefore when searching and reading for regular expressions, focus on the .NET or C# ones. For example this.
update
As it was pointed out afterwards by comments, the regex is not correct but it was posted as an example for the regular expressions validation. An alternative could be ((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)

Issue in Power shell script while using Ping command

I am trying to read the host file and trying to ping the each host name and after that capturing the IP address in the response and trying to match with the IP address mentioned in the host file.
I have three scenarios:-
1) Its pinging the host and getting the reply back with the correct IP
Result :-Resolved and Replied
2) It's Not pinging at all and not resolving the IP
Result :-Not Resolved and Not Replied
3) It's Pinging but not resolving the IP correctly mentioned to the IP in the host file
Result :-Not Resolved and Replied
I am trying to achieve that scenario with the below script but not fully achieved as different expression need to be used.
Can someone help me to finish it
$lines = Get-Content myfile.txt | Where {$_ -notmatch "((^#)|(^\s+$))"}
# get all test pairs
$tests=$lines |
ForEach-Object{
$fields = $_ -split '\s+'
echo " Fields are $fields"
for ($i = 1; $i -lt $fields.Length; $i++){
New-Object PsObject -Property #{IP=$fields[0];Host=$fields[$i]}
}
}
$tests |
ForEach-Object{
$props=#{
IPAddress=$_.ip
Hostname=$_.Host
Resolve =' '
Reply = ' '
}
$PingResult = ping -n 1 -w 10 $_.host
#echo "$PingResult"
foreach ($line in $PingResult)
{
if ($line.StartsWith("Pinging") -eq $true)
{
$_.ip= $line -match '\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}'
echo "IP is $IP"
if ($matches[0])
{
$props.Resolve ='Y'
$props.Reply='Y'
}
else
{
$props.Resolve ='Y'
$props.Reply='N'
}
}
}New-Object PsCustomObject -Property $props
}|
Format-Table -AutoSize | Out-String | Out-File D:\CEP\testlogging.txt
Note:- Cannot use Test-Connection because it throws exception when server wont reply back or doesnot exist and it takes more time to ping.
Thanks.
Suppose it's too late to be of much help but this should resolve the issues you are reporting with Test-Connection.
Test-Connection -ComputerName $IP -Count 1 -ErrorAction SilentlyContinue
That will limit the ping count to 1 and error will be ignored. Then you can work with the object it produces instead of having to parse lines.

How to select a specific column

I need to extract values of specific column. I need to parse output generated with cmd :
netstat -an |
Select-String "TCP\s+.+\:.+\s+(.+)\:(\d+)\s+(\w+)" |
ForEach-Object {
$key = $_.matches[0].Groups[1].value
$Status = $_.matches[0].Groups[3].value.
Above 2 strings when printed gives me Foreign IP and connection state. I need a column with port no of local IP to which a foreign IP is connected.
If you are running on Windows 8 or Windows Server 2012, you can use the following command examples in Powershell V3:
Pipelining with Select-Object
Get-NetTCPConnection | Select LocalAddress,LocalPort,RemoteAddress,RemotePort
Selecting each property individually
(Get-NetTCPConnection).LocalAddress
(Get-NetTCPConnection).LocalPort
(Get-NetTCPConnection).RemoteAddress
(Get-NetTCPConnection).RemoteAddress
Creating variables using each property
$LocalAddress = (Get-NetTCPConnection).LocalAddress
$LocalPort = (Get-NetTCPConnection).LocalPort
$Remote Address = (Get-NetTCPConnection).RemoteAddress
$RemotePort = (Get-NetTCPConnection).RemoteAddress
These should all come out as lists.
Hope this helps :)
I'm not sure what you mean by a column but I've tweaked your regex and this gets the local and foreign addresses and ports:
netstat -an |
Select-String "TCP\s+(.+)\:(.+)\s+(.+)\:(\d+)\s+(\w+)" |
ForEach-Object {
$LocalAddress = $_.matches[0].Groups[1].value
$LocalPort = $_.matches[0].Groups[2].value
$ForeignAddress = $_.matches[0].Groups[3].value
$ForeignPort = $_.matches[0].Groups[4].value
Write-Output "ForeignAddress: $ForeignAddress `t ForeignPort: $ForeignPort `t LocalAddress: $LocalAddress `t LocalPort: $LocalPort"
}