Expert Solution for the 2011 Scripting Games Advanced Event 2: Use PowerShell to Identify Services Dependent on Windows

Expert Solution for the 2011 Scripting Games Advanced Event 2: Use PowerShell to Identify Services Dependent on Windows

  • Comments 6
  • Likes

Summary: Microsoft PowerShell MVP Brandon Shell solves 2011 Scripting Games Advanced Event 2, and identifies Windows service dependencies.

Microsoft Scripting Guy, Ed Wilson, here. Today Brandon Shell offers his solution to the Windows PowerShell 2011 Scripting Games Advanced Event 2.

Photo of Brandon Shell

Brandon is a Microsoft MVP, and a moderator for the Official Scripting Guys Forum.
Brandon's contact information:
Blog: BSonPoSH: The Power of Shell

Worked solution

When reviewing the specs for this challenge, I wanted to focus on the portability and reusability of the script. This is generally my approach unless there is a very specific need. In this particular case, it was very difficult. I say difficult because it has a very specific need: "report on dependent services." I would normally output objects and stay away from the strings, but the design spec was pretty specific about this. The important thing to note is that there are often reasons to "break" best practices.

Although it was difficult to make it portable and reusable, I did what I could. I added piping support for the built-in Active Directory (AD) cmdlets and text files. I also chose to avoid adding the AD stuff directly to the function so that users can use whatever source they would like to for the information (such as adfind, Quest AD cmdlets, Microsoft AD cmdlets, or SQL).

Examples of use:

# To get a report from a single machine

Get-DependentServiceReport MyServerX

 

# To get a report from all the machines in a text file

get-content C:\data\myservers.txt | Get-DepenentServiceReport

 

# To get a report from all servers in a domain with at least one 2008 R2 domain controller

Get-ADComputer -Filter {operatingSystem -like "*Server*"} | Get-DependantServiceReport

 

# To get a report from all servers using adfind

c:\tools\AdFind.exe -f 'operatingsystem=*server*' dnshostname -list | Get-DependantServiceReport

 

# To get a report using the all servers using Quest AD cmdlets

Get-QADComputer -OSName *Server* | Get-DependantServiceReport

The complete Get-DependentServiceReport function appears here.

Get-DependentServiceReport

 

function Get-DependentServiceReport

{

    [Cmdletbinding()]

    Param(

        [alias('ComputerName')]

        [Parameter(ValueFromPipelineByPropertyName=$True,ValueFromPipeline=$True)]

        [string]$DNSHostName = $Env:COMPUTERNAME

    )

    process 

    {

        ""

        $Message = "****** {0} ******" -f $DNSHostName

        "*" * $Message.Length

        $Message

        "*" * $Message.Length

        ""

        

        $Services = Get-Service -ComputerName $DNSHostName

        

        foreach($Service in $Services)

        {

            "{0}" -f $Service.DisplayName

            "-" * ($Service.DisplayName).Length

            "{0,-20} {1,-60} {2}" -f $Service.Name,$Service.DisplayName,$Service.Status

            

            $Dependents = $Service | Get-Service -DependentServices -ComputerName $DNSHostName

            if($Dependents)

            {

                foreach($Dependent in $Dependents)

                {

                    "{0,-20} {1,-60} {2}" -f $Dependent.Name,$Dependent.DisplayName,$Dependent.Status

                }

            }

            ""

        }

    

    }

}

Thank you, Brandon, for providing this solution to Advanced Event 2.

I invite you to follow me on Twitter and Facebook. If you have any questions, send email to me at scripter@microsoft.com, or post your questions on the Official Scripting Guys Forum. See you tomorrow. Until then, peace.

Ed Wilson, Microsoft Scripting Guy

Your comment has been posted.   Close
Thank you, your comment requires moderation so it may take a while to appear.   Close
Leave a Comment
  • Nice Script. It works ( though I can test only the part for my local machine ) and it shows some of the advanced formatting capabilities of PS which are really good. But again this script might fail in some environments and errors are not handled.

    I really would like to get to know a cool way of handling all errors inn PS without spoiling the layout of a script.

    kind regard, Klaus

  • I'd like to see the function itself to determine if an account is a server or not. ComputerSystem.DomainRole may be more accurate than using "like 'server'" clause?

  • my standard one question on a script I tried.  I couldn't get past the part after querying the running services for their dependent services.  I knew it had to do something with an array but couldn't figure out how to build a separate array for each service.  I see in the code where you did this but other than being able to see it, I have no idea what it's doing.  Could you expand on the foreach loops?

  • @Klaus, Ideally you would use try/catch to determine error state and use Write-Host with "error" color to allow the user to see there was an error without killing the format.

    @John, The problem with that is that it doesn't scale. If thousands or tens of thousands of computer objects you cannot query each one to determine if it is "REALLY" a server. In this case I chose to just trust AD.

    @Cseiter, can you clarify your question? I am not sure I understand what you are asking.

  • in your foreach loops your using "{0,-20} {1,-60} {2}" -f $bla-bla-headexplodes.  I don't understand what the bracketed numbers represent.

  • @Cseiter read here : bsonposh.com/.../229