Feeding the data from a CSV into a foreach loop

This topic contains 4 replies, has 3 voices, and was last updated by Profile photo of Anthony Anthony 1 month, 3 weeks ago.

Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
    Posts
  • #48757
    Profile photo of Sanjay Luintel
    Sanjay Luintel
    Participant

    I am writing a script that has to get the list of the servers and some services from a CSV file, and change the serviceaccount passwords. The script looks more or less like :

    <

    $csvimports = import-csv $folder\services.csv
    foreach($csvimport in $csvimports)
    {
    "change serviceaccount password for these services"
    }
    >

    However, since, I have more than 100 servers the script has to loop through and more than 600 services that it needs to change the password for and then restart, it's taking the script hours to run as it goes through one item at a time from the list.

    Is it possible to tell the script to pick up multiple items at the same time and run it for may be 3 or may be even more servers are the same time?

    Thanks,
    Sanjaya

    #48775
    Profile photo of Anthony
    Anthony
    Participant

    You could take a look in to opening remote sessions on the servers and starting a bunch of jobs and moving on. The job will run in the background then at the end of your foreach you can then do some logic to check if it completed successfully or not. Something like this:

    $csv = Import-Csv -Path C:\temp\AWSPortTests.csv
    $creds = Get-Credential
    foreach ($item in $csv) 
    {
      $session = New-PSSession -ComputerName $item -Credential $creds
      Invoke-Command -Session $session -ScriptBlock {
        Start-Job -ScriptBlock {
          input job to start here
        }
      }
    }
    
    $remotesessions = Get-PSSession
    foreach ($item in $remotesessions) 
    {
      $session = Get-PSSession $item.computername
      $jobstatus = Invoke-Command -Session $session -ScriptBlock {
        Get-Job
      }
      foreach ($job in $jobstatus) 
      {
        if ($jobstatus -eq 'Completed') 
        {
          'do something'
        }
        else 
        {
          'fix it'
        }
      }
      Get-PSSession $item.computername | Remove-PSSession
    }
    
    • This reply was modified 1 month, 4 weeks ago by Profile photo of Anthony Anthony.
    • This reply was modified 1 month, 4 weeks ago by Profile photo of Anthony Anthony.
    #48781
    Profile photo of Jonathan Warnken
    Jonathan Warnken
    Participant

    + 1 for Anthony
    Not only will the jobs allow you to do more servers at the same time but it moves the "work" from your pc to the server where the change is occurring.

    #49008
    Profile photo of Sanjay Luintel
    Sanjay Luintel
    Participant

    Hi Anthony,
    Thanks for the tip. It works like a charm. However, creating PSSSesions require me to enable winrm listeners on all the target servers and that might be too much to ask in production. Is there any other way that this problem can be handled?

    #49036
    Profile photo of Anthony
    Anthony
    Participant

    How were you doing it before? I'm assuming since the winrm listener isn't setup on some of your servers you are just loading the script up locally on each server and just executing it then letting it run through the foreach loop? If so you can still use jobs just without the remote sessions.

    Using your example

    $csvimports = import-csv $folder\services.csv
    foreach($csvimport in $csvimports)
    {
        Start-Job -ScriptBlock {
          "change serviceaccount password for these services"
        } 
    }
    • This reply was modified 1 month, 3 weeks ago by Profile photo of Anthony Anthony.
Viewing 5 posts - 1 through 5 (of 5 total)

You must be logged in to reply to this topic.