We help IT Professionals succeed at work.

PowerShell Export NSLooKUp Printer Properties to CSV

JB4375
JB4375 asked
on
I have a PowerShell script that reads a list of IP address in a csv file, performs NSLookUp, and is supposed to output the results to another csv. Ideally, I'd like for the properties that are being returned e.g. Server, Address, Printer Name, and IP to be returned to the individual columns.

Instead it's returning the output window of Primal Script. I've worked with VBScript for a while and I'm trying to make the conversion to PowerShell. So what am I doing wrong?

Thanks in advance,

JB
#Prt_Query_By_IP.ps1

$hostCur = “”
$outfilename = “PrtIP_Out.csv”
“IP,hostname” | Out-File $outfilename -encoding ASCII

foreach ( $obj in $input ) {
if ( $obj -ilike “*address*” ) {
$objCur = $obj.substring($obj.lastindexof(”:”)+3)
Write-Output “$hostCur, $objCur”
“$hostCur, $objCur” | Out-File $outfilename -encoding ASCII -append
}
}
Get-Content ./PrtIP.csv | foreach {$hostCur = $_; nslookup $hostCur}

Open in new window

Comment
Watch Question

steforIT Security Architect

Commented:
Where do you get $input from? You don't declare that here.
When you've looped through $input you use another CSV-file as input than the one you export "IP,Hostname" and if we assume you put something in $input, you also add $hostCur and $objCur to the same file.

Assume you have built a working CSV-file and import that aswell.

Get-Content will read the entire file as unique rows. So a foreach here will tell the script to read everything, which includes the header in your CSV-file.
The first result when running row 14 above will then translate to
nslookup "IP,Hostname"

Open in new window


If you do have a file with a bunch of IP-addresses looking something like this:
IP
10.10.10.10
10.10.10.11
10.10.10.12
10.10.10.13

Open in new window


$CSV = Import-CSV "IPAddresses.csv"
foreach ($Obj in $CSV){
$IP = $Obj.IP
$Hostname = ([System.Net.DNS]::GetHostEntry("$IP")).Hostname
Write-Host "$Hostname - $IP"
}

Open in new window

Author

Commented:
The input is PrtIP.csv and is specified on line 14:
Get-Content ./PrtIP.csv | foreach {$hostCur = $_; nslookup $hostCur}

It's reading the IP addresses that I've specified in the input file, and it's writing the headers to the output file, but it's sending the output to the Primal Script output window as opposed to writing it to the output file.

Any idea why it's doing that?
steforIT Security Architect

Commented:
You need to put it in the right order, and if you want something in $input you need to declare that before using $input.

$Input = Get-Content/Import-csv ...
foreach ($obj in $input){}

Open in new window


This will do something for each row in $input.

Author

Commented:
Sorry about that... Long night and I'd actually made a change since posting. I have the input file declared at the top, and I understand that the data displayed to the output window is coming from the get-content statement.

I've added what you suggested, and tried to send the output with the following but still no results:

#Prt_Query_By_IP.ps1

$hostCur = “”
$input = “PrtIP.csv”
$outfilename = “PrtIP_Out.csv”
“Server,Server IP,Printer,Printer IP” | Out-File $outfilename -encoding ASCII

foreach ( $obj in $input ) {
$IP = $Obj.IP
$Hostname = ([System.Net.DNS]::GetHostEntry("$IP")).Hostname
Write-Host "$Hostname - $IP" | Out-File $outfilename -encoding ASCII -append
}
you have to actually get the content of the CSV file to loop through it, you can't jusy declare $input in a csv file, and then loop through it.

For example create a CSV with this content and save it:

Header1, Header2
Row1-1, Row1-2
Row2-1, Row 2-2

And then call each line like this:

$CSVFileContent = Import-Csv "C:\Temp\file.csv"

foreach ($Line in $CSVFileContent)
{
	Write-Host "New Line"
	Write-Host "Header 1 Value - $($Line.Header1)"
	Write-Host "Header 2 Value - $($Line.Header2)"
}

Open in new window

steforIT Security Architect

Commented:
Ok, so you want the content of PrtIP.csv right, not just the string "PrtIP.csv"
When you say Server,Server IP do you actually want which DNS server responds to your request? As it's probably gonna be the same for the entire script I assume you can do without.

If you want to use the Out-File approach we need to create our own header and then add each new row as we loop through the lines of your script.
I take it you still have it as my above example with a IP for header, so using a Import-CSV seems the logical choice.
# Import the content of PrtIP.csv
$Input = Import-CSV "PrtIP.csv"

# Declare what we want to call the output file.
$Outfilename = "PrtIP_Out.csv"

# Creates an empty array where we can store each result before exporting it.
$Output = @()

# Loop through each line that we call $obj, remember that "IP" is a property of the line, or $obj as we declare below
foreach ($obj in $Input){

   # Set the property into a variable we can relate to, we could just aswell have used $obj.IP in the next bit.
   $IP = $obj.IP

   # We'll call the DNS class of System.Net and use the GetHostEntry method to reverse lookup the name if there's any in DNS
   # and just grab the hostname property of the result back, we'll then store it in a variable
   $Hostname = ([System.Net.DNS]::GetHostEntry($IP)).hostname

   # We create a new empty object where we can store our information.
   $objResult = New-Object System.Object

   # Now we need to store our information in this object.
   $objResult | Add-Member -Membertype Noteproperty -Name "IP" -Value $IP
   $objResult | Add-Member -Membertype Noteproperty -Name "Hostname" -Value $Hostname

   # Then store our new object in our array.
   $Array += $objResult

# End foreach loop.
}

# Now we want to export our result to a file, so we just grab our array, Pipe the properties we want to a Export-CSV command, you can set to use ASCII encoding, but this usually doesn't matter.
$Array | Select-Object IP,Hostname | Export-CSV $Outfilename

Open in new window

Author

Commented:
OK... Now I'm getting the following:
ERROR: Exception calling "GetHostEntry" with "1" argument(s): "Value cannot be null.
ERROR: Parameter name: address"
ERROR: At line:18 char:47
ERROR: +    $Hostname = ([System.Net.DNS]::GetHostEntry <<<< ($IP)).hostname
ERROR:     + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
ERROR:     + FullyQualifiedErrorId : DotNetMethodException
ERROR:

*** PowerShell Script finished. ***
steforIT Security Architect

Commented:
What's in your CSV-file?

Add
Write-Host "This is the value I use: $IP"

Open in new window

to line 15. Is that line empty after use: when you run the script?
If it is then there's an empty line in your csv-file, or the first line in the CSV-file doesn't say "IP" like in my example.

Author

Commented:
All that exists in the CSV are two IP addresses in column one. The first line is now IP.

Adding line 15 as you suggested prints out the IP addresses, followed by:

ERROR: Method invocation failed because [System.Object] doesn't contain a method named
ERROR:  'op_Addition'.
ERROR: At line:28 char:13
ERROR: +    $Array += <<<<  $objResult
ERROR:     + CategoryInfo          : InvalidOperation: (op_Addition:String) [], Runti
ERROR:    meException
ERROR:     + FullyQualifiedErrorId : MethodNotFound

It repeats this error several times.
IT Security Architect
Commented:
bah, I'm so sorry

Instead of array there you should put $output

Author

Commented:
OK... now it runs like lightening, with no errors, but doesn't write anything to the output file. :)
steforIT Security Architect

Commented:
it shouldn't until it's done.

Author

Commented:
Ah... ok.... I see. I changed "$array" to $output on lines 28 AND 34. Works like a champ now.

Author

Commented:
Thanks for all your help and patience, Stefor. Your assistance was above and beyond.

Thanks again,

JB