Ike
Ike

Reputation: 11

Creating a CSV file to use for starting services on multiple servers

I have created a tsv file to list Servers and Services as follows: TSV File as follows:

Hostname    Services
=========================
             
Server01    SP4AdminV4,SPTraceV4,SPWriterV4,WAS,W3SVC
Server02    SP4AdminV4,SPTraceV4,SPWriterV4,WAS,W3SVC,SPSearchHostController, OSearch16

PowerShell command

Import-csv C:\ServerServerList.tsv  
$Services = $_.Services -Split ',' 
Start-Service -Computer 'Server01' -Name $Services 

I then get the following error:

Start-Service: Cannot Bind Argument to parameter 'Name' because it is an empty string.
At Line:3 char:43
+ Start-Service -Computer $_.Hostname -Name **$Services**
                                           
+
         +categoryinfo: InvalidData (:) [Start-Service], ParameterBindingValidationException
         +FullyQualifiedErrorId: ParameterArgumentValidationErrorEmptyStringNotAllowed, 
          Microsoft.Powershell.Commands.StartServiceCommand

Upvotes: 1

Views: 138

Answers (2)

Steven
Steven

Reputation: 7087

There are a couple of problems I can spot at a glance. First you don't seem to be assigning $Services correctly. 2nd you Start-Service doesn't have a -ComputerName parameter.

To get around that you can use the use Get-Service in conjunction with Set-Service implicitly using the -InputObject parameter via the pipeline.

Import-csv C:\ServerServerList.tsv -Delimiter "`t" |
ForEach-Object{
    $Services = $_.Services -Split ','
    Get-Service -Computer $_.HostName -Name $Services
} |
Start-Service

I'm assuming this is a Tab separated file as you described. Also assuming the services are listed in such a way to make the split proper.

The loop sends [System.ServiceProcess.ServiceController] objects down the pipeline. Those are bound to the -InputObject parameter. Internally Start-Service uses the .MachineName property to make the change on the remote system.

Warning: Get/Set-Service doesn't always report errors properly in this kind of scenario. The primary obstacle I've encountered is misleading errors and/or silent failures in cases where the operator account doesn't have access to the remote system.

Upvotes: 1

Abraham Zinala
Abraham Zinala

Reputation: 4694

I'm sure there's easier ways to go about this but, here's what I got:

# import csv and save to variable.
$CSV = Import-Csv -Path 'C:\ServerServerList.tsv' 
    
# Use a foreach loop to iterate throw csv 
# one row at a time - assigning the current iteration to $Row.
    foreach ($Row in $CSV) {

        # Split services into an array
        $Services = ($Row.Services -split ',').Trim()
        
        # Invoke the start-service call due to it not 
        # having it's own -ComputerName parameter to work with.+
        Invoke-Command -ScriptBlock {

            # Start the service using the newly created array of $Services.
            # Note: we must use a *Remote Variable* to pass over our local variable
            # by specifying the $using: keyword.
            Start-Service -Name $using:Services -PassThru -WhatIf

        } -ComputerName $Row.Hostname

    }

- This is untested -

Upvotes: 0

Related Questions