How to select a specific column - powershell

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"
}

Related

Powershell, Need to input IP in racadm command

I would like to validate a list of DRAC IP's using racadm. I created a powershell script to go through each IP and the run the racadm to get the sysinfo. I'm very new to powershell and hoping get some assistance in get a result sent to a csv file with serverName and getsysinfo.
$dracList = import-csv .\currentDracList.csv -header("Server_Name","Ilo_drac_ip")
$results = #()
$dracList | % {
$dracIP = $_.Ilo_drac_Ip
$dracProps = #{
racadm -r $dracIP -u root -p P#ssword! Getsysinfo
}
$resultt += New-Object -TypeName psobject -Property $dracProps
}
$Result | export-csv .\dracResults.csv
Currently getting an error:
Missing '=' operator after key in hash literal.
t line:4 char:22
racadm -r <<<< $dracIP -u root -p P#ssword! Getsysinfo
I'm able to run the command one at a time, hoping to come up with a good script to run against IP's.
CSV file contains two columns, "Server_Name","Ilo_drac_ip" as mentioned in the script.
Please let me know if any other information is needed. It would be great to have the Server_Name appear in the results.
Thanks,
Here's how I do it on a Single server. Maybe this can put you a step closer to a solution.
$ipv4 = (racadm getsysinfo -4) | Select-String -Pattern "Current IP Address" |
ConvertFrom-StringData
$result = $ipv4."Current IP Address"
$result

getting two ipaddress from the same FQDN

I am trying to get a list of IP addresses from several servers defined in server.txt.
Each server has 2 IP addresses and 2 FQDN.
Example:
servername (Production lan):server1 IPaddress:147.111.111.16
servername (backup lan):server1-bck IPaddress:10.0.4.12
Here is the code I'm using:
$servers = Get-Content server.txt
$server2 = "$servers-bck"
$zai = ""
foreach ($server in $servers)
{
$zai = $zai + $server + "`t" +
([System.Net.Dns]::GetHostAddresses($server) | foreach {echo $_.IPAddressToString}) +
"`t" +
([System.Net.Dns]::GetHostAddresses($server2) | foreach {echo $_.IPAddressToString}) +
"`n"
}
$zai > IP-address.csv
Unfortunately only the IP for Production lan is correct. The IP for backup lan only shows the IP of the last server in server.txt. I assume the problem is in: "foreach { echo $._IPAddressToString". I don't know how to fix it.
Any idea or advice will be helpful.
You seem to assume that
$server2="$servers-bck"
would append -bck to the name of each element in the array $servers. That is not the case. Instead, the array is expanded by joining its elements using the output field separator, so that -bck ends up after the last array element:
PS C:\> $a = 'a', 'b', 'c'
PS C:\> $a
a
b
c
PS C:\> "$a-bck"
a b c-bck
To get the backup server for each server from your list you need to append -bck inside the loop:
...([System.Net.Dns]::GetHostAddresses("$server-bck"))...
As a side-note, you shouldn't build CSVs manually. Let PowerShell do that for you:
$servers | % {
New-Object -Type PSObject -Property #{
'Name' = $_
'Production' = ([Net.Dns]::GetHostAddresses($_) | select -Expand IPAddressToString) -join ' '
'Backup' = ([Net.Dns]::GetHostAddresses("$_-bck") | select -Expand IPAddressToString) -join ' '
}
} | Export-Csv 'IP-address.csv' -NoType -Delimiter "`t"

Powershell Script- Pipe to export CSV for Reverse DNS fails.

I'm trying to write a script that will take input from a .txt file of IP address. Do a reverse DNS lookup to get the hostname of the IP address and then export that data into .csv file.
Here is what I have so far.
# getting the IP's from the file
$IPADDR = Get-Content "C:\Users\douglasfrancis\Desktop\IP_Test.txt"
ForEach ($IPADDR in $IPADDR)
{
[System.Net.DNS]::GetHostbyAddress($IPADDR) | Add-Member -Name IP -Value $IPADDR - MemberType NoteProperty -PassThru | select IP, HostName | sort -property Hostname | export- csv "C:\Users\douglasfrancis\Desktop\ReverseLookup.csv"
}
How it is now the created CSV file will have the column heads that I assigned and the last IP address in the list with its hostname. So somehow its dropping everything else.
If I run it with the export-csv commented out then all the IP's are displayed in the console but are not sorted by hostname.
I've used this same basic pipe before with no issues so I'm kinda at a loss for what is going on here. Any help would be awesome.
Thanks,
You should put the result in an array before exporting it to CSV :
# getting the IP's from the file
$IPADDRS = Get-Content "C:\Users\douglasfrancis\Desktop\IP_Test.txt"
$result = #()
ForEach ($IPADDR in $IPADDRS)
{
$result += [System.Net.DNS]::GetHostbyAddress($IPADDR) | Add-Member -Name IP -Value $IPADDR -MemberType NoteProperty -PassThru | select IP, HostName
}
$result | sort -property Hostname | export-csv "C:\Users\douglasfrancis\Desktop\ReverseLookup.csv" -NoTypeInformation
#David Braban is true, this was not your trouble but I use $IPADDRS for the collection and $IPADDR for each value, this way it's much correct (en readable)/
In your code, I see:
ForEach ($IPADDR in $IPADDR)
That's very wrong: you use the same variable both as your collection and as the variable to iterate.
Use:
$ipaddr | %{ [System.Net.DNS]::GetHostbyAddress($_) } | ...

Format the output of a hash table in Powershell to output to one line

Is it possible to format the output of a hashtable in Powershell to output all the values onto one line?
e.g.
I have the hash table $hashErr with the below values:
$hashErr = #{"server1" = "192.168.17.21";
"server2" = "192.168.17.22";
"server3" = "192.168.17.23"}
Which are written to a log with the below:
$hashErr.GetEnumerator() | Sort-Object Name | ForEach-Object {ForEach-Object {"{0}`t{1}" -f $_.Name,($_.Value -join ", ")} | Add-Content $log
The will cause the below to be written to the log:
Name Value
---- -----
server2 192.168.17.22
server1 192.168.17.21
server3 192.168.17.23
My question is, how can I format this hash table so the output is written all to one line, like the below?
server2 192.168.17.22 | server1 192.168.17.21 | server3 192.168.17.23
This could be done by looping through all the values in the hash table and putting them into an array but surely there is a more direct way?
You can iterate over the keys of a hash table, and then in the loop lookup the values. By using the pipeline you don't need an intermediate collection:
($hashErr.Keys | foreach { "$_ $($hashErr[$_])" }) -join "|"
The V4 version of Richard's solution:
$hashErr = #{"server1" = "192.168.17.21";
"server2" = "192.168.17.22";
"server3" = "192.168.17.23"}
$hashErr.Keys.ForEach({"$_ $($hashErr.$_)"}) -join ' | '
server3 192.168.17.23 | server2 192.168.17.22 | server1 192.168.17.21
Not excat output as you want but also 1 line output.
$hashErr | ConvertTo-Json -Compress
outputs:
{"server2":"192.168.17.22","server3":"192.168.17.23","server1":"192.168.17.21"}
A bit late to the party, expanding on #mjolinor's solution, you can use the type accelerator [ordered]:
$hashErr = [ordered]#{"server1" = "192.168.17.21";
"server2" = "192.168.17.22";
"server3" = "192.168.17.23"}
$hashErr.Keys.ForEach({"$_ $($hashErr.$_)"}) -join ' | '
server1 192.168.17.21 | server2 192.168.17.22 | server3 192.168.17.23
I think [ordered] was introduced in PS v. 3.0.
Do you want to keep the sorting, and support for multiple ip addresses on a single server, both of which are in the code you showed but not in your output?
If so I think the best you'll get is just a minor modification on the original:
C:\scripts> ($hashErr.GetEnumerator() | sort Name | % { "$($_.Name) $($_.Value -join ',')" }) -join "|"
server1 192.168.17.21|server2 192.168.17.22|server3 192.168.17.23,1.2.3.4

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.