Reputation: 21
I have a script that obtains that gathers information about a computer then outputs it to a csv file. You can see I have tried multiple approaches to this issue and cannot quite get any of them to work. A fix to this, or a completely different solution would be welcome.
#Objective is to create a csv file with
# "hostname of public IP","public IP","machine name",date,time-24hour
# for example: (note no header in file)
# "97-94-177-139.dhcp.ftwo.tx.charter.com","97.94.177.139","IT-BHOLLING",8/23/2014,06:52:35
# quotes around text fields are an optional objective (helps with some csv import engines)
# some approaches require that the path c:\IP\Working exists (or change lines 46 & 47
# Change line 61 to try each output method
#Variables
# I am defining website url in a variable
$url = "http://checkip.dyndns.com"
# Creating a new .Net Object names a System.Net.Webclient
$webclient = New-Object System.Net.WebClient
# In this new webdownlader object we are telling $webclient to download the url $url
#get public IP address
$Ip = $webclient.DownloadString($url)
# Just a simple text manuplation to get the ipadress form downloaded URL
# If you want to know what it contain try to see the variable $Ip
#$Ip2 = $Ip.ToString()
#$ip3 = $Ip2.Split(" ")
#$ip4 = $ip3[5]
#$ip5 = $ip4.replace("</body>","")
#-- or - do this
$FinalIPAddress = $Ip.ToString().Split(" ")[5].replace("</body>","").replace("</html>","")
#get machine name
$MNme = $env:computername
#Get Hostname from IP address
try {
$Resolved = [system.net.dns]::GetHostEntry($FinalIPAddress)
}
catch {
$Resolved = ((&nslookup $FinalIPAddress)|where {$_ -match "^Name:"}).split(':')[1].trim()
}
#$Qstring = "select * from win32_pingstatus where address=" + """$FinalIPAddress""" + " AND ResolveAddressNames=True"
#$Qstring = "'" + $Qstring + "'"
# $AName = Get-WmiObject -Query $Qstring |
# select ProtocolAddressResolved | ConvertTo-Csv
#$AName = Get-WMIObject -q 'select * from win32_pingstatus where address="97.93.177.138" AND ResolveAddressNames=True'|
# select ProtocolAddressResolved | ConvertTo-Csv
#$AName[2..2].ToString()
$FinalIPAddress = $FinalIPAddress.Replace("`r`n","")
#get date
$GDte = Get-Date -format("G")
$GTme = Get-Date -format("u")
$infile = "C:\IP\Working\" + $MNme + ".txt"
$outfile = "C:\IP\Working\" + $MNme + ".csv"
$Dsplit = $GDte.split(" ")
$Dte = $Dsplit[0]
$Tsplit = $GTme.split(" ")
$Tme = $Tsplit[1].replace("Z","")
#remove previous files
If (Test-Path $infile){
Remove-Item $infile
}
If (Test-Path $outfile){
Remove-Item $outfile
}
#Write accumulated data to a file; modify $CMethod to test each alternate approach to creating csv file
$CMethod = "D"
if ($CMethod -eq "A") {
#this method produces a file that works with Access but not with Excel. Excel sees it as unicode-text
$content = """$Resolved""" + "," + """$FinalIPAddress""" + "," + """$MNme""" + "," + $Dte + "," + $Tme
$content > $outfile
}
if ($CMethod -eq "B") {
#This method produces an empty csv file, with a few tweaks it procudes a file with Length info instead of results
#tried with quotes
$content = """$Resolved""" + " " + """$FinalIPAddress""" + " " + """$MNme""" + " " + $Dte + " " + $Tme
#also tried without quotes
#$content = $Resolved + " " + $FinalIPAddress + " " + $MNme + " " + $Dte + " " + $Tme
$content > $infile
import-csv $infile -delimiter " " | export-csv -NoTypeInformation $outfile
}
If ($CMethod -eq "C") {
$content = """$Resolved""" + " " + """$FinalIPAddress""" + " " + """$MNme""" + " " + $Dte + " " + $Tme
add-content $infile $content
import-csv $infile -delimiter " " | export-csv -NoTypeInformation $outfile
}
if ($CMethod -eq "D") {
#Yet another method, convert to object first
#$content = """$Resolved""" + " " + """$FinalIPAddress""" + " " + """$MNme""" + " " + $Dte + " " + $Tme
#$content = """$Resolved""" + "," + """$FinalIPAddress""" + "," + """$MNme""" + "," + $Dte + "," + $Tme
$content = $Resolved + "," + $FinalIPAddress + "," + $MNme + "," + $Dte + "," + $Tme
$psObject = $null
$psObject = New-Object psobject
$Csplit = $content.Split(",")
#alternate approaches to converting PSobjecdt to csv
foreach($o in $Csplit)
{
Add-Member -InputObject $psobject -MemberType noteproperty -Name $o -Value $o -PassThru
}
$psObject | Export-Csv $outfile -NoTypeInformation
#Add-Member -InputObject $psobject -MemberType noteproperty -Name $Csplit -Value $Csplit
#$psObject | Export-Csv $outfile -NoTypeInformation
}
#echo to console
"Mehtod Choosen = " + $CMethod
$content
$Csplit
"end of the script....."
Upvotes: 2
Views: 8582
Reputation: 2679
I would suggest letting PowerShell do the CSV creation for you. All that you need to do for that is to create a custom object with the properties you're after, then you can use the Export-Csv or ConvertTo-Csv cmdlets. You can also control the encoding used since it sounds like you might be having some encoding issues with the programs that are consuming your CSV. I've modified your code below to create a PSObject. See if this works for you:
$url = "http://checkip.dyndns.com"
$Now = Get-Date
$webclient = New-Object System.Net.WebClient
$ErrorString = "<ERROR>"
$CsvEncoding = "ASCII" # Any encoding from [System.Text.Encoding] should work
$outfile = "C:\IP\Working\{0}.csv" -f $env:computername
If (Test-Path $outfile){
Remove-Item $outfile
}
try {
$Ip = $null
$Ip = $webclient.DownloadString($url)
}
catch {
Write-Warning ("Error getting IP address: {0}" -f $_.Exception.Message)
}
if ($Ip -match ".*IP Address:\s*((\d{1,3}\.){3}\d{1,3}).*") {
$FinalIpAddress = $matches[1]
#Get Hostname from IP address
try {
$Resolved = [system.net.dns]::GetHostEntry($FinalIpAddress) | select -ExpandProperty HostName
}
catch {
try {
$Resolved = ((&nslookup $FinalIpAddress)|where {$_ -match "^Name:"}).split(':')[1].trim()
}
catch {
$Resolved = $ErrorString
Write-Warning ("Error resolving IP address '$FinalIpAddress': {0}" -f $_.Exception.Message)
}
}
}
else {
$FinalIpAddress = $ErrorString
$Resolved = $ErrorString
}
# This won't work as is in PSv2, but a simple mod would fix it:
$ReturnObject = [PSCustomObject] @{
Resolved = $Resolved
FinalIpAddress = $FinalIpAddress
MNme = $env:computername
Dte = $Now.ToShortDateString()
Tme = $Now.ToString("HH:mm:ss")
}
# At this point, you can let PS do all of the work to create a CSV
# Create normal CSV with encoding defined above:
$ReturnObject | Export-Csv -Path $outfile -Encoding $CsvEncoding -NoTypeInformation
# Create a CSV w/o header (this line will actually append a second line to $outfile):
$ReturnObject | ConvertTo-Csv -NoTypeInformation | select -Skip 1 | Out-File -FilePath $outfile -Encoding $CsvEncoding -Append
Upvotes: 1
Reputation: 2208
You can use Add-Content -Path "FilePath" -Value "$Resolved,$FinalIPAddress,$MNme,$Dte,$Tme"
.
Then you have no header and the data seperated with ",".
Upvotes: 2