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

This topic contains 5 replies, has 3 voices, and was last updated by  Ramachandran Chakkravarthi 2 years, 3 months ago.

  • Author
    Posts
  • #28867

    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.

  • #28869

    Rob Simmers
    Participant

    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
        }
     }
    
  • #28871

    Robbie Courtney
    Participant

    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"

  • #28872

    Robbie Courtney
    Participant

    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.

  • #28896

    Thanks Robbie.It helped.

  • #28897

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

You must be logged in to reply to this topic.