Expert Solution for 2011 Scripting Games Advanced Event 4: Use PowerShell to Find Services Hiding in the SvcHost Process
Summary: Microsoft research software developer, Chris O’Prey, solves Windows PowerShell 2011 Scripting Games Advanced Event 4 and finds services that are running in the SvcHost process.
Microsoft Scripting Guy, Ed Wilson, here. With us today with his solution to the Windows PowerShell 2011 Scripting Games Advanced Event 4 is Chris O’Prey. Chris tells us about himself then and continues with his solution.
I’ve been a professional developer and tester since 1995, working mainly in the web development and research fields and using a plethora of different operating systems and programming languages. Currently, I’m working for Microsoft Research in Cambridge, UK as a senior development engineer in test, and I am working on leading edge research and development projects. I’ve been using Windows PowerShell on a daily basis since the early days of version 1.
Worked solution
The basic requirements from the team lead are as follows:
- Show all SvcHost processes with committed memory, page fault count, and command line
- Show all services running inside each SvcHost process
- Use a single server only
- Provide reusable code
- Produce a written report
- Return objects instead of string or table data
Although Windows PowerShell contains its own implementation of the Get-Process and Get-Service cmdlets, in this case we require information that is not easily obtained from the resulting objects from these cmdlets. Therefore, the better option will be to rely on the Get-WmiObject cmdlet, which returns further information of use.
To ensure a fast response (because WMI can be slow), the filtering should begin by only selecting the SvcHost processes. In WMI, these are identified readily by selecting the entries with the name svchost.exe. Using the filter parameter on the Get-WmiObject cmdlet allows us to do this easily and also speeds up the return of data because we no longer have to filter in Windows PowerShell. Note that we make a copy of the current entry in the pipeline ($_) into a local variable ($process) because we intend to use this in the next pipeline level.
For each of the returned process objects, we can make a second WMI call to get the services filtered by the Process ID, which will provide the services running in this particular instance of the SvcHost process.
We would prefer to return objects. To this end we can use the intrinsic PSObject type, and use the Property parameter on the New-Object cmdlet to allow us to easily splat all the required properties from both the Process and Service WMI objects into a single PSObject. By explicitly not assigning the return of this cmdlet, it will automatically become part of the script output.
One of the requirements was the ability to provide a written report. We have a nice object set, so we can rely on the ConverTo-HTML cmdlet to do this automatically, and the Out-File cmdlet to write it to the current folder. A nice feature was to use the “&” operator to also automatically display the resulting HTML file in the active browser. By adding an OutHMTL switch parameter we can make this script reusable without impacting the ability to provide this report.
For instant use, an OutGrid switch parameter was also added, which takes the output data and shows it using the Out-GridView cmdlet.
Finally, although there was no explicit requirement for multiple computer support, a Computers parameter was provided, defaulting to the current machine, to allow the code to be reusable and access machines other than the current one.
The complete script is shown here.
<#
.Synopsis
Provide a report on all SvcHost processes and embedded services.
.Description
Gets the details on all services running inside of SvcHost processes along with memory
consumption, page faults and command lines.
.Parameter computer
The machine to test. Defaults to the current machine.
.Parameter outHTML
A switch. Will return a HTML formatted output of the process & service details.
.Parameter outGrid
A switch. Will return a GridView formatted output of the process & service details.
.INPUTS
None. You cannot pipe objects to Invoke-Task.
.OUTPUTS
A collection of PSObjects containing the details of each service.
.Example
Get-ServiceDetails
Gets the details for the current machine as a PSObject collection.
.Example
Get-ServiceDetails “SERVER-001”
Gets the details for the given machine as a PSObject collection.
.Example
Get-ServiceDetails -outHTML
Gets the details for the current machine as a PSObject collection and also displays the details in
the current browser as an HTML formatted file. This file is also persisted to the current folder.
.Example
Get-ServiceDetails -outGrid
Gets the details for the current machine as a PSObject collection and also displays the details in
a GridView.
#>
param (
[string]$computer = “.”,
[switch]$outHTML,
[switch]$outGrid
)
$results = (Get-WmiObject -Class Win32_Process -ComputerName $computer -Filter “Name=’svchost.exe'” | % {
$process = $_
Get-WmiObject -Class Win32_Service -ComputerName $computer -Filter “ProcessId=$($_.ProcessId)” | % {
New-Object PSObject -Property @{ProcessId=$process.ProcessId;
CommittedMemory=$process.WS;
PageFaults=$process.PageFaults;
CommandLine=$_.PathName;
ServiceName=$_.Name;
State=$_.State;
DisplayName=$_.DisplayName;
StartMode=$_.StartMode}
}
})
if ($outHTML)
{
$results | ConvertTo-Html | Out-File “.\temp.html”
& .\temp.html
}
if ($outGrid)
{
$results | Out-GridView
}
$results
Thanks, Chris, for writing this solution to Advanced Event 4.
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
0 comments