Home > Enterprise >  Powershell get-content question with foreach
Powershell get-content question with foreach

Time:06-22

I am using PowerShell to connect to an API for a load balancer, this is to be able to enable/disable servers within their respective pools.

This script connects to the API and is supposed to pass a JSON body to the API, as well as pool name in the URI

My command looks as below for a single server, in a single pool, in this case:

$poolname = pool1
$json = get-content  -path file.json
Invoke-WebRequest -Uri "https://load.balancer/pool/$poolname"-Method PATCH -Body $json -ContentType "application/json" -Headers $Headers -WebSession $session

Now I need to do this multiple times, for each pool and server in that pool (which happens through the JSON in the body)

I need to update the pool name and the JSON content for the body.

I update the pool name for each pool from the data I have previously collected and created a JSON file from the file name as below:

$location = (Get-ChildItem C:\Users\name\Documents\transform\*).Name 

$action = foreach($name in $location){


    Invoke-WebRequest -Uri "https://load.balancer/pool/$name" -UseBasicParsing -Method PATCH -Body $json -ContentType "application/json" -Headers $Headers -WebSession $session

    } 

This updates the pool name without issue. So I get multiple hits to the API from powershell with each pool name

I also need to give the command, the JSON content from each file in the same location. So I end up with something looking like below:

$action = foreach($name in $location){

    $json = get-content $name
    
    Invoke-WebRequest -Uri "https://load.balancer/pool/$name" -UseBasicParsing -Method PATCH -Body $json -ContentType "application/json" -Headers $Headers -WebSession $session

    } 

When get-content runs, it grabs all of the content from each of the files in the location $name/$location and puts them into one huge array, which is contained in $json, so when the invoke-webrequest runs, it get a lot of JSON pushed to it

What I would like is to be able to do is:

  1. Look at the URI $name (pool name)
  2. Find the file that correlates to the pool name
  3. Use get-content against that file and store that in $json
  4. Pass that $json in the command
  5. loop until it completes

I have tried to copy each item and then run a get-content command against each using both foreach and foreach-object but that doesn’t work.

CodePudding user response:

Get-Content, the way you use it, should get the content of only one file. The reason you see an array is that its default behavior is to parse the file and put each line as an array element. If you don't need that specific behavior, adding the -Raw switch will load the file as a single string and also be more performant.

I could also potentially a problem with the fact you are using the name attribute as the location for your Get-Content call as if you are not in the correct location, you will run into issue. For that reason, you should use the FullName.

That being said, you also want the names for the pool name. Here is a revised sample that do all that.

Also, if the name of your files have an extension (eg: Pool1.txt and your actual pool doesn't, then you will need to take that into account. In this case, just uncomment the $PoolName line and replace $($Item.Name) part in the Invoke-WebRequest with $PoolName.

$location = (Get-ChildItem C:\Users\name\Documents\transform\*) 

$action = foreach ($item in $location) {
  
  $json = get-content $item.FullName -Raw
  #If the file have an extension and the poolname is named after it but without ext.
  #$PoolName = [System.IO.Path]::GetFileNameWithoutExtension($item.name)
  Invoke-WebRequest -Uri "https://load.balancer/pool/$($item.name)" -UseBasicParsing -Method PATCH -Body $json -ContentType "application/json" -Headers $Headers -WebSession $session

} 
  • Related