Public/real-time-response.ps1
function Confirm-FalconCommand { <# .SYNOPSIS Verify the status of a Real-time Response 'read-only' command issued to a single-host session .DESCRIPTION Requires 'Real Time Response: Read'. Confirms the status of an executed 'read-only' command. The single-host Real-time Response APIs require that commands be confirmed to 'acknowledge' that they have been processed as part of your API-based workflow. Failing to confirm after commands can lead to unexpected results. A 'sequence_id' value of 0 is added if the parameter is not specified. .PARAMETER SequenceId Sequence identifier .PARAMETER CloudRequestId Command request identifier .LINK https://github.com/crowdstrike/psfalcon/wiki/Real-time-Response #> [CmdletBinding(DefaultParameterSetName='/real-time-response/entities/command/v1:get')] param( [Parameter(ParameterSetName='/real-time-response/entities/command/v1:get',Position=1)] [Alias('sequence_id')] [int32]$SequenceId, [Parameter(ParameterSetName='/real-time-response/entities/command/v1:get',Mandatory,ValueFromPipeline, ValueFromPipelineByPropertyName,Position=2)] [ValidatePattern('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')] [Alias('cloud_request_id','task_id')] [string]$CloudRequestId ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName Format = @{ Query = @('cloud_request_id','sequence_id') } } if (!$PSBoundParameters.SequenceId) { $PSBoundParameters['sequence_id'] = 0 } } process { Invoke-Falcon @Param -Inputs $PSBoundParameters } } function Confirm-FalconGetFile { <# .SYNOPSIS Verify the status of a Real-time Response 'get' command .DESCRIPTION Requires 'Real Time Response: Write'. .PARAMETER SessionId Session identifier .PARAMETER Timeout Length of time to wait for a result, in seconds .PARAMETER BatchGetCmdReqId Batch 'get' command identifier .LINK https://github.com/crowdstrike/psfalcon/wiki/Real-time-Response #> [CmdletBinding(DefaultParameterSetName='/real-time-response/combined/batch-get-command/v1:get')] param( [Parameter(ParameterSetName='/real-time-response/entities/file/v2:get',Mandatory, ValueFromPipelineByPropertyName)] [ValidatePattern('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')] [Alias('session_id')] [string]$SessionId, [Parameter(ParameterSetName='/real-time-response/combined/batch-get-command/v1:get',Position=1)] [ValidateRange(30,600)] [int32]$Timeout, [Parameter(ParameterSetName='/real-time-response/combined/batch-get-command/v1:get',Mandatory, ValueFromPipelineByPropertyName)] [ValidatePattern('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')] [Alias('batch_get_cmd_req_id')] [string]$BatchGetCmdReqId ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Format = @{ Query = @('session_id','batch_get_cmd_req_id','timeout') } } } process { # Verify 'Endpoint' using SessionId/BatchGetCmdReqId $Endpoint = if ($PSBoundParameters.SessionId) { '/real-time-response/entities/file/v2:get' } else { '/real-time-response/combined/batch-get-command/v1:get' } @(Invoke-Falcon @Param -Endpoint $Endpoint -Inputs $PSBoundParameters).foreach{ if ($Endpoint -eq '/real-time-response/combined/batch-get-command/v1:get') { @($_.PSObject.Properties).foreach{ # Append 'aid' and 'batch_get_cmd_req_id' to each host result and output ($_.Value).PSObject.Properties.Add((New-Object PSNoteProperty('aid',$_.Name))) ($_.Value).PSObject.Properties.Add((New-Object PSNoteProperty( 'batch_get_cmd_req_id',$BatchGetCmdReqId))) $_.Value } } else { $_ } } } } function Confirm-FalconResponderCommand { <# .SYNOPSIS Verify the status of a Real-time Response 'active-responder' command issued to a single-host session .DESCRIPTION Requires 'Real Time Response: Write'. Confirms the status of an executed 'active-responder' command. The single-host Real-time Response APIs require that commands be confirmed to 'acknowledge' that they have been processed as part of your API-based workflow. Failing to confirm after commands can lead to unexpected results. A 'sequence_id' value of 0 is added if the parameter is not specified. .PARAMETER SequenceId Sequence identifier .PARAMETER CloudRequestId Command request identifier .LINK https://github.com/crowdstrike/psfalcon/wiki/Real-time-Response #> [CmdletBinding(DefaultParameterSetName='/real-time-response/entities/active-responder-command/v1:get')] param( [Parameter(ParameterSetName='/real-time-response/entities/active-responder-command/v1:get',Position=1)] [Alias('sequence_id')] [int32]$SequenceId, [Parameter(ParameterSetName='/real-time-response/entities/active-responder-command/v1:get',Mandatory, ValueFromPipeline,ValueFromPipelineByPropertyName,Position=2)] [ValidatePattern('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')] [Alias('cloud_request_id','task_id')] [string]$CloudRequestId ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName Format = @{ Query = @('cloud_request_id','sequence_id') } } if (!$PSBoundParameters.SequenceId) { $PSBoundParameters['sequence_id'] = 0 } } process { Invoke-Falcon @Param -Inputs $PSBoundParameters } } function Get-FalconSession { <# .SYNOPSIS Search for Real-time Response sessions .DESCRIPTION Requires 'Real Time Response: Read'. Real-time Response sessions are segmented by permission,meaning that only sessions that were created using your OAuth2 API Client will be visible. 'Get-FalconQueue' can be used to find and export information about sessions in the 'offline queue'. .PARAMETER Id Session identifier .PARAMETER Filter Falcon Query Language expression to limit results .PARAMETER Sort Property and direction to sort results .PARAMETER Limit Maximum number of results per request .PARAMETER Offset Position to begin retrieving results .PARAMETER Queue Restrict search to sessions that have been queued .PARAMETER Detailed Retrieve detailed information .PARAMETER All Repeat requests until all available results are retrieved .PARAMETER Total Display total result count instead of results .LINK https://github.com/crowdstrike/psfalcon/wiki/Real-time-Response #> [CmdletBinding(DefaultParameterSetName='/real-time-response/queries/sessions/v1:get')] param( [Parameter(ParameterSetName='/real-time-response/entities/queued-sessions/GET/v1:post',Mandatory, ValueFromPipeline,ValueFromPipelineByPropertyName)] [Parameter(ParameterSetName='/real-time-response/entities/sessions/GET/v1:post',Mandatory, ValueFromPipeline,ValueFromPipelineByPropertyName)] [ValidatePattern('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')] [Alias('Ids')] [string[]]$Id, [Parameter(ParameterSetName='/real-time-response/queries/sessions/v1:get',Position=1)] [ValidateScript({ Test-FqlStatement $_ })] [string]$Filter, [Parameter(ParameterSetName='/real-time-response/queries/sessions/v1:get',Position=2)] [string]$Sort, [Parameter(ParameterSetName='/real-time-response/queries/sessions/v1:get',Position=3)] [ValidateRange(1,100)] [int32]$Limit, [Parameter(ParameterSetName='/real-time-response/queries/sessions/v1:get')] [int32]$Offset, [Parameter(ParameterSetName='/real-time-response/entities/queued-sessions/GET/v1:post',Mandatory)] [switch]$Queue, [Parameter(ParameterSetName='/real-time-response/queries/sessions/v1:get')] [switch]$Detailed, [Parameter(ParameterSetName='/real-time-response/queries/sessions/v1:get')] [switch]$All, [Parameter(ParameterSetName='/real-time-response/queries/sessions/v1:get')] [switch]$Total ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName Format = @{ Query = @('sort','offset','limit','filter') Body = @{ root = @('ids') } } } [System.Collections.Generic.List[string]]$List = @() } process { if ($Id) { @($Id).foreach{ $List.Add($_) } } else { Invoke-Falcon @Param -Inputs $PSBoundParameters } } end { if ($List) { $PSBoundParameters['Id'] = @($List | Select-Object -Unique) Invoke-Falcon @Param -Inputs $PSBoundParameters } } } function Invoke-FalconBatchGet { <# .SYNOPSIS Issue a Real-time Response batch 'get' command to an existing batch session .DESCRIPTION Requires 'Real Time Response: Write'. When a 'get' command has been issued,the 'batch_get_cmd_req_id' property will be returned. That value is used to verify the completion of the file transfer using 'Confirm-FalconBatchGet'. The 'Confirm' parameter will use 'Confirm-FalconGetFile' to check for command results every 5 seconds for a total of 60 seconds. .PARAMETER FilePath Path to file on target host .PARAMETER Timeout Length of time to wait for a result, in seconds .PARAMETER OptionalHostId Restrict execution to specific host identifiers .PARAMETER BatchId Batch session identifier .PARAMETER Confirm Use 'Confirm-FalconGetFile' to attempt to retrieve results .LINK https://github.com/crowdstrike/psfalcon/wiki/Real-time-Response #> [CmdletBinding(DefaultParameterSetName='/real-time-response/combined/batch-get-command/v1:post')] param( [Parameter(ParameterSetName='/real-time-response/combined/batch-get-command/v1:post',Mandatory,Position=1)] [Alias('file_path')] [string]$FilePath, [Parameter(ParameterSetName='/real-time-response/combined/batch-get-command/v1:post',Position=2)] [ValidateRange(30,600)] [int32]$Timeout, [Parameter(ParameterSetName='/real-time-response/combined/batch-get-command/v1:post',Position=3)] [ValidatePattern('^\w{32}$')] [Alias('optional_hosts','OptionalHostIds')] [string[]]$OptionalHostId, [Parameter(ParameterSetName='/real-time-response/combined/batch-get-command/v1:post',Mandatory, ValueFromPipeline,ValueFromPipelineByPropertyName,Position=4)] [ValidatePattern('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')] [Alias('batch_id')] [string]$BatchId, [Parameter(ParameterSetName='/real-time-response/combined/batch-get-command/v1:post')] [switch]$Confirm ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName Format = @{ Query = @('timeout') Body = @{ root = @('batch_id','file_path','optional_hosts') } } } [System.Collections.Generic.List[string]]$List = @() } process { if ($OptionalHostId) { @($OptionalHostId).foreach{ $List.Add($_) }}} end { if ($List) { $PSBoundParameters['OptionalHostId'] = @($List | Select-Object -Unique) } @(Invoke-Falcon @Param -Inputs $PSBoundParameters).foreach{ if ($_.batch_get_cmd_req_id -and $_.combined.resources) { # Output result with 'batch_get_cmd_req_id' and 'hosts' values $Request = [PSCustomObject]@{ batch_get_cmd_req_id = $_.batch_get_cmd_req_id hosts = $_.combined.resources.PSObject.Properties.Value } @($Request.hosts).Where({ $_.errors }).foreach{ # Write warning for hosts in batch that produced errors Write-Warning "[Invoke-FalconBatchGet] $( @($_.errors.code,$_.errors.message) -join ': ') [aid: $($_.aid)]" } @($Request.hosts).Where({ $_.stderr }).foreach{ # Write warning for hosts in batch that produced 'stderr' Write-Warning "[Invoke-FalconBatchGet] $($_.stderr) [aid: $($_.aid)]" } if ($Confirm) { for ($i = 0; $i -lt 60 -and !$Result.sha256; $i += 5) { # Attempt to 'confirm' for 60 seconds Start-Sleep 5 $Result = $Request | Confirm-FalconGetFile } $Result } else { $Request } } else { $_ } } } } function Invoke-FalconCommand { <# .SYNOPSIS Issue a Real-time Response read-only command to an existing single-host or batch session .DESCRIPTION Requires 'Real Time Response: Read'. Sessions can be started using 'Start-FalconSession'. A successfully issued session will contain a 'session_id' or 'batch_id' value which can be used with the '-SessionId' or '-BatchId' parameters. The 'Confirm' parameter will use 'Confirm-FalconCommand' to check for command results every 5 seconds for a total of 60 seconds. .PARAMETER Command Real-time Response command .PARAMETER Argument Arguments to include with the command .PARAMETER OptionalHostId Restrict execution to specific host identifiers .PARAMETER Timeout Length of time to wait for a result, in seconds .PARAMETER SessionId Session identifier .PARAMETER BatchId Batch session identifier .PARAMETER Confirm Use 'Confirm-FalconCommand' to retrieve single-host command results .LINK https://github.com/crowdstrike/psfalcon/wiki/Real-time-Response #> [CmdletBinding(DefaultParameterSetName='/real-time-response/combined/batch-command/v1:post')] param( [Parameter(ParameterSetName='/real-time-response/entities/command/v1:post',Mandatory,Position=1)] [Parameter(ParameterSetName='/real-time-response/combined/batch-command/v1:post',Mandatory,Position=1)] [ValidateSet('cat','cd','clear','csrutil','env','eventlog backup','eventlog export','eventlog list', 'eventlog view','filehash','getsid','help','history','ifconfig','ipconfig','ls','mount','netstat', 'ps','reg query','users',IgnoreCase=$false)] [Alias('base_command')] [string]$Command, [Parameter(ParameterSetName='/real-time-response/entities/command/v1:post',Position=2)] [Parameter(ParameterSetName='/real-time-response/combined/batch-command/v1:post',Position=2)] [Alias('Arguments')] [string]$Argument, [Parameter(ParameterSetName='/real-time-response/combined/batch-command/v1:post',Position=3)] [ValidatePattern('^\w{32}$')] [Alias('optional_hosts','OptionalHostIds')] [string[]]$OptionalHostId, [Parameter(ParameterSetName='/real-time-response/combined/batch-command/v1:post',Position=4)] [ValidateRange(30,600)] [int32]$Timeout, [Parameter(ParameterSetName='/real-time-response/entities/command/v1:post',Mandatory, ValueFromPipelineByPropertyName)] [ValidatePattern('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')] [Alias('session_id')] [string]$SessionId, [Parameter(ParameterSetName='/real-time-response/combined/batch-command/v1:post',Mandatory, ValueFromPipelineByPropertyName)] [ValidatePattern('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')] [Alias('batch_id')] [string]$BatchId, [Parameter(ParameterSetName='/real-time-response/entities/command/v1:post')] [Parameter(ParameterSetName='/real-time-response/combined/batch-command/v1:post')] [switch]$Confirm ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Format = @{ Query = @('timeout') Body = @{ root = @('session_id','base_command','command_string','optional_hosts','batch_id') } } } [System.Collections.Generic.List[string]]$List = @() } process { if ($OptionalHostId) { @($OptionalHostId).foreach{ $List.Add($_) }}} end { # Verify 'Endpoint' using BatchId/SessionId $Endpoint = if ($PSBoundParameters.BatchId) { if ($List) { $PSBoundParameters['OptionalHostId'] = @($List | Select-Object -Unique) } '/real-time-response/combined/batch-command/v1:post' } else { '/real-time-response/entities/command/v1:post' } if ($Endpoint) { $PSBoundParameters['command_string'] = if ($PSBoundParameters.Argument) { # Join 'Command' and 'Argument' into 'command_string' @($PSBoundParameters.Command,$PSBoundParameters.Argument) -join ' ' [void]$PSBoundParameters.Remove('Argument') } else { $PSBoundParameters.Command } @(Invoke-Falcon @Param -Endpoint $Endpoint -Inputs $PSBoundParameters).foreach{ if ($BatchId) { # Add 'batch_id' to each result and output Set-Property $_ batch_id $BatchId $_ } elseif ($SessionId -and $Confirm) { for ($i = 0; $i -lt 60 -and $Result.Complete -ne $true -and !$Result.sha256; $i += 5) { # Attempt to 'confirm' for 60 seconds Start-Sleep 5 $Result = $_ | Confirm-FalconCommand } $Result } else { $_ } } } } } function Invoke-FalconResponderCommand { <# .SYNOPSIS Issue a Real-time Response active-responder command to an existing single-host or batch session .DESCRIPTION Requires 'Real Time Response: Write'. Sessions can be started using 'Start-FalconSession'. A successfully issued session will contain a 'session_id' or 'batch_id' value which can be used with the '-SessionId' or '-BatchId' parameters. The 'Confirm' parameter will use 'Confirm-FalconResponderCommand' to check for command results every 5 seconds for a total of 60 seconds. .PARAMETER Command Real-time Response command .PARAMETER Argument Arguments to include with the command .PARAMETER OptionalHostId Restrict execution to specific host identifiers .PARAMETER Timeout Length of time to wait for a result, in seconds .PARAMETER SessionId Session identifier .PARAMETER BatchId Batch session identifier .PARAMETER Confirm Use 'Confirm-FalconResponderCommand' to retrieve single-host command results .LINK https://github.com/crowdstrike/psfalcon/wiki/Real-time-Response #> [CmdletBinding(DefaultParameterSetName='/real-time-response/combined/batch-active-responder-command/v1:post')] param( [Parameter(ParameterSetName='/real-time-response/entities/active-responder-command/v1:post',Mandatory, Position=1)] [Parameter(ParameterSetName='/real-time-response/combined/batch-active-responder-command/v1:post', Mandatory,Position=1)] [ValidateSet('cat','cd','clear','cp','csrutil','encrypt','env','eventlog backup','eventlog export', 'eventlog list','eventlog view','filehash','get','getsid','help','history','ifconfig','ipconfig', 'kill','ls','map','memdump','mkdir','mount','mv','netstat','ps','reg delete','reg load','reg query', 'reg set','reg unload','restart','rm','runscript','shutdown','umount','unmap','update history', 'update install','update list','update install','users','xmemdump','zip',IgnoreCase=$false)] [Alias('base_command')] [string]$Command, [Parameter(ParameterSetName='/real-time-response/entities/active-responder-command/v1:post',Position=2)] [Parameter(ParameterSetName='/real-time-response/combined/batch-active-responder-command/v1:post', Position=2)] [Alias('Arguments')] [string]$Argument, [Parameter(ParameterSetName='/real-time-response/combined/batch-active-responder-command/v1:post', Position=3)] [ValidatePattern('^\w{32}$')] [Alias('optional_hosts','OptionalHostIds')] [string[]]$OptionalHostId, [Parameter(ParameterSetName='/real-time-response/combined/batch-active-responder-command/v1:post', Position=4)] [ValidateRange(30,600)] [int32]$Timeout, [Parameter(ParameterSetName='/real-time-response/entities/active-responder-command/v1:post',Mandatory, ValueFromPipelineByPropertyName)] [ValidatePattern('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')] [Alias('session_id')] [string]$SessionId, [Parameter(ParameterSetName='/real-time-response/combined/batch-active-responder-command/v1:post', Mandatory,ValueFromPipelineByPropertyName)] [ValidatePattern('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')] [Alias('batch_id')] [string]$BatchId, [Parameter(ParameterSetName='/real-time-response/entities/active-responder-command/v1:post')] [Parameter(ParameterSetName='/real-time-response/combined/batch-active-responder-command/v1:post')] [switch]$Confirm ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Format = @{ Query = @('timeout') Body = @{ root = @('session_id','base_command','command_string','optional_hosts','batch_id') } } } [System.Collections.Generic.List[string]]$List = @() } process { if ($OptionalHostId) { @($OptionalHostId).foreach{ $List.Add($_) }}} end { if ($PSBoundParameters.BatchId -and $PSBoundParameters.Command -eq 'get') { # Redirect to 'Invoke-FalconBatchGet' for multi-host 'get' requests $GetParam = @{ FilePath = $PSBoundParameters.Argument BatchId = $PSBoundParameters.BatchId Confirm = $PSBoundParameters.Confirm } if ($Timeout) { $GetParam['Timeout'] = $PSBoundParameters.Timeout } if ($List) { $GetParam['OptionalHostId'] = @($List | Select-Object -Unique) } Invoke-FalconBatchGet @GetParam } else { # Verify 'Endpoint' using BatchId/SessionId $Endpoint = if ($PSBoundParameters.BatchId) { if ($List) { $PSBoundParameters['OptionalHostId'] = @($List | Select-Object -Unique) } '/real-time-response/combined/batch-active-responder-command/v1:post' } elseif ($PSBoundParameters.SessionId) { '/real-time-response/entities/active-responder-command/v1:post' } if ($Endpoint) { $PSBoundParameters['command_string'] = if ($PSBoundParameters.Argument) { # Join 'Command' and 'Argument' into 'command_string' @($PSBoundParameters.Command,$PSBoundParameters.Argument) -join ' ' [void]$PSBoundParameters.Remove('Argument') } else { $PSBoundParameters.Command } @(Invoke-Falcon @Param -Endpoint $Endpoint -Inputs $PSBoundParameters).foreach{ if ($BatchId) { # Add 'batch_id' to each result and output Set-Property $_ batch_id $BatchId $_ } elseif ($SessionId -and $Confirm) { for ($i = 0; $i -lt 60 -and $Result.Complete -ne $true -and !$Result.sha256; $i += 5) { # Attempt to 'confirm' for 60 seconds Start-Sleep 5 $Result = if ($Command -eq 'get') { $_ | Confirm-FalconGetFile } else { $_ | Confirm-FalconResponderCommand } } $Result } else { $_ } } } } } } function Receive-FalconGetFile { <# .SYNOPSIS Download a password protected .7z archive containing a Real-time Response 'get' file [password: 'infected'] .DESCRIPTION Requires 'Real Time Response: Write'. 'Sha256' and 'SessionId' values can be found using 'Confirm-FalconGetFile'. 'Invoke-FalconResponderCommand' or 'Invoke-FalconAdminCommand' can be used to issue a 'get' command to a single-host, and 'Invoke-FalconBatchGet' can be used for multiple hosts within existing Real-time Response session. .PARAMETER Path Destination path .PARAMETER Sha256 Sha256 hash value .PARAMETER SessionId Session identifier .PARAMETER Force Overwrite an existing file when present .LINK https://github.com/crowdstrike/psfalcon/wiki/Real-time-Response #> [CmdletBinding(DefaultParameterSetName='/real-time-response/entities/extracted-file-contents/v1:get')] param( [Parameter(ParameterSetName='/real-time-response/entities/extracted-file-contents/v1:get',Position=1)] [string]$Path, [Parameter(ParameterSetName='/real-time-response/entities/extracted-file-contents/v1:get',Mandatory, ValueFromPipelineByPropertyName,Position=2)] [ValidatePattern('^\w{64}$')] [string]$Sha256, [Parameter(ParameterSetName='/real-time-response/entities/extracted-file-contents/v1:get',Mandatory, ValueFromPipelineByPropertyName,Position=3)] [ValidatePattern('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')] [Alias('session_id')] [string]$SessionId, [Parameter(ParameterSetName='/real-time-response/entities/extracted-file-contents/v1:get')] [switch]$Force ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName Headers = @{ Accept = 'application/x-7z-compressed' } Format = @{ Query = @('session_id','sha256') Outfile = 'path' } } } process { if (!$PSBoundParameters.Path -and $PSBoundParameters.Sha256) { # When 'Path' is not specified, use 'sha256' from a 'Confirm-FalconGetFile' result $PSBoundParameters['Path'] = Join-Path (Get-Location).Path $PSBoundParameters.Sha256 } $PSBoundParameters.Path = Assert-Extension $PSBoundParameters.Path '7z' $OutPath = Test-OutFile $PSBoundParameters.Path if ($OutPath.Category -eq 'ObjectNotFound') { Write-Error @OutPath } elseif ($PSBoundParameters.Path) { if ($OutPath.Category -eq 'WriteError' -and !$Force) { Write-Error @OutPath } elseif ($PSBoundParameters.SessionId -and $PSBoundParameters.Sha256) { Invoke-Falcon @Param -Inputs $PSBoundParameters } } } } function Remove-FalconCommand { <# .SYNOPSIS Remove a command from a queued Real-time Response session .DESCRIPTION Requires 'Real Time Response: Read'. .PARAMETER SessionId Session identifier .PARAMETER CloudRequestId Cloud request identifier .LINK https://github.com/crowdstrike/psfalcon/wiki/Real-time-Response #> [CmdletBinding(DefaultParameterSetName='/real-time-response/entities/queued-sessions/command/v1:delete')] param( [Parameter(ParameterSetName='/real-time-response/entities/queued-sessions/command/v1:delete',Mandatory, ValueFromPipelineByPropertyName,Position=1)] [ValidatePattern('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')] [Alias('session_id')] [string]$SessionId, [Parameter(ParameterSetName='/real-time-response/entities/queued-sessions/command/v1:delete',Mandatory, ValueFromPipelineByPropertyName,Position=2)] [ValidatePattern('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')] [Alias('cloud_request_id','task_id')] [string]$CloudRequestId ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName Format = @{ Query = @('session_id','cloud_request_id') } } } process { Invoke-Falcon @Param -Inputs $PSBoundParameters } } function Remove-FalconGetFile { <# .SYNOPSIS Remove Real-time Response 'get' files .DESCRIPTION Requires 'Real Time Response: Write'. Delete files previously retrieved during a Real-time Response session. The required 'Id' and 'SessionId' values are contained in the results of 'Start-FalconSession' and 'Invoke-FalconAdminCommand' or 'Invoke-FalconBatchGet' commands. .PARAMETER SessionId Session identifier .PARAMETER Id Real-time Response 'get' file identifier .LINK https://github.com/crowdstrike/psfalcon/wiki/Real-time-Response #> [CmdletBinding(DefaultParameterSetName='/real-time-response/entities/file/v2:delete')] param( [Parameter(ParameterSetName='/real-time-response/entities/file/v2:delete',Mandatory, ValueFromPipelineByPropertyName,Position=1)] [ValidatePattern('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')] [Alias('session_id')] [string]$SessionId, [Parameter(ParameterSetName='/real-time-response/entities/file/v2:delete',Mandatory, ValueFromPipelineByPropertyName,Position=2)] [ValidatePattern('^\w{64}$')] [Alias('Ids','sha256')] [string]$Id ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName Format = @{ Query = @('session_id','ids') } } } process { Invoke-Falcon @Param -Inputs $PSBoundParameters } } function Remove-FalconSession { <# .SYNOPSIS Remove a Real-time Response session .DESCRIPTION Requires 'Real Time Response: Read'. .PARAMETER Id Session identifier .LINK https://github.com/crowdstrike/psfalcon/wiki/Real-time-Response #> [CmdletBinding(DefaultParameterSetName='/real-time-response/entities/sessions/v1:delete')] param( [Parameter(ParameterSetName='/real-time-response/entities/sessions/v1:delete',Mandatory,ValueFromPipeline, ValueFromPipelineByPropertyName,Position=1)] [ValidatePattern('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')] [Alias('session_id')] [string]$Id ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName Format = @{ Query = @('session_id') } } } process { Invoke-Falcon @Param -Inputs $PSBoundParameters } } function Start-FalconSession { <# .SYNOPSIS Initialize a single-host or batch Real-time Response session .DESCRIPTION Requires 'Real Time Response: Read'. Real-time Response sessions require Host identifier values. Sessions that are successfully started return a 'session_id' (for single hosts) or 'batch_id' (multiple hosts) value which can be used to issue commands that will be processed by the host(s) in the session. Commands can be issued using 'Invoke-FalconCommand', 'Invoke-FalconResponderCommand', 'Invoke-FalconAdminCommand' and 'Invoke-FalconBatchGet'. .PARAMETER QueueOffline Add non-responsive hosts to the offline queue .PARAMETER Timeout Length of time to wait for a result, in seconds [default: 30] .PARAMETER ExistingBatchId Add hosts to an existing batch session .PARAMETER HostId Host identifier .LINK https://github.com/crowdstrike/psfalcon/wiki/Real-time-Response #> [CmdletBinding(DefaultParameterSetName='/real-time-response/combined/batch-init-session/v1:post')] param( [Parameter(ParameterSetName='/real-time-response/entities/sessions/v1:post',Position=1)] [Parameter(ParameterSetName='/real-time-response/combined/batch-init-session/v1:post',Position=1)] [Alias('queue_offline')] [boolean]$QueueOffline, [Parameter(ParameterSetName='/real-time-response/combined/batch-init-session/v1:post',Position=2)] [ValidateRange(1,600)] [int32]$Timeout, [Parameter(ParameterSetName='/real-time-response/combined/batch-init-session/v1:post',Position=3)] [ValidatePattern('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')] [Alias('existing_batch_id')] [string]$ExistingBatchId, [Parameter(ParameterSetName='/real-time-response/entities/sessions/v1:post',Mandatory)] [Parameter(ParameterSetName='/real-time-response/combined/batch-init-session/v1:post',Mandatory, ValueFromPipeline,ValueFromPipelineByPropertyName)] [ValidatePattern('^\w{32}$')] [ValidateLength(1,10000)] [Alias('host_ids','device_id','device_ids','aid','HostId','HostIds')] [string[]]$Id ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Format = @{ Query = @('timeout') Body = @{ root = @('existing_batch_id','host_ids','queue_offline','device_id') } } } [System.Collections.Generic.List[string]]$List = @() } process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} end { if ($List) { # Verify 'Endpoint' using BatchId/SessionId and select hosts [void]$PSBoundParameters.Remove('Id') if ($List.Count -eq 1 -and !$Timeout -and !$ExistingBatchId) { $PSBoundParameters['device_id'] = $List[0] $Endpoint = '/real-time-response/entities/sessions/v1:post' } else { $PSBoundParameters['host_ids'] = @($List | Select-Object -Unique) $Endpoint = '/real-time-response/combined/batch-init-session/v1:post' } @(Invoke-Falcon @Param -Endpoint $Endpoint -Inputs $PSBoundParameters).foreach{ if ($_.batch_id -and $_.resources) { $BatchId = $_.batch_id @($_.resources.PSObject.Properties.Value).Where({ $_.errors }).foreach{ # Write warning for hosts in batch that produced errors Write-Warning "[Start-FalconSession] $( @($_.errors.code,$_.errors.message) -join ': ') [aid: $($_.aid)]" } @($_.resources.PSObject.Properties.Value).Where({ $_.session_id }).foreach{ # Append 'batch_id' for hosts with a 'session_id' Set-Property $_ batch_id $BatchId } [PSCustomObject]@{ batch_id = $_.batch_id hosts = $_.resources.PSObject.Properties.Value } } else { # Append 'aid' to single host session result Set-Property $_ aid $List[0] $_ } } } } } function Update-FalconSession { <# .SYNOPSIS Refresh a single-host or batch Real-time Response session to prevent expiration .DESCRIPTION Requires 'Real Time Response: Read'. Real-time Response sessions expire after 10 minutes by default. Any commands that were issued to a session that take longer than 10 minutes will not return results without refreshing the session to keep it alive until the command process completes. .PARAMETER QueueOffline Add non-responsive hosts to the offline queue .PARAMETER Timeout Length of time to wait for a result, in seconds .PARAMETER HostToRemove Host identifiers to remove from a batch Real-time Response session .PARAMETER HostId Host identifier, for a single-host session .PARAMETER BatchId Batch session identifier .LINK https://github.com/crowdstrike/psfalcon/wiki/Real-time-Response #> [CmdletBinding(DefaultParameterSetName='/real-time-response/entities/refresh-session/v1:post')] param( [Parameter(ParameterSetName='/real-time-response/entities/refresh-session/v1:post',Position=1)] [Parameter(ParameterSetName='/real-time-response/combined/batch-refresh-session/v1:post',Position=1)] [Alias('queue_offline')] [boolean]$QueueOffline, [Parameter(ParameterSetName='/real-time-response/combined/batch-refresh-session/v1:post',Position=2)] [ValidateRange(30,600)] [int32]$Timeout, [Parameter(ParameterSetName='/real-time-response/combined/batch-refresh-session/v1:post',Position=3)] [ValidatePattern('^\w{32}$')] [Alias('hosts_to_remove','HostsToRemove')] [string[]]$HostToRemove, [Parameter(ParameterSetName='/real-time-response/entities/refresh-session/v1:post',Mandatory, ValueFromPipeline,ValueFromPipelineByPropertyName)] [ValidatePattern('^\w{32}$')] [Alias('device_id','host_ids','aid')] [string]$HostId, [Parameter(ParameterSetName='/real-time-response/combined/batch-refresh-session/v1:post',Mandatory, ValueFromPipelineByPropertyName)] [ValidatePattern('^\w{8}-\w{4}-\w{4}-\w{4}-\w{12}$')] [Alias('batch_id')] [string]$BatchId ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Format = @{ Query = @('timeout') Body = @{ root = @('queue_offline','device_id','batch_id','hosts_to_remove') } } } [System.Collections.Generic.List[string]]$List = @() } process { if ($HostsToRemove) { @($HostsToRemove).foreach{ $List.Add($_) }}} end { # Verify 'Endpoint' using HostId/BatchId $Endpoint = if ($PSBoundParameters.HostId) { '/real-time-response/entities/refresh-session/v1:post' } elseif ($PSBoundParameters.BatchId) { if ($List) { $PSBoundParameters['HostsToRemove'] = @($List | Select-Object -Unique) } '/real-time-response/combined/batch-refresh-session/v1:post' } if ($Endpoint) { @(Invoke-Falcon @Param -Endpoint $Endpoint -Inputs $PSBoundParameters).foreach{ if ($Endpoint -eq '/real-time-response/combined/batch-refresh-session/v1:post') { @($_.PSObject.Properties.Value).Where({ $_.errors }).foreach{ # Write warning for hosts in batch that produced errors Write-Warning "[Update-FalconSession] $( @($_.errors.code,$_.errors.message) -join ': ') [aid: $($_.aid)]" } # Output 'batch_id' and 'hosts' containing result [PSCustomObject]@{ batch_id = $BatchId hosts = $_.PSObject.Properties.Value } } else { # Append 'aid' to single host session result Set-Property $_ aid $HostId $_ } } } } } |