urtonbay
urtonbay

Reputation: 23

Use a variable as the verb when calling a cmdlet

I am trying to write a script that will start, stop or restart a service on a remote computer.

I found this:

Start-Service -InputObject $(Get-Service -Computer COMPUTER1 -Name spooler)

and started building my script around it.

This is what I have:

$Action = Read-Host "Start, Stop or Restart service?"
$Serv = Read-Host "Service name?"
$Comp = Read-Host "Computer name?"
"$Action"-Service -InputObject $(Get-Service -Computer "$Comp" -Name "$Serv")

When I run this script I get this error:

At U:\Serv.ps1:4 char:10
+ "$Action"-Service -InputObject $(Get-Service -Computer "$Comp" -Name "$Serv")
+          ~~~~~~~~
Unexpected token '-Service' in expression or statement.
At U:\Serv.ps1:4 char:19
+ "$Action"-Service -InputObject $(Get-Service -Computer "$Comp" -Name "$Serv")
+                   ~~~~~~~~~~~~

I have tried this instead:

$Action = Read-Host "Start, Stop or Restart service?"
$Action = $Action + "-Service"
$Serv = Read-Host "Service name?"
$Comp = Read-Host "Computer name?"
"$Action" -InputObject $(Get-Service -Computer "$Comp" -Name "$Serv")

But I get a similar error:

At U:\Serv.ps1:5 char:11
+ "$Action" -InputObject $(Get-Service -Computer "$Comp" -Name "$Serv")
+           ~~~~~~~~~~~~
Unexpected token '-InputObject' in expression or statement.
At U:\Serv.ps1:5 char:24
+ "$Action" -InputObject $(Get-Service -Computer "$Comp" -Name "$Serv")
+                        ~~
Unexpected token '$(' in expression or statement.
    + CategoryInfo          : ParserError: (:) [], ParseException
    + FullyQualifiedErrorId : UnexpectedToken

    Unexpected token '-InputObject' in expression or statement.
        + CategoryInfo          : ParserError: (:) [], ParseException
        + FullyQualifiedErrorId : UnexpectedToken

How Can I pass the input - "start", "stop" or "restart" to the verb part of the command?

Upvotes: 1

Views: 159

Answers (2)

urtonbay
urtonbay

Reputation: 23

Here's the code:

$message  = 'Manage Services'
$question = 'Start, Stop or Restart service?'
$message
Write-Host
$Comp = Read-Host "Computer name?"
Write-Host
$ListServ = Read-Host "List services on remote computer? y or n"
If ($ListServ -eq "y")
  {
    Get-Service -ComputerName $Comp
  }
Write-Host
$Serv = Read-Host "Service name?"
Write-Host

$choices = New-Object Collections.ObjectModel.Collection[Management.Automation.Host.ChoiceDescription]
$choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&Start'))
$choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList 'Sto&p'))
$choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&Restart'))

$Action = $Host.UI.PromptForChoice($message, $question, $choices, 0)
$svc = Get-Service -ComputerName $Comp -Name $Serv
switch ($Action) {
  0 { $svc | Start-Service }
  1 { $svc | Stop-Service }
  2 { $svc | Restart-Service }
}
$svc

Upvotes: 0

Ansgar Wiechers
Ansgar Wiechers

Reputation: 200213

That's a rather convoluted way of managing services with PowerShell. Consider doing it like this instead:

$Action = Read-Host "Start, Stop or Restart service?"
$Serv   = Read-Host "Service name?"
$Comp   = Read-Host "Computer name?"

$svc = Get-Service -Computer $Comp -Name $Serv
switch ($Action) {
  'Start'   { $svc | Start-Service }
  'Stop'    { $svc | Stop-Service }
  'Restart' { $svc | Restart-Service }
}

If for some reason you must construct the cmdlet name you have to use the call operator (&):

& $Action ...

Without that operator PowerShell won't recognize your string as a cmdlet, but will (try to) print it via Out-Default.

Also, consider using the PromptForChoice() method of the host UI instead of Read-Host:

$message  = 'Manage Services'
$question = 'Start, Stop or Restart service?'

$choices = New-Object Collections.ObjectModel.Collection[Management.Automation.Host.ChoiceDescription]
$choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&Start'))
$choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList 'Sto&p'))
$choices.Add((New-Object Management.Automation.Host.ChoiceDescription -ArgumentList '&Restart'))

$Action = $Host.UI.PromptForChoice($message, $question, $choices, 0)

switch ($Action) {
  0 { $svc | Start-Service }
  1 { $svc | Stop-Service }
  2 { $svc | Restart-Service }
}

Upvotes: 2

Related Questions