How to create an array from a file in Powershell? - arrays

I want to read a file and load all its content to an array, one file line= one array member. from a weird reason- I don't manage to do it, it keep "merging" all the lines into 1 line.
I tried few ways-
1) Fetch the file content to list, and then
`$FilesList = New-Object System.Collections.Generic.List[String]
foreach($line in Get-Content $OutputFileName) {
$FilesList.Add($line)
}
This gives me good list, but then-
[String[]]$FilesArray = $FilesList.ToArray();
And I receive for-
$FilesArray[0] -> line1 line2 [0]
$FilesArray[1] -> line1 line2 [1]
2) Using the solution-
[string[]]$arrayFromFile = Get-Content -Path $OutputFileName
$arrayFromFile = [string[]](Get-Content -Path $OutputFileName)
Same result when printing $arrayFromFile[0] and $arrayFromFile[1]
3) Using the solution -
[String[]]$arrayFromFile = [IO.File]::ReadAllLines($OutputFileName)
Same result when printing $arrayFromFile[0] and $arrayFromFile[1]
What am I doing wrong, How can it be that I can create a list but not an array?
The problem is that I need to allow the client to choose between the values, so it is important to me to receive array that I can choose specific location

OK, found the problem. nothing to do with the array.
The problem was that the Write-Output can not receive as a parameter "$array[index]", it then prints the full array, and then the index itself.

Related

[array]::Reverse() method not working on Get-Content return object

I am writing a script to install/uninstall a collection of software. Some of this software must be installed before others, and when uninstalling they need to go in reverse order. I am attempting to design this script to read a text file containing the paths to all of the .msi files. This way I can read them with Get-Content in appropriate order, then if they need to be uninstalled I can read the same file and just reverse the array.
I'm new to powershell, but it's my understanding that get-object returns an object of type [array]. Microsoft's documentation on Get-Content doesn't specify a return type but every discussion of Get-Content on stack overflow describes the output as an array.
Here's the problem:
When I store the output of Get-Content to a variable $data = Get-Content -Path "C:\my\data.txt" then I print what's stored in $data write-host $data I get the expected output:
line 1
line 2
line 3
etc...
However
When I try to reverse $data = [array]::Reverse($data). It returns null
When I manually create an array $letters = #("a","b","c") and reverse it $letters = [array]::reverse($letters) then the out put of write-host $letters is, as expected:
c
b
a
Here's the question
Why is my call to [array]::reverse($data) returning null? instead of doing as I would expect in my latter example [array]::reverse($letters)?
NOTE: the only difference between those two examples is how I created the array. So either the return type of get-content is not an array, or their is something uniquely different about the returned array that I am missing.
The [array]::reverse() method does not output the array in reverse, it simply reverses it in place, so given:
$x = 'A','B','C'
[array]::reverse($x)
$x
That will output:
C
B
A
If you want to have a second variable that is a reverse of an existing array you can clone the array to the second variable, and then reverse the array contained in the second variable:
$x = 'A','B','C'
$y = $x.clone()
[array]::reverse($y)
At this point $x = 'A', 'B', 'C' while $y = 'C', 'B', 'A'.
I thought I would share that I was able to accomplish my goal using a different line of code.
$data = ($data[($data.Length-1)..0])
This reversed my Get-Content return object. But it doesn't answer my question why the reverse method returns null.

Compare Elements in Array for While Loop - Powershell

I am attempting to create a script to read a CSV, then perform some operations on the contents where the first field are similar. Right now I'm stuck on trying to set up the second While loop to compare the current element to the next one.
I'm fairly new to this, because I wasn't getting anywhere trying this in Java. I can't seem to find a combination of commands that will let the loop work.
Some things I've tried are:
While($csv[$count].ip -eq $csv[$count++].ip)
While((diff $csv[count].ip $csv[$count++].ip) = true)
While($csv[$count].ip = $csv[$count++].ip)
Don't use $count++ unless you want to actually change the value of $count itself. Instead use $count + 1 as the array index
$count = 0
while($count -le $csv.Count){
if($csv[$count].ip -eq $csv[$count + 1].ip){
# Do your stuff here
}
$count++
}

PowerShell read Excel cells in a array and create xml doument?

I use an array reading Excel content which should be used to create an xml file, but have troubles to allocate the array values to the write xml statements.
Code of the array:
# Parse Excel columns A and B and store it in array "$headerInit"
for ($j=1; $j -le $rowMax-1; $j++)
{
$Obj = New-Object Psobject -Property #{
Value = $ws.Cells.Item($j,2).text
Header = $ws.Cells.Item($j,1).text
No = $j
}
$DataArray.add($obj) # Visualize the array content
}
$DataArray | Out-Gridview
Example of the array content:
No Header Value
...
12 Address 1234,0x3030
...
Here the code excerpt to create the xml document (values "1234" and "0x3030" are insert manually, but should be allocated from the array $DataArray):
...
# Write node <address1>
$xmlWriter.WriteStartElement('address1')
$xmlWriter.WriteAttributeString('address','1234')
$xmlWriter.WriteEndElement() # <-- Closing the node <address1>
# Write node <address2>
$xmlWriter.WriteStartElement('address2')
$xmlWriter.WriteAttributeString('address','0x3030')
$xmlWriter.WriteEndElement() # <-- Closing the node <address2>
...
How can I allocate the 2 values, divided by comma "1234,0x3030" from the array $DataArray, Header "Address" in the create xml statement? Any help is appreciated - Thanks.
Meanwhile I have solved the issue seperating the 2 values devided by comma.
Solution is:
$a,$b = $DataArray[12].Value.split(',')
Is there any easy way to alocate the values direct to the write xml statement without additional variables?
As you've found from my suggestion, you can use Split to separate the two values you want:
$addressLeft,$addressRight = $DataArray[12].Value.Split(',')
You can also reference the seperate parts of the split directly, as Split creates an array you can use the index number to access each element:
$DataArray[12].Value.split(',')[0]
$DataArray[12].Value.split(',')[1]
The other option is to split the value into two propertys when you build $DataArray:
$Obj = New-Object Psobject -Property #{
Value = $ws.Cells.Item($j,2).text
addressLeft = $ws.Cells.Item($j,2).text.Split(',')[0]
addressRight = $ws.Cells.Item($j,2).text.Split(',')[1]
Header = $ws.Cells.Item($j,1).text
No = $j
}
I've left the original Value property in, but you could remove it if you only want the split values.

Get specific value from text and insert in array, then compare on it

I'm new to Powershell and I'm trying to make a script in order to extract some data and then launch a command.
Here is the deal:
I have an application that sometimes goes in error (I have to look in the log file) with a specific error code (always the same) and in the same line I have an "ID", the IDT.
So my problem is:
I have to take a look in this log file every 5 minutes and search for the error code CFTT82E and in this line to get the value of my IDT that is numeric, here what looks like the line:
14/01/15 12:20:06 CFTT82E transfer aborted IDTU=A0009L7Q PART=DGISSL IDF=LKEMDDIB IDT=A1512489 730 ABO 215>
Once I got the value in a variable, I have to wait 5 more minutes and then to launch a command by using the value of my IDT, that is to say:
cmd -toto $IDT_value
Now, once the command succeeded (I have to compare only with CFTR12I code AND my IDT value), I will have a message like that:
14/01/15 15:48:39 CFTR12I END Treated for USER Système PART=DGISSL IDF=* IDT=A1512489>
At this moment, I'll exit, else, I'll relaunch the same command.
But, as this script should work in Loop every 5 minutes, the next time that I'll parse the log file, I should ignore the IDT that I already used before.
I thought to make an array with the daily IDT values (at the end of the date we could empty the array or the variable or whatever this object will be) and then compare the values at every loop.
I already started with this but as I'm newbie,I think that I didn't make a good start :
clear
Get-Content C:\CFT\LOG2014011523590001 |
foreach {
$line = $_.Trim()
If ($line.Contains('CFTT82E')) {
$str = $line.Split(' ')
$TIDT = [ordered]#{
IDT = $_.SubString(101)
}
New-Object PsObject -Property $TIDT
}
} | Out-String
I know that I ask a lot but, any suggestion is welcome.
This may help you. Create an ArrayList for finding stored values then look at your file. Do something with IDT if it's not in the list, then add it to the list so it will be ignored on subsequent runs.
$list = New-Object System.Collections.ArrayList
while (1) {
$content = get-content "C:\your\file.txt"
foreach ($line in $content) {
if ($line -match "CFTT82E.*IDT=(.+?)\b.*") {
$idt = $matches[1]
if(!$list.contains($idt) {
#
# Do whatever you need to do with $idt
#
$list.add($idt)
}
}
}
sleep -Seconds(5*60)
}

Read values from INI file into string array

I have decided to have an accompanying .ini file with an executable so that I do not have to hard code items that appear in a drop down menu. I have created the .ini file and using the IniReadSection function I have been able to look through the section and output each Key=Value pair within that section.
How would I go about placing the value's only into a string array? I am writing this utility using AutoIT.
I made this ini file:
[JHamill]
key1=value1
key2=value2
key3=value3
I took a bit of code from IniReadSection example and modified this to be able to use it for a drop down menu.
$var = IniReadSection("test.ini", "JHamill")
$str = ""
For $i = 1 To $var[0][0]
$str &= $var[$i][1] & "|"
Next
$str = StringTrimRight($str, 1)
GUICreate("JHamill GUI combo")
GUICtrlCreateCombo("", 10, 10)
GUICtrlSetData(-1, $str)
GUISetState()
While 1
$msg = GUIGetMsg()
If $msg = -3 Then ExitLoop
WEnd
Here you see you don't have to make a new array to make it work. But since you asked, here is the same thing by making a new array first, copying only the value elements, and then using that array to fill the combo box:
#include <Array.au3>
$var = IniReadSection("test.ini", "JHamill")
Local $arr[$var[0][0]]
For $i = 1 To $var[0][0]
$arr[$i-1] = $var[$i][1]
Next
_ArrayDisplay($arr)

Resources