Harman Nieves
Harman Nieves

Reputation: 161

beginner Powershell Script Error

To load a text file of 3 ip addresses comma separated values, into an array, and then have the contents in the array changed for every 3rd octet of the ip address, and then exported back to a csv or text file.

##load file to an array
    $ipFileName="C:\Users\HarmanGrewal\Google Drive\win213\assignment2\IP.txt"
    $array1=@()
    $array1=Get-Content $ipFileName -Delimiter ","
#now we have the contents in an array
    $count=0
foreach($i in $array1){
                       $array1[$count] = $array1[$count] -replace "\.\d{1}\.",".2."
                       $count++
                      }
Get-Content $array1 | export-csv -path "C:\Users\HarmanGrewal\test.txt"

A successful exportation of data to a csv file. An empty csv file instead.

Get-Content : Cannot find path 'C:\Users\HarmanGrewal\192.168.2.10,' because it does not exist.
At C:\Users\HarmanGrewal\Google Drive\win213\assignment2\assignment2QuestionAnswer1.ps1:13 char:1
+ Get-Content $array1 | export-csv -path "C:\Users\HarmanGrewal\test.tx …
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (C:\Users\HarmanGrewal\192.168.2.10,:String) [Get-Content], ItemNotFound  Exception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

Get-Content : Cannot find path 'C:\Users\HarmanGrewal\192.168.2.14,' because it does not exist.
At C:\Users\HarmanGrewal\Google Drive\win213\assignment2\assignment2QuestionAnswer1.ps1:13 char:1
+ Get-Content $array1 | export-csv -path "C:\Users\HarmanGrewal\test.tx …
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (C:\Users\HarmanGrewal\192.168.2.14,:String) [Get-Content], ItemNotFound Exception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

Get-Content : Illegal characters in path.
At C:\Users\HarmanGrewal\Google Drive\win213\assignment2\assignment2QuestionAnswer1.ps1:13 char:1
+ Get-Content $array1 | export-csv -path "C:\Users\HarmanGrewal\test.tx …
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (C:\Users\HarmanGrewal\192.168.2.15:String) [Get-Content], ArgumentException
+ FullyQualifiedErrorId : ItemExistsArgumentError,Microsoft.PowerShell.Commands.GetContentCommand

Get-Content : Cannot find path 'C:\Users\HarmanGrewal\192.168.2.15' because it does not exist.
At C:\Users\HarmanGrewal\Google Drive\win213\assignment2\assignment2QuestionAnswer1.ps1:13 char:1
+ Get-Content $array1 | export-csv -path "C:\Users\HarmanGrewal\test.tx …
+ ~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : ObjectNotFound: (C:\Users\HarmanGrewal\192.168.2.15:String) [Get-Content], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetContentCommand

Upvotes: 1

Views: 207

Answers (2)

mklement0
mklement0

Reputation: 437062

# Read the 3 IP addresses from the input file into an array.
# .TrimEnd() ensures that a trailing newline, if any, is stripped (syntax requires PSv3+)
$ips = (Get-Content $ipFileName -Delimiter ",").TrimEnd()

# Replace single-digit IP octets with fixed value 2,
# join the resulting IPs with ',' again, and write to an output file.
$ips -replace '\.\d{1}\.', '.2.' -join ',' | Set-Content "C:\Users\HarmanGrewal\test.txt"

As for what you tried:

$array1=@()
$array1 = ...

$array1=@() is pointless, because the next line assigns to $array1 again, which means that its RHS determines the data type of $array1, irrespective of the previous =@() assignment;
if the Get-Content command happens to return a single value, $array1 will be a scalar; you could prevent that by enclosing the Get-Content command in @(...), the array-subexpression operator, but in PSv3+ that is generally not necessary, due to its unified handling of scalars and collections.

foreach($i in $array1) enumerates the array elements themselves, where $i is a by-value copy of each array element.
Instead of using a separate $count variable to access the elements by reference via their index in order to update them, PowerShell allows you to simply recreate the array as a whole:

$array1 = foreach ($el in $array1) { $el -replace "\.\d{1}\.",".2." }

or, more concisely, relying on the -replace operator's support for array-valued LHS values:

$array1 = $array1 -replace "\.\d{1}\.",".2."

As Harsh Jaswal's answer points out, Get-Content $array1 mistakenly passes intended file contents, whereas what Get-Content expects are filename arguments to read contents from.

Since the values to output - in array $array1 - are already in memory, you can simply send them through the pipeline directly.

Export-Csv operates on the properties of an object, and since you're supplying string objects that only have a .Length property, all that will be exported is that property, which is not the intent.

In the case at hand you have to write a text file directly, using Set-Content, based on constructing CSV-format strings in memory.
Note that Set-Content uses the system's legacy "ANSI" code page by default; use -Encoding <encodingName> to change that.

Upvotes: 1

Harsh Jaswal
Harsh Jaswal

Reputation: 447

The first thing is if you are using foreach here then there is no need of $count variable. And the second thing is in your last line you are passing collection $array1 to Get-Content. It takes the path as a parameter. So it is trying to get the contents of the file stored at $array1, which is not correct. Please modify the code as below.

$ipFileName="C:\Users\HarmanGrewal\Google Drive\win213\assignment2\IP.txt"
$array1=@()
$array1=Get-Content $ipFileName -Delimiter ","
#now we have the contents in an array
foreach($i in $array1){
    $i = $i -replace "\.\d{1}\.",".2."
    $i
}
$array1 | export-csv -path C:\Users\HarmanGrewal\test.txt 

Upvotes: 1

Related Questions