This is going to be a short post. I know I’ve already posted about using fzf with PowerShell, but I got carried away by own call to action in the last one. So here’s one more cool thing using fzf.

One thing I do a lot of is logging onto my UAT app server just to check if services are up, or to change the configuration for a service or just to restart one. I need to do this often enough for it to be a pain - a usecase ripe for optimization.

This function has two parts to it:

  • Show me all the services on a remote machine and interactively let me select the ones I want to operate on.

  • Show me a list of operations I can perform on them and let me pick one.

Function Invoke-ServiceManager() {
  param(
    [Parameter()]
    [String] $ComputerName = 'localhost'
  )

  # get all services on the machine
  $services = Get-Service -ComputerName $ComputerName `
    | ForEach-Object { "$($_.Status) | $($_.DisplayName)" }

  $previewCommand = @"
    echo Viewing services on: $computerName && echo `"==========================================================`"
"@

  # interactively select a set of those services
  $selectedServices = $services `
    | Invoke-Fzf -Multi -Bind 'ctrl-a:select-all,ctrl-d:deselect-all,ctrl-t:toggle-all' -Preview $previewCommand `
    | ForEach-Object { $_.Split('|')[1].Trim() }

  if($null -eq $selectedServices) { Return }

  # select an operation to perform on those services (preview shows the previously selected list)
  $previewCommand = "$previewCommand && echo [X] " + [String]::Join('&& echo [X] ', $selectedServices)
  $selectedOperation = @('NoOperation','Start','Stop','Restart') | Invoke-Fzf -Exact -Preview $previewCommand

  if($null -eq $selectedOperation) { Return }

  # perform the operation on all the services
  switch($selectedOperation) {
    'NoOperation' {
      # nothing to do here
    }
    'Start' {
      $selectedServices | ForEach-Object {
        Get-Service -ComputerName $computerName -DisplayName $_ | Start-Service
      }
    }
    'Stop' {
      $selectedServices | ForEach-Object {
        Get-Service -ComputerName $computerName -DisplayName $_ | Stop-Service
      }
    }
    'Restart' {
      $selectedServices | ForEach-Object {
        Get-Service -ComputerName $computerName -DisplayName $_ | Stop-Service
        Get-Service -ComputerName $computerName -DisplayName $_ | Start-Service
      }
    }
  }

  # write out current status of the services
  Get-Service -ComputerName $computerName | Where-Object { $selectedServices.Contains($_.DisplayName) } | Format-Table -AutoSize
}

Set-Alias -Name ism -Value Invoke-ServiceManager

This can probably be written in a more concise and elegant manner but I’m still learning PowerShell (properly this time) - so feedback is always welcome. Also, I want to add a few operations to this still:

  • Edit config file to launch in Notepad++

  • Deploy latest version