67
Get-Service *sql* | sort DisplayName | out-file c:/servicelist.txt

I have a one line PowerShell script to extract list of all services running on my local machine, now, in addition to displaying "Status", "Name" and "DisplayName" I also want to display "Path to executable"

Abilash A
  • 951
  • 2
  • 8
  • 14

7 Answers7

90

I think you'll need to resort to WMI:

Get-WmiObject win32_service | ?{$_.Name -like '*sql*'} | select Name, DisplayName, State, PathName

Update If you want to perform some manipulation on the selected data, you can use calculated properties as described here.

For example if you just wanted the text within quotes for the Pathname, you could split on double quotes and take the array item 1:

Get-WmiObject win32_service | ?{$_.Name -like '*sql*'} | select Name, DisplayName, @{Name="Path"; Expression={$_.PathName.split('"')[1]}} | Format-List

Get-CimInstance can also be used to achieve the same, see here for the difference between CIM and WMI.

Get-CimInstance win32_service | ?{$_.Name -like '*sql*'} | select Name, DisplayName, @{Name="Path"; Expression={$_.PathName.split('"')[1]}} | Format-List
David Martin
  • 11,764
  • 1
  • 61
  • 74
  • 1
    Thanks, but with the "PathName", I don't get the full path instead I get something like `C:\Program Files (x86)\Microsoft SQL S...` `E:\apps\MySQL\MySQL Server 5.0\bin\mys...` after certain number of characters the path truncates, is there any way to get the full path? – Abilash A Jun 27 '14 at 12:45
  • 2
    Looks like something was missed off your comment, I'm going to guess that you have displayed it to the screen and the path is being trunctated. Try piping it through Format-List to see the full path. – David Martin Jun 27 '14 at 12:49
  • Thanks, I have tried **Format-List** and it works well. Can I truncate part of the path after .exe? for instance `"C:\Program Files (x86)\Microsoft SQL Server\MSSQL.3\MSSQL\Binn\sqlservr.exe" -sSQLEXPRESS` I don't need the part of path after .exe, I need something like this `"C:\Program Files (x86)\Microsoft SQL Server\MSSQL.3\MSSQL\Binn\sqlservr.exe"` Removing the quotes should be even better – Abilash A Jun 27 '14 at 13:27
  • 1
    I've added an example for using calculated properties which should help you. – David Martin Jun 30 '14 at 09:21
  • Thanks for helping me out, the `PathName.split` cmdlet is what I was looking for, but it would have been better and more flexible if it supported Regular expressions, splitting based on `"` character doesn't apply to paths that don't have the `"` character. I tried replacing the quotes character with `space` and `.` characters and it resulted in truncated paths. Anyhow, your response has helped me well, thanks – Abilash A Jul 01 '14 at 16:17
  • 1
    If $_.PathName.Split doesn't give you the flexibility, then you can indeed use regex: $_.PathName -replace which does support regex, see here: http://blogs.technet.com/b/heyscriptingguy/archive/2011/03/21/use-powershell-to-replace-text-in-strings.aspx – David Martin Jul 02 '14 at 09:26
  • When you see those `...` indicating the output has been truncated, I always use `Export-CSV -NoTypeInformation` to get the results in an easy to copy from format. – user4317867 Dec 05 '15 at 22:26
12

Since Get-WmiObject have been deprecated in PowerShell Core, you can use

Get-CimInstance -ClassName win32_service | ?{$_.Name -match '^sql'} | Select Name, DisplayName, State, PathName >> C:\temp\sqlservices.txt

instead.

If you don't need to check against a regular expression you can also use the -Filter parameter:

Get-CimInstance -ClassName win32_service -Filter "Name like 'sql%'" | Select Name, DisplayName, State, PathName >> C:\temp\sqlservices.txt
7

A variant on the WMI Query that may be faster (I just had to do this for an SCCM Client)

$SQLService=(get-wmiobject -Query 'Select * from win32_service where Name like "*SQL*"') | Select-object Name, DisplayName, State, Pathname

The other trick is to trap for the multiple SQL results if you want the path names without the Double Quotes (so you can action upon them)

$SQLService | Select-Object Name, DisplayName, State, @{Name='PathName';Expression=$_.Pathname.replace('"','')}

The big advantage to using -query in the get-wmiobject (or get-ciminstance) is the speed of processing. The older example gets a full list and then filters, whilst the latter grabs a very direct list.

Just adding in two cents :)

Cheers all! Sean The Energized Tech

MikeT
  • 51,415
  • 16
  • 49
  • 68
user7371585
  • 71
  • 1
  • 1
  • 1
    And a variant on yours but using -Filter instead of -Query. I expect it's very similar under the hood but may be a fraction less typing :-) `Get-WmiObject win32_service -Filter 'Name like "%SQL%"'` – Martin Hollingsworth Sep 11 '17 at 23:03
  • 1
    The proposed answer doesn't work for me. The problem is that `where Name like "*SQL*"` should be `where Name like "%SQL%"` (notice that `%` is the wildcard for SQL) – Bozzy Mar 23 '21 at 10:57
2

You can also use the Regular Expression pattern and dump the result to file.

Get-WmiObject win32_service | ?{$_.Name -match '^sql'} | select Name, DisplayName, State, PathName >> C:\temp\sqlservices.txt
Aidar Gatin
  • 755
  • 1
  • 7
  • 9
1

I'm not comfortable with the accepted answer's use of Expression={$_.PathName.split('"')[1]}} because it doesn't handle the variants of quotes, spaces, and args that I see in the data.

Here's a clunky method that does.

function PathFromServicePathName($pathName) {
  # input can have quotes, spaces, and args like any of these:
  #   C:\WINDOWS\system32\lsass.exe
  #   "C:\Program Files\Realtek\Audio\HDA\RtkAudioService64.exe"
  #   C:\WINDOWS\system32\svchost.exe -k netsvcs -p
  #   "C:\Program Files\Websense\Websense Endpoint\wepsvc.exe" -k ss

  # if it starts with quote, return what's between first and second quotes
  if ($pathName.StartsWith("`"")) {
    $pathName = $pathName.Substring(1)
    $index = $pathName.IndexOf("`"")
    if ($index -gt -1) {
      return $pathName.Substring(0, $index)
    }
    else {
      # this should never happen... but whatever, return something
      return $pathName
    }
  }
  
  # else if it contains spaces, return what's before the first space
  if ($pathName.Contains(" ")) {
    $index = $pathName.IndexOf(" ")
    return $pathName.Substring(0, $index)
  }
  
  # else it's a simple path
  return $pathName
}

Get-WmiObject win32_service | select Name, DisplayName, @{Name="Path"; Expression={PathFromServicePathName $_.PathName}} | Format-List
1

A variant with Format-List with full path, results in file :

Get-WmiObject win32_service | Format-Table -Wrap -AutoSize -Property State,Name,PathName | out-file C:\servicelist.txt
mdelpeix
  • 177
  • 8
0

In Powershell 7 this property has been added, thus you can also use Get-Service meanwhile:

Get-Service *sql* | Select-Object -Property Status, Name, DisplayName, BinaryPathName
Wernfried Domscheit
  • 54,457
  • 9
  • 76
  • 110