Powershell - set Json to variable - json

So I'm making a MySQL query, and one of the columns is a chunk of json that I want to set a particular subset of info to a variable. Wondering if I can condense my code a little. Right now my code is:
$data = Query -Query "select * from TABLE where fqdn = 'testhost.mycompany.com'"
$json = $data.request | ConvertFrom-Json
$WhatIreallyWant = $json.build_request
Can I condense the last two lines? build_request is part of the request json.

You could use a pipeline like this
$WhatIWant = $data.request | ConvertFrom-Json | Select-Object -ExpandProperty build_request
or like suggested by TessellatingHeckler in the comments
$WhatIWant = ($data.request | ConvertFrom-Json).build_request

Related

Powershell variable from HTML table one value

I'm beginner in power shell ( HTML ) and I need some help. I want to get a variable from the McAfee website. In this page there is a table where you can download the latest .dat files.
I only need the version number - now it's 8963 - from the first table ( Download V2 Virus Definition Updates (DATs) ) and this result needs to be saved in a variable because I want to compare it with other variable from another script.
Now I'm able to query all of the tables with all of the data:
$r = Invoke-WebRequest -Uri https://www.mcafee.com/enterprise/en-us/downloads/security-updates.html
$r.parsedhtml.getelementsbytagname("TR") |
% { ( $_.children | ?{ $_.tagName -eq "td"} | % innerText ) }
Write-Host
Unfortunately it's too much information for me, because list all of the data which is in a table.
The retrived data in pic.: data
Thanks for the help.
Well this isn't the cleanest method, but if you expect the first entry to allwayse be the one supplying the Filename of the needed .exe you could use this:
($r.parsedhtml.getelementsbytagname("TR") |% { ( $_.children | ?{ $_.tagName -eq "td"} | % innerText ) } | Select-Object -First 1).Split('xdat')[0]
This basically takes the first String of your query, splits the string on the position of xdat and than takes everything before xdat.
The Output then is 8963.
If you want to do it the more correct way, you should look out for the correct html-attribute to filter for.

Expand Multi-level Powershell nested hash tables from JSON api call

I am having an issue with a JSON API call using Powershell, that returns a multi-level nested array. Using the standard convertfrom-json & convertto-json doesn't give me the full results. I just get a ...
I have done a lot of research on this and found the following link on stack for expanding the nested hash tables, and this is about the best format that I have gotten. For reference, I am trying to insert employee records into SQL Server. I have a JSON function for doing so, and need to get the JSON response in the expanded format. There are some security aspects, that won't allow me to post the actual detail so I am trying to provide an example of some issues that I am having. Keep in mind the response is for 1 employee record out of hundreds overall, and in SQL will be one table with a row per employee.
$json1 = Invoke-webRequest -Uri $Workeruri -Certificate $cert -Headers $WorkerHeader | convertfrom-json
$workers = $json1.workers | select -property *
$workers | format-table Name, #{n='Value'; e={
if ($_.Value -is [Hashtable]) {
$ht = $_.Value
$a = $ht.keys | sort | % { '{0}={1}' -f $_, $ht[$_] }
'{{{0}}}' -f ($a -join ', ')
} else {
$_.Value
}
}}
$workers
I have also tried:
$workers | convertto-json
and
$workers = json1.workers | foreach-object {$_}
The data returned comes back like this:
associateOID : XXXXXXXXXXXXXX
workerID : #{idValue=XXXXXXX}
person : #{governmentIDs=System.Object[]; legalName=; birthDate=0000-00-00; legalAddress=; genderCode=; maritalStatusCode=; socialInsurancePrograms=System.Object[]; tobaccoUserIndicator=False; raceCode=; customFieldGroup=}
workerDates : #{originalHireDate=2015-03-09; terminationDate=2016-03-18}
workerStatus : #{statusCode=}
businessCommunication : #{emails=System.object[]}
workAssignments : {#{itemID=xxxxxx; occupationalclassification=System.Object[]; etc}}
I need it to come back with all of the columns on the left side, utilizing the "AssociateOID" as the key identifier for the individual. I have previously gotten the JSON response to come back completely expanded using this format but it wasn't working with the import into SQL Server or looking very nice like the Google Postman response:
$json1 = Invoke-webRequest -Uri $Workeruri -Certificate $cert -Headers $WorkerHeader | format-list -property *
You mean you want to get a JSON file that all objects/properties are expanded, right? Use the -Depth option of ConvertTo-Json to write a JSON file properly. Default value of -Depth option is 2.
$workers | ConvertTo-Json -Depth 100
Specify the appropriate depth according to your JSON files.

Putting CSV Data as is into a New CSV

I have a CSV file with two columns; Identitiy, and User. the User column contains UserPrincipalNames, and the Identity column contains a name. What I'm trying to do is to take the Userprincipalnames and get the Displayname from them, which I am able to do.
What I can't figure out it how to get each rows Identity (which is already in the csv I imported) to be displayed alongside the newly found Displayname. I'm not using the Identity column to get anything, I just want to display the values again.
The code I'm using is this:
$accounts = ipcsv 'D:\code-folder\small-results.csv'
$accounts | % {
$Identity = $_.Identity
$User = $_.User
Get-MsolUser -UserPrincipalName $User | select Displayname
}
This gets the displayname, but nothing more. I tried placing the $Identity variable in the select, but that didn't work. I feel like there must be a simple solution to this.
For example,a row in the CSV file would look like this
But I want the output to look like this, but the output I'm getting leaves out the Identity, and I don't know how to have it added.
You can make a custom column with Select-Object (select):
$accounts = ipcsv 'D:\code-folder\small-results.csv'
$accounts | % {
$Identity = $_.Identity
$User = $_.User
Get-MsolUser -UserPrincipalName $User | select #{n='Identity';e={$Identity}},Displayname
}
I would create a new PSCustomObjectfor each row and pipe the result to Export-Csv:
$accounts = ipcsv 'D:\code-folder\small-results.csv'
$accounts | % {
[PSCustomObject] #{
Identity = $_.Identity
User = Get-MsolUser -UserPrincipalName $_.User | select Displayname
}
} | Export-Csv -Path 'D:\code-folder\small-results.csv' -NoTypeInformation

Import only select data from json to powershell

I want to Import selected data from Json url and so I can convert it to XML.
I am using following code to import.
(Invoke-RestMethod -URI "http://www.broadbandmap.gov/broadbandmap/broadband/dec2013/wireline?latitude=29.488412&longitude=-98.550208&format=json").Results.wirelineServices.providerName | Select-Object | Format-Table –AutoSize
so I am using .Results.wirelineServices.providerName to pull selected columns from one branch/table.
how can I pull data from .Results.broadbandSource.stateFips also at same time?
Thanks bunch.
Json code screenshot.
follow up question
I think that you should separate out your steps a bit:
$r = Invoke-RestMethod -URI "http://www.broadbandmap.gov/broadbandmap/broadband/dec2013/wireline?latitude=29.488412&longitude=-98.550208&format=json"
$providers = $r.Results.wirelineServices.providerName
$stateFips = $r.Results.broadbandSource.stateFips
Note that in your example, your call to Select-Object is redundant (you're not selecting anything, so it's not changing the input object).
Also, a very important point about Format-Table (and any Format- cmdlet) is that those are for display only so they should always be the last thing you do, if in fact they're needed at all.
The code I've given gives you the information in objects, which you can then work with, filter or, display as needed. I'm not sure how you wanted to use/display it, but since there are multiple providers and only one stateFips value, I might assume that you would apply the Fips value to each provider. Here's an example of that which uses the $stateFips variable we created:
$r.Results.wirelineServices | Select-Object providerName,#{Name='stateFips' ; Expression={ $stateFips }}
And here's an example that uses only the original result $r:
$r.Results.wirelineServices | Select-Object providerName,#{Name='stateFips' ; Expression={ $r.Results.broadbandSource.stateFips }}
The Select-Object computed column syntax
Note that the second column definition looks a bit wonky. It's actually a hashtable that allows you to specify the name of the column, and an expression (a complete code block) whose return value will be the value of the column. It could be spread over multiple lines like this:
$r.Results.wirelineServices | Select-Object providerName,#{
Name = 'stateFips'
Expression = {
$r.Results.broadbandSource.stateFips
}
}
Or you could even create the hashtable as a variable first:
$computed = #{
Name = 'stateFips'
Expression = {
$r.Results.broadbandSource.stateFips
}
}
$r.Results.wirelineServices | Select-Object providerName,$computed
XML?
#Stephen Connolly's answer reminded me that you wanted to make XML out of this. Let's take the above code and assign it to a variable:
$computed = #{
Name = 'stateFips'
Expression = {
$r.Results.broadbandSource.stateFips
}
}
$data = $r.Results.wirelineServices | Select-Object providerName,$computed
Because $data is still an object and wasn't sent through a Format- command, we can still use it!
$xml = $data | ConvertTo-Xml -NoTypeInformation
As his comment also suggested though, we don't know how you wanted the resultant XML to be formatted.
So here's another approach:
Forget the JSON
$r = Invoke-RestMethod -URI "http://www.broadbandmap.gov/broadbandmap/broadband/dec2013/wireline?latitude=29.488412&longitude=-98.550208&format=xml"
Now $r contains XML already. You can filter it out and modify it using XPATH. I won't get into that at the moment unless you think that way would work better for you.
Hope this helps, let me know if I've misunderstood what you're trying to do here.
If you want a composite object try something like
$results = (Invoke-RestMethod -URI "http://www.broadbandmap.gov/broadbandmap/broadband/dec2013/wireline?latitude=29.488412&longitude=-98.550208&format=json")
$obj = $results.Results.wirelineServices
$obj | add-member -type noteproperty -Name StateFips -Value $($results.Results.broadbandSource.stateFips) -PassThru
$obj | convertto-xml -as string

delete the last column from a csv file in powershell

I am new to powershell. Currently we are in need of a poweshell script to compare two large (100000 rows and n columns (n > 300, also column headers are Dates corresponding to each wednesday). The value of n keeps on incrementing each week in the file. We need to compare the files (current week and last week), and need to make sure that the only difference between the two files is the last column.
I have gone through some Forums and Blogs and I could do only Little due to my ignorance.
If there is a way to drop the last column from a csv file in powershell, we may be able to make use of the below script below to compare the previous week's file and the current week's file after droping the last column from current week's file.
It would be really helpful if someone can help me here with your hard earned knowledge
[System.Collections.ArrayList]$file1Array = Get-Content "C:\Risk Management\ref_previous.csv"|Sort-Object
[System.Collections.ArrayList]$file2Array = Get-Content "C:\Risk Management\ref_current.csv"|Sort-Object
$matchingEntries = #()
foreach ($entry in $file1Array) {
if ($file2Array.Contains($entry)) {
$matchingEntries += $entry
}
}
foreach ($entry in $matchingEntries){
$file1Array.Remove($entry)
$file2Array.Remove($entry)
}
Cheers,
Anil
Assuming that the column name you want to exclude is LastCol (adjust to your actual column name):
$previous = Import-csv "C:\Risk Management\ref_previous.csv" | Select-Object -Property * -ExcludeProperty LastCol | Sort-Object;
$current = Import-csv "C:\Risk Management\ref_current.csv" | Sort-Object;
Compare-Object $previous $current;
This will drop the last column from each of the input files and indicate whether the remaining content differs.
Based on the answer that alroc gave, you should be able to get the last column name using a split operation on the first line of the CSV file, and then using that on the -ExcludeProperty parameter.
However, the Compare-Object command on this doesn't work for me, but it does pull back the right data into each variable.
$CurrentFile = "C:\Temp\Current.csv"
$PreviousFile = "C:\Temp\Previous.csv"
$CurrentHeaders = gc $CurrentFile | Select -First 1
$CurrentHeadersSplit = $CurrentHeaders.Split(",")
$LastColumn = $CurrentHeadersSplit[-1] -Replace '"'
$Current = Import-Csv $CurrentFile | Select -Property * -ExcludeProperty $LastColumn | Sort-Object
$Previous = Import-Csv $PreviousFile | Sort-Object
Compare-Object $Current $Previous
The import-csv and export-csv both give the opportunity to exclude columns.
The import-csv has the -header option and you simply name the incoming headers and exclude the last columns header. If there are 10 columns, only name 9. The last column will be excluded.
For export-csv, select the columns you'd like to write out ( |select col1,col2,col3|export-csv... ) and don't select the column you're trying to exclude.