powershell - dynamic object properties readed from a txt file - file

I have a question, example:
$myxml.SelectSingleNode('//space:XMIS', $space).provider.factories.property.resources[0].name;
I would like to read the properties '.provider.factories.property.resources[0].name' from a text file and assign them to the object.
Can someone help please? I have no idea how to do this dynamically.

Property names can be specified dynamically e.g.:
$date = Get-Date
$prop1 = 'DayOfWeek'
$prop2 = 'value__'
$date.$prop1.$prop2
So read in your dynamic properties from a file and assign each to a variable. This assumes that the depth of properties is the same. That may not work. Another approach is to use XPath for the whole query and then define the XPath in the txt file e.g.:
$ns = #{space = 'http://some-xml-namespace'}
$xpath = Get-Content query.txt -raw
Select-Xml -Xml $myxml -XPath $xpath -Namespace $ns
Content of query.txt
//space:XMIS/space:provider/space:factorties/space:property/space:resources[position()=1]#name
The xpath pattern is just a guess given that I can't see the structure of your xml.

Related

In PowerShell, how can I extract a key-value pair from an array of records?

I am reading data from a CSV file and want to extract the URL value (abc.com, def.com). My simple code returns the data in an array of key-value pairs (see below), but I haven't been able to extract an individual item.
#{Product=a; Description=xyz; URL=abc.com}
#{Product=b; Description=abc; URL=def.com}
I tried indexing into the array, using IndexOf, etc. Any suggestions?
$list = Import-Csv ".\file"
foreach ($item in $list) {
write-host $item
}
Those are not arrays of key-value pairs, but custom objects created from the rows of your CSV.
You can either use PowerShell's property enumeration behavior to grab all values from the URL property of each object:
$allURLs = $list.URL
Or use ForEach-Object -MemberName to grab only a single property value from a collection:
$allURLs = $list |ForEach-Object -MemberName URL
If you need this to run in PowerShell earlier than version 3.0, use Select-Object -ExpandProperty:
$allURLs = $list |Select-Object -ExpandProperty URL

How to build dynamic link list with powershell and WPF?

I have an array of variable length with several website names und corresponding links. I will show them up in a Windows Forms based GUI.
The array will be read from an XML file, but it looks like this
$linklist = #(
("Site 1" , "https://link1.com"),
("Site 2" , "https://link2.com")
)
Then i have a Windows Forms window named "mainform" and create each item in there:
$Link1 = New-Object System.Windows.Forms.LinkLabel
$Link1.Text = $sitename
$Link1.Location = New-Object System.Drawing.Point(40,$calculatedPosition)
$Link1.add_Click({ start $sitelink })
$mainform.Controls.Add($Link1)
That could be done manually for each item in my array - so far, so easy, as log i have a fixed amount of items in my array.
But i like to do it dynamically, to handle arrays with customized content.
I tried to use dynamic variables, because every LinkLabel needs a different variable name.
I know, Dynamic variable names can be created by the New-Variable Cmdlet, but i have no idea, how manage this new variable for building a LinkLabel.
Thank you in advance for all your helpful ideas...
I would first create an ordered Hashtable out of your $linklist array-of-arrays to make things easier:
$linklist = #(
("Site 1" , "https://link1.com"),
("Site 2" , "https://link2.com")
)
# convert the array of arrays into an ordered Hashtable
$linkHash = [ordered]#{}
$linklist | ForEach-Object { $linkHash[$_[0]] = $_[1] }
Using that hashtable, creating the linklabels dynamically is not very hard to do:
$linkHash.GetEnumerator() | ForEach-Object {
$lnk = New-Object System.Windows.Forms.LinkLabel
$lnk.Text = $_.Name # set the name for the label
$lnk.Tag = $_.Value # store the link url inside the control's Tag property
$lnk.Location = New-Object System.Drawing.Point(40, $calculatedPosition)
# inside the scriptblock, $this refers to the LinkLabel control itself
$lnk.Add_Click({ Start-Process $this.Tag })
$mainform.Controls.Add($lnk)
$calculatedPosition += 15 # just a guess, you may want different vertical spacing
}

Extract partial line of text from text file

I need to keep the first 5 characters from data being pulled from a text file.
Data looks like this:
S1831KWT0081
S2004KWT0083
S2351KWT0085
S0054KWT0087
Results should looks like this:
S1831
S2004
S2351
S0054
I can get it working when setting the variable within PowerShell:
PS> $a = "S1831KWT0081"
PS> $a.Substring(0, $a.IndexOf('K'))
S1831
but I'm stuck when trying to pull from a text file.
To solve this, you will need to parse the text file on a line-by-line basis. Basically treating each line as a value in an array.
Get-Content location.txt | foreach { $_.Substring(0, $_.IndexOf('K')) }
Another option would be a regular expression replacement:
(Get-Content 'C:\path\to\input.txt') -replace '^(.{5}).*', '$1'
That would also allow you more specific matches, e.g. like this:
$re = '^([a-z]\d{4}).*'
(Get-Content 'C:\path\to\input.txt') -match $re -replace $re, '$1'
Just to show there always is more than one PoSh way ;-)
gc .\input.txt|%{$_.split('K')[0]}
Or the more verbose version
Get-Content .\input.txt |
ForEach-Object { $_.split('K')[0] }

Invoke-WebRequest : Cannot bind parameter 'Uri'. Cannot convert the "#{

Would like to retrive innerText of a P html element for all the URLS i got listed in a text file. I'm rather newbie for this, but thought i can solve it. Atm. i've failed, as i can't handle how i shall pass each array items for the loop correctly:
$theURLS = Import-CSV linkek_alatt.txt
$item = New-Object System.Collections.ArrayList
for ($i=0; $i -le $theURLS.length;$i++)
{
foreach($item in $theURLS)
{
$Site = Invoke-WebRequest -URI $item
$Igotit = $Site.AllElements | Where-Object {$_.tagName -eq "P"} |
Select -First 1 -Skip 3 -ExpandProperty innerText
$Igotit
}
}
> FilteredContent.txt
The Filtered file shall contain the informations.
For now, i receive a "Invoke-WebRequest : Cannot bind parameter 'Uri'. Cannot convert the "#{" error and i see repeated first URL and a random - the one for next step - one in the error message. Any ideas welcome.
Best regards,
Geza
Per the comments, the issue occurs because you are using Import-CSV here:
$theURLS = Import-CSV linkek_alatt.txt
This attempts to create a PowerShell object by using the first line of text in the file as headers.
If your .txt file is not a .csv file and you want to return an array of strings, instead use Get-Content:
$theURLS = Get-Content linkek_alatt.txt
If your file is a CSV file, then you'll need to reference the property name that matches the header of the URLs when using it in Invoke-WebRequest. E.g if it had a header of "URL":
Invoke-WebRequest -URI $item.URL
But I suspect this is not the case for you.

Combining and modifying objects from an array in powershell to create a new array

I have a csv with columns that contain a user's first name last name. I have firgured out how to import the csv data from each column using:
$firstname = Import-csv .\data.csv | select-object "Employee First Name"
$lastname = Import-csv .\data.csv | select-object "Employee Last Name"
I have also figured out that:
$username=$firstname.substring(0,1)+$lastname
works when using system.string objects. The problem is I need to loop through all of names to create a new column with the username and I get the error
System.Object[]] doesn't contain a method named 'substring'
I thought I could convert to string using $firstname.ToString() but I seem to have botched that. Any help is geatly appreciated as I am still trying to learn powershell.
The error is self expressive $firstname is not a string. $firstname is an array of string.
Try :
$username = ($firstname[0]).substring(0,1)+$lastname[0]
you'd better use :
$employees = Import-csv .\data.csv
foreach ($employee in $employees)
{
$username=($employee.'Employee First Name').substring(0,1)+($employee.'Employee Last Name')
}
Looks like you are trying to make a user name. So i'm not sure why you want to import one column at a time?
But this might work for you.
$names = Import-Csv .\test.csv
$userNames = New-Object 'System.Collections.Generic.List[String]'
foreach ($name in $names)
{
$userNames.Add($($name.firstName.Substring(0,1) + $name.lastName))
}

Resources