Skip to content

Instantly share code, notes, and snippets.

@toyg
Created November 2, 2017 12:05
Show Gist options
  • Save toyg/37d10edf705e591c6764c405aa2e2bc1 to your computer and use it in GitHub Desktop.
Save toyg/37d10edf705e591c6764c405aa2e2bc1 to your computer and use it in GitHub Desktop.
PowerShell Function to query each service and show the start time from the associated process
function Get-ServiceUpTime
{
[CmdletBinding()]
param
(
# Name of Computer(s) to query
[Parameter(Mandatory = $false,
Position = 1,
ValueFromPipelineByPropertyName = $true)]
[string[]]$ComputerName = $env:COMPUTERNAME,
# Service Name of the Service(s) to query
[Parameter(Mandatory = $false,
Position = 2,
ValueFromPipeline = $true,
ValueFromPipelineByPropertyName = $true)]
[string[]]$ServiceName = '%',
# Show 'STOPPED' Service details
[Switch]$ShowStopped = $false
)
Process
{
$compID = 0
# Loop each Computer specified in params
foreach ($comp in $ComputerName)
{
try
{
#get ALL processes from the computer - So much quicker than running a seperate query to WMI for each ProcessID found in $wmiService
$wmiProcess = Get-WmiObject -Query 'SELECT __Server, Name, CreationDate, ProcessID from Win32_Process' -ComputerName $comp -ErrorAction Stop | Sort-Object -Property ProcessID
}
catch
{
Write-Warning -Message "Unable to retrieve WIN32_Process data from computer: $($comp.ToUpper())"
}
foreach ($pattern in $ServiceName)
{
try
{
#replace '*' wildcard character with '%' for WMI query
$wqlPattern = $pattern -replace '\*', '%'
$wmiService = Get-WmiObject -Query "SELECT Name, ProcessID from Win32_Service WHERE Name LIKE '$wqlPattern'" -ComputerName $comp #-ErrorAction SilentlyContinue
if ($wmiService)
{
$svcID = 0
# Loop each Service found that matches the pattern
foreach ($svc in $wmiService)
{
$match = $false
$processID = $svc.ProcessID
#filter any services that have no PID: unless -ShowStopped
if ($processID -ne 0 -or $ShowStopped)
{
$procID = 0
#loop until we find a Process mathcing the Service PID
while (!$match)
{
$proc = $wmiProcess[$procID]
### Fix so that loops exits when 1st match found
if ($proc.ProcessId -eq $processID)
{
$match = $true
if ($processID -ne 0)
{
$creationDate = $proc.ConvertToDateTime($proc.CreationDate)
$currentUpTime = (Get-Date) - $creationDate
}
Else
{
[datetime]$creationDate = 0
[timespan]$currentUpTime = 0
}
$objProps = @{
#'Computer' = $proc.__Server
'Service' = $($svc.Name)
'Process' = $proc.Name
'PID' = $processID
'StartedDate' = $creationDate
'CurrentUpTime' = '{0:d\.hh\:mm\:ss}' -f $currentUpTime
}
$obj = New-Object -TypeName PSObject -Property $objProps
$obj.psobject.typenames.insert(0, 'Coeus.Healthcheck.ServiceUpTime')
Write-Output -InputObject $obj
}
$procID += 1
}
}
$svcID += 1
} #/foreach svc
} #/if wmiservice
} #/try
catch
{
Write-Warning -Message "Unable to retrieve data from computer: $($comp.ToUpper()) when searching for service(s): $($pattern.ToUpper())"
$procID = 0
}
} #/foreach pattern
$compID += 1
} #/foreach comp
} #/PROCESS
}
# Example
Get-ServiceUpTime | sort currentuptime | ft -Property PID, Service, Process, StartedDate, currentuptime
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment