Powershell Quotes - powershell

I am trying to play around with echoing out specific path of a file using a csv file with input to use as variable.
So far I got something as simple as this,
$input = Import-Csv 'C:\Folder\file.csv' -Header "User"
echo 'C:\Users\User\Desktop\folder\'$input.User'.txt'
The output is
C:C:\Users\User\Desktop\folder\
Tom
.txt
My desired output is:
C:\Users\User\Desktop\folder\Tom.txt
How would I do something like that?

In addition to my comment, you can utilize a string subexpression to accomplish your goal (note double-quotes as single-quotes indicate a string literal which do not expand variables):
$csv = Import-Csv -Path C:\Folder\file.csv -Header User
foreach ($row in $csv)
{
"C:\Users\User\Desktop\folder\$($row.User).txt"
}
Or string concatenation:
'C:\Users\User\Desktop\folder\' + $row.User + '.txt'
Or string formatter (this method takes an array of arguments to the -f operator; useful article):
'C:\Users\User\Desktop\folder\{0}.txt' -f $row.User
Or variable expansion:
$user = $row.User
"C:\Users\User\Desktop\folder\$user.txt"
footnote: using echo (alias for Write-Output) is unnecessary since any output not "captured" (by using redirection or variable assignment) will be output to the success stream (i.e., the console). See this document about streams and redirection.

Related

Powershell 5.1 prepending $line variable to the result before appending (>>) to .csv

In powershell 5.1, my foreach loop appends data from myProgram to data.csv, using the append syntax, (>>). The code below successfully appends/writes the result of my getData --query to the data.csv file.
I want/need a small change to the generation of data.csv;
I want/need the $line variable and "/" merged into the beginning of each line of data.csv. How can this be solved?
generation code (data.csv):
foreach($line in Get-Content -Path .\Folders.txt){$scrpt = 'myProgram getData --query "select key from datatable where key =''$line'')" --resultformat=csv >> data.csv'; Invoke-Expression $scrpt `
} `;
Expected result (data.csv)
$line/data
$line/data
$line/data
Actual result (data.csv):
data
data
data
I solved this by making use of the $_ concept in powershell.
foreach($line in Get-Content -Path .\Folders.txt){$scrpt = 'myProgram getData --query "select key from datatable where key =''$line'')" --resultformat=csv |foreach {$line+"/"+$_} >> data.csv'; Invoke-Expression $scrpt `
} `;

Converting string with object layout to object

Some objects has been saved to a txt.file
looking like this:
#{flightNumber=01; flightDate=2010-01-10; flightIdentification=201001}
#{flightNumber=01; flightDate=2010-01-10; flightIdentification=201002}
and I'm trying to read them in another program and convert them back into objects. What bothers me is that it understands each of the "objects" as a string and I have been unable to cast it into an object.
$list = Get-Content -Path 'C:\Users\XXXXX\Downloads\TemplateObject.txt'
foreach (#object in $list) {
Write-Host $object.flightNumber
}
From what I've shown, I would expect to see 2 different objects with the variables flightNumber, flightDate and flightIdentification
I've tried piping it by using ConvertFrom-StringData
I've tried casting to an object
I expect 2 separate objects containing 3 variables in each.
Don't pipe objects directly to files!
As has been pointed out, take advantage of built-in options for serialization to disk, like ConvertTo-Csv/Export-Csv for flat objects, ConvertTo-Json or Export-Clixml for more complex objects.
As a one-off thing, if you need to recover and re-encode this data, you could use the regex -replace operator to add quotes around the values, at which point the parser should accept them as hashtable entries and you can cast it to an object:
$string = '#{flightNumber=01; flightDate=2010-01-10; flightIdentification=201001}'
# Place double-quotes around anything found between a `=` and `;` or `}`
$quotedString = $string -replace '(?<=\=)([^=;}]+)(?=\s*(?:;|}))', '"$1"'
# Parse the resulting string as if it was PowerShell code
$errors = #()
$objectAST = [System.Management.Automation.Language.Parser]::ParseInput($quotedString, [ref]$null,[ref]$errors)
$objects = if(-not $errors){
# This is pretty dangerous, you should NEVER do this in a production script
$objectAST.GetScriptBlock.Invoke() |ForEach-Object {
[pscustomobject]$_
}
}
# This variable now contains the re-animated objects
$objects
You can convert a string to a hashtable using convertfrom-stringdata after some manipulation:
$a = '#{flightNumber=01; flightDate=2010-01-10; flightIdentification=201001}'
$a = $a -replace '#{' -replace '}' -replace ';',"`n" | ConvertFrom-StringData
[pscustomobject]$a
flightNumber flightIdentification flightDate
------------ -------------------- ----------
01 201001 2010-01-10

GeoJson Powershell

I have a geojson file that needs to be submitted to an API. I am modifying a preexisting powershell script to execute this query but I am having trouble getting the geojson to parse correctly in the query string to pass to the API. Powershell is not my language at all but I've been able to get it to read the geojson. My print statement in my code looks like this:
$inputjson = Get-Content -Raw -Path C:/path/to/file.geojson | ConvertFrom-Json
Foreach ($feature in $inputjson.features){
$gjson = $feature.geometry
Write-Host $gjson
My output is then:
#{type=Polygon; coordinates=System.Object[]}
I have tried ToString() or even casting $gjson as string to try and force this to read as it appears in the file. In python I can do this easily enough but this is a complex script I don't have the time to rewrite from scratch. How do I get this to translate to string correctly? What exactly does that '#' decorator connote in json subfield in Powershell?
The point is that GeoJSON is not a flat object. This means that you have to (recursively) iterate through each embedded object to get each containing subitem:
$inputjson = Get-Content -Raw -Path C:/path/to/file.geojson | ConvertFrom-Json
Foreach ($feature in $inputjson.features){
$gjson = $feature.geometry
Write-Host "Type = " $gjson.Type
Foreach ($coordinate in $coordinates){
Write-Host "coordinate = " $coordinate
Maybe this will help you: $inputjson | Flatten, see: https://stackoverflow.com/a/46081131/1701026
#{key=value} is an hashtable
it's not clear what you are trying to achieve, maybe you want to reconvert ypur geometry to json ?
if so
$feature.geometry | ConvertTo-Json
is what you need

How to append last field of a line in a file to a variable on powershell cli?

Here is my file hello.txt:
"ReceiptHandle" = "hellomyfriend==++"
I would like to append only the last field of a line to a variable:
$friend = hellomyfriend==++
Assuming that is all that's in your hello.txt file. The following would assign "" to your $friend variable...
$myhash = (gc 'hello.txt') -replace """","" | ConvertFrom-StringData
$friend = $myhash["ReceiptHandle"]
ConvertFrom-StringData makes this easy because your text is already in "something = value" format.
So what's going on here? First,
gc 'hello.txt'
is getting the contents of your file. I encapsulate it in () so that i can use..
-replace """",""
.. to get rid of the surrounding double-quotes. That's piped into ConvertFrom-StringData, which converts the string into a named key/value pair [hashtable]. From there, I can access the second part by interrogating the hashtable.
Alternatively, you could put this all on one line...
(gc 'hello.txt') -replace """","" | ConvertFrom-StringData | %{$friend = $_["ReceiptHandle"]}

Powershell to read some strings from each line

I have a requirement like:
Have a text file containing the following in the following pattern
172.26.xxy.zxy:Administrator:Password
172.26.xxy.yyx:Administrator:Password
172.26.xxy.yyy:Administrator:Password
172.26.xxy.yxy:Administrator:Password
I need my powershell script to read each word and use that word whereever required. For example,
foreach(something)
{
I want the IP's(172.26.---.---) to read and store the value as a variable.
I want to store the two words after **:** in seperate variables.
}
How can this be done? I know to read an entire file or get some specific string. But I need the same to be done on each line.Any help would be really appreciated.
Something like this? You can just split on the : and then store your variables based on the index
$contents = Get-Content C:\your\file.txt
foreach($line in $contents) {
$s = $line -split ':'
$ip = $s[0]
$user = $s[1]
$pass = $s[2]
write-host $ip $user $pass
}
minor edit: "t" missing in content.
You can write a regular expression to replace to remove the parts you do not need
$ip_address= '172.26.xxy.zxy:Administrator:Password' -replace '^(.+):(.+):(.+)$','$1'
$user= '172.26.xxy.zxy:Administrator:Password' -replace '^(.+):(.+):(.+)$','$2'
$pwd= '172.26.xxy.zxy:Administrator:Password' -replace '^(.+):(.+):(.+)$','$3'
I think the more generic and pure Powershell way would be something like this:
Select-String "(.*):(.*):(.*)" c:\file.txt |
Select #{Name="IP"; Expression = {$_.Matches.Groups[1]}},
#{Name="User"; Expression = {$_.Matches.Groups[2]}},
#{Name="Password"; Expression = {$_.Matches.Groups[3]}}
The Output would be then an array of objects each having three properties IP, User and Password. So you can now use them for your purposes, or just add more commands at the end of the pipe.