CIM/Get-CimProcess.ps1
function Get-CimProcess { <# .SYNOPSIS Query the CIM Object database for a list of processes on a target host. .DESCRIPTION Query the CIM Object database for a list of processes on a target host. The function allows for filtering so as to better target the desired processes. .EXAMPLE PS C:\> Get-CimProcess -CimSession (Get-CimSession -Id 2) -ExecutablePath "C:\\User" ProcessId : 4560 ParentProcessId : 4556 Name : mimikatz.exe ExecutablePath : C:\Users\Administrator\Desktop\mimikatz_trunk-2\x64\mimikatz.exe CommandLine : "C:\Users\Administrator\Desktop\mimikatz_trunk-2\x64\mimikatz.exe" CreationDate : 8/21/2019 4:56:05 PM SessionId : 1 ComputerName : dc1 ProcessId : 2284 ParentProcessId : 796 Name : mimikatz.exe ExecutablePath : C:\Users\Administrator\Desktop\mimikatz_trunk-2\x64\mimikatz.exe CommandLine : "C:\Users\Administrator\Desktop\mimikatz_trunk-2\x64\mimikatz.exe" rpc::server service::me exit CreationDate : 8/21/2019 4:56:14 PM SessionId : 0 ComputerName : dc1 Enumerate processes running under C:\Users folder. .EXAMPLE PS C:\> Get-CimProcess -CimSession (Get-CimSession -Id 2) -CreatedBefore "9/1/2019" -CreatedAfter "8/20/2019" Find processes that where created inside a given time window. .EXAMPLE PS C:\> Get-CimProcess -CimSession (Get-CimSession -Id 2) -SessionId 0 -name pse ProcessId : 4800 ParentProcessId : 796 Name : PSEXESVC.exe ExecutablePath : C:\Windows\PSEXESVC.exe CommandLine : C:\Windows\PSEXESVC.exe CreationDate : 8/17/2019 12:00:42 AM SessionId : 0 ComputerName : dc1 Find processes started by SYSTEM (Always session ID 0) whose name contains *pse* .EXAMPLE PS C:\> Get-CimProcess -CimSession (Get-CimSession -Id 2) -name conhost,powershell,cmd Query for all terminal processes on a system. .INPUTS Microsoft.Management.Infrastructure.CimSession .OUTPUTS PSGumshoe.Process .NOTES Pulling the process owner will have an impact on the speed of execution on large numbers of targets. #> [CmdletBinding(DefaultParameterSetName = "Local")] param ( # Name or part of the process name to query for. [Parameter(Mandatory=$false, ValueFromPipelineByPropertyName = $true)] [SupportsWildcards()] [string[]] $Name, # Commandline or part of a commandline to query for. [Parameter(mandatory=$false)] [SupportsWildcards()] [string[]] $commandline, # Path or part of the path of the executable to query for. [Parameter(mandatory=$false)] [SupportsWildcards()] [string[]] $ExecutablePath, # ProcessId to query for. [Parameter(Mandatory=$false)] [int[]] $ProcessId, # Created before the specified time. [Parameter(Mandatory=$false)] [datetime] $CreatedBefore, # Created after the specified time. [Parameter(mandatory=$false)] [datetime] $CreatedAfter, # Session Id [Parameter(mandatory=$false)] [int[]] $SessionId, # Parent Process Id [Parameter(mandatory=$false)] [int[]] $ParentProcessId, # CIMSession to perform query against [Parameter(ValueFromPipelineByPropertyName = $True, ValueFromPipeline = $true, ParameterSetName = 'CimInstance')] [Alias('Session')] [Microsoft.Management.Infrastructure.CimSession[]] $CimSession, # Specifies the computer on which you want to run the CIM operation. You can specify a fully qualified # domain name (FQDN) a NetBIOS name, or an IP address. [Parameter(ValueFromPipelineByPropertyName = $True, ValueFromPipeline = $true, ParameterSetName = 'ComputerName')] [Alias('Host')] [String[]] $ComputerName, # Process properties to get. [Parameter(Mandatory = $false)] [String[]] [ValidateSet( 'Caption', 'CommandLine', 'CreationClassName', 'CreationDate', 'CSCreationClassName', 'CSName', 'Description', 'ExecutablePath', 'ExecutionState', 'Handle', 'HandleCount', 'InstallDate', 'KernelModeTime', 'MaximumWorkingSetSize', 'MinimumWorkingSetSize', 'Name', 'OSCreationClassName', 'OSName', 'OtherOperationCount', 'OtherTransferCount', 'PageFaults', 'PageFileUsage', 'ParentProcessId', 'PeakPageFileUsage', 'PeakVirtualSize', 'PeakWorkingSetSize', 'Priority', 'PrivatePageCount', 'ProcessId', 'QuotaNonPagedPoolUsage', 'QuotaPagedPoolUsage', 'QuotaPeakNonPagedPoolUsage', 'QuotaPeakPagedPoolUsage', 'ReadOperationCount', 'ReadTransferCount', 'SessionId', 'Status', 'TerminationDate', 'ThreadCount', 'UserModeTime', 'VirtualSize', 'WindowsVersion', 'WorkingSetSize', 'WriteOperationCount', 'WriteTransferCount')] $Property = @('ProcessId', 'ParentProcessId', 'Name', 'ExecutablePath', 'CommandLine', 'CreationDate', 'SessionId'), # Get the owner for each process. This will require an addional query per process. [Parameter(mandatory=$false)] [switch] $GetOwner, # Invert the logic of the filtering showing only processes that do not match [Parameter(Mandatory=$false)] [switch] $InvertLogic ) begin { # If no CIMSession is provided we create one for localhost. if ($null -eq $CimSession -or $CimSession.Count -eq 0) { $sessop = New-CimSessionOption -Protocol Dcom $CimSession += New-CimSession -ComputerName $Env:Computername -SessionOption $sessop } # Build WQL Query $PassedParams = $PSBoundParameters.Keys $filter = @() switch ($PassedParams) { "Name" { $nFilter = @() foreach($n in $name){ if ($n -match "\*") { $nfilter += "Name LIKE '$($n.Replace('*','%'))'" } else { $nfilter += "Name = '$($n)'" } } $filter += "($($nfilter -join " OR "))" } "Commandline" { $cFilter = @() foreach($n in $Commandline){ if ($n -match "\*") { $cFilter += "Commandline LIKE '$($n.Replace('*','%'))'" } else { $cFilter += "Commandline = '$($n)'" } } $filter += "($($cFilter -join " OR "))" } "ExecutablePath" { $eFilter = @() foreach($n in $ExecutablePath){ if ($n -match "\*") { $eFilter += "ExecutablePath LIKE '$($n.Replace('*','%'))'" } else { $eFilter += "ExecutablePath = '$($n)'" } } $filter += "($($eFilter -join " OR "))" } "ProcessId" { $pidFilter = @() foreach($pid in $ProcessId){ $pidFilter += "ProcessId = $($pid)" } $filter += "($($pidFilter -join " OR "))" } "ParentProcessId" { $pidFilter = @() foreach($pid in $ParentProcessId){ $ppidFilter += "ParentProcessID = $($pid)" } $filter += "($($ppidFilter -join " OR "))" } "SessionId" { $sidFilter = @() foreach($sid in $SessionId){ $sidFilter += "SessionId = $($sid)" } $filter += "($($sidFilter -join " OR "))" } "CreatedBefore" { $before = [system.management.ManagementDateTimeConverter]::ToDmtfDateTime(($CreatedBefore)) $filter += "CreationDate <= '$($before)'" } "CreatedAfter" { $after = [system.management.ManagementDateTimeConverter]::ToDmtfDateTime(($CreatedAfter)) $filter += "CreationDate >= '$($after)'" } Default {} } $filterLogic = '' if ($InvertLogic) { $filterLogic = "NOT" } if ($filter.Length -eq 0) { $Wql = "SELECT $( $Property -join ',' ) FROM Win32_Process" } else { $Wql = "SELECT $( $Property -join ',' ) FROM Win32_Process WHERE $($filterLogic) $($filter -join " AND " )" } } process { $CimParamters = @{ 'Query' = $Wql } switch ($pscmdlet.ParameterSetName) { 'Local' { # DCOM to ensure propper connection to local host since WinRM is not garateed. $sessop = New-CimSessionOption -Protocol Dcom $LocalSession = New-CimSession -ComputerName $Env:Computername -SessionOption $sessop $CimSession += $LocalSession # Clean session after execution. $CleanSession = $true $CimParamters.Add('CimSession', $CimSession) } 'ComputerName' { $CimParamters.Add('ComputerName', $ComputerName) } 'CimInstance' { $CimParamters.Add('CimSession', $CimSession) } Default {} } Get-CimInstance @CimParamters | ForEach-Object { $objectProps = [ordered]@{} foreach($p in $Property) { $objectProps.Add($p, $_."$($p)") } $objectProps.Add('ComputerName', $_.PSComputerName) if($GetOwner) { $ownerInfo = Invoke-CimMethod -InputObject $_ -MethodName GetOwner if ($ownerInfo.ReturnValue -eq 0) { $objectProps.Add('Owner', "$($ownerInfo.Domain)\$($ownerInfo.User)") } else { $objectProps.Add('Owner', "") } } $obj = [PSCustomObject]$objectProps $obj.pstypenames.insert(0,'PSGumshoe.Process') $obj } } end { if ($CleanSession) { Remove-CimSession -CimSession $LocalSession } } } |