Reads CSV file and Restart listed services on multiple servers based on status

Input File: CSV file which contains 4 columns as below
Time,ServerName,ServiceName,ServiceStatus
3:00:02 AM,Server1,Service1,Stopped
3:00:04 AM,Server2,Service1,Stopped
3:00:04 AM,Server2,Service2,Running
(will contain multiple rows)

  1. I need to read the content of this CSV file and I need to restart the services which are in stopped status on corresponding remote server
  2. Sometime ServerName will not be a valid
  3. Sometime Server may not be pingable
    For these I came up with script
    function RestartService{
    Param(
    [String] $FilePath,
    [String] $Status
    )
    $data = Import-Csv $FilePath | Where-Object{$.ServiceStatus-eq $Status}
    if(Test-Connection -ComputerName $data.ServerName-Count 1){
    Get-Service -ComputerName $data.ServerName-DisplayName $data.ServiceName | Where-Object {$
    .ServiceStatus-eq $Status} | Restart-Service
    }
    }

Example:RestartService -FilePath D:\Test\ServiceFile.csv -ServiceStatus Stopped

I am facing an issue when server is not valid or not pingable. So in that case how I can handle it. If any one server is not pingable or not valid it should not error out instead it should continue to next just by logging error details in file.
The services which are in stopped state need to started parallel on servers, it shouldn’t use any for or foreach to loop through the collection.

Issue: Not able to continue Silently when error occurs with any server or service.

Your issue with the server not pinging is because you are not passing the -Quiet switch, which returns a Boolean value (true\false). Try to name your function with standard naming. Look at this function which can be updated to accept pipeline input and called like:

Import-CSV C:\Test.csv | Restart-SrvService

function Restart-SrvService{
     Param(
         [String]$ServerName,
         [String]$ServiceName,
         [string]$Status
     )
    begin{}
    process{
        
        if(Test-Connection -ComputerName $ServerName -Count 1 -Quiet){
            try{
                $service= Get-Service -ComputerName $ServerName -DisplayName $ServiceName -ErrorAction Stop |
                Where-Object {$_.ServiceStatus-eq $Status}
                $service | Restart-Service -ErrorAction Stop -WhatIf
                $result = "Success"
            }
            catch {
                $result = "Failed. {0}"-f  $_.Exception.Message
            }
        }
        else {
            $result = "Offline"
        }
    }
    end{
        $PSBoundParameters.Add("Result", $result)
        New-Object -TypeName PSObject -Property $PSBoundParameters
    }
 }

Help me understand the logic of your script. You have a csv file that contains servername , service name, and the status of the service.

What is your end state goal? To start there services that are currently stopped, listed in the csv?

Is this cvs being generated by another script or program?

Is the goal to make sure that certain services on certain servers are started?

If the goal is to just make sure that certain services on servers are started, we can get rid of a lot of the logic in your function. You would just need to check to see if the services are stopped and if so start them.

This should get you started, but I would try to figure out exactly what you are trying to accomplish and simplify the code.

In this example it

function RestartService {
Param(
[String] $FilePath,
[String] $Status,
[String] $ErrorFilePath
)

$data = Import-Csv $FilePath | Where-Object{$_.ServiceStatus-eq $Status}
$computer = $data | select -ExpandProperty ServerName

foreach ($d in $data) {
    $computer = $d.ServerName
    $service = $d.ServiceName
    if (Test-Connection $computer -Quiet -Count 1) {
        
        Get-Service -ComputerName $computer -Name $service | Restart-Service
    }
    else {
        Write-Output "Could not connect to $computer" | Out-File -FilePath $ErrorFilePath -Append
    }
  }
}
RestartService -FilePath D:\Test\ServiceFile.csv -ErrorFilePath D:\Test\Error.txt -Status “Stopped"

Rob Simmers example is a much better approach, and he beat me to it by 5 minutes :). Much more flexible, and powershell like allowing you to pipe in the a cvs, or hash table or array into the function.

Thanks Robbie.It helped.

Thanks Rob.As you said i missed -Quiet switch.Thanks lot.It helped.