1

I'm building a script to take a IP addresses from a CSV and then attempt to ping/connect to them. Eventually I will run some commands against them and output all of it as extra data in the CSV. Right now I'm working with 2 different CSVs (input and output) until I figure out the append process.

#Create a CSV
$CSVOutput = "$PSScriptRoot\Addresses scanned $(Get-Date -format “MM-dd-yyyy HHmm ss”).csv"
Write-Host "Creating output file " $CSVOutput
New-Item $CSVOutput -type file
$NewLine = "{0},{1}" -f "IPAddress", "Status"
$NewLine | add-content -path $CSVOutput

$inputCSV = "$PSScriptRoot\Addresses.csv"
$ipaddresses = import-csv $inputCSV | select-object "IPAddress" #$ColumnHeader

$inputCSV = "$PSScriptRoot\Addresses.csv"
$ipaddresses = import-csv $inputCSV
foreach($ip in $ipaddresses) {
Write-Host $ip
    if (test-connection $ip.("IPAddress") -count 1 -quiet) {
        $NewLine = "{0},{1}" -f $ip, "online"
        $NewLine | add-content -path $CSVOutput
    } else {
         write-host $ip.("IPAddress") "Ping failed." -foreground red
         $NewLine = "{0},{1}" -f $ip, "offline"
         $NewLine | add-content -path $CSVOutput
    }
}

For some strange reason, the script is outputting the IP address in the form of @{IPAddress=172.18.16.1}, or if I comment out the piped output from the import line, I get this: @{IPAddress=172.18.16.2; Status=}. In trying to debug this, I added Write-Host $ip as the first line in the foreach loop.

I can only guess I'm running into some kind of object vs string issue, or I am pulling in additional formatting somehow, but I can't get past it. I only want to work with an actual IP address, I don't want the leading and trailing formatting @{}

What am I doing wrong? How do I get rid of the extra formatting?

1

You just need to change $ip in your $NewLine definition to $ip.IPAddress. $ip is of type PSCustomObject, where $ip.IPAddress is of type String.

You also haven't defined $CSVOutput, and should remove the second definition of $ipaddresses.

$inputCSV = ".\ipadr.csv"
$CSVOutput = ".\out.csv"
$ipaddresses = import-csv $inputCSV | select-object

foreach($ip in $ipaddresses) {
    Write-Host $ip.IPAddress
    if (test-connection $ip.IPAddress -count 1 -quiet) {
        $NewLine = "{0},{1}" -f $ip.IPAddress, "online"
        $NewLine | add-content -path $CSVOutput
    } else {
         write-host $ip.IPAddress "Ping failed." -foreground red
         $NewLine = "{0},{1}" -f $ip.IPAddress, "offline"
         $NewLine | add-content -path $CSVOutput
    }
}
  • $ip.IPAddress and $ip.("IPAddress") seem to give me the same result, which was what I was looking for. Are they the same? – YetAnotherRandomUser Jul 28 '17 at 1:22
  • They are equivalent, though you only used either variant in the if() and not $NewLine. – root Jul 28 '17 at 1:40
0

Here's what I did to get this working in a limited fashion, the main change is your ForEach loop, which I used this instead: $ipaddresses.IPAddress | ForEach-Object.

The other change is in the Write-Host line to output Success/Failure: Write-Host $_ "Ping failed." -foreground red.

Also, the $NewLine variable: $NewLine = "{0},{1}" -f $_, "online".

In the end, here's what I had that worked. I wasn't able to fully test it as you will be able to, but using 2 IP's in my dummy Addresses.csv where one IP is legit the other isn't, it worked as I think you are expecting it to:

$inputCSV = "$PSScriptRoot\Addresses.csv"
$ipaddresses = Import-CSV $inputCSV
$ipaddresses.IPAddress | ForEach-Object {
    if (test-connection $_ -count 1 -quiet) {
        Write-Host $_ "Ping success." -foreground green
        $NewLine = "{0},{1}" -f $_, "online"
        $NewLine | add-content -path $CSVOutput
    } else {
         Write-Host $_ "Ping failed." -foreground red
         $NewLine = "{0},{1}" -f $_, "offline"
         $NewLine | add-content -path $CSVOutput
    }
}
  • 1
    I think the test connection must also use $_ in your case – eckes Jul 27 '17 at 20:26
  • 1
    @eckes Good catch, editing Answer reflecting your comment. :) – DukeSilversJazz Jul 27 '17 at 20:30
  • @root found my problem, but I'm still trying to digest your answer. My next hurdle is to figure out how to get a faster fail, and I was thinking switching to a foreach-object might help speed things along. But you guys lost me at $_. Is that some kind of a reference to the pre-pipe object? Maybe like a this reference or something? – YetAnotherRandomUser Jul 28 '17 at 1:29
  • 2
    @DanWhaley $_ in a For-Each is the current object. For example, if you were parsing an array defined as a, b, c with For-Each, $_ on the first run would equal a, on the second run equal b, and on the third run equal c. – root Jul 28 '17 at 1:48
  • *ForEach-Object – root Jul 28 '17 at 18:24
0

A PowerShell way to create a new CSV file would be:

$OutputCSV = "$PSScriptRoot\AddressesChecked.csv"
$InputCSV = "$PSScriptRoot\Addresses.csv"

$IpAddresses = Import-Csv $InputCSV

$IPStatus = ForEach($IP in $IpAddresses.IPAddress) {
    If (Test-Connection $IP -Count 1 -Quiet) {
        [PSCustomObject]@{IPAddress = $IP
                          Status    = "online"}
    } else {
        [PSCustomObject]@{IPAddress = $IP
                          Status    =  "offline"}
    }
}
$IPStatus | Export-Csv $OutputCSV -NoTypeInformation
$IPStatus

Sample Ouput to screen:

> .\SU_1235174.ps1

IPAddress     OnlineStatus
---------     ------------
192.168.1.1   online
192.168.1.60  offline
192.168.1.91  offline
192.168.1.92  offline

To Csv fle:

> gc .\AddressesChecked.csv
"IPAddress","OnlineStatus"
"192.168.1.1","online"
"192.168.1.60 ","offline"
"192.168.1.91 ","offline"
"192.168.1.92 ","offline"
  • I forgot to add the part of the script where I was creating the output file. Added it to OP. – YetAnotherRandomUser Jul 28 '17 at 1:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.