Search code examples
powershellwindows-serviceswindows-server-2008windows-server-2012windows-server-2012-r2

Getting properties of all Stopped Automatic services on Windows Server w/ PowerShell


I want to get the Display Name, Name, Start Mode, Start Name, and State of all Automatic services that are in a Stopped state on a Windows server. Normally, I would just do

get-wmiobject -class win32_service | ? {$_.StartMode -eq "Auto" -and $_.State -eq "Stopped"} | select DisplayName, Name, StartMode, StartName, State

However, the cmdlet above does not distinguish between a state of "Automatic" and "Automatic Delayed Start". The cmdlet I have below will not report any services that have a state of auto delayed start, but I don't know how to get it to also display the other properties I need.

(Get-WmiObject -Class Win32_Service -Filter "state = 'stopped' and startmode = 'auto'" | Select-Object -ExpandProperty name) | Where-Object {(Get-ChildItem HKLM:\SYSTEM\CurrentControlSet\Services | Where-Object {$_.property -contains "DelayedAutoStart"} | Select-Object -ExpandProperty PSChildName) -notcontains $_} | Select-Object @{l='Service Name';e={$_}}

How can I modify the above cmdlet so that it will also display the other properties I want?

EDIT: I know the method below will work, but its inefficient and non-powershell-like.

$auto_services = @((get-wmiobject -class win32_service -filter "state='stopped' and startmode='auto'" | select-object -expandproperty name) | ? {(get-childitem HKLM:\SYSTEM\CurrentControlSet\Services | ? {$_.property -contains "DelayedAutoStart"} | Select-Object -ExpandProperty PSChildName) -notcontains $_})

foreach ($service in $auto_services) { Get-WMIobject -class win32_service | ? {$_.Name -eq $service} | Select DisplayName, name, startmode, startname, state}

EDIT 2: What would be even better is if you could list all services and the desired properties and somehow make it so that the "Automatic Delayed Start" services actually show "Auto Delayed Start" as the StartMode instead of showing just "Auto".


Solution

  • Using PowerShell 4.0 (with -PipelineVariable) you can do the following :

    get-wmiobject -class win32_service  -PipelineVariable s | ? {$_.StartMode -eq "Auto" -and $_.State -eq "Stopped"}| where {(Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\services\$($_.name)" -Name 'DelayedAutoStart' -ErrorAction  "silentlycontinue").DelayedAutoStart -eq 1} | % {select  -InputObject $s -Property DisplayName, Name, StartMode, StartName, State}
    

    Using previous versions you should assign the service object to a var during the pipeline.

     get-wmiobject -class win32_service  | % {$s=$_;$s} | ? {$_.StartMode -eq "Auto" -and $_.State -eq "Stopped"}| where {(Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\services\$($_.name)" -Name 'DelayedAutoStart' -ErrorAction  "silentlycontinue").DelayedAutoStart -eq 1} | % {select  -InputObject $s -Property DisplayName, Name, StartMode, StartName, State}
    

    Edited

    Here is a version for PowerShell 2.0 of all stopped services that are in "Automatic" startmode and not not "Automatic Delayed Start" :

    get-wmiobject -class win32_service  | % {$s=$_;$s} | ? {$_.StartMode -eq "Auto" -and $_.State -eq "Stopped"}| % {$d = (Get-ItemProperty "HKLM:\SYSTEM\CurrentControlSet\services\$($_.name)" -Name 'DelayedAutoStart' -ErrorAction  "silentlycontinue").DelayedAutoStart;$_ } | where {$d -ne '1'} |% {select  -InputObject $s -Property @{name="DelayedAutoStart";expression={$d}},DisplayName, Name, StartMode, StartName, State}