{"id":908,"date":"2014-07-31T00:01:00","date_gmt":"2014-07-31T00:01:00","guid":{"rendered":"https:\/\/blogs.technet.microsoft.com\/heyscriptingguy\/2014\/07\/31\/exclude-delayed-start-services-when-checking-status-with-powershell\/"},"modified":"2014-07-31T00:01:00","modified_gmt":"2014-07-31T00:01:00","slug":"exclude-delayed-start-services-when-checking-status-with-powershell","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/scripting\/exclude-delayed-start-services-when-checking-status-with-powershell\/","title":{"rendered":"Exclude Delayed Start Services when Checking Status with PowerShell"},"content":{"rendered":"<p><b>Summary<\/b>: Windows PowerShell MVP, Mike Robbins, shows us how to use Windows PowerShell to check the status of Windows services and improve the accuracy of results.<\/p>\n<p>Microsoft Scripting Guy, Ed Wilson, is here. Welcome back guest blogger, Mike Robbins.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-1.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-1.png\" alt=\"Photo of Mike Robbins\" title=\"Photo of Mike Robbins\" \/><\/a><\/p>\n<p style=\"margin-left:30px\">Mike F Robbins is a senior systems engineer with 20 years of professional experience as an IT pro. Mike has provided enterprise computing solutions for educational, financial, health care, and manufacturing customers. He&rsquo;s a Windows PowerShell MVP and self-proclaimed evangelist who uses Windows PowerShell on a daily basis to administer and manage Windows Server, Hyper-V, SQL Server, Exchange Server, SharePoint, Active Directory, Remote Desktop, EqualLogic storage area networks, AppAssure, and Backup Exec.<\/p>\n<p style=\"margin-left:30px\">Mike is the winner of the advanced category in the 2013 PowerShell Scripting Games. He has written guest blog posts for the Hey, Scripting Guy! Blog, PowerShell.org, and PowerShell Magazine, and he is a contributing author of a chapter in <a href=\"http:\/\/manning.com\/hicks\/\" target=\"_blank\">PowerShell Deep Dives<\/a>. Mike is the leader and cofounder of the <a href=\"http:\/\/mspsug.com\/\" target=\"_blank\">Mississippi PowerShell User Group<\/a>. Mike is also a frequent speaker at Windows PowerShell and SQL Server Saturday technology events. He blogs at <a href=\"http:\/\/mikefrobbins.com\/\" target=\"_blank\">mikefrobbins.com<\/a> and can be found on twitter at <a href=\"https:\/\/twitter.com\/mikefrobbins\">@mikefrobbins<\/a>.<\/p>\n<p>Here&rsquo;s Mike&hellip;<\/p>\n<p>When it comes to the subject of checking the status of services with Windows PowerShell, the first cmdlet that comes to mind is <b>Get-Service<\/b>, so we&rsquo;ll take a look at it first.<\/p>\n<p style=\"margin-left:30px\">Get-Service -Name sppsvc |<\/p>\n<p style=\"margin-left:30px\">Select-Object -Property *<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-2.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-2.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>As shown in the previous example, <b>Get-Service<\/b> has a <b>Status<\/b> property, but the issue is that it doesn&rsquo;t have a property that tells us whether the service is set to be started automatically, so there&rsquo;s no way of knowing whether the service should be running.<\/p>\n<p>Because the <b>Get-Service<\/b> cmdlet doesn&rsquo;t have properties that contain the necessary information to determine what the start mode of a service is, we&rsquo;ll resort to using Windows Management Instrumentation (WMI). In this scenario, I&rsquo;m going to maintain backwards compatibility with Windows PowerShell&nbsp;2.0, &nbsp;so I&rsquo;ll use the <b>Get-WmiObject<\/b> cmdlet instead of <b>Get-CimInstance<\/b> cmdlet.<\/p>\n<p style=\"margin-left:30px\">Get-WmiObject -Class Win32_Service -Filter {State != &#039;Running&#039; and StartMode = &#039;Auto&#039;}<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-3.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-3.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>In this example, notice the following:<\/p>\n<ul>\n<li>Querying the Win32_Service WMI class with Windows PowerShell allows us to see the start mode of a service.<\/li>\n<li>Best practices were followed because the command uses the <b>Filter<\/b> parameter to filter left instead of piping the information for all services to the <b>Where-Object<\/b> cmdlet.<\/li>\n<li>In the results from WMI, the <b>State<\/b> property returns the value that was listed in the <b>Status<\/b> property in the results of <b>Get-Service<\/b>.<\/li>\n<\/ul>\n<p>To learn more about the service that isn&rsquo;t started, we need to determine if any additional properties exist that could provide us with additional information. Any cmdlet that produces output can be piped to the <b>Get-Member<\/b> cmdlet to determine what properties and methods exist, so that&rsquo;s exactly what we&rsquo;ll do in this scenario. We&rsquo;re specifically looking for properties, so we&rsquo;ll specify that via the <b>MemberType<\/b> property of <b>Get-Member<\/b>:<\/p>\n<p style=\"margin-left:30px\">Get-WmiObject -Class Win32_Service -Filter {State != &#039;Running&#039; and StartMode = &#039;Auto&#039;} |<\/p>\n<p style=\"margin-left:30px\">Get-Member -MemberType Properties<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-4.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-4.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>The <b>DisplayName<\/b> property looks promising to give us a friendlier name for this service:<\/p>\n<p style=\"margin-left:30px\">Get-WmiObject -Class Win32_Service -Filter {State != &#039;Running&#039; and StartMode = &#039;Auto&#039;} |<\/p>\n<p style=\"margin-left:30px\">Select-Object -Property DisplayName, Name, StartMode, State<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-5.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-5.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>To determine a little more information about this service, let&rsquo;s take a look at it in the GUI. We&rsquo;re specifically looking to see what the GUI says the startup type is.<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-6.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-6.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>We&rsquo;ve just discovered that querying WMI for the startup mode of services doesn&rsquo;t differentiate services that are set to start automatically from the ones that are set to start automatically with a delayed start. This could be a problem because the delayed start services might return a false positive if we make the assumption that services set to automatic should be running. The delayed start services aren&rsquo;t necessarily supposed to be running because, by definition, their startup is delayed.<\/p>\n<p>To determine which services are set to start automatically, but not with a delayed start, we&rsquo;ll need to query the registry:<\/p>\n<p style=\"margin-left:30px\">Get-ItemProperty &#039;HKLM:\\SYSTEM\\CurrentControlSet\\Services\\*&#039; |<\/p>\n<p style=\"margin-left:30px\">Where-Object {$_.Start -eq 2 -and $_.DelayedAutoStart -ne 1} |<\/p>\n<p style=\"margin-left:30px\">Select-Object -Property PSChildName<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-7.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-7.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>We&rsquo;re specifically looking for services that have a value of 2 for the <b>Start<\/b> property. This can mean automatic or automatic with delayed start. We&rsquo;re also looking for services that don&rsquo;t have a value of 1 for the <b>DelayedAutoStart<\/b> property. The <b>DelayedAutoStart<\/b> property is created when a service is set to start automatically with a delayed start. If the service is changed later, that property will remain, but its value will be 0 if the service is set to start automatically (not a delayed start). If the service is set to manual, the <b>Start<\/b> property will be 3, and if it&rsquo;s disabled, it will be 4.<\/p>\n<p style=\"margin-left:30px\">Get-Item -Path &#039;HKLM:\\SYSTEM\\CurrentControlSet\\Services\\sppsvc&#039;<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-8.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-8.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>Now we need to combine what we previously accomplished by querying WMI with the information we retrieved from the registry to eliminate the delayed start services. In the following example, I&rsquo;ve stopped the Windows Audio and Print Spooler services on the local computer so we should receive some results, but the Software Protection service should be excluded this time.<\/p>\n<p style=\"margin-left:30px\">Get-WmiObject -Class Win32_Service -Filter {State != &#039;Running&#039; and StartMode = &#039;Auto&#039;} |<\/p>\n<p style=\"margin-left:30px\">ForEach-Object {Get-ItemProperty -Path &quot;HKLM:\\SYSTEM\\CurrentControlSet\\Services\\$($_.Name)&quot; |<\/p>\n<p style=\"margin-left:30px\">Where-Object {$_.Start -eq 2 -and $_.DelayedAutoStart -ne 1}} |<\/p>\n<p style=\"margin-left:30px\">Select-Object -Property @{label=&#039;ServiceName&#039;;expression={$_.PSChildName}}<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-9.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-9.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>While we could accomplish the tasks we set out to accomplish with a one-liner as in the previous example. For remote machines, this command needs to run locally on the remote computer because the registry provider doesn&rsquo;t natively support remote access. We&rsquo;ll write a couple of reusable functions that use the Windows PowerShell remoting <b>Invoke-Command<\/b> cmdlet. These functions could be integrated into a Windows PowerShell script module.<\/p>\n<p><b>Note<\/b>&nbsp;&nbsp;You can download the two functions that are used from this point forward from the <a href=\"http:\/\/gallery.technet.microsoft.com\/scriptcenter\/Exclude-Delayed-Start-when-cdaee604\" target=\"_blank\">Script Center Repository<\/a>.<\/p>\n<p style=\"margin-left:30px\">Get-MrAutoStoppedService -ComputerName dc01, sql01, sql02, web01<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-10.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-10.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>You could also retrieve the computer names from a text file (or from Active Directory) and pipe them to these functions. This time, we&rsquo;ll use the Start-<b>MrAutoStoppedService<\/b> function to start the services that should be running. We&rsquo;ll also use the <b>Credential<\/b> parameter to specify alternate credentials when connecting to the remote computers.<\/p>\n<p style=\"margin-left:30px\">Get-Content -Path C:\\Scripts\\servers.txt |<\/p>\n<p style=\"margin-left:30px\">Start-MrAutoStoppedService -Credential (Get-Credential)<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-11.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-11.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>Now when we check to see if any services on our servers aren&rsquo;t running, nothing is returned because all of the services that should be running are running.<\/p>\n<p style=\"margin-left:30px\">Get-Content -Path C:\\Scripts\\servers.txt |<\/p>\n<p style=\"margin-left:30px\">Get-MrAutoStoppedService<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-12.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-12.png\" alt=\"Image of command output\" title=\"Image of command output\" \/><\/a><\/p>\n<p>We could schedule the <b>Start-MrAutoStoppedService<\/b> function to run periodically by using a scheduled task, and then use the following command to notify us via email if problems were found and action was taken.<\/p>\n<p style=\"margin-left:30px\">if (Get-Content -Path C:\\Scripts\\servers.txt | Start-MrAutoStoppedService | Out-String -OutVariable Services) {&nbsp;&nbsp;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; $Params = @{<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; From = &#039;serverstatus@mikefrobbins.com&#039;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SmtpServer = &#039;mail.mikefrobbins.com&#039;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Subject = &#039;Server Service Status Update&#039;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; To = &#039;helpdesk@mikefrobbins.com&#039;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Body = &quot;The following services are configured with a startup type of Automatic. They were in the stopped state and they have now been started: `n $Services&quot;<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; }<\/p>\n<p style=\"margin-left:30px\">&nbsp;&nbsp;&nbsp; Send-MailMessage @Params<\/p>\n<p style=\"margin-left:30px\">}<\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-13.png\"><img decoding=\"async\" src=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/29\/2019\/02\/hsg-7-31-14-13.png\" alt=\"Image of message\" title=\"Image of message\" \/><\/a><\/p>\n<p>~Mike<\/p>\n<p>Thanks, Mike, for sharing your time and knowledge.<\/p>\n<p>I invite you to follow me on <a href=\"http:\/\/bit.ly\/scriptingguystwitter\" target=\"_blank\">Twitter<\/a> and <a href=\"http:\/\/bit.ly\/scriptingguysfacebook\" target=\"_blank\">Facebook<\/a>. If you have any questions, send email to me at <a href=\"mailto:scripter@microsoft.com\" target=\"_blank\">scripter@microsoft.com<\/a>, or post your questions on the <a href=\"http:\/\/bit.ly\/scriptingforum\" target=\"_blank\">Official Scripting Guys Forum<\/a>. See you tomorrow. Until then, peace.<\/p>\n<p><b>Ed Wilson, Microsoft Scripting Guy<\/b>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Summary: Windows PowerShell MVP, Mike Robbins, shows us how to use Windows PowerShell to check the status of Windows services and improve the accuracy of results. Microsoft Scripting Guy, Ed Wilson, is here. Welcome back guest blogger, Mike Robbins. Mike F Robbins is a senior systems engineer with 20 years of professional experience as an [&hellip;]<\/p>\n","protected":false},"author":596,"featured_media":87096,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[56,344,31,3,39,45],"class_list":["post-908","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-scripting","tag-guest-blogger","tag-mike-f-robbins","tag-operating-system","tag-scripting-guy","tag-services","tag-windows-powershell"],"acf":[],"blog_post_summary":"<p>Summary: Windows PowerShell MVP, Mike Robbins, shows us how to use Windows PowerShell to check the status of Windows services and improve the accuracy of results. Microsoft Scripting Guy, Ed Wilson, is here. Welcome back guest blogger, Mike Robbins. Mike F Robbins is a senior systems engineer with 20 years of professional experience as an [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/908","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/users\/596"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/comments?post=908"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/posts\/908\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media\/87096"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/media?parent=908"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/categories?post=908"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/scripting\/wp-json\/wp\/v2\/tags?post=908"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}