1

I'm trying to add additional columns when piping output of a command to csv.

the command I'm running is this:

Invoke-RestMethod -Uri $uri"<Request><Login><Username>admin</Username><Password>admin</Password></Login><Set operation='add'><IPHost><Name>$Name</Name><IPFamily>IPv4</IPFamily><HostType>IP</HostType><IPAddress>$IPAddress</IPAddress></IPHost></Set></Request>" | Select-Object -Expand Response | Select-Object -Expand IPHost | Select-Object -Expand Status | Export-csv -Append -Path "C:\Powershell\output.csv"

I get an output as follows in output.csv;

"code","#text"
"200","Configuration applied successfully."

I'd like to append the values of $Name and $IPAddress in columns 3 and 4 but I can't figure out how to do this.

Edit-

I'd like it to look like;

"code","#text"    
"200","Configuration applied successfully.","Server 1","192.168.1.1"

(It's not important that a header is added for these columns)

Edit2 - I'll expand on my explanation here. The code is to add a list of hosts via API to a firewall, this is the full script;

$csv = import-csv C:\Powershell\network.csv


$uri = "https://172.16.16.16:4444/webconsole/APIController?reqxml="


$csv | ForEach-Object {
            $Name = $_.name
            $IPAddress =$_.ipaddress

            Invoke-RestMethod -Uri $uri"<Request><Login><Username>admin</Username><Password>admin</Password></Login><Set operation='add'><IPHost><Name>$Name</Name><IPFamily>IPv4</IPFamily><HostType>IP</HostType><IPAddress>$IPAddress</IPAddress></IPHost></Set></Request>" | Select-Object -Expand Response | Select-Object -Expand IPHost | Select-Object -Expand Status Name, IPAddress | Export-csv -Append -Path "C:\Powershell\output.csv" -NoTypeInformation
            

} 

If I was to run just the original request directly I do;

https://172.16.16.16:4444/webconsole/APIController?reqxml=<Request><Login><Username>admin</Username><Password>admin</Password></Login><Set operation="add"><IPHost><Name>Server1</Name><IPFamily>IPv4</IPFamily><HostType>IP</HostType><IPAddress>192.168.1.1</IPAddress></IPHost></Set></Request>

in the browser, which gives me the following (XML) output;

 <Response APIVersion="1700.1">
 <Login>
 <status>Authentication Successful</status>
 </Login>
 <IPHost transactionid="">
 <Status code="200">Configuration applied successfully.</Status>
 </IPHost>
 </Response>

when I run this through Invoke-RESTMethod, I get the following in the powershell console;

xml                            Response
---                            --------
version="1.0" encoding="UTF-8" Response


PS C:\powershell>

Each iteration of the Select-Object commands expands until reaching the result

Select-Object -Expand Response

gives;

APIVersion Login IPHost
---------- ----- ------
1700.1     Login IPHost


PS C:\powershell>

and

 Select-Object -Expand Response | Select-Object -Expand IPHost

gives;

 transactionid Status
 ------------- ------
               Status

PS C:\powershell>

and finally, the full command;

 Select-Object -Expand Response | Select-Object -Expand IPHost | Select-Object -Expand Status 

gives;

code #text
---- -----
200  Configuration applied successfully.

for each host, which is what I wanted (ie the result of the operation). I then just wanted to export this to an output file, but also with an indication for which IP Host the status applies to. I assumed CSV was the easiest format, perhaps not though?

Hope this is more clear!

Community
  • 1
  • 1
MatF
  • 13
  • 4

2 Answers2

0

What you're trying to do is to combine input information $Name, $IPAddress with the output from an Invoke-RESTMethod call that returns XML and export that combination to a CSV file.

You can achieve this with the help of a single Select-Object call that defines calculated properties:

Assume that $response contains the output from your
Invoke-RestMethod -Uri $uri"<Request>...</Request>" call:

# Use Select-Object to extract the properties of interest and also
# add the input variables $Name and $IPAddress as properties:
$response | Select-Object @{ n='code';      e={ $_.Response.IPHost.Status.code } }, 
                          @{ n='status';    e={ $_.Response.IPHost.Status.InnerText } }, 
                          @{ n='Name';      e={ $Name } }, 
                          @{ n='IPAddress'; e={ $IPAddress } } |
              Export-Csv -NoTypeInformation -Append -Path "C:\Powershell\output.csv" 

The above yields something like:

"code","status","Name","IPAddress"
"200","Configuration applied successfully.","Server1","192.168.1.1"
mklement0
  • 382,024
  • 64
  • 607
  • 775
0

If you are using the foreach loop you could create a pscustomobject and export it:

$csv = Import-Csv C:\Powershell\network.csv
$uri = "https://172.16.16.16:4444/webconsole/APIController?reqxml="

$csv | ForEach-Object {
    $Name = $_.name
    $IPAddress =$_.ipaddress

    $RestMethod = Invoke-RestMethod -Uri $uri"<Request><Login><Username>admin</Username><Password>admin</Password></Login><Set operation='add'><IPHost><Name>$Name</Name><IPFamily>IPv4</IPFamily><HostType>IP</HostType><IPAddress>$IPAddress</IPAddress></IPHost></Set></Request>"

    $Export = [pscustomobject] @{
        'code' = $RestMethod.Response.IPHost.Status.Code
        'text' = $RestMethod.Response.IPHost.Status.text
        'name' = $Name
        'ipaddress' = $IPAddress
    }

    $Export | Export-csv -Append -Path "C:\Powershell\output.csv" -NoTypeInformation 
} 
Shawn Esterman
  • 2,292
  • 1
  • 10
  • 15
  • 1
    thanks for your help :) I will try this way tomorrow too, just to try understand the different method, though I have used the solution provided by mklement0 for now. I still appreciate the answer though! – MatF Apr 06 '18 at 22:27