Compare similar values from hashtable with loop in Powershell - arrays

I have 2 hash tables :
[hashtable]$Localisation = #{
"Macdo" = "OU=France,OU=Paris";
"BurgerKing" = "OU=USA,OU=LA";
"Quick" = "OU=Japan,OU=Tokyo";
}
[hashtable]$Profil = #{
"Big Mac" = "Macdo";
"Whooper" = "BurgerKing";
"Burger" = "Quick, BurgerKing, Macdo";
"Fries" = "BurgerKing, Macdo";
"Coke" = "Quick, Macdo";
"HappyMeal" = "Macdo";
}
I need to get this kind of result:
"Big Mac" = "OU=France,OU=Paris"
"Whooper" = "OU=USA,OU=LA";
"Burger" = "OU=Japan,OU=Tokyo, OU=USA,OU=LA, OU=France,OU=Paris"
"Fries" = "OU=USA,OU=LA, OU=France,OU=Paris";
"Coke" = "OU=Japan,OU=Tokyo, OU=France,OU=Paris";
"HappyMeal" = "OU=France,OU=Paris";
or
Big Mac = OU=France,OU=Paris
Whooper = OU=USA,OU=LA
Burger = OU=Japan,OU=Tokyo,
OU=USA,OU=LA,
OU=France,OU=Paris
Fries = OU=USA,OU=LA,
OU=France,OU=Paris
Coke = OU=Japan,OU=Tokyo,
OU=France,OU=Paris
HappyMeal = OU=France,OU=Paris
I tried :
$tempLoca = #()
foreach ($value in $Profil.values) {
if($Localisation.Contains($value)) {
$tempLoca = $Localisation.Contains($value),$Profil.key
}
}
But I get :
$tempLoca
OU=France,OU=Paris
With my code I have only the last value. I don't know if I need to put my values in array or in hashtable (because they are multiple similar values).
Do you have an idea? Thanks

Try this:
[hashtable]$Localisation = #{
"Macdo" = "OU=France,OU=Paris";
"BurgerKing" = "OU=USA,OU=LA";
"Quick" = "OU=Japan,OU=Tokyo";
}
[hashtable]$Profil = #{
"Big Mac" = "Macdo";
"Whooper" = "BurgerKing";
"Burger" = "Quick, BurgerKing, Macdo";
"Fries" = "BurgerKing, Macdo";
"Coke" = "Quick, Macdo";
"HappyMeal" = "Macdo";
}
$tempLoca = #()
foreach ($key in $Profil.Keys) {
$locals = ($Profil.$key -split ',') | ForEach-Object { $_.Trim() }
$result = #()
foreach ($item in $locals) {
if($Localisation.ContainsKey($item)) {
$result += $Localisation.$item
}
}
$tempLoca += '"{0}" = "{1}"' -f $key, ($result -join '; ')
}
$temploca
It will output
"Big Mac" = "OU=France,OU=Paris"
"HappyMeal" = "OU=France,OU=Paris"
"Burger" = "OU=Japan,OU=Tokyo; OU=USA,OU=LA; OU=France,OU=Paris"
"Whooper" = "OU=USA,OU=LA"
"Fries" = "OU=USA,OU=LA; OU=France,OU=Paris"
"Coke" = "OU=Japan,OU=Tokyo; OU=France,OU=Paris"
Note that I combine the OU values from the $Localisation hash with a semicolon ; to distinct them from the values themselves. If that is not what you want, just replace ($result -join '; ') with ($result -join ', ')

An IMO more PowerShell like way, building a PSCustomObject and grouping it:
$ProfileLocalisation = ForEach ($key in $Profil.Keys) {
ForEach ($local in ($Profil.$key -split ',').Trim() ) {
[PSCustomObject]#{
Profile = $key
Localisation = $Localisation.$local
}
}
}
$ProfileLocalisation
Sample output:
Profile Localisation
------- ------------
Big Mac OU=France,OU=Paris
HappyMeal OU=France,OU=Paris
Burger OU=Japan,OU=Tokyo
Burger OU=USA,OU=LA
Burger OU=France,OU=Paris
Whooper OU=USA,OU=LA
Fries OU=USA,OU=LA
Fries OU=France,OU=Paris
Coke OU=Japan,OU=Tokyo
Coke OU=France,OU=Paris
And grouped:
$ProfileLocalisation | Group-Object Profile | ForEach-Object {
[PSCustomObject]#{
Profile = $_.Name
Localisations = ($_.Group.Localisation -join ';')
}
}
Profile Localisations
------- -------------
Big Mac OU=France,OU=Paris
HappyMeal OU=France,OU=Paris
Burger OU=Japan,OU=Tokyo;OU=USA,OU=LA;OU=France,OU=Paris
Whooper OU=USA,OU=LA
Fries OU=USA,OU=LA;OU=France,OU=Paris
Coke OU=Japan,OU=Tokyo;OU=France,OU=Paris

Related

Copy Azure Storage Table Service data to SQL Server

How can I copy huge amounts of data from Azure Storage Table Service to SQL Server using PowerShell?
AzTable which Microsoft recommends using does not support incremental load without underlying information about partition keys, and the documentation website is down...:
https://learn.microsoft.com/en-us/azure/storage/tables/table-storage-how-to-use-powershell
I am answering this question myself, because I have lots of trouble findind a solution online, and would like to help other people with this crap.
$StorageAccountResourceGroup = "MyResourceGroup"
$StorageAccountName = "MyStorageAccount"
$TableName = "MyStorageTableName"
$SqlConnectionString = "MySqlConnectionString"
$BulkCopy = [System.Data.SqlClient.SqlBulkCopy]::new()
$BulkCopy.DestinationTableName = "[myschema].[mytablename]"
$DataTable = <<Generate datatable from SQL-table>> # Code not included
Connect-AzAccount
$StorageAccountKey = (Get-AzStorageAccountKey -ResourceGroupName $StorageAccountResourceGroup -AccountName $StorageAccountName | Where-Object -FilterScript {$_.KeyName -eq "Key1"}).Value
$Context = New-AzStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey
$CloudTable = (Get-AzStorageTable -Context $Context -Name $TableName).CloudTable
$TableQuery = [Microsoft.Azure.Cosmos.Table.TableQuery]::new()
$Token = $null
BulkCounter = 0
do{
$ReturnObject = $CloudTable.ExecuteQuerySegmented($TableQuery, $Token)
$Token = $ReturnObject.ContinuationToken
foreach($Entry in $ReturnObject){
$Row = $DataTable.NewRow()
foreach($Column in $DataTable.Columns){
if($Column.ColumnName -eq "TimeStamp"){
$Value = $Entry.TimeStamp
} elseif($Column.ColumnName -eq "RowKey"){
$Value = $Entry.RowKey
} elseif($Column.ColumnName -eq "PartitionKey"){
$Value = $Entry.PartitionKey
} else {
if($Column.DataType -eq [System.Decimal]){
$Value = $Entry.Properties.$($Column.ColumnName).DoubleValue
} elseif($Column.DataType -eq [System.String]){
$Value = $Entry.Properties.$($Column.ColumnName).StringValue
} elseif($Column.DataType -eq [System.Guid]){
$Value = $Entry.Properties.$($Column.ColumnName).GuidValue
} elseif($Column.DataType -eq [System.datetimeoffset]){
$Value = $Entry.Properties.$($Column.ColumnName).DateTimeOffsetValue
} elseif($Column.DataType -eq [System.Int32]){
$Value = $Entry.Properties.$($Column.ColumnName).Int32Value
} elseif($Column.DataType -eq [System.Int64]){
$Value = $Entry.Properties.$($Column.ColumnName).Int64Value
} elseif($Column.DataType -eq [System.Boolean]){
$Value = $Entry.Properties.$($Column.ColumnName).BooleanValue
} elseif($Column.DataType -eq [System.Binary]){
$Value = $Entry.Properties.$($Column.ColumnName).BinaryValue
}
}
if([System.String]::IsNullOrWhiteSpace($Value)){
$Value = [System.DBNull]::value
}
$Row.($Column.ColumnName) = $Value
}
$DataTable.Rows.Add($Row)
$Counter++
}
$BulkCounter ++
if($BulkCounter % 25 -eq 0 -and $BulkCounter -ne 0){
$BulkCopy.WriteToServer($Datatable.CreateDataReader()) | Out-Null
$Datatable.Clear() | Out-Null
$BulkCounter = 0
}
} while ($Token)
if($Datatable.rows.count -gt 0){
$BulkCopy.WriteToServer($Datatable.CreateDataReader()) | Out-Null
$Datatable.Clear() | Out-Null
}
Here is also some functions for automatically generating tables from storage account tables:
function ConvertTo-SqlTypeFromEDM {
param (
$EDMType
)
if($EDMType -eq "String"){
return "varchar(100)"
} elseif($EDMType -eq "Guid"){
return "uniqueidentifier"
} elseif ($EDMType -eq "DateTime"){
return "datetimeoffset(0)"
} elseif ($EDMType -eq "Binary"){
return "varbinary(max)"
} elseif ($EDMType -eq "Int32"){
return "int"
} elseif ($EDMType -eq "Int64"){
return "long"
} elseif ($EDMType -eq "Double"){
return "decimal(25,5)"
} elseif ($EDMType -eq "Boolean"){
return "bit"
} else {
throw "Tybe $EDMType not implemented"
}
}
function Get-SqlQueryFromStorageTableSerivce {
param(
$CloudTable,
$SchemaName
)
$Query = [Microsoft.Azure.Cosmos.Table.TableQuery]::new()
$Query.TakeCount = 1
$Token = $null
$Result = $CloudTable.ExecuteQuerySegmented($Query, $Token)
$TableName = $CloudTable.Name
$TableString = "DROP TABLE IF EXISTS [$SchemaName].[$TableName]`n"
$TableString += "CREATE TABLE [$SchemaName].[$TableName] (`n`t"
$ColumnString = #()
$TableKeys = #()
if($Result.PartitionKey){
$ColumnString += "[PartitionKey] varchar(100) NOT NULL"
$TableKeys += "[PartitionKey]"
}
if($Result.RowKey){
$ColumnString += "[RowKey] varchar(100) NOT NULL"
$TableKeys += "[RowKey]"
}
if($Result.Timestamp){
$ColumnString += "[Timestamp] datetimeoffset(0) NULL"
}
foreach($Column in $Result.Properties.Keys){
$ColumnString += "[$Column] $(ConvertTo-SqlTypeFromEDM -EDMType $Result.Properties.$Column.PropertyType) NULL"
}
$TableString += $ColumnString -join ",`n`t"
$TableString += "`nCONSTRAINT [PK_1_$($TableName)_1] PRIMARY KEY CLUSTERED`n"
$TableString += "(`n`t" + ($TableKeys -join ",`n`t")
$TableString += "`n)WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, OPTIMIZE_FOR_SEQUENTIAL_KEY = OFF, DATA_COMPRESSION = PAGE) ON [PRIMARY]"
$TableString += "`n) ON [PRIMARY]`n"
return $TableString
}

Powershell , array1 , Array2 , find String, replace String

Well i want only to know what i Have to do if that what read out (includs like words like "leiter" in Verkaufsabteilungsleiter or Gesamtleitung and save in Variables like MitgliedÄndern2, $Mitgliedlesen2 , $MitgliedÄndern3 , $Mitgliedlesen3 filtered out that this things doesn't generate.
Or It finds things like Verkaufsabteilung-Inland and add there something in String.
So i think to compare two arrays are shorter If i write line for line.
if ($Abt -match "leiter") {$Standortsleitunglesen2 = $Mtl2 + "s" + "leitung" + "-" + "Lesen"}
if ($Abt -match "leiter") {$Standortsleitunglesen2 = $Mtl2 + "s" + "leitung" + "-" + "Lesen"}
if ($Standortsleitunglesen2 -match "Geschäft" ) {$Standortsleitunglesen2 = "" }
So i can set the terms in array2 and i don't need to write lots of lines and type it manualy. I hope you understand it now.
So I think my Solution goes in following direction:
$array = #($MitgliedÄndern2, $Mitgliedlesen2 , $MitgliedÄndern3 , $Mitgliedlesen3)
$array2 = "leiter" , "leitung"
for([int] $i = 0; $i -le ($array.Count -1); $i++)
{
foreach($word in $array2)
{
if($array[$i] -like "*$word*")
{
if ($array[$i] -match $MitgliedÄndern2) { ($MitgliedÄndern2 = "") }
if ($array[$i] -match $Mitgliedlesen2) { ($Mitgliedlesen2 = "") }
if ($array[$i] -match $MitgliedÄndern3) { ($MitgliedÄndern3 = "") }
if ($array[$i] -match $Mitgliedlesen3) { $Mitgliedlesen3 = ""}
$array[$i] = ""
}
}
}
I have a problem in Variables would generate Usernames of a Table of CSV.
CSV: Inhalt
Nummer;Ordner1;Ordner2;Ordner3;Benutzername;;;Beschreibung;Mitglied;Mitglied 2;Gruppenbeschreibung;Gruppenbeschreibung 2
1;Hamburg;Geschäftsleitung;HH-GL;Stefan Berti;;;Standortleiter;GG-H-Geschäftsleiter;;Geschäftsleitung Hamburg;
in array2 i would like to Words that the the loop have to search in array1.
and if he find the string of array2 for example 'leiter' or another word like "Sekretär" in $array1 in $MitgliedÄndern2, $Mitgliedlesen2 , $MitgliedÄndern3 it would be Write "" in $MitgliedÄndern2, $Mitgliedlesen2 , $MitgliedÄndern3.
I have a method that works with an easy array but that method doesn't work in that example.
I'm new in Powershell and have find lots of things out but that. I don't know.
$File=Import-Csv '.\Datenbank\Hamburg.csv' -Delimiter ";" -Encoding UTF8 | foreach-object {
$Mtl1 = ""
$Mtl2 = ""
$Mtl3 = ""
$Org1 = ""
$Org2 = ""
$Org3 = ""
$Nummer = $_.Nummer
$User = ""
$Ordner1 = $_.Ordner1
$Ordner2 = $_.Ordner2
$Ordner3 = $_.Ordner3
$Beschreibung = $_.Gruppenbeschreibung
$Beschreibung2 = $_.Gruppenbeschreibung2
if ($Ordner1 -ne '') {$Org1 = echo HH}
if ($Ordner2 -ne '') {$Org2 = $($_.'Ordner2')}
if ($Ordner3 -ne '') {$Org3 = $($_.'Ordner3')}
$Mtl1 = "$Org1"
$Mtl2 = "$Org1" + "-" + "$Org2"
$Mtl3 = "$Org1" + "-" + "$Org2" + "-" + "$Org3"
#Lesen
$Mitgliedlesen3 = ""
$Mitgliedlesen2 = ""
$MitgliedÄndern3 = ""
$MitgliedÄndern2 = ""
$Bes = $_.Beschreibung
if ($Org3 -ne '') {$Mitgliedlesen3 = $Mtl3 + "-"+ "Lesen"}
if ($Org2 -ne '') {$Mitgliedlesen2 = $Mtl2 + "-" + "Lesen"}
$MitgliedÄndern2 = "Abteilungsleiter"
$Mitgliedlesen2 = "Bundesleiter"
$MitgliedÄndern3 = "Mitarbeiter"
$Mitgliedlesen3 = "Mitarbeiterleiter"
$array = $MitgliedÄndern2, $Mitgliedlesen2 , $MitgliedÄndern3
$array2 = "leiter" , ""
have tested follow things.
#$array3 = (Compare-Object $array2 $array).InputObject
#$Array4 = $Array | where {$_ -match "leiter"}
$result = $array | Where {$array -notContains "leiter"}
#$result = $array1 | ?{$_.Split('=')[0] -in ($array2 | %{$_.Split('=')[0]})}
#$result = compare $Array $Array2 -Property Key -IncludeEqual -ExcludeDifferent -,
Passthru $result
#$Array -like "*$array2*"
#$Array4
#$array3[0..1]
#ForEach ($array in $array2){
#$array -replace "^[$i0 .. $i]$array2",""
#}
..
}
thanks for help.
I had some problems with the characters in your variables so I renamed them.
$MitgliedAndern2 = "Abteilungsleiter"
$Mitgliedlesen2 = "Bunde"
$MitgliedAndern3 = "Mitarbeiter"
$Mitgliedlesen3 = "Mitarbeiterleiter"
$array1 = #($MitgliedAndern2 , $Mitgliedlesen2 , $MitgliedAndern3 , $Mitgliedlesen3)
$array2 = "leiter" , "Sekretär"
"array1 before before script runs: $array1`r"
for([int] $i = 0; $i -le ($array1.Count -1); $i++)
{
foreach($word in $array2)
{
if($array1[$i] -like "*$word*")
{
$array1[$i] = ""
}
}
}
"`rarray1 after script run: $array1`r"
the solution is this is my groundsolution:
$MitgliedÄndern2 = "Abteilungsleiter"
$Mitgliedlesen2 = "Bundespräsident"
$MitgliedÄndern3 = "Mitarbeiter"
$Mitgliedlesen3 = "Mitarbeiterleiter"
$array = #($MitgliedÄndern2, $Mitgliedlesen2 , $MitgliedÄndern3 , $Mitgliedlesen3)
$array2 = "leiter" , "präsident"
"array1 before before script runs: $array`r"
for([int] $i = 0; $i -le ($array.Count -1); $i++)
{
foreach($word in $array2)
{
if($array[$i] -like "*$word*")
{
if ($array[$i] -match $MitgliedÄndern2) { if ($MitgliedÄndern2 -like "*$word*") {$MitgliedÄndern2 = ""}}
if ($array[$i] -match $Mitgliedlesen2) { if ($Mitgliedlesen2 -like "*$word*") {$Mitgliedlesen2 = ""} }
if ($array[$i] -match $MitgliedÄndern3) { if ($MitgliedÄndern3 -like "*$word*") {$MitgliedÄndern3 = ""} }
if ($array[$i] -match $Mitgliedlesen3) { if ($Mitgliedlesen3 -like "*$word*") {$Mitgliedlesen3 = ""} }
$array[$i] = ""
}
}
}
#$array[$i] = ""
"`rarray1 after script run: $array`r"
$MitgliedÄndern2
$Mitgliedlesen2
$MitgliedÄndern3
$Mitgliedlesen3

Display multiple array values in list in Powershell

I have multiple arrays like this:
$arrayList1 = #()
$arrayList2 = #()
$arrayList1 += "james"
$arrayList1 += "henry"
$arrayList1 += "bob"
$arrayList2 += "scott"
$arrayList2 += "john"
$arrayList2 += "meera"
$arrayList2 += "lisa"
$arrayList2 += "joseph"
And i want to display the output like this:
arrayList1
arrayList2
james
scott
henry
john
bob
meera
lisa
joseph
Here is what i tried:
$output = #{}
$output.add('arrayList1',$arrayList)
$output.add('arrayList2',$arrayLis2)
[PSCustomObject]$output
$output
And the output looks like this:
arrayList2
arrayList1
{scott,john,meera,lisa,joseph}
{james,henry,bob}
Note: The array won't have same number of data.
Any suggestions how i can get it in the order i want it?
Thanks
Sanjeev
A concise solution (note: assumes that at least one of the arrays is non-empty):
$arrayList1 = 'james', 'henry', 'bob'
$arrayList2 = 'scott', 'john', 'meera', 'lisa', 'joseph'
foreach ($i in 0..([Math]::Max($arrayList1.Count, $arrayList2.Count)-1)) {
[pscustomobject] #{ arrayList1 = $arrayList1[$i]; arrayList2 = $arrayList2[$i] }
}
The above yields the following, as desired:
arrayList1 arrayList2
---------- ----------
james scott
henry john
bob meera
lisa
joseph
As an aside: The - ultimately rejected - proposal in GitHub issue #14732 suggested enhancing the foreach statement in a way that would have made parallel enumeration more convenient, along the lines of
foreach ($elemFromList1, $elemFromList2 in $arrayList1, $arrayList2) { ... }
Try something like this:
$Boys = "Bob", "Noah", "Liam"
$Girls = "Olivia", "Sophia", "Charlotte", "Emma"
Function Fix-Arrays {
Param(
[Parameter(Mandatory=$True)]
[string[]]$ArrayNames,
[switch]$NoWarnings = $False
)
$ValidArrays,$ItemCounts = #(),#()
$VariableLookup = #{}
ForEach ($Array in $ArrayNames) {
Try {
$VariableData = Get-Variable -Name $Array -ErrorAction Stop
$VariableLookup[$Array] = $VariableData.Value
$ValidArrays += $Array
$ItemCounts += ($VariableData.Value | Measure).Count
}
Catch {
If (!$NoWarnings) {Write-Warning -Message "No variable found for [$Array]"}
}
}
$MaxItemCount = ($ItemCounts | Measure -Maximum).Maximum
$FinalArray = #()
For ($Inc = 0; $Inc -lt $MaxItemCount; $Inc++) {
$FinalObj = New-Object PsObject
ForEach ($Item in $ValidArrays) {
$FinalObj | Add-Member -MemberType NoteProperty -Name $Item -Value $VariableLookup[$Item][$Inc]
}
$FinalArray += $FinalObj
}
$FinalArray
}
Fix-Arrays -ArrayNames "Boys","Girls"
Just edit Fix-Arrays (line 41) and the top two example arrays to suit your needs.

Filter TreeView Nodes in PowerShell

I have a ton of Nodes in my TreeView, and have a textbox that filters through them to highlight the matched search. However, its a bit messy as it shows all the other nodes, and after I change my search, it leaves all nodes expanded.
I am trying to make something like this, https://www.codeproject.com/Tips/1000621/Filtering-and-Hiding-Tree-Nodes-WinForms
But I am using Windows forms / Powershell ISE and seem to struggle with implementing it into my own code.
For closing nodes I tried using things along the line of (Textbox.textlength -eq 0) to trigger a close all nodes function, but that was not working.
Here is what I want it too look like. Left is what I want, Right is what mine looks like.
Here is an example of the search function I am using.
Add-Type -AssemblyName System.Windows.Forms
function GetNodes([System.Windows.Forms.TreeNodeCollection] $nodes)
{
foreach ($n in $nodes) {
$n
GetNodes($n.Nodes)
}
}
$form = New-Object System.Windows.Forms.Form
$form.Text ="Test"
$form.Controls.AddRange(#(
($txt = [System.Windows.Forms.TextBox] #{
Location = [System.Drawing.Point]::new(8, 8);
Width = 100;
}),
($btn = [System.Windows.Forms.Button] #{
Location = [System.Drawing.Point]::new(120, 8);
Width = 50;
Text = "Search";
}),
($tree = [System.Windows.Forms.TreeView] #{
Location = [System.Drawing.Point]::new(8, 40);
Width = 170;
HideSelection = $false
})
))
$form.AcceptButton= $btn
$tree.Nodes.Add("A1", "A1")
$tree.Nodes.Add("A2", "A2")
$tree.Nodes[0].Nodes.Add("A11", "A11")
$tree.Nodes[0].Nodes.Add("A12", "A12")
$tree.Nodes[1].Nodes.Add("A21", "A21")
$tree.Nodes[1].Nodes.Add("A22", "A22")
$btn.Add_Click({param($sender,$e)
$nodes = GetNodes($tree.Nodes)
foreach ($node in $nodes) {
if($node.Text -like $txt.Text){
$tree.SelectedNode = $node
$node.EnsureVisible()
break
}
}
})
$form.ShowDialog() | Out-Null
$form.Dispose()
Assuming you are searching on a data source like a folder structure, this is what I'll do:
Create a function to get list of all directories recursively into a list
Create a function to filter the list of directories and return a list of directories which contain a specific text in their names.
Create a function to populate treeview
create a function to highlight treenode if it contains a specific text
Then in the text-changed event of the textbox, I'll filter and highlight tree:
Here is the code:
Add-Type -AssemblyName System.Windows.Forms
function GetPaths($root)
{
Get-ChildItem $root -Recurse -Directory | % {
$_.FullName.Replace($root, "").Trim("\")}
}
function FilterPaths($paths, $like)
{
$paths | ? {$_ -like "*$like*"} | % {
$i = $_.LastIndexOf("$like", [System.Globalization.CompareOptions]::IgnoreCase)
if($i -gt -1) {
$j = $_.IndexOf("\", $i, [System.Globalization.CompareOptions]::IgnoreCase)
if($j -gt -1) {
$_.SubString(0,$j)
} else {
$_
}
}
}
}
function GetNodes($nodes)
{
foreach ($n in $nodes) {
$n
GetNodes($n.Nodes)
}
}
function HighlightNodes($nodes, $like)
{
if(!$like){ return }
$nodes | ? {$_ -like "*$like*"} | % {
$_.BackColor = "Yellow"
}
}
function PopulateTree($treeView, $paths)
{
$treeView.Nodes.Clear()
foreach ($path in $paths)
{
$lastNode = $null
$subPathAgg = ""
foreach ($subPath in ($path -split '\\'))
{
$subPathAgg += ($subPath + '\')
$nodes = $treeView.Nodes.Find($subPathAgg, $true)
if ($nodes.Length -eq 0) {
if ($lastNode -eq $null) {
$lastNode = $treeView.Nodes.Add($subPathAgg, $subPath)
} else {
$lastNode = $lastNode.Nodes.Add($subPathAgg, $subPath)
}
} else {
$lastNode = $nodes[0]
}
}
}
}
$form = New-Object System.Windows.Forms.Form
$form.Text ="Test"
$form.Controls.AddRange(#(
($txt = [System.Windows.Forms.TextBox] #{
Location = [System.Drawing.Point]::new(8, 8);
Width = $form.ClientSize.Width - 16;
Anchor = [System.Windows.Forms.AnchorStyles]13
}),
($tree = [System.Windows.Forms.TreeView] #{
Location = [System.Drawing.Point]::new(8, 40);
Width = $form.ClientSize.Width - 16;
Anchor = [System.Windows.Forms.AnchorStyles]15
Height = 200;
HideSelection = $false
})
))
$form.AcceptButton= $btn
$root = "C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\IDE\ItemTemplates\CSharp"
$paths = GetPaths $root
PopulateTree $tree $paths
$tree.ExpandAll()
$txt.Add_TextChanged({param($sender,$e)
$tree.BeginUpdate()
$like = $txt.Text
$filtered = FilterPaths $paths $like
PopulateTree $tree $filtered
HighlightNodes (GetNodes $tree.Nodes) $like
$tree.ExpandAll()
$tree.TopNode = $tree.Nodes[0]
$tree.EndUpdate()
})
$form.ShowDialog() | Out-Null
$form.Dispose()

Create an object from an array

I have a string of data which I turn into an array thus:
$cfg_data = #(
"AppName1,data1",
"AppName2,data2"
)
I then run a foreach query to work on each line at a time:
FOREACH($a in $cfg_data)
{
$dataSplit = $a -split"(,)"
$AppN = $dataSplit[0]
$AppD = $dataSplit[2]
#Do stuff here
}
But I want to convert this from a string to an Object, so I can add/remove additional items,
and then run some more foreach statements, updating the different bits as I go.
I have got as far as:
FOREACH($a in $cfg_data)
{
$dataSplit = $a -split"(,)"
$AppN = $dataSplit[0]
$AppD = $dataSplit[2]
$objHere = #(
#{
appItem = "$AppN";
appData = "$AppD";
})
}
But when I check $objHere it just has the last entry in it (AppName2, datat2)
I tried adding:
$b=0
and
$objHere[$b]
but then I get
Array assignment failed because index '1' was out of range.
What is the correct way to do this?
By declaring $objHere in the loop, you overwrite the value on each iteration. You need to initialise an empty array outside the loop and append to it from within the loop:
$objHere = #()
foreach($a in $cfg_data)
{
$dataSplit = $a -split"(,)"
$AppN = $dataSplit[0]
$AppD = $dataSplit[2]
$objHere +=
#{
appItem = "$AppN";
appData = "$AppD";
}
}
In addition, you're not actually creating an object, you're creating a hashtable. If you wanted to create an object instead, you could do this:
$objHere = #()
foreach($a in $cfg_data)
{
$dataSplit = $a -split"(,)"
$AppN = $dataSplit[0]
$AppD = $dataSplit[2]
$objHere += New-Object PSObject -property #{appItem = "$AppN";appData = "$AppD";}
}
Giving:
appItem appData
------- -------
AppName1 data1
AppName2 data2

Resources