diff --git a/Class/Class.ps1 b/Class/Class.ps1 index 0c33e61c..e9cbe553 100644 --- a/Class/Class.ps1 +++ b/Class/Class.ps1 @@ -45,6 +45,8 @@ class ApiClient { [System.IO.FileMode]::Open) $Filename = [System.IO.Path]::GetFileName($this.Path($_.Value)) $StreamContent = [System.Net.Http.StreamContent]::New($FileStream) + $FileType = $this.StreamType($Filename) + if ($FileType) { $StreamContent.Headers.ContentType = $FileType } $Message.Content.Add($StreamContent,$_.Key,$Filename) @($_.Key,'') -join '=' } else { @@ -74,6 +76,9 @@ class ApiClient { if ($Output.Result.Headers) { Write-Verbose "[ApiClient.Invoke] $($Output.Result.Headers.GetEnumerator().foreach{ @($_.Key,(@($_.Value) -join ', ')) -join '=' } -join ', ')" + ($Output.Result.Headers.GetEnumerator().Where({ $_.Key -match '^X-Api-Deprecation' })).foreach{ + Write-Warning ([string]$_.Key,[string]$_.Value -join ': ') + } } if ($Output.Result -and $this.Collector.Enable -contains 'responses') { $this.Log($Output.Result) } } catch { @@ -135,4 +140,37 @@ class ApiClient { Remove-Job -Id $_.Id } } + [string] StreamType([string]$String) { + [string]$Extension = [System.IO.Path]::GetExtension($String) -replace '^\.',$null + $Output = switch -Regex ($Extension) { + '^(bmp|gif|jp(e?)g|png)$' { "image/$_" } + '^(pdf|zip)$' { "application/$_" } + '^7z$' { 'application/x-7z-compressed' } + '^(csv|txt)$' { + if ($_ -eq 'txt') { 'text/plain' } else { "text/$_" } + } + '^doc(x?)$' { + if ($_ -match 'x$') { + 'application/vnd.openxmlformats-officedocument.wordprocessingml.document' + } else { + 'application/msword' + } + } + '^ppt(x?)$' { + if ($_ -match 'x$') { + 'application/vnd.openxmlformats-officedocument.presentationml.presentation' + } else { + 'application/vnd.ms-powerpoint' + } + } + '^xls(x?)$' { + if ($_ -match 'x$') { + 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' + } else { + 'application/vnd.ms-excel' + } + } + } + return $Output + } } \ No newline at end of file diff --git a/PSFalcon.psd1 b/PSFalcon.psd1 index 71ab125a..e81523cb 100644 --- a/PSFalcon.psd1 +++ b/PSFalcon.psd1 @@ -1,6 +1,6 @@ @{ RootModule = 'PSFalcon.psm1' - ModuleVersion = '2.2.3' + ModuleVersion = '2.2.4' CompatiblePSEditions = @('Desktop','Core') GUID = 'd893eb9f-f6bb-4a40-9caf-aaff0e42acd1' Author = 'Brendan Kremian' @@ -13,420 +13,465 @@ ScriptsToProcess = @('Class/Class.ps1') FunctionsToExport = @( # alerts - 'Get-FalconAlert', - 'Invoke-FalconAlertAction', + 'Get-FalconAlert' + 'Invoke-FalconAlertAction' + + # archives + 'Expand-FalconSampleArchive' + 'Get-FalconSampleArchive' + 'Get-FalconSampleExtraction' + 'Remove-FalconSampleArchive' + 'Send-FalconSampleArchive' # cloud-connect-aws - 'Confirm-FalconDiscoverAwsAccess', - 'Edit-FalconDiscoverAwsAccount', - 'Get-FalconDiscoverAwsAccount', - 'Get-FalconDiscoverAwsSetting', - 'New-FalconDiscoverAwsAccount', - 'Remove-FalconDiscoverAwsAccount', - 'Update-FalconDiscoverAwsSetting', + 'Confirm-FalconDiscoverAwsAccess' + 'Edit-FalconDiscoverAwsAccount' + 'Get-FalconDiscoverAwsAccount' + 'Get-FalconDiscoverAwsLink' + 'Get-FalconDiscoverAwsSetting' + 'New-FalconDiscoverAwsAccount' + 'Receive-FalconDiscoverAwsScript' + 'Remove-FalconDiscoverAwsAccount' + 'Update-FalconDiscoverAwsSetting' # cloud-connect-azure - 'Get-FalconDiscoverAzureAccount', - 'Get-FalconDiscoverAzureCertificate', - 'New-FalconDiscoverAzureAccount', - 'Receive-FalconDiscoverAzureScript', - 'Update-FalconDiscoverAzureAccount', + 'Get-FalconDiscoverAzureAccount' + 'Get-FalconDiscoverAzureCertificate' + 'New-FalconDiscoverAzureAccount' + 'Receive-FalconDiscoverAzureScript' + 'Update-FalconDiscoverAzureAccount' # cloud-connect-cspm-aws - 'Edit-FalconHorizonAwsAccount', - 'Get-FalconHorizonAwsAccount', - 'Get-FalconHorizonAwsLink', - 'New-FalconHorizonAwsAccount', - 'Receive-FalconHorizonAwsScript', - 'Remove-FalconHorizonAwsAccount', + 'Edit-FalconHorizonAwsAccount' + 'Get-FalconHorizonAwsAccount' + 'Get-FalconHorizonAwsLink' + 'New-FalconHorizonAwsAccount' + 'Receive-FalconHorizonAwsScript' + 'Remove-FalconHorizonAwsAccount' # cloud-connect-cspm-azure - 'Edit-FalconHorizonAzureAccount', - 'Get-FalconHorizonAzureAccount', - 'Get-FalconHorizonAzureCertificate', - 'New-FalconHorizonAzureAccount', - 'Receive-FalconHorizonAzureScript', - 'Remove-FalconHorizonAzureAccount', + 'Edit-FalconHorizonAzureAccount' + 'Get-FalconHorizonAzureAccount' + 'Get-FalconHorizonAzureCertificate' + 'New-FalconHorizonAzureAccount' + 'Receive-FalconHorizonAzureScript' + 'Remove-FalconHorizonAzureAccount' # cloud-connect-gcp - 'Get-FalconDiscoverGcpAccount', - 'New-FalconDiscoverGcpAccount', - 'Receive-FalconDiscoverGcpScript', + 'Get-FalconDiscoverGcpAccount' + 'New-FalconDiscoverGcpAccount' + 'Receive-FalconDiscoverGcpScript' # container-security - 'Get-FalconContainerAssessment', - 'Get-FalconContainerSensor', - 'Remove-FalconRegistryCredential', - 'Request-FalconRegistryCredential', - 'Remove-FalconContainerImage', - 'Show-FalconRegistryCredential', + 'Get-FalconContainerAssessment' + 'Get-FalconContainerSensor' + 'Remove-FalconRegistryCredential' + 'Request-FalconRegistryCredential' + 'Remove-FalconContainerImage' + 'Show-FalconRegistryCredential' # detects - 'Edit-FalconDetection', - 'Get-FalconDetection', - 'Get-FalconHorizonIoa', - 'Get-FalconHorizonIom', + 'Edit-FalconDetection' + 'Get-FalconDetection' + 'Get-FalconHorizonIoa' + 'Get-FalconHorizonIom' # devices - 'Add-FalconGroupingTag', - 'Edit-FalconHostGroup', - 'Get-FalconHost', - 'Get-FalconHostGroup', - 'Get-FalconHostGroupMember', - 'Invoke-FalconHostAction', - 'Invoke-FalconHostGroupAction', - 'New-FalconHostGroup', - 'Remove-FalconGroupingTag', - 'Remove-FalconHostGroup', + 'Add-FalconGroupingTag' + 'Edit-FalconHostGroup' + 'Get-FalconHost' + 'Get-FalconHostGroup' + 'Get-FalconHostGroupMember' + 'Invoke-FalconHostAction' + 'Invoke-FalconHostGroupAction' + 'New-FalconHostGroup' + 'Remove-FalconGroupingTag' + 'Remove-FalconHostGroup' # discover - 'Get-FalconAsset', + 'Get-FalconAsset' + + # enrollments + 'Invoke-FalconMobileAction' # falcon-complete-dashboards - 'Get-FalconCompleteAllowlist', - 'Get-FalconCompleteBlocklist', - 'Get-FalconCompleteCollection', - 'Get-FalconCompleteDetection', - 'Get-FalconCompleteEscalation', - 'Get-FalconCompleteIncident', - 'Get-FalconCompleteRemediation', + 'Get-FalconCompleteAllowlist' + 'Get-FalconCompleteBlocklist' + 'Get-FalconCompleteCollection' + 'Get-FalconCompleteDetection' + 'Get-FalconCompleteEscalation' + 'Get-FalconCompleteIncident' + 'Get-FalconCompleteRemediation' # falconx - 'Get-FalconReport', - 'Get-FalconSubmission', - 'Get-FalconSubmissionQuota', - 'New-FalconSubmission', - 'Receive-FalconArtifact', - 'Remove-FalconReport', + 'Get-FalconReport' + 'Get-FalconSubmission' + 'Get-FalconSubmissionQuota' + 'New-FalconSubmission' + 'Receive-FalconArtifact' + 'Remove-FalconReport' # filevantage - 'Get-FalconFimChange', + 'Get-FalconFimChange' # fwmgr - 'Edit-FalconFirewallGroup', - 'Edit-FalconFirewallSetting', - 'Get-FalconFirewallEvent', - 'Get-FalconFirewallField', - 'Get-FalconFirewallGroup', - 'Get-FalconFirewallPlatform', - 'Get-FalconFirewallRule', - 'Get-FalconFirewallSetting', - 'New-FalconFirewallGroup', - 'Remove-FalconFirewallGroup', + 'Edit-FalconFirewallGroup' + 'Edit-FalconFirewallSetting' + 'Get-FalconFirewallEvent' + 'Get-FalconFirewallField' + 'Get-FalconFirewallGroup' + 'Get-FalconFirewallPlatform' + 'Get-FalconFirewallRule' + 'Get-FalconFirewallSetting' + 'New-FalconFirewallGroup' + 'Remove-FalconFirewallGroup' + 'Test-FalconFirewallPath' # identity-protection - 'Invoke-FalconIdentityGraph', + 'Invoke-FalconIdentityGraph' + + # image-assessment + 'Get-FalconContainerVulnerability' # incidents - 'Get-FalconBehavior', - 'Get-FalconIncident', - 'Get-FalconScore', - 'Invoke-FalconIncidentAction', + 'Get-FalconBehavior' + 'Get-FalconIncident' + 'Get-FalconScore' + 'Invoke-FalconIncidentAction' # indicators - 'Get-FalconIocHost', - 'Get-FalconIocProcess', + 'Get-FalconIocHost' + 'Get-FalconIocProcess' # intel - 'Get-FalconActor', - 'Get-FalconIndicator', - 'Get-FalconIntel', - 'Get-FalconRule', - 'Receive-FalconIntel', - 'Receive-FalconRule', + 'Get-FalconActor' + 'Get-FalconAttck' + 'Get-FalconCve' + 'Get-FalconIndicator' + 'Get-FalconIntel' + 'Get-FalconRule' + 'Receive-FalconIntel' + 'Receive-FalconRule' # installation-tokens - 'Edit-FalconInstallToken', - 'Get-FalconInstallToken', - 'Get-FalconInstallTokenEvent', - 'Get-FalconInstallTokenSetting', - 'New-FalconInstallToken', - 'Remove-FalconInstallToken', + 'Edit-FalconInstallToken' + 'Edit-FalconInstallTokenSetting' + 'Get-FalconInstallToken' + 'Get-FalconInstallTokenEvent' + 'Get-FalconInstallTokenSetting' + 'New-FalconInstallToken' + 'Remove-FalconInstallToken' # ioa - 'Get-FalconHorizonIoaEvent', - 'Get-FalconHorizonIoaUser', + 'Get-FalconHorizonIoaEvent' + 'Get-FalconHorizonIoaUser' # ioarules - 'Edit-FalconIoaGroup', - 'Edit-FalconIoaRule', - 'Get-FalconIoaGroup', - 'Get-FalconIoaPlatform', - 'Get-FalconIoaRule', - 'Get-FalconIoaSeverity', - 'Get-FalconIoaType', - 'New-FalconIoaGroup', - 'New-FalconIoaRule', - 'Remove-FalconIoaGroup', - 'Remove-FalconIoaRule', - 'Test-FalconIoaRule', + 'Edit-FalconIoaGroup' + 'Edit-FalconIoaRule' + 'Get-FalconIoaGroup' + 'Get-FalconIoaPlatform' + 'Get-FalconIoaRule' + 'Get-FalconIoaSeverity' + 'Get-FalconIoaType' + 'New-FalconIoaGroup' + 'New-FalconIoaRule' + 'Remove-FalconIoaGroup' + 'Remove-FalconIoaRule' + 'Test-FalconIoaRule' # iocs - 'Edit-FalconIoc', - 'Get-FalconIoc', - 'New-FalconIoc', - 'Remove-FalconIoc', + 'Edit-FalconIoc' + 'Get-FalconIoc' + 'Get-FalconIocAction' + 'Get-FalconIocPlatform' + 'Get-FalconIocSeverity' + 'Get-FalconIocType' + 'New-FalconIoc' + 'Remove-FalconIoc' # kubernetes-protection - 'Edit-FalconContainerAwsAccount', - 'Get-FalconContainerAwsAccount', - 'Get-FalconContainerCloud', - 'Get-FalconContainerCluster', - 'Invoke-FalconContainerScan', - 'New-FalconContainerAwsAccount', - 'New-FalconContainerKey', - 'Receive-FalconContainerYaml', - 'Remove-FalconContainerAwsAccount', + 'Edit-FalconContainerAwsAccount' + 'Edit-FalconContainerAzureAccount' + 'Get-FalconContainerAwsAccount' + 'Get-FalconContainerAzureAccount' + 'Get-FalconContainerCloud' + 'Get-FalconContainerCluster' + 'Invoke-FalconContainerScan' + 'New-FalconContainerAwsAccount' + 'New-FalconContainerAzureAccount' + 'New-FalconContainerKey' + 'Receive-FalconContainerYaml' + 'Remove-FalconContainerAwsAccount' + 'Remove-FalconContainerAzureAccount' # malquery - 'Get-FalconMalQuery', - 'Get-FalconMalQueryQuota', - 'Get-FalconMalQuerySample', - 'Group-FalconMalQuerySample', - 'Invoke-FalconMalQuery', - 'Receive-FalconMalQuerySample', - 'Search-FalconMalQueryHash', + 'Get-FalconMalQuery' + 'Get-FalconMalQueryQuota' + 'Get-FalconMalQuerySample' + 'Group-FalconMalQuerySample' + 'Invoke-FalconMalQuery' + 'Receive-FalconMalQuerySample' + 'Search-FalconMalQueryHash' # message-center - 'Add-FalconCompleteActivity', - 'Edit-FalconCompleteCase', - 'New-FalconCompleteCase', - 'Get-FalconCompleteActivity', - 'Get-FalconCompleteCase', - 'Receive-FalconCompleteAttachment', - 'Send-FalconCompleteAttachment', - - # mobile-enrollment - 'Invoke-FalconMobileAction', + 'Add-FalconCompleteActivity' + 'Edit-FalconCompleteCase' + 'New-FalconCompleteCase' + 'Get-FalconCompleteActivity' + 'Get-FalconCompleteCase' + 'Receive-FalconCompleteAttachment' + 'Send-FalconCompleteAttachment' # mssp - 'Add-FalconCidGroupMember', - 'Add-FalconGroupRole', - 'Add-FalconUserGroupMember', - 'Edit-FalconCidGroup', - 'Edit-FalconUserGroup', - 'Get-FalconCidGroup', - 'Get-FalconCidGroupMember', - 'Get-FalconGroupRole', - 'Get-FalconMemberCid', - 'Get-FalconUserGroup', - 'Get-FalconUserGroupMember', - 'New-FalconCidGroup', - 'New-FalconUserGroup', - 'Remove-FalconCidGroup', - 'Remove-FalconCidGroupMember', - 'Remove-FalconGroupRole', - 'Remove-FalconUserGroup', - 'Remove-FalconUserGroupMember', + 'Add-FalconCidGroupMember' + 'Add-FalconGroupRole' + 'Add-FalconUserGroupMember' + 'Edit-FalconCidGroup' + 'Edit-FalconUserGroup' + 'Get-FalconCidGroup' + 'Get-FalconCidGroupMember' + 'Get-FalconGroupRole' + 'Get-FalconMemberCid' + 'Get-FalconUserGroup' + 'Get-FalconUserGroupMember' + 'New-FalconCidGroup' + 'New-FalconUserGroup' + 'Remove-FalconCidGroup' + 'Remove-FalconCidGroupMember' + 'Remove-FalconGroupRole' + 'Remove-FalconUserGroup' + 'Remove-FalconUserGroupMember' # oauth2 - 'Request-FalconToken', - 'Revoke-FalconToken', - 'Test-FalconToken', + 'Request-FalconToken' + 'Revoke-FalconToken' + 'Test-FalconToken' + + # ods + 'Get-FalconScan' + 'Get-FalconScanFile' + 'Get-FalconScanHost' + 'Get-FalconScheduledScan' + 'New-FalconScheduledScan' + 'Remove-FalconScheduledScan' + 'Start-FalconScan' + 'Stop-FalconScan' # overwatch-dashboards - 'Get-FalconOverWatchEvent', - 'Get-FalconOverWatchDetection', - 'Get-FalconOverWatchIncident', + 'Get-FalconOverWatchEvent' + 'Get-FalconOverWatchDetection' + 'Get-FalconOverWatchIncident' # policy-device-control - 'Edit-FalconDeviceControlPolicy', - 'Get-FalconDeviceControlPolicy', - 'Get-FalconDeviceControlPolicyMember', - 'Invoke-FalconDeviceControlPolicyAction', - 'New-FalconDeviceControlPolicy', - 'Remove-FalconDeviceControlPolicy', - 'Set-FalconDeviceControlPrecedence', + 'Edit-FalconDeviceControlPolicy' + 'Get-FalconDeviceControlPolicy' + 'Get-FalconDeviceControlPolicyMember' + 'Invoke-FalconDeviceControlPolicyAction' + 'New-FalconDeviceControlPolicy' + 'Remove-FalconDeviceControlPolicy' + 'Set-FalconDeviceControlPrecedence' # policy-firewall-management - 'Edit-FalconFirewallPolicy', - 'Get-FalconFirewallPolicy', - 'Get-FalconFirewallPolicyMember', - 'Invoke-FalconFirewallPolicyAction', - 'New-FalconFirewallPolicy', - 'Remove-FalconFirewallPolicy', - 'Set-FalconFirewallPrecedence', + 'Edit-FalconFirewallPolicy' + 'Get-FalconFirewallPolicy' + 'Get-FalconFirewallPolicyMember' + 'Invoke-FalconFirewallPolicyAction' + 'New-FalconFirewallPolicy' + 'Remove-FalconFirewallPolicy' + 'Set-FalconFirewallPrecedence' # policy-ioa-exclusions - 'ConvertTo-FalconIoaExclusion', - 'Edit-FalconIoaExclusion', - 'Get-FalconIoaExclusion', - 'New-FalconIoaExclusion', - 'Remove-FalconIoaExclusion', + 'ConvertTo-FalconIoaExclusion' + 'Edit-FalconIoaExclusion' + 'Get-FalconIoaExclusion' + 'New-FalconIoaExclusion' + 'Remove-FalconIoaExclusion' # policy-ml-exclusions - 'ConvertTo-FalconMlExclusion', - 'Edit-FalconMlExclusion', - 'Get-FalconMlExclusion', - 'New-FalconMlExclusion', - 'Remove-FalconMlExclusion', + 'ConvertTo-FalconMlExclusion' + 'Edit-FalconMlExclusion' + 'Get-FalconMlExclusion' + 'New-FalconMlExclusion' + 'Remove-FalconMlExclusion' # policy-prevention - 'Edit-FalconPreventionPolicy', - 'Get-FalconPreventionPolicy', - 'Get-FalconPreventionPolicyMember', - 'Invoke-FalconPreventionPolicyAction', - 'New-FalconPreventionPolicy', - 'Remove-FalconPreventionPolicy', - 'Set-FalconPreventionPrecedence', + 'Edit-FalconPreventionPolicy' + 'Get-FalconPreventionPolicy' + 'Get-FalconPreventionPolicyMember' + 'Invoke-FalconPreventionPolicyAction' + 'New-FalconPreventionPolicy' + 'Remove-FalconPreventionPolicy' + 'Set-FalconPreventionPrecedence' # policy-response - 'Edit-FalconResponsePolicy', - 'Get-FalconResponsePolicy', + 'Edit-FalconResponsePolicy' + 'Get-FalconResponsePolicy' 'Get-FalconResponsePolicyMember' - 'Invoke-FalconResponsePolicyAction', - 'New-FalconResponsePolicy', - 'Remove-FalconResponsePolicy', - 'Set-FalconResponsePrecedence', + 'Invoke-FalconResponsePolicyAction' + 'New-FalconResponsePolicy' + 'Remove-FalconResponsePolicy' + 'Set-FalconResponsePrecedence' # policy-sensor-update - 'Edit-FalconSensorUpdatePolicy', - 'Get-FalconBuild', - 'Get-FalconKernel', - 'Get-FalconSensorUpdatePolicy', - 'Get-FalconSensorUpdatePolicyMember', - 'Get-FalconUninstallToken', - 'Invoke-FalconSensorUpdatePolicyAction', - 'New-FalconSensorUpdatePolicy', - 'Remove-FalconSensorUpdatePolicy', - 'Set-FalconSensorUpdatePrecedence', + 'Edit-FalconSensorUpdatePolicy' + 'Get-FalconBuild' + 'Get-FalconKernel' + 'Get-FalconSensorUpdatePolicy' + 'Get-FalconSensorUpdatePolicyMember' + 'Get-FalconUninstallToken' + 'Invoke-FalconSensorUpdatePolicyAction' + 'New-FalconSensorUpdatePolicy' + 'Remove-FalconSensorUpdatePolicy' + 'Set-FalconSensorUpdatePrecedence' # policy-sv-exclusions - 'Edit-FalconSvExclusion', - 'Get-FalconSvExclusion', - 'New-FalconSvExclusion', - 'Remove-FalconSvExclusion', + 'Edit-FalconSvExclusion' + 'Get-FalconSvExclusion' + 'New-FalconSvExclusion' + 'Remove-FalconSvExclusion' # psf-config - 'Export-FalconConfig', - 'Import-FalconConfig', + 'Export-FalconConfig' + 'Import-FalconConfig' # psf-devices - 'Find-FalconDuplicate', - 'Find-FalconHostname', + 'Find-FalconDuplicate' + 'Find-FalconHostname' - # psf-humio - 'Register-FalconEventCollector', - 'Send-FalconEvent', - 'Show-FalconEventCollector', - 'Unregister-FalconEventCollector', + # psf-fwmgr + 'ConvertTo-FalconFirewallRule' + + # psf-logscale + 'Register-FalconEventCollector' + 'Send-FalconEvent' + 'Show-FalconEventCollector' + 'Unregister-FalconEventCollector' # psf-output - 'Export-FalconReport', - 'Send-FalconWebhook', - 'Show-FalconMap', - 'Show-FalconModule', + 'Export-FalconReport' + 'Send-FalconWebhook' + 'Show-FalconMap' + 'Show-FalconModule' # psf-policies - 'Compare-FalconPreventionPhase', - 'Copy-FalconDeviceControlPolicy', - 'Copy-FalconFirewallPolicy', - 'Copy-FalconPreventionPolicy', - 'Copy-FalconResponsePolicy', - 'Copy-FalconSensorUpdatePolicy', + 'Compare-FalconPreventionPhase' + 'Copy-FalconDeviceControlPolicy' + 'Copy-FalconFirewallPolicy' + 'Copy-FalconPreventionPolicy' + 'Copy-FalconResponsePolicy' + 'Copy-FalconSensorUpdatePolicy' # psf-sensors - 'Add-FalconSensorTag', - 'Get-FalconSensorTag', - 'Remove-FalconSensorTag', - 'Uninstall-FalconSensor', + 'Add-FalconSensorTag' + 'Get-FalconSensorTag' + 'Remove-FalconSensorTag' + 'Uninstall-FalconSensor' # psf-real-time-response - 'Get-FalconQueue', - 'Invoke-FalconDeploy', - 'Invoke-FalconRtr', + 'Get-FalconQueue' + 'Invoke-FalconDeploy' + 'Invoke-FalconRtr' # quarantine - 'Get-FalconQuarantine', - 'Invoke-FalconQuarantineAction', - 'Test-FalconQuarantineAction', + 'Get-FalconQuarantine' + 'Invoke-FalconQuarantineAction' + 'Test-FalconQuarantineAction' # real-time-response - 'Confirm-FalconAdminCommand', - 'Confirm-FalconCommand', - 'Confirm-FalconGetFile', - 'Confirm-FalconResponderCommand', - 'Edit-FalconScript', - 'Get-FalconPutFile', - 'Get-FalconScript', - 'Get-FalconSession', - 'Invoke-FalconAdminCommand', - 'Invoke-FalconBatchGet', - 'Invoke-FalconCommand', - 'Invoke-FalconResponderCommand', - 'Receive-FalconGetFile', - 'Remove-FalconCommand', - 'Remove-FalconGetFile', - 'Remove-FalconPutFile', - 'Remove-FalconScript', - 'Remove-FalconSession', - 'Send-FalconPutFile', - 'Send-FalconScript', - 'Start-FalconSession', - 'Update-FalconSession', + 'Confirm-FalconAdminCommand' + 'Confirm-FalconCommand' + 'Confirm-FalconGetFile' + 'Confirm-FalconResponderCommand' + 'Edit-FalconScript' + 'Get-FalconPutFile' + 'Get-FalconScript' + 'Get-FalconSession' + 'Invoke-FalconAdminCommand' + 'Invoke-FalconBatchGet' + 'Invoke-FalconCommand' + 'Invoke-FalconResponderCommand' + 'Receive-FalconGetFile' + 'Remove-FalconCommand' + 'Remove-FalconGetFile' + 'Remove-FalconPutFile' + 'Remove-FalconScript' + 'Remove-FalconSession' + 'Send-FalconPutFile' + 'Send-FalconScript' + 'Start-FalconSession' + 'Update-FalconSession' # recon - 'Edit-FalconReconAction', - 'Edit-FalconReconNotification', - 'Edit-FalconReconRule', - 'Get-FalconReconAction', - 'Get-FalconReconNotification', - 'Get-FalconReconRule', - 'Get-FalconReconRulePreview', - 'New-FalconReconAction', - 'New-FalconReconRule', - 'Remove-FalconReconAction', - 'Remove-FalconReconRule', - 'Remove-FalconReconNotification', + 'Edit-FalconReconAction' + 'Edit-FalconReconNotification' + 'Edit-FalconReconRule' + 'Get-FalconReconAction' + 'Get-FalconReconExport' + 'Get-FalconReconNotification' + 'Get-FalconReconRecord' + 'Get-FalconReconRule' + 'Get-FalconReconRulePreview' + 'Invoke-FalconReconExport' + 'New-FalconReconAction' + 'New-FalconReconRule' + 'Receive-FalconReconExport' + 'Remove-FalconReconAction' + 'Remove-FalconReconExport' + 'Remove-FalconReconRule' + 'Remove-FalconReconNotification' # reports - 'Get-FalconScheduledReport', - 'Invoke-FalconScheduledReport', - 'Receive-FalconScheduledReport', - 'Redo-FalconScheduledReport', + 'Get-FalconScheduledReport' + 'Invoke-FalconScheduledReport' + 'Receive-FalconScheduledReport' + 'Redo-FalconScheduledReport' # samples - 'Get-FalconSample', - 'Send-FalconSample', - 'Receive-FalconSample', - 'Remove-FalconSample', + 'Get-FalconSample' + 'Send-FalconSample' + 'Receive-FalconSample' + 'Remove-FalconSample' # scanner - 'Get-FalconQuickScan', - 'Get-FalconQuickScanQuota', - 'New-FalconQuickScan', + 'Get-FalconQuickScan' + 'Get-FalconQuickScanQuota' + 'New-FalconQuickScan' # sensors - 'Get-FalconCcid', - 'Get-FalconInstaller', - 'Get-FalconStream', - 'Receive-FalconInstaller', - 'Update-FalconStream', + 'Get-FalconCcid' + 'Get-FalconInstaller' + 'Get-FalconStream' + 'Receive-FalconInstaller' + 'Update-FalconStream' # settings - 'Edit-FalconHorizonPolicy', - 'Edit-FalconHorizonSchedule', - 'Get-FalconHorizonPolicy', - 'Get-FalconHorizonSchedule', + 'Edit-FalconHorizonPolicy' + 'Edit-FalconHorizonSchedule' + 'Get-FalconHorizonPolicy' + 'Get-FalconHorizonSchedule' + + # settings-discover + 'Get-FalconDiscoverAwsScript' # spotlight - 'Get-FalconRemediation', - 'Get-FalconVulnerability', - 'Get-FalconVulnerabilityLogic', + 'Get-FalconRemediation' + 'Get-FalconVulnerability' + 'Get-FalconVulnerabilityLogic' # ti - 'Get-FalconTailoredEvent', - 'Get-FalconTailoredRule', + 'Get-FalconTailoredEvent' + 'Get-FalconTailoredRule' # user-management - 'Add-FalconRole', - 'Edit-FalconUser', - 'Get-FalconRole', - 'Get-FalconUser', - 'Invoke-FalconUserAction', - 'New-FalconUser', - 'Remove-FalconRole', - 'Remove-FalconUser', + 'Add-FalconRole' + 'Edit-FalconUser' + 'Get-FalconRole' + 'Get-FalconUser' + 'Invoke-FalconUserAction' + 'New-FalconUser' + 'Remove-FalconRole' + 'Remove-FalconUser' # zero-trust-assessment 'Get-FalconZta' @@ -438,76 +483,10 @@ PSData = @{ Tags = @('CrowdStrike','Falcon','OAuth2','REST','API','PSEdition_Desktop','PSEdition_Core', 'Windows','Linux','MacOS') - LicenseUri = 'https://raw.githubusercontent.com/CrowdStrike/psfalcon/master/LICENSE' + LicenseUri = 'https://raw.githubusercontent.com/crowdstrike/psfalcon/master/LICENSE' ProjectUri = 'https://github.com/crowdstrike/psfalcon' - IconUri = 'https://raw.githubusercontent.com/CrowdStrike/psfalcon/master/icon.png' - ReleaseNotes = "@ -New Commands - -* psf-policies - 'Compare-FalconPreventionPhase' - -* ti - 'Get-FalconTailoredEvent' - 'Get-FalconTailoredRule' - -General Changes - -* Created 'Confirm-Property' private function to filter [hashtable] and [PSCustomObject] into pre-defined - properties containing values. - -* Updated comment-based help to link directly to specific wiki pages for each command. Using 'Get-Help - -Online' will launch the appropriate wiki page. These pages will be updated with current examples present within - existing wiki pages, and those pages will be re-organized. - -* Modified 'Get-ParamSet' private function to look for 'ids' and 'samples' as potential body values to break into - groups of 'Max' values, instead of only 'ids'. - -* Updated Falcon X references to Falcon Intelligence due to product name change. - -Command Changes - -* Updated 'Invoke-FalconIdentityGraph' to no longer modify the GraphQL statement when attempting to use '-All' for - pagination. Renamed 'Query' parameter to 'String' and made it work for both query and mutation statements but - kept 'Query' as an alias. Now, when your statement includes a 'Cursor' variable definition and the required - 'pageInfo { hasNextPage endCursor }' properties, '-All' will automatically paginate results. If either of those - requirements are missing, a warning message will be displayed and pagination will not occur. - -* Modified 'Get-FalconUser' to remove deprecated API when using 'Username' parameter. 'Username' now submits - filtered searches for provided 'uid' values to the appropriate /user-management/ API. - -* Added 'Max' of 1,000 sha256 values for 'New-FalconQuickScan'. - -* Added 'sha256' as a PipelineByPropertyName value for 'New-FalconQuickScan' to support pipeline input from - 'Send-FalconSample'. - -* Added pattern validation to 'Remove-FalconUser' for the 'Id' parameter. - -* Modified 'Status' parameter for 'Edit-FalconDetection' to support ValueFromPipelineByPropertyName and changed - parameter to position 3. - -* Modified 'Edit-FalconSensorUpdatePolicy' and 'New-FalconSensorUpdatePolicy' to filter out properties with - empty string values in order to prevent errors when creating and/or modifying Sensor Update policies. - -* Modified 'Import-FalconConfig' to prevent an attempt to modify a policy when the policy was not successfully - created earlier in the import process. Also ensured that the precedence warnings when existing policies were - found would only be displayed once. - -Resolved Issues - -* Issue #241: Updated 'Confirm-Parameter' to eliminate 'Cannot validate argument on parameter 'Array'. Key cannot - be null. (Parameter 'key')' errors generated when using 'Import-FalconConfig'. - -* Issue #242: Modified 'Edit-FalconDetection' to check whether a 'status' value is present with a 'comment' value - during command execution rather than during parameter validation. This will prevent errors from occurring when - parameters are specified in an unexpected order. - -* Issue #246: Created 'Confirm-Property' function to properly filter 'Rule' content for both [hashtable] and - [PSCustomObject] rules. This will eliminate errors caused by [hashtable] objects being improperly filtered - in PowerShell 5.1. - - * Issue #247: Updated 'Write-Warning' to use a PSCmdlet method in order to properly support 'WarningVariable'. -@" + IconUri = 'https://raw.githubusercontent.com/crowdstrike/psfalcon/master/icon.png' + ReleaseNotes = 'https://github.com/crowdstrike/psfalcon/releases/tag/2.2.4' } } } \ No newline at end of file diff --git a/Policy/linux.json b/Policy/linux.json index f39f954b..7af901f2 100644 Binary files a/Policy/linux.json and b/Policy/linux.json differ diff --git a/Policy/mac.json b/Policy/mac.json index 7a9e11fb..9b5f0015 100644 Binary files a/Policy/mac.json and b/Policy/mac.json differ diff --git a/Policy/windows.json b/Policy/windows.json index 17e3742d..1de321bb 100644 Binary files a/Policy/windows.json and b/Policy/windows.json differ diff --git a/Private/Private.ps1 b/Private/Private.ps1 index b600cdf6..314e2e9b 100644 --- a/Private/Private.ps1 +++ b/Private/Private.ps1 @@ -3,8 +3,8 @@ function Add-Include { [OutputType([void])] param( [object[]]$Object, - [System.Object]$Inputs, - [System.Collections.Hashtable]$Index, + [object]$Inputs, + [hashtable]$Index, [string]$Command ) if ($Inputs.Include) { @@ -36,9 +36,9 @@ function Add-Include { foreach ($i in (& "$($_.Value)" -Id $Object.id)) { $SetParam = @{ Object = if ($i.policy_id) { - $Object | Where-Object { $_.id -eq $i.policy_id } + @($Object).Where({ $_.id -eq $i.policy_id }) } else { - $Object | Where-Object { $_.id -eq $i.id } + @($Object).Where({ $_.id -eq $i.id }) } Name = $_.Key Value = $i @@ -54,9 +54,9 @@ function Add-Include { # Append all properties from 'Include' $SetParam = @{ Object = if ($i.device_id) { - $Object | Where-Object { $_.id -eq $i.device_id } + @($Object).Where({ $_.id -eq $i.device_id }) } else { - $Object | Where-Object { $_.id -eq $i.id } + @($Object).Where({ $_.id -eq $i.id }) } Name = $_ Value = $i.$_ @@ -86,7 +86,7 @@ function Assert-Extension { function Build-Content { [CmdletBinding()] [OutputType([hashtable])] - param([System.Object]$Format,[System.Object]$Inputs) + param([hashtable]$Format,[object]$Inputs) begin { function Build-Body ($Format,$Inputs) { $Body = @{} @@ -116,8 +116,8 @@ function Build-Content { $ByteArray.Headers.Add('Content-Type',$Headers.ContentType) } else { if (!$Body) { $Body = @{} } - if (($Value -is [array] -or $Value -is [string]) -and $Value | - Get-Member -MemberType Method | Where-Object { $_.Name -eq 'Normalize' }) { + if (($Value -is [array] -or $Value -is [string]) -and ($Value | + Get-Member -MemberType Method).Where({ $_.Name -eq 'Normalize' })) { # Normalize values to avoid Json conversion errors when 'Get-Content' was used if ($Value -is [array]) { $Value = [array] ($Value).Normalize() @@ -221,7 +221,7 @@ function Confirm-Parameter { [OutputType([boolean])] param( [Parameter(Mandatory)] - [System.Object]$Object, + [object]$Object, [Parameter(Mandatory)] [string]$Command, [Parameter(Mandatory)] @@ -230,66 +230,50 @@ function Confirm-Parameter { [string[]]$Allowed, [string[]]$Content, [string[]]$Pattern, - [System.Collections.Hashtable]$Format + [hashtable]$Format ) begin { - function Get-ValidPattern ([string]$Command,[string]$Endpoint,[string]$Parameter) { - # Return 'ValidPattern' from parameter of a given command - (Get-Command $Command).ParameterSets.Where({ $_.Name -eq $Endpoint }).Parameters.Where({ - $_.Name -eq $Parameter -or $_.Aliases -contains $Parameter }).Attributes.RegexPattern - } - function Get-ValidValues ([string]$Command,[string]$Endpoint,[string]$Parameter) { - # Return 'ValidValues' from parameter of a given command - (Get-Command $Command).ParameterSets.Where({ $_.Name -eq $Endpoint }).Parameters.Where({ - $_.Name -eq $Parameter -or $_.Aliases -contains $Parameter }).Attributes.ValidValues - } - # Create object string - $ObjectString = ConvertTo-Json $Object -Depth 32 -Compress + # Retrieve parameters from target $Endpoint and create object string for error message + $ParamList = @((Get-Command $Command).Parameters.Values).Where({ $_.ParameterSets.Keys -contains + $Endpoint }) + [string]$ErrorObject = ConvertTo-Json $Object -Depth 32 -Compress } process { - if ($Object -is [System.Collections.Hashtable]) { - @($Required).foreach{ - # Verify object contains required fields - if ($Object.Keys -notcontains $_) { throw "Missing '$_'. $ObjectString" } else { $true } - } - if ($Allowed) { - @($Object.Keys).foreach{ - # Error if field is not in allowed list - if ($Allowed -notcontains $_) { throw "Unexpected '$_'. $ObjectString" } else { $true } - } - } + [string[]]$Keys = if ($Object -is [hashtable]) { + $Object.Keys } elseif ($Object -is [PSCustomObject]) { - @($Required).foreach{ - # Verify object contains required fields - if ($Object.PSObject.Members.Where({ $_.MemberType -eq 'NoteProperty' }).Name -notcontains $_) { - throw "Missing '$_'. $ObjectString" - } else { - $true - } - } - if ($Allowed) { - @($Object.PSObject.Members.Where({ $_.MemberType -eq 'NoteProperty' }).Name).foreach{ - # Error if field is not in allowed list - if ($Allowed -notcontains $_) { throw "Unexpected '$_'. $ObjectString" } else { $true } - } + $Object.PSObject.Members.Where({ $_.MemberType -eq 'NoteProperty' }).Name + } + @($Required).foreach{ + # Verify object contains required fields + if ($Keys -notcontains $_) { throw "Missing property '$_'. $ErrorObject" } else { $true } + } + @($Keys).foreach{ + # Error if field is not in allowed list + if ($Allowed -and $Allowed -notcontains $_) { + throw "Unexpected property '$_'. $ErrorObject" + } else { + $true } } if ($Content) { @($Content).foreach{ # Match property name with parameter name - [string]$Parameter = if ($Format -and $Format.$_) { $Format.$_ } else { $_ } + [string]$Name = if ($Format -and $Format.$_) { $Format.$_ } else { $_ } if ($Object.$_) { # Verify that 'ValidValues' contains provided value - [string[]]$ValidValues = Get-ValidValues $Command $Endpoint $Parameter + [string[]]$ValidValues = @($ParamList).Where({ $_.Name -eq $Name }).Attributes.ValidValues if ($ValidValues) { if ($Object.$_ -is [array]) { foreach ($Item in $Object.$_) { if ($ValidValues -notcontains $Item) { - "'$Item' is not a valid '$_' value. $ObjectString" + "'$Item' is not a valid '$_' value. $ErrorObject" } } } elseif ($ValidValues -notcontains $Object.$_) { - throw "'$($Object.$_)' is not a valid '$_' value. $ObjectString" + throw "'$($Object.$_)' is not a valid '$_' value. $ErrorObject" + } else { + $true } } } @@ -298,12 +282,15 @@ function Confirm-Parameter { if ($Pattern) { @($Pattern).foreach{ # Match property name with parameter name - [string]$Parameter = if ($Format -and $Format.$_) { $Format.$_ } else { $_ } + [string]$Name = if ($Format -and $Format.$_) { $Format.$_ } else { $_ } if ($Object.$_) { # Verify provided value matches 'ValidPattern' - $ValidPattern = Get-ValidPattern $Command $Endpoint $Parameter + [string]$ValidPattern = @($ParamList).Where.({ $_.Name -eq $Name -or $_.Aliases -contains + $Name }).Attributes.RegexPattern if ($ValidPattern -and $Object.$_ -notmatch $ValidPattern) { - throw "'$($Object.$_)' is not a valid '$_' value. $ObjectString" + throw "'$($Object.$_)' is not a valid '$_' value. $ErrorObject" + } else { + $true } } } @@ -359,9 +346,9 @@ function Get-ParamSet { [CmdletBinding()] param( [string]$Endpoint, - [System.Object]$Headers, - [System.Object]$Inputs, - [System.Object]$Format, + [hashtable]$Headers, + [object]$Inputs, + [hashtable]$Format, [int32]$Max, [string]$HostUrl ) @@ -485,12 +472,12 @@ function Get-RtrCommand { $_.Key -eq 'Command' }).Value.Attributes.ValidValues } # Filter 'Responder' and 'Admin' to unique command(s) - $Index.Responder = $Index.Responder | Where-Object { $Index.ReadOnly -notcontains $_ } - $Index.Admin = $Index.Admin | Where-Object { $Index.ReadOnly -notcontains $_ -and - $Index.Responder -notcontains $_ } + $Index.Responder = @($Index.Responder).Where({ $Index.ReadOnly -notcontains $_ }) + $Index.Admin = @($Index.Admin).Where({ $Index.ReadOnly -notcontains $_ -and $Index.Responder -notcontains + $_ }) if ($Command) { # Determine command to invoke using $Command and permission level - $Result = if ($Command -eq 'runscript') { + [string]$Result = if ($Command -eq 'runscript') { # Force 'Admin' for 'runscript' command 'Invoke-FalconAdminCommand' } else { @@ -513,14 +500,14 @@ function Get-RtrResult { param([object[]]$Object,[object[]]$Output) begin { # Real-time Response fields to capture from results - $RtrFields = @('aid','batch_get_cmd_req_id','batch_id','cloud_request_id','complete','errors', + [string[]]$RtrFields = 'aid','batch_get_cmd_req_id','batch_id','cloud_request_id','complete','errors', 'error_message','name','offline_queued','progress','queued_command_offline','session_id','sha256', - 'size','status','stderr','stdout','task_id') + 'size','status','stderr','stdout','task_id' } process { foreach ($Result in ($Object | Select-Object $RtrFields)) { # Update 'Output' with populated result(s) from 'Object' - @($Result.PSObject.Properties | Where-Object { $_.Value -or $_.Value -is [boolean] }).foreach{ + @($Result.PSObject.Properties).Where({ $_.Value -or $_.Value -is [boolean] }).foreach{ $Name = if ($_.Name -eq 'task_id') { # Rename 'task_id' to 'cloud_request_id' 'cloud_request_id' @@ -542,7 +529,7 @@ function Get-RtrResult { # Update 'Output' with result using 'aid' or 'session_id' $Match = if ($Result.aid) { 'aid' } else { 'session_id' } if ($Result.$Match) { - @($Output | Where-Object { $Result.$Match -eq $_.$Match }).foreach{ + @($Output).Where({ $Result.$Match -eq $_.$Match }).foreach{ Set-Property $_ $Name $Value } } @@ -556,12 +543,13 @@ function Invoke-Falcon { param( [string]$Command, [string]$Endpoint, - [System.Collections.Hashtable]$Headers, - [System.Object]$Inputs, - [System.Object]$Format, + [hashtable]$Headers, + [object]$Inputs, + [hashtable]$Format, [switch]$RawOutput, [int32]$Max, - [string]$HostUrl + [string]$HostUrl, + [switch]$BodyArray ) begin { function Invoke-Loop ([hashtable]$Splat,[object]$Object,[int]$Int) { @@ -634,11 +622,11 @@ function Invoke-Falcon { } if (!$Script:Falcon.Api.Client.DefaultRequestHeaders.Authorization -or !$Script:Falcon.Hostname) { # Force initial authorization token request - Request-FalconToken + if ($PSCmdlet.ShouldProcess('Request-FalconToken','Get-ApiCredential')) { Request-FalconToken } } # Gather request parameters and split into groups $GetParam = @{} - $PSBoundParameters.GetEnumerator().Where({ $_.Key -notmatch '^(Command|RawOutput)$' }).foreach{ + $PSBoundParameters.GetEnumerator().Where({ $_.Key -notmatch '^(BodyArray|Command|RawOutput)$' }).foreach{ $GetParam.Add($_.Key,$_.Value) } # Add 'Accept: application/json' when undefined @@ -681,11 +669,16 @@ function Invoke-Falcon { process { Get-ParamSet @GetParam | ForEach-Object { [string]$Operation = $_.Endpoint.Method.ToUpper() - [string]$Target = New-ShouldMessage $_.Endpoint if ($_.Endpoint.Headers.ContentType -eq 'application/json' -and $_.Endpoint.Body) { - # Convert body to Json - $_.Endpoint.Body = ConvertTo-Json $_.Endpoint.Body -Depth 32 -Compress + $_.Endpoint.Body = if ($BodyArray) { + # Force Json array when 'BodyArray' is present + ConvertTo-Json @($_.Endpoint.Body) -Depth 32 -Compress + } else { + # Convert body to Json + ConvertTo-Json $_.Endpoint.Body -Depth 32 -Compress + } } + [string]$Target = New-ShouldMessage $_.Endpoint if ($PSCmdlet.ShouldProcess($Target,$Operation)) { if ($Script:Falcon.Expiration -le (Get-Date).AddSeconds(60)) { Request-FalconToken } try { @@ -725,7 +718,7 @@ function Invoke-Falcon { function New-ShouldMessage { [CmdletBinding()] [OutputType([string[]])] - param ([System.Collections.Hashtable]$Object) + param ([hashtable]$Object) process { try { $Output = [PSCustomObject]@{} @@ -754,17 +747,69 @@ function New-ShouldMessage { } if ($Object.Body -and $Object.Headers.ContentType -eq 'application/json') { # Add 'Body' value - [string]$Body = try { $Object.Body | ConvertTo-Json -Depth 8 } catch {} - if ($Body) { Set-Property $Output Body $Body } + Set-Property $Output Body $Object.Body + } + if ($Object.Formdata) { + # Add 'Formdata' value + [string]$Formdata = try { $Object.Formdata | ConvertTo-Json -Depth 8 } catch {} + if ($Formdata) { Set-Property $Output Formdata $Formdata } } "`r`n",($Output | Format-List | Out-String).Trim(),"`r`n" -join "`r`n" } catch {} } } +function Select-Property { + [CmdletBinding()] + param( + [Parameter(Mandatory,Position=1)] + [object[]]$Object, + [Parameter(Mandatory,Position=2)] + [string]$Parameter, + [Parameter(Mandatory,Position=3)] + [string]$Pattern, + [Parameter(Mandatory,Position=4)] + [string]$Command, + [Parameter(Mandatory,Position=5)] + [string]$Property, + [Parameter(Position=6)] + [string]$Parent + ) + function Select-StringMatch ([string[]]$String,[string]$Parameter,[string]$Pattern,[string]$Command) { + @($String).foreach{ + if ($_ -notmatch $Pattern) { + # Output error record for eventual return + [string]$Message = "Cannot validate argument on parameter '$Parameter'.", + ('The argument "{0}" does not match the "{1}" pattern.' -f $_,$Pattern), + ('Supply an argument that matches "{0}" and try the command again.' -f $Pattern) -join ' ' + [System.Management.Automation.ErrorRecord]::New( + [Exception]::New($Message), + 'ParameterArgumentValidationError', + [System.Management.Automation.ErrorCategory]::InvalidData, + $_ + ) + } elseif ($_ -match $Pattern) { + # Output matching string value + $_ + } + } + } + @($Object).foreach{ + if ($Parent -and $_.$Parent.$Property) { + # Check 'Property' under 'Parent' for matching value + @($_.$Parent.$Property).foreach{ Select-StringMatch $_ $Parameter $Pattern $Command } + } elseif ($_.$Property) { + # Check 'Property' for matching value + @($_.$Property).foreach{ Select-StringMatch $_ $Parameter $Pattern $Command } + } elseif (![string]::IsNullOrEmpty($_)) { + # Treat value as [string] and check for match + Select-StringMatch $_ $Parameter $Pattern $Command + } + } +} function Set-Property { [CmdletBinding()] [OutputType([void])] - param([System.Object]$Object,[string]$Name,[System.Object]$Value) + param([object]$Object,[string]$Name,[object]$Value) process { if ($Object.$Name) { # Update existing property @@ -797,7 +842,7 @@ function Test-FqlStatement { } function Test-OutFile { [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] + [OutputType([hashtable])] param([string]$Path) process { if (!$Path) { @@ -857,7 +902,7 @@ function Test-RegexValue { } function Write-Result { [CmdletBinding()] - param([System.Object]$Request) + param([object]$Request) begin { function Write-Meta ($Object) { # Convert [array] and [PSCustomObject] into a flat Verbose output message @@ -924,8 +969,8 @@ function Write-Result { # Output single field $Json.$ResponseFields } - } elseif ($Json.meta) { - # Output 'meta' fields when nothing else is available + } elseif ($Json.meta -and !$Json.errors) { + # Output 'meta' fields when nothing else is available and no errors were produced [string[]]$MetaFields = @($Json.meta.PSObject.Properties).Where({ $_.Name -notmatch '^(entity|pagination|powered_by|query_time|trace_id)$' }).foreach{ $_.Name } if ($MetaFields) { $Json.meta | Select-Object $MetaFields } @@ -952,7 +997,7 @@ function Write-Result { } function Wait-RetryAfter { [CmdletBinding()] - param([System.Object]$Request) + param([object]$Request) process { if ($Request.Result.StatusCode -and $Request.Result.StatusCode.GetHashCode() -eq 429 -and $Request.Result.RequestMessage.RequestUri.AbsolutePath -ne '/oauth2/token') { diff --git a/Public/alerts.ps1 b/Public/alerts.ps1 index 3e19173d..e1292161 100644 --- a/Public/alerts.ps1 +++ b/Public/alerts.ps1 @@ -27,8 +27,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconAlert #> [CmdletBinding(DefaultParameterSetName='/alerts/queries/alerts/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/alerts/entities/alerts/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/alerts/entities/alerts/v1:post',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}:(aggind|ind):[a-fA-F0-9]{32}:.+$')] [Alias('Ids','composite_id')] [string[]]$Id, @@ -93,8 +93,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconAlertAction [string]$Name, [Parameter(ParameterSetName='/alerts/entities/alerts/v2:patch',Position=2)] [string]$Value, - [Parameter(ParameterSetName='/alerts/entities/alerts/v2:patch',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=3)] + [Parameter(ParameterSetName='/alerts/entities/alerts/v2:patch',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}:(aggind|ind):[a-fA-F0-9]{32}:.+$')] [Alias('Ids','composite_id')] [string[]]$Id diff --git a/Public/archives.ps1 b/Public/archives.ps1 new file mode 100644 index 00000000..d8c5c062 Binary files /dev/null and b/Public/archives.ps1 differ diff --git a/Public/cloud-connect-aws.ps1 b/Public/cloud-connect-aws.ps1 index 58437432..b98592c6 100644 --- a/Public/cloud-connect-aws.ps1 +++ b/Public/cloud-connect-aws.ps1 @@ -7,13 +7,13 @@ Requires 'AWS Accounts: Write'. .PARAMETER Id AWS account identifier .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Confirm-FalconDiscoverAwsAccess +https://github.com/crowdstrike/psfalcon/wiki/Confirm-FalconDiscoverAwsAccess #> [CmdletBinding(DefaultParameterSetName='/cloud-connect-aws/entities/verify-account-access/v1:post', SupportsShouldProcess)] param( [Parameter(ParameterSetName='/cloud-connect-aws/entities/verify-account-access/v1:post',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=1)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^\d{12}$')] [Alias('Ids')] [string[]]$Id @@ -55,7 +55,7 @@ Maximum number of requests within 'RateLimitTime' .PARAMETER Id AWS account identifier .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Edit-FalconDiscoverAwsAccount +https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconDiscoverAwsAccount #> [CmdletBinding(DefaultParameterSetName='/cloud-connect-aws/entities/accounts/v1:patch',SupportsShouldProcess)] param( @@ -110,56 +110,60 @@ Search for Falcon Discover for Cloud AWS accounts Requires 'AWS Accounts: Read'. .PARAMETER Id AWS account identifier -.PARAMETER Filter -Falcon Query Language expression to limit results -.PARAMETER Sort -Property and direction to sort results +.PARAMETER OrganizationId +AWS organization identifier +.PARAMETER ScanType +Scan type +.PARAMETER Status +AWS account status +.PARAMETER Migrated +Account migration status .PARAMETER Limit Maximum number of results per request .PARAMETER Offset Position to begin retrieving results -.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/Get-FalconDiscoverAwsAccount +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconDiscoverAwsAccount #> - [CmdletBinding(DefaultParameterSetName='/cloud-connect-aws/queries/accounts/v1:get',SupportsShouldProcess)] + [CmdletBinding(DefaultParameterSetName='/cloud-connect-aws/entities/account/v2:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/cloud-connect-aws/entities/accounts/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/cloud-connect-aws/entities/account/v2:get',ValueFromPipelineByPropertyName, + ValueFromPipeline)] [ValidatePattern('^\d{12}$')] - [Alias('Ids')] + [Alias('ids')] [string[]]$Id, - [Parameter(ParameterSetName='/cloud-connect-aws/queries/accounts/v1:get',Position=1)] - [Parameter(ParameterSetName='/cloud-connect-aws/combined/accounts/v1:get',Position=1)] - [ValidateScript({ Test-FqlStatement $_ })] - [string]$Filter, - [Parameter(ParameterSetName='/cloud-connect-aws/queries/accounts/v1:get',Position=2)] - [Parameter(ParameterSetName='/cloud-connect-aws/combined/accounts/v1:get',Position=2)] - [string]$Sort, - [Parameter(ParameterSetName='/cloud-connect-aws/queries/accounts/v1:get',Position=3)] - [Parameter(ParameterSetName='/cloud-connect-aws/combined/accounts/v1:get',Position=3)] + [Parameter(ParameterSetName='/cloud-connect-aws/entities/account/v2:get',Position=1)] + [ValidatePattern('^o-[0-9a-z]{10,32}$')] + [Alias('organization-ids')] + [string[]]$OrganizationId, + [Parameter(ParameterSetName='/cloud-connect-aws/entities/account/v2:get',Position=2)] + [ValidateSet('full','dry',IgnoreCase=$false)] + [Alias('scan-type')] + [string]$ScanType, + [Parameter(ParameterSetName='/cloud-connect-aws/entities/account/v2:get',Position=3)] + [ValidateSet('provisioned','operational',IgnoreCase=$false)] + [string]$Status, + [Parameter(ParameterSetName='/cloud-connect-aws/entities/account/v2:get',Position=4)] + [boolean]$Migrated, + [Parameter(ParameterSetName='/cloud-connect-aws/entities/account/v2:get',Position=5)] [ValidateRange(1,500)] [int32]$Limit, - [Parameter(ParameterSetName='/cloud-connect-aws/queries/accounts/v1:get')] - [Parameter(ParameterSetName='/cloud-connect-aws/combined/accounts/v1:get')] + [Parameter(ParameterSetName='/cloud-connect-aws/entities/account/v2:get')] [int32]$Offset, - [Parameter(ParameterSetName='/cloud-connect-aws/combined/accounts/v1:get',Mandatory)] - [switch]$Detailed, - [Parameter(ParameterSetName='/cloud-connect-aws/queries/accounts/v1:get')] + [Parameter(ParameterSetName='/cloud-connect-aws/entities/account/v2:get')] [switch]$All, - [Parameter(ParameterSetName='/cloud-connect-aws/queries/accounts/v1:get')] + [Parameter(ParameterSetName='/cloud-connect-aws/entities/account/v2:get')] [switch]$Total ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName - Format = @{ Query = @('sort','ids','offset','limit','filter') } + Format = @{ Query = @('migrated','ids','scan-type','status','limit','organization-ids','offset') } } [System.Collections.Generic.List[string]]$List = @() } @@ -169,14 +173,40 @@ https://github.com/CrowdStrike/psfalcon/wiki/Get-FalconDiscoverAwsAccount Invoke-Falcon @Param -Inputs $PSBoundParameters } } +function Get-FalconDiscoverAwsLink { +<# +.SYNOPSIS +Retrieve previously generated Falcon Discover AWS CloudFormation links +.DESCRIPTION +Requires 'AWS Accounts: Read'. +.PARAMETER Region +AWS region +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconDiscoverAwsLink +#> + [CmdletBinding(DefaultParameterSetName='/cloud-connect-aws/entities/console-setup-urls/v1:get', + SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/cloud-connect-aws/entities/console-setup-urls/v1:get',Position=1)] + [string]$Region + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Query = @('region') } + } + } + process { Invoke-Falcon @Param -Inputs $PSBoundParameters } +} function Get-FalconDiscoverAwsSetting { <# .SYNOPSIS -Retrieve Global Settings Falcon Discover for Cloud AWS accounts +Retrieve global settings for Cloud AWS accounts in Falcon Discover .DESCRIPTION Requires 'AWS Accounts: Read'. .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Get-FalconDiscoverAwsSetting +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconDiscoverAwsSetting #> [CmdletBinding(DefaultParameterSetName='/cloud-connect-aws/combined/settings/v1:get',SupportsShouldProcess)] param() @@ -188,60 +218,43 @@ function New-FalconDiscoverAwsAccount { Provision Falcon Discover for Cloud AWS Accounts .DESCRIPTION Requires 'AWS Accounts: Write'. -.PARAMETER Mode -Provisioning mode [default: manual] -.PARAMETER ExternalId -AWS account identifier with cross-account IAM role access -.PARAMETER IamRoleArn -Full ARN of the IAM role created in the AWS account to control access -.PARAMETER CloudtrailBucketOwnerId -AWS account identifier containing cloudtrail logs -.PARAMETER CloudtrailBucketRegion +.PARAMETER OrganizationId +AWS organization identifier +.PARAMETER AccountType +AWS account type +.PARAMETER IsMaster +AWS master account status +.PARAMETER CloudtrailRegion AWS region where the account containing cloudtrail logs resides -.PARAMETER RateLimitTime -Number of seconds between requests defined by 'RateLimitReq' -.PARAMETER RateLimitReq -Maximum number of requests within 'RateLimitTime' .PARAMETER Id AWS account identifier .LINK -https://github.com/CrowdStrike/psfalcon/wiki/New-FalconDiscoverAwsAccount +https://github.com/crowdstrike/psfalcon/wiki/New-FalconDiscoverAwsAccount #> - [CmdletBinding(DefaultParameterSetName='/cloud-connect-aws/entities/accounts/v1:post',SupportsShouldProcess)] + [CmdletBinding(DefaultParameterSetName='/cloud-connect-aws/entities/account/v2:post',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/cloud-connect-aws/entities/accounts/v1:post', - ValueFromPipelineByPropertyName,Position=1)] - [ValidateSet('cloudformation','manual',IgnoreCase=$false)] - [string]$Mode, - [Parameter(ParameterSetName='/cloud-connect-aws/entities/accounts/v1:post', - ValueFromPipelineByPropertyName,Position=2)] - [ValidatePattern('^\d{12}$')] - [Alias('external_id')] - [string]$ExternalId, - [Parameter(ParameterSetName='/cloud-connect-aws/entities/accounts/v1:post', - ValueFromPipelineByPropertyName,Position=3)] - [Alias('iam_role_arn')] - [string]$IamRoleArn, - [Parameter(ParameterSetName='/cloud-connect-aws/entities/accounts/v1:post', - ValueFromPipelineByPropertyName,Position=4)] - [ValidatePattern('^\d{12}$')] - [Alias('cloudtrail_bucket_owner_id')] - [string]$CloudtrailBucketOwnerId, - [Parameter(ParameterSetName='/cloud-connect-aws/entities/accounts/v1:post', + [Parameter(ParameterSetName='/cloud-connect-aws/entities/account/v2:post',ValueFromPipelineByPropertyName, + Position=1)] + [ValidatePattern('^o-[0-9a-z]{10,32}$')] + [Alias('organization_id')] + [string]$OrganizationId, + [Parameter(ParameterSetName='/cloud-connect-aws/entities/account/v2:post',ValueFromPipelineByPropertyName, + Position=2)] + [ValidateSet('commercial','gov',IgnoreCase=$false)] + [Alias('account_type')] + [string]$AccountType, + [Parameter(ParameterSetName='/cloud-connect-aws/entities/account/v2:post',ValueFromPipelineByPropertyName, + Position=3)] + [Alias('is_master')] + [boolean]$IsMaster, + [Parameter(ParameterSetName='/cloud-connect-aws/entities/account/v2:post',ValueFromPipelineByPropertyName, + Position=4)] + [Alias('cloudtrail_region')] + [string]$CloudtrailRegion, + [Parameter(ParameterSetName='/cloud-connect-aws/entities/account/v2:post',Mandatory, ValueFromPipelineByPropertyName,Position=5)] - [Alias('cloudtrail_bucket_region')] - [string]$CloudtrailBucketRegion, - [Parameter(ParameterSetName='/cloud-connect-aws/entities/accounts/v1:post', - ValueFromPipelineByPropertyName,Position=6)] - [Alias('rate_limit_time')] - [int64]$RateLimitTime, - [Parameter(ParameterSetName='/cloud-connect-aws/entities/accounts/v1:post', - ValueFromPipelineByPropertyName,Position=7)] - [Alias('rate_limit_reqs','RateLimitReqs')] - [int32]$RateLimitReq, - [Parameter(ParameterSetName='/cloud-connect-aws/entities/accounts/v1:post',Mandatory, - ValueFromPipelineByPropertyName,Position=8)] [ValidatePattern('^\d{12}$')] + [Alias('account_id')] [string]$Id ) begin { @@ -249,38 +262,98 @@ https://github.com/CrowdStrike/psfalcon/wiki/New-FalconDiscoverAwsAccount Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName Format = @{ - Query = @('mode') - Body = @{ resources = @('rate_limit_time','external_id','rate_limit_reqs', - 'cloudtrail_bucket_region','iam_role_arn','id','cloudtrail_bucket_owner_id') } + Body = @{ + resources = @('account_id','account_type','cloudtrail_region','is_master','organization_id') + } } } } process { Invoke-Falcon @Param -Inputs $PSBoundParameters } } +function Receive-FalconDiscoverAwsScript { +<# +.SYNOPSIS +Download a Bash script which grants Falcon Discover access using the AWS CLI +.DESCRIPTION +Requires 'AWS Accounts: Read'. +.PARAMETER Path +Destination path +.PARAMETER Id +AWS Account identifier +.PARAMETER Force +Overwrite existing file when present +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Receive-FalconDiscoverAwsScript +#> + [CmdletBinding(DefaultParameterSetName='/cloud-connect-aws/entities/user-scripts-download/v1:get', + SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/cloud-connect-aws/entities/user-scripts-download/v1:get',Mandatory, + Position=1)] + [string]$Path, + [Parameter(ParameterSetName='/cloud-connect-aws/entities/user-scripts-download/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] + [Alias('ids','account_id')] + [string[]]$Id, + [Parameter(ParameterSetName='/cloud-connect-aws/entities/user-scripts-download/v1:get')] + [switch]$Force + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Headers = @{ Accept = 'application/octet-stream' } + Format = @{ + Query = @('ids') + Outfile = 'path' + } + } + } + process { + $PSBoundParameters.Path = Assert-Extension $PSBoundParameters.Path 'sh' + $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 + } else { + Invoke-Falcon @Param -Inputs $PSBoundParameters + } + } + } +} function Remove-FalconDiscoverAwsAccount { <# .SYNOPSIS Remove Falcon Discover for Cloud AWS accounts .DESCRIPTION Requires 'AWS Accounts: Write'. +.PARAMETER OrganizationId +AWS organization identifier .PARAMETER Id AWS account identifier .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Remove-FalconDiscoverAwsAccount +https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconDiscoverAwsAccount #> - [CmdletBinding(DefaultParameterSetName='/cloud-connect-aws/entities/accounts/v1:delete',SupportsShouldProcess)] + [CmdletBinding(DefaultParameterSetName='/cloud-connect-aws/entities/account/v2:delete',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/cloud-connect-aws/entities/accounts/v1:delete',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/cloud-connect-aws/entities/account/v2:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] + [ValidatePattern('^o-[0-9a-z]{10,32}$')] + [Alias('organization-ids')] + [string[]]$OrganizationId, + [Parameter(ParameterSetName='/cloud-connect-aws/entities/account/v2:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^\d{12}$')] - [Alias('Ids')] + [Alias('ids')] [string[]]$Id ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName - Format = @{ Query = @('ids') } + Format = @{ Query = @('ids','organization-ids') } } [System.Collections.Generic.List[string]]$List = @() } @@ -303,7 +376,7 @@ AWS account identifier containing cloudtrail logs .PARAMETER StaticExternalId Default external identifier to apply to AWS accounts .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Update-FalconDiscoverAwsSetting +https://github.com/crowdstrike/psfalcon/wiki/Update-FalconDiscoverAwsSetting #> [CmdletBinding(DefaultParameterSetName='/cloud-connect-aws/entities/settings/v1:post',SupportsShouldProcess)] param( diff --git a/Public/cloud-connect-azure.ps1 b/Public/cloud-connect-azure.ps1 index 13fa5156..79dfaa04 100644 --- a/Public/cloud-connect-azure.ps1 +++ b/Public/cloud-connect-azure.ps1 @@ -17,8 +17,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconDiscoverAzureAccount [ValidateSet('full','dry',IgnoreCase=$false)] [Alias('scan-type')] [string]$ScanType, - [Parameter(ParameterSetName='/cloud-connect-azure/entities/account/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=2)] + [Parameter(ParameterSetName='/cloud-connect-azure/entities/account/v1:get',ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=2)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('Ids')] [string[]]$Id @@ -56,7 +56,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconDiscoverAzureCertificate [Parameter(ParameterSetName='/cloud-connect-azure/entities/download-certificate/v1:get',Position=1)] [boolean]$Refresh, [Parameter(ParameterSetName='/cloud-connect-azure/entities/download-certificate/v1:get',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=2)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] + [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('tenant_id')] [string[]]$TenantId ) @@ -163,7 +164,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Update-FalconDiscoverAzureAccount SupportsShouldProcess)] param( [Parameter(ParameterSetName='/cloud-connect-azure/entities/client-id/v1:patch',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=1)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [string]$Id ) diff --git a/Public/cloud-connect-cspm-aws.ps1 b/Public/cloud-connect-cspm-aws.ps1 index f3b681c0..61302e09 100644 --- a/Public/cloud-connect-cspm-aws.ps1 +++ b/Public/cloud-connect-cspm-aws.ps1 @@ -19,7 +19,6 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconHorizonAwsAccount [ValidatePattern('^\d{12}$')] [Alias('account_id','id')] [string]$AccountId, - [Parameter(ParameterSetName='/cloud-connect-cspm-aws/entities/account/v1:patch', ValueFromPipelineByPropertyName,Position=2)] [Alias('cloudtrail_region')] @@ -66,8 +65,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconHorizonAwsAccount [CmdletBinding(DefaultParameterSetName='/cloud-connect-cspm-aws/entities/account/v1:get', SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/cloud-connect-cspm-aws/entities/account/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/cloud-connect-cspm-aws/entities/account/v1:get', + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^\d{12}$')] [Alias('Ids')] [string[]]$Id, @@ -232,7 +231,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconHorizonAwsAccount SupportsShouldProcess)] param( [Parameter(ParameterSetName='/cloud-connect-cspm-aws/entities/account/v1:delete',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=1)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^\d{12}$')] [Alias('Ids')] [string[]]$Id, @@ -248,7 +247,6 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconHorizonAwsAccount Format = @{ Query = @('ids','organization-ids') } } [System.Collections.Generic.List[string]]$List = @() - } process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} end { diff --git a/Public/cloud-connect-cspm-azure.ps1 b/Public/cloud-connect-cspm-azure.ps1 index 9dd53f35..949b943d 100644 --- a/Public/cloud-connect-cspm-azure.ps1 +++ b/Public/cloud-connect-cspm-azure.ps1 @@ -68,8 +68,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconHorizonAzureAccount [CmdletBinding(DefaultParameterSetName='/cloud-connect-cspm-azure/entities/account/v1:get', SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/cloud-connect-cspm-azure/entities/account/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/cloud-connect-cspm-azure/entities/account/v1:get', + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('Ids')] [string[]]$Id, @@ -123,7 +123,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconHorizonAzureCertificate [Parameter(ParameterSetName='/cloud-connect-cspm-azure/entities/download-certificate/v1:get',Position=1)] [boolean]$Refresh, [Parameter(ParameterSetName='/cloud-connect-cspm-azure/entities/download-certificate/v1:get',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=2)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] + [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('tenant_id')] [string[]]$TenantId ) @@ -194,7 +195,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Receive-FalconHorizonAzureScript Position=1)] [string]$Path, [Parameter(ParameterSetName='/cloud-connect-cspm-azure/entities/user-scripts-download/v1:get', - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=2)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('tenant-id','tenant_id')] [string]$TenantId, @@ -241,7 +242,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconHorizonAzureAccount SupportsShouldProcess)] param( [Parameter(ParameterSetName='/cloud-connect-cspm-azure/entities/account/v1:delete',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=1)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('Ids')] [string[]]$Id diff --git a/Public/cloud-connect-gcp.ps1 b/Public/cloud-connect-gcp.ps1 index 3b31ddc1..e3e4c6b6 100644 --- a/Public/cloud-connect-gcp.ps1 +++ b/Public/cloud-connect-gcp.ps1 @@ -17,8 +17,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconDiscoverGcpAccount [ValidateSet('full','dry',IgnoreCase=$false)] [Alias('scan-type')] [string]$ScanType, - [Parameter(ParameterSetName='/cloud-connect-gcp/entities/account/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=2)] + [Parameter(ParameterSetName='/cloud-connect-gcp/entities/account/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^\d{10,}$')] [Alias('Ids')] [string[]]$Id @@ -53,8 +53,8 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconDiscoverGcpAccount [CmdletBinding(DefaultParameterSetName='/cloud-connect-gcp/entities/account/v1:post', SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/cloud-connect-gcp/entities/account/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/cloud-connect-gcp/entities/account/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^\d{12}$')] [Alias('parent_id')] [string]$ParentId diff --git a/Public/container-security.ps1 b/Public/container-security.ps1 index da14df6d..57a046e7 100644 --- a/Public/container-security.ps1 +++ b/Public/container-security.ps1 @@ -84,8 +84,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconContainerImage #> [CmdletBinding(DefaultParameterSetName='/images/{id}:delete',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/images/{id}:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/images/{id}:delete',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] [object]$Id ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name; HostUrl = Get-ContainerUrl }} diff --git a/Public/detects.ps1 b/Public/detects.ps1 index 8aef7753..12221a84 100644 --- a/Public/detects.ps1 +++ b/Public/detects.ps1 @@ -15,7 +15,7 @@ User identifier for assignment .PARAMETER Id Detection identifier .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Edit-FalconDetection +https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconDetection #> [CmdletBinding(DefaultParameterSetName='/detects/entities/detects/v2:patch',SupportsShouldProcess)] param( @@ -34,8 +34,8 @@ https://github.com/CrowdStrike/psfalcon/wiki/Edit-FalconDetection [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('assigned_to_uuid','uuid')] [string]$AssignedToUuid, - [Parameter(ParameterSetName='/detects/entities/detects/v2:patch',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=5)] + [Parameter(ParameterSetName='/detects/entities/detects/v2:patch',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=5)] [ValidatePattern('^ldt:[a-fA-F0-9]{32}:\d+$')] [Alias('Ids','detection_id','detection_ids')] [string[]]$Id @@ -84,12 +84,12 @@ Repeat requests until all available results are retrieved .PARAMETER Total Display total result count instead of results .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Get-FalconDetection +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconDetection #> [CmdletBinding(DefaultParameterSetName='/detects/queries/detects/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/detects/entities/summaries/GET/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/detects/entities/summaries/GET/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^ldt:[a-fA-F0-9]{32}:\d+$')] [Alias('Ids','detection_id','detection_ids')] [string[]]$Id, diff --git a/Public/devices.ps1 b/Public/devices.ps1 index 85ba81aa..bb956d87 100644 --- a/Public/devices.ps1 +++ b/Public/devices.ps1 @@ -24,8 +24,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Add-FalconGroupingTag })] [Alias('Tags')] [string[]]$Tag, - [Parameter(ParameterSetName='/devices/entities/devices/tags/v1:patch',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=2)] + [Parameter(ParameterSetName='/devices/entities/devices/tags/v1:patch',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('device_ids','device_id','Ids')] [string[]]$Id @@ -127,14 +127,14 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconHost #> [CmdletBinding(DefaultParameterSetName='/devices/queries/devices-scroll/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/devices/entities/devices/v2:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] - [Parameter(ParameterSetName='/devices/combined/devices/login-history/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/devices/entities/devices/v2:post',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] + [Parameter(ParameterSetName='/devices/combined/devices/login-history/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [Parameter(ParameterSetName='/devices/combined/devices/network-address-history/v1:post',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName)] - [Parameter(ParameterSetName='/devices/entities/online-state/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + ValueFromPipelineByPropertyName,ValueFromPipeline)] + [Parameter(ParameterSetName='/devices/entities/online-state/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids','device_id','host_ids','aid')] [string[]]$Id, @@ -307,8 +307,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconHostGroup #> [CmdletBinding(DefaultParameterSetName='/devices/queries/host-groups/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/devices/entities/host-groups/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/devices/entities/host-groups/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -389,10 +389,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconHostGroupMember #> [CmdletBinding(DefaultParameterSetName='/devices/queries/host-group-members/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/devices/queries/host-group-members/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] - [Parameter(ParameterSetName='/devices/combined/host-group-members/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/devices/queries/host-group-members/v1:get',ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] + [Parameter(ParameterSetName='/devices/combined/host-group-members/v1:get',ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id, [Parameter(ParameterSetName='/devices/queries/host-group-members/v1:get',Position=2)] @@ -454,8 +454,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconHostAction 'product_type_desc','reduced_functionality_mode','serial_number','system_manufacturer', 'system_product_name','tags',IgnoreCase=$false)] [string[]]$Include, - [Parameter(ParameterSetName='/devices/entities/devices-actions/v2:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=3)] + [Parameter(ParameterSetName='/devices/entities/devices-actions/v2:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids','device_id')] [string[]]$Id @@ -512,8 +512,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconHostGroupAction [Parameter(ParameterSetName='/devices/entities/host-group-actions/v1:post',Mandatory,Position=2)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id, - [Parameter(ParameterSetName='/devices/entities/host-group-actions/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=3)] + [Parameter(ParameterSetName='/devices/entities/host-group-actions/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids','device_id','HostIds')] [string[]]$HostId @@ -663,8 +663,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconGroupingTag })] [Alias('Tags')] [string[]]$Tag, - [Parameter(ParameterSetName='/devices/entities/devices/tags/v1:patch',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=2)] + [Parameter(ParameterSetName='/devices/entities/devices/tags/v1:patch',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('device_ids','device_id','Ids')] [string[]]$Id @@ -699,8 +699,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconHostGroup #> [CmdletBinding(DefaultParameterSetName='/devices/entities/host-groups/v1:delete',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/devices/entities/host-groups/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/devices/entities/host-groups/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id diff --git a/Public/discover.ps1 b/Public/discover.ps1 index 02d271cf..53ebf3e1 100644 --- a/Public/discover.ps1 +++ b/Public/discover.ps1 @@ -31,12 +31,12 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconAsset #> [CmdletBinding(DefaultParameterSetName='/discover/queries/hosts/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/discover/entities/hosts/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] - [Parameter(ParameterSetName='/discover/entities/accounts/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] - [Parameter(ParameterSetName='/discover/entities/logins/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/discover/entities/hosts/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] + [Parameter(ParameterSetName='/discover/entities/accounts/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] + [Parameter(ParameterSetName='/discover/entities/logins/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}_\w+$')] [Alias('Ids')] [string[]]$Id, diff --git a/Public/enrollments.ps1 b/Public/enrollments.ps1 new file mode 100644 index 00000000..93a836ce --- /dev/null +++ b/Public/enrollments.ps1 @@ -0,0 +1,52 @@ +function Invoke-FalconMobileAction { +<# +.SYNOPSIS +Trigger on-boarding process for a mobile device +.DESCRIPTION +Requires 'Mobile Enrollment: Write'. +.PARAMETER Name +Action to perform +.PARAMETER ExpiresAt +Expiration time [default: 30 days] +.PARAMETER Email +Email address +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconMobileAction +#> + [CmdletBinding(DefaultParameterSetName='/enrollments/entities/details/v3:post',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/enrollments/entities/details/v3:post',Mandatory,Position=1)] + [ValidateSet('enroll','re-enroll',IgnoreCase=$false)] + [Alias('action_name')] + [string]$Name, + [Parameter(ParameterSetName='/enrollments/entities/details/v3:post',Position=2)] + [Alias('expires_at')] + [string]$ExpiresAt, + [Parameter(ParameterSetName='/enrollments/entities/details/v3:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] + [ValidateScript({ + if ((Test-RegexValue $_) -eq 'email') { $true } else { throw "'$_' is not a valid email address." } + })] + [Alias('email_addresses')] + [string[]]$Email + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ + Body = @{ root = @('email_addresses','expires_at') } + Query = @('action_name') + } + } + [System.Collections.Generic.List[string]]$List = @() + if (!$PSBoundParameters.ExpiresAt) { $PSBoundParameters.ExpiresAt = Convert-Rfc3339 720 } + } + process { if ($Email) { @($Email).foreach{ $List.Add($_) }}} + end { + if ($List) { + $PSBoundParameters['Email'] = @($List | Select-Object -Unique) + Invoke-Falcon @Param -Inputs $PSBoundParameters + } + } +} \ No newline at end of file diff --git a/Public/falconx.ps1 b/Public/falconx.ps1 index 0289607b..667293dd 100644 --- a/Public/falconx.ps1 +++ b/Public/falconx.ps1 @@ -27,10 +27,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconReport #> [CmdletBinding(DefaultParameterSetName='/falconx/queries/reports/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/falconx/entities/reports/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] - [Parameter(ParameterSetName='/falconx/entities/report-summaries/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/falconx/entities/reports/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] + [Parameter(ParameterSetName='/falconx/entities/report-summaries/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}_[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -94,8 +94,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconSubmission #> [CmdletBinding(DefaultParameterSetName='/falconx/queries/submissions/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/falconx/entities/submissions/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/falconx/entities/submissions/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}_[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -145,7 +145,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconSubmissionQuota $Request = Invoke-Falcon -Endpoint $PSCmdlet.ParameterSetName -RawOutput -EA 0 if ($Request.Result.Content) { (ConvertFrom-Json ($Request.Result.Content).ReadAsStringAsync().Result).meta.quota - } else { + } elseif ($Request) { throw "Unable to retrieve submission quota. Check client permissions." } } @@ -161,12 +161,8 @@ before they can be provided to the Falcon Intelligence Sandbox. Requires 'Sandbox (Falcon Intelligence): Write'. .PARAMETER EnvironmentId Analysis environment -.PARAMETER Sha256 -Sha256 hash value .PARAMETER Url A webpage or file URL -.PARAMETER SubmitName -Submission name .PARAMETER ActionScript Runtime script for sandbox analysis .PARAMETER CommandLine @@ -183,6 +179,10 @@ Network settings to use in the analysis environment Route traffic via TOR .PARAMETER UserTag Tags to categorize the submission +.PARAMETER SubmitName +Submission name +.PARAMETER Sha256 +Sha256 hash value .LINK https://github.com/crowdstrike/psfalcon/wiki/New-FalconSubmission #> @@ -193,42 +193,44 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconSubmission [Alias('environment_id')] [string]$EnvironmentId, [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=2)] - [ValidatePattern('^[A-Fa-f0-9]{64}$')] - [string]$Sha256, - [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=3)] [string]$Url, - [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=4)] - [Alias('submit_name')] - [string]$SubmitName, - [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=5)] + [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=3)] [ValidateSet('default','default_maxantievasion','default_randomfiles','default_randomtheme', 'default_openie',IgnoreCase=$false)] [Alias('action_script')] [string]$ActionScript, - [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=6)] + [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=4)] [Alias('command_line')] [string]$CommandLine, - [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=7)] + [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=5)] [ValidatePattern('^\d{4}-\d{2}-\d{2}$')] [Alias('system_date')] [string]$SystemDate, - [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=8)] + [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=6)] [ValidatePattern('^\d{2}:\d{2}$')] [Alias('system_time')] [string]$SystemTime, - [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=9)] + [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=7)] [Alias('document_password')] [string]$DocumentPassword, - [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=10)] + [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=8)] [ValidateSet('default','tor','simulated','offline',IgnoreCase=$false)] [Alias('network_settings','NetworkSettings')] [string]$NetworkSetting, - [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=11)] + [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=9)] [Alias('enable_tor')] [boolean]$EnableTor, - [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=12)] + [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',Position=10)] [Alias('user_tags','UserTags')] - [string[]]$UserTag + [string[]]$UserTag, + [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',ValueFromPipelineByPropertyName, + Position=11)] + [Alias('submit_name','file_name')] + [string]$SubmitName, + [Parameter(ParameterSetName='/falconx/entities/submissions/v1:post',ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=12)] + [ValidatePattern('^[A-Fa-f0-9]{64}$')] + [string]$Sha256 ) begin { $Param = @{ @@ -282,8 +284,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Receive-FalconArtifact param( [Parameter(ParameterSetName='/falconx/entities/artifacts/v1:get',Mandatory,Position=1)] [string]$Path, - [Parameter(ParameterSetName='/falconx/entities/artifacts/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=2)] + [Parameter(ParameterSetName='/falconx/entities/artifacts/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=2)] [ValidatePattern('^[A-Fa-f0-9]{64}$')] [string]$Id, [Parameter(ParameterSetName='/falconx/entities/artifacts/v1:get')] @@ -326,8 +328,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconReport #> [CmdletBinding(DefaultParameterSetName='/falconx/entities/reports/v1:delete',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/falconx/entities/reports/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/falconx/entities/reports/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [Alias('Ids')] [string]$Id ) diff --git a/Public/filevantage.ps1 b/Public/filevantage.ps1 index 02ea95a9..68981f5e 100644 --- a/Public/filevantage.ps1 +++ b/Public/filevantage.ps1 @@ -25,8 +25,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconFimChange #> [CmdletBinding(DefaultParameterSetName='/filevantage/queries/changes/v2:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/filevantage/entities/changes/v2:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/filevantage/entities/changes/v2:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, diff --git a/Public/fwmgr.ps1 b/Public/fwmgr.ps1 index 9e7d0e92..27a8f5f6 100644 --- a/Public/fwmgr.ps1 +++ b/Public/fwmgr.ps1 @@ -24,12 +24,15 @@ Firewall rule 'family' value(s) from the existing rule group [or 'temp_id' for e Firewall rule version value(s) from the existing rule group [or 'null' for each new rule] .PARAMETER Id Rule group identifier +.PARAMETER Validate +Toggle to perform validation, instead of modifying rule group .LINK https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconFirewallGroup #> [CmdletBinding(DefaultParameterSetName='/fwmgr/entities/rule-groups/v1:patch',SupportsShouldProcess)] param( [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:patch',Mandatory,Position=1)] + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/validation/v1:patch',Mandatory,Position=1)] [ValidateScript({ foreach ($Object in $_) { $Param = @{ @@ -48,19 +51,26 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconFirewallGroup [Alias('diff_operations','DiffOperations')] [object[]]$DiffOperation, [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:patch',Position=2)] + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/validation/v1:patch',Position=2)] [string]$Comment, [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:patch',Position=3)] + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/validation/v1:patch',Position=3)] [ValidatePattern('^(\d+|[a-fA-F0-9]{32})$')] [Alias('rule_ids','RuleIds')] [string[]]$RuleId, [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:patch',Position=4)] + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/validation/v1:patch',Position=4)] [ValidatePattern('^(null|\d+)$')] [Alias('rule_versions','RuleVersions')] [int[]]$RuleVersion, - [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:patch',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=6)] + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:patch',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=5)] + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/validation/v1:patch',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=5)] [ValidatePattern('^[a-fA-F0-9]{32}$')] - [string]$Id + [string]$Id, + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/validation/v1:patch',Mandatory)] + [switch]$Validate ) begin { $Param = @{ @@ -76,29 +86,32 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconFirewallGroup } } process { - ($Param.Format.Body.root | Where-Object { $_ -notmatch '^(diff_operations|id)$' }).foreach{ - if (!$PSBoundParameters.$_) { - # When not provided, add required fields using existing rule group - if (!$Group) { $Group = try { Get-FalconFirewallGroup -Id $PSBoundParameters.Id -EA 0 } catch {}} - $PSBoundParameters[$_] = if ($_ -eq 'rulegroup_version') { - if ($Group.version) { $Group.version } else { 0 } - } elseif ($_ -eq 'rule_versions') { - if ($PSBoundParameters.RuleId) { - (Get-FalconFirewallRule -Id $PSBoundParameters.RuleId).version + if ($PSCmdlet.ShouldProcess('Edit-FalconFirewallGroup','Get-FalconFirewallGroup')) { + @($Param.Format.Body.root).Where({ $_ -notmatch '^(diff_operations|id)$' }).foreach{ + if (!$PSBoundParameters.$_) { + # When not provided, add required fields using existing rule group + if (!$Group) { + $Group = try { Get-FalconFirewallGroup -Id $PSBoundParameters.Id -EA 0 } catch {} + } + $PSBoundParameters[$_] = if ($_ -eq 'rulegroup_version') { + if ($Group.version) { $Group.version } else { 0 } + } elseif ($_ -eq 'rule_versions') { + if ($PSBoundParameters.RuleId) { + (Get-FalconFirewallRule -Id $PSBoundParameters.RuleId).version + } else { + (Get-FalconFirewallRule -Id $Group.rule_ids).version + } } else { - (Get-FalconFirewallRule -Id $Group.rule_ids).version + $Group.$_ } - } else { - $Group.$_ } } + if (!$PSBoundParameters.Tracking) { + throw "Unable to obtain 'tracking' value from rule group '$($PSBoundParameters.Id)'." + } } - if (!$PSBoundParameters.Tracking) { - throw "Unable to obtain 'tracking' value from rule group '$($PSBoundParameters.Id)'." - } else { - $PSBoundParameters['diff_type'] = 'application/json-patch+json' - Invoke-Falcon @Param -Inputs $PSBoundParameters - } + $PSBoundParameters['diff_type'] = 'application/json-patch+json' + Invoke-Falcon @Param -Inputs $PSBoundParameters } } function Edit-FalconFirewallSetting { @@ -131,40 +144,40 @@ Policy identifier .LINK https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconFirewallSetting #> - [CmdletBinding(DefaultParameterSetName='/fwmgr/entities/policies/v1:put',SupportsShouldProcess)] + [CmdletBinding(DefaultParameterSetName='/fwmgr/entities/policies/v2:put',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/fwmgr/entities/policies/v1:put',ValueFromPipelineByPropertyName, + [Parameter(ParameterSetName='/fwmgr/entities/policies/v2:put',ValueFromPipelineByPropertyName, Position=1)] [ValidateSet('0','1')] [Alias('platform_id')] [string]$PlatformId, - [Parameter(ParameterSetName='/fwmgr/entities/policies/v1:put',ValueFromPipelineByPropertyName, + [Parameter(ParameterSetName='/fwmgr/entities/policies/v2:put',ValueFromPipelineByPropertyName, Position=2)] [boolean]$Enforce, - [Parameter(ParameterSetName='/fwmgr/entities/policies/v1:put',ValueFromPipelineByPropertyName, + [Parameter(ParameterSetName='/fwmgr/entities/policies/v2:put',ValueFromPipelineByPropertyName, Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('rule_group_ids','RuleGroupIds')] [string[]]$RuleGroupId, - [Parameter(ParameterSetName='/fwmgr/entities/policies/v1:put',ValueFromPipelineByPropertyName, + [Parameter(ParameterSetName='/fwmgr/entities/policies/v2:put',ValueFromPipelineByPropertyName, Position=4)] [ValidateSet('ALLOW','DENY',IgnoreCase=$false)] [Alias('default_inbound')] [string]$DefaultInbound, - [Parameter(ParameterSetName='/fwmgr/entities/policies/v1:put',ValueFromPipelineByPropertyName, + [Parameter(ParameterSetName='/fwmgr/entities/policies/v2:put',ValueFromPipelineByPropertyName, Position=5)] [ValidateSet('ALLOW','DENY',IgnoreCase=$false)] [Alias('default_outbound')] [string]$DefaultOutbound, - [Parameter(ParameterSetName='/fwmgr/entities/policies/v1:put',ValueFromPipelineByPropertyName, + [Parameter(ParameterSetName='/fwmgr/entities/policies/v2:put',ValueFromPipelineByPropertyName, Position=6)] [Alias('test_mode')] [boolean]$MonitorMode, - [Parameter(ParameterSetName='/fwmgr/entities/policies/v1:put',ValueFromPipelineByPropertyName, + [Parameter(ParameterSetName='/fwmgr/entities/policies/v2:put',ValueFromPipelineByPropertyName, Position=7)] [Alias('local_logging')] [boolean]$LocalLogging, - [Parameter(ParameterSetName='/fwmgr/entities/policies/v1:put',Mandatory,ValueFromPipelineByPropertyName, + [Parameter(ParameterSetName='/fwmgr/entities/policies/v2:put',Mandatory,ValueFromPipelineByPropertyName, Position=8)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('policy_id','PolicyId')] @@ -183,11 +196,13 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconFirewallSetting } } process { - ($Param.Format.Body.root | Where-Object { $_ -ne 'policy_id' }).foreach{ - # When not provided, add required fields using existing policy settings - if (!$PSBoundParameters.$_) { - if (!$Existing) { $Existing = Get-FalconFirewallSetting -Id $Id -EA 0 } - if ($Existing) { $PSBoundParameters[$_] = $Existing.$_ } + if ($PSCmdlet.ShouldProcess('Edit-FalconFirewallSetting','Get-FalconFirewallPolicy')) { + ($Param.Format.Body.root | Where-Object { $_ -ne 'policy_id' }).foreach{ + # When not provided, add required fields using existing policy settings + if (!$PSBoundParameters.$_) { + if (!$Existing) { $Existing = Get-FalconFirewallSetting -Id $Id -EA 0 } + if ($Existing) { $PSBoundParameters[$_] = $Existing.$_ } + } } } Invoke-Falcon @Param -Inputs $PSBoundParameters @@ -224,8 +239,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconFirewallEvent #> [CmdletBinding(DefaultParameterSetName='/fwmgr/queries/events/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/fwmgr/entities/events/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/fwmgr/entities/events/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [Alias('Ids')] [string[]]$Id, [Parameter(ParameterSetName='/fwmgr/queries/events/v1:get',Position=1)] @@ -289,8 +304,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconFirewallField #> [CmdletBinding(DefaultParameterSetName='/fwmgr/queries/firewall-fields/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/fwmgr/entities/firewall-fields/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/fwmgr/entities/firewall-fields/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [Alias('Ids')] [string[]]$Id, [Parameter(ParameterSetName='/fwmgr/queries/firewall-fields/v1:get',Position=1)] @@ -354,8 +369,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconFirewallGroup #> [CmdletBinding(DefaultParameterSetName='/fwmgr/queries/rule-groups/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -418,8 +433,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconFirewallPlatform #> [CmdletBinding(DefaultParameterSetName='/fwmgr/queries/platforms/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/fwmgr/entities/platforms/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/fwmgr/entities/platforms/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [ValidateSet('0','1')] [Alias('Ids')] [string[]]$Id, @@ -482,8 +497,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconFirewallRule #> [CmdletBinding(DefaultParameterSetName='/fwmgr/queries/rules/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/fwmgr/entities/rules/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/fwmgr/entities/rules/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [Alias('Ids')] [string[]]$Id, [Parameter(ParameterSetName='/fwmgr/queries/policy-rules/v1:get',Mandatory,Position=1)] @@ -561,8 +576,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconFirewallSetting #> [CmdletBinding(DefaultParameterSetName='/fwmgr/entities/policies/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/fwmgr/entities/policies/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/fwmgr/entities/policies/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id @@ -603,6 +618,10 @@ Audit log comment Clone default Firewall rules .PARAMETER CloneId Clone an existing rule group +.PARAMETER Platform +Operating system platform [default: 0 (Windows)] +.PARAMETER Validate +Toggle to perform validation, instead of creating rule group .LINK https://github.com/crowdstrike/psfalcon/wiki/New-FalconFirewallGroup #> @@ -610,26 +629,45 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconFirewallGroup param( [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:post',Mandatory, ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/validation/v1:post',Mandatory, + ValueFromPipelineByPropertyName,Position=1)] [string]$Name, [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:post',Mandatory, ValueFromPipelineByPropertyName,Position=2)] + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/validation/v1:post',Mandatory, + ValueFromPipelineByPropertyName,Position=2)] [boolean]$Enabled, [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:post',ValueFromPipelineByPropertyName, Position=3)] + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/validation/v1:post', + ValueFromPipelineByPropertyName,Position=3)] [string]$Description, [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:post',ValueFromPipelineByPropertyName, Position=4)] + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/validation/v1:post', + ValueFromPipelineByPropertyName,Position=4)] [Alias('rules')] [object[]]$Rule, [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:post',ValueFromPipelineByPropertyName, Position=5)] + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/validation/v1:post', + ValueFromPipelineByPropertyName,Position=5)] [string]$Comment, [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:post',Position=6)] + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/validation/v1:post',Position=6)] [string]$Library, [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:post',Position=7)] + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/validation/v1:post',Position=7)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('clone_id','id')] - [string]$CloneId + [string]$CloneId, + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:post',ValueFromPipelineByPropertyName, + Position=8)] + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/validation/v1:post', + ValueFromPipelineByPropertyName,Position=8)] + [string]$Platform, + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/validation/v1:post',Mandatory)] + [switch]$Validate ) begin { $Param = @{ @@ -637,15 +675,15 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconFirewallGroup Endpoint = $PSCmdlet.ParameterSetName Format = @{ Query = @('library','comment','clone_id') - Body = @{ root = @('enabled','name','rules','description') } + Body = @{ root = @('enabled','name','rules','description','platform') } } } } process { if ($PSBoundParameters.Rule) { - [object[]]$PSBoundParameters.Rule = Confirm-Property 'name','description','enabled','platform_ids', - 'direction','action','address_family','local_address','remote_address','protocol','local_port', - 'remote_port','icmp','monitor','fields' $PSBoundParameters.Rule + [object[]]$PSBoundParameters.Rule = Confirm-Property 'action','address_family','description', + 'direction','enabled','fields','icmp','local_address','local_port','log','monitor','name', + 'protocol','remote_address','remote_port','temp_id' $PSBoundParameters.Rule } Invoke-Falcon @Param -Inputs $PSBoundParameters } @@ -667,8 +705,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconFirewallGroup param( [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:delete',Position=1)] [string]$Comment, - [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=2)] + [Parameter(ParameterSetName='/fwmgr/entities/rule-groups/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id @@ -688,4 +726,38 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconFirewallGroup Invoke-Falcon @Param -Inputs $PSBoundParameters } } -} \ No newline at end of file +} +function Test-FalconFirewallPath { +<# +.SYNOPSIS +Validate that a string matches a Firewall Management executable filepath glob pattern +.DESCRIPTION +Requires 'Firewall management: Write'. +.PARAMETER Pattern +Glob pattern +.PARAMETER String +Filepath string +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Test-FalconFirewallPath +#> + [CmdletBinding(DefaultParameterSetName='/fwmgr/entities/rules/validate-filepath/v1:post', + SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/fwmgr/entities/rules/validate-filepath/v1:post',Mandatory,Position=1)] + [Alias('filepath_pattern')] + [string]$Pattern, + [Parameter(ParameterSetName='/fwmgr/entities/rules/validate-filepath/v1:post',Mandatory,Position=2)] + [Alias('filepath_test_string')] + [string]$String + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Body = @{ root = @('filepath_test_string','filepath_pattern') }} + } + } + process { Invoke-Falcon @Param -Inputs $PSBoundParameters } +} +Register-ArgumentCompleter -CommandName New-FalconFirewallGroup -ParameterName Platform -ScriptBlock { + (Get-FalconFirewallPlatform -Detailed -EA 0).label } \ No newline at end of file diff --git a/Public/image-assessment.ps1 b/Public/image-assessment.ps1 new file mode 100644 index 00000000..7347df83 --- /dev/null +++ b/Public/image-assessment.ps1 @@ -0,0 +1,44 @@ +function Get-FalconContainerVulnerability { +<# +.SYNOPSIS +Retrieve known vulnerabilities for the provided image +.DESCRIPTION +Requires 'Falcon Container CLI: Write'. +.PARAMETER OsVersion +Operating system version +.PARAMETER Package +Key and value pairs to filter packages. Accepted properties include: 'layerindex', 'packageprovider', 'layerhash', +'packagehash', 'packagesource', 'softwarearchitecture', 'status', 'majorversion', 'product', and 'vendor'. +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconContainerVulnerability +#> + [CmdletBinding(DefaultParameterSetName='/image-assessment/combined/vulnerability-lookups/v1:post', + SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/image-assessment/combined/vulnerability-lookups/v1:post',Position=1)] + [string]$OsVersion, + [Parameter(ParameterSetName='/image-assessment/combined/vulnerability-lookups/v1:post',Position=2)] + [ValidateScript({ + foreach ($Object in $_) { + $Param = @{ + Object = $Object + Command = 'Get-FalconContainerVulnerability' + Endpoint = '/image-assessment/combined/vulnerability-lookups/v1:post' + Allowed = @('layerindex','packageprovider','layerhash','packagehash','packagesource', + 'softwarearchitecture','status','majorversion','product','vendor') + } + Confirm-Parameter @Param + } + })] + [Alias('packages')] + [object[]]$Package + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Body = @{ root = @('osversion','packages') }} + } + } + process { Invoke-Falcon @Param -Inputs $PSBoundParameters } +} \ No newline at end of file diff --git a/Public/incidents.ps1 b/Public/incidents.ps1 index b7eda5d8..e261eec2 100644 --- a/Public/incidents.ps1 +++ b/Public/incidents.ps1 @@ -21,12 +21,12 @@ Repeat requests until all available results are retrieved .PARAMETER Total Display total result count instead of results .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Get-FalconBehavior +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconBehavior #> [CmdletBinding(DefaultParameterSetName='/incidents/queries/behaviors/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/incidents/entities/behaviors/GET/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/incidents/entities/behaviors/GET/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^ind:[a-fA-F0-9]{32}:(\d|\-)+$')] [Alias('Ids','behavior_id')] [string[]]$Id, @@ -88,12 +88,12 @@ Repeat requests until all available results are retrieved .PARAMETER Total Display total result count instead of results .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Get-FalconIncident +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIncident #> [CmdletBinding(DefaultParameterSetName='/incidents/queries/incidents/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/incidents/entities/incidents/GET/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/incidents/entities/incidents/GET/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^inc:[a-fA-F0-9]{32}:[a-fA-F0-9]{32}$')] [Alias('Ids','incident_id')] [string[]]$Id, @@ -154,7 +154,7 @@ Repeat requests until all available results are retrieved .PARAMETER Total Display total result count instead of results .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Get-FalconScore +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconScore #> [CmdletBinding(DefaultParameterSetName='/incidents/combined/crowdscores/v1:get',SupportsShouldProcess)] param( @@ -200,7 +200,7 @@ Replace existing status for related detections .PARAMETER Id Incident identifier .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Invoke-FalconIncidentAction +https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconIncidentAction #> [CmdletBinding(DefaultParameterSetName='/incidents/entities/incident-actions/v1:post',SupportsShouldProcess)] param( @@ -216,8 +216,8 @@ https://github.com/CrowdStrike/psfalcon/wiki/Invoke-FalconIncidentAction [Parameter(ParameterSetName='/incidents/entities/incident-actions/v1:post',Position=4)] [Alias('overwrite_detects')] [boolean]$OverwriteDetects, - [Parameter(ParameterSetName='/incidents/entities/incident-actions/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=5)] + [Parameter(ParameterSetName='/incidents/entities/incident-actions/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=5)] [ValidatePattern('^inc:[a-fA-F0-9]{32}:[a-fA-F0-9]{32}$')] [Alias('Ids','incident_id')] [string[]]$Id diff --git a/Public/indicators.ps1 b/Public/indicators.ps1 index 45c835d4..42604e0d 100644 --- a/Public/indicators.ps1 +++ b/Public/indicators.ps1 @@ -17,7 +17,7 @@ Repeat requests until all available results are retrieved .PARAMETER Total Display the total result count instead of results .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Get-FalconIocHost +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIocHost #> [CmdletBinding(DefaultParameterSetName='/indicators/queries/devices/v1:get',SupportsShouldProcess)] param( @@ -74,7 +74,7 @@ Retrieve detailed information .PARAMETER All Repeat requests until all available results are retrieved .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Get-FalconIocProcess +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIocProcess #> [CmdletBinding(DefaultParameterSetName='/indicators/queries/processes/v1:get',SupportsShouldProcess)] param( diff --git a/Public/installation-tokens.ps1 b/Public/installation-tokens.ps1 index acdcf8e7..799e25f1 100644 --- a/Public/installation-tokens.ps1 +++ b/Public/installation-tokens.ps1 @@ -1,9 +1,41 @@ +function Edit-FalconInstallTokenSetting { +<# +.SYNOPSIS +Update installation token settings +.DESCRIPTION +Requires 'Installation token settings: Write'. +.PARAMETER TokensRequired +Installation token requirement +.PARAMETER MaxActiveToken +Maximum number of active installation tokens +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconInstallTokenSetting +#> + [CmdletBinding(DefaultParameterSetName='/installation-tokens/entities/customer-settings/v1:patch', + SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/installation-tokens/entities/customer-settings/v1:patch',Position=1)] + [Alias('tokens_required')] + [boolean]$TokenRequired, + [Parameter(ParameterSetName='/installation-tokens/entities/customer-settings/v1:patch',Position=2)] + [Alias('max_active_tokens')] + [int]$MaxActiveToken + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Body = @{ root = @('tokens_required','max_active_tokens') }} + } + } + process { Invoke-Falcon @Param -Inputs $PSBoundParameters } +} function Edit-FalconInstallToken { <# .SYNOPSIS Modify installation tokens .DESCRIPTION -Requires 'Installation Tokens: Write'. +Requires 'Installation tokens: Write'. .PARAMETER Label Installation token label .PARAMETER ExpiresTimestamp @@ -58,7 +90,7 @@ function Get-FalconInstallToken { .SYNOPSIS Search for installation tokens .DESCRIPTION -Requires 'Installation Tokens: Read'. +Requires 'Installation tokens: Read'. .PARAMETER Id Installation token identifier .PARAMETER Filter @@ -80,8 +112,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconInstallToken #> [CmdletBinding(DefaultParameterSetName='/installation-tokens/queries/tokens/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/installation-tokens/entities/tokens/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/installation-tokens/entities/tokens/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -121,7 +153,7 @@ function Get-FalconInstallTokenEvent { .SYNOPSIS Search for installation token audit events .DESCRIPTION -Requires 'Installation Tokens: Read'. +Requires 'Installation tokens: Read'. .PARAMETER Id Installation token audit event identifier .PARAMETER Filter @@ -145,7 +177,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconInstallTokenEvent SupportsShouldProcess)] param( [Parameter(ParameterSetName='/installation-tokens/entities/audit-events/v1:get',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName)] + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -187,7 +219,7 @@ Retrieve installation token settings Returns the maximum number of allowed installation tokens,and whether or not they are required for installation of the Falcon sensor. -Requires 'Installation Tokens: Read'. +Requires 'Installation tokens: Read'. .LINK https://github.com/crowdstrike/psfalcon/wiki/Get-FalconInstallTokenSetting #> @@ -201,7 +233,7 @@ function New-FalconInstallToken { .SYNOPSIS Create an installation token .DESCRIPTION -Requires 'Installation Tokens: Write'. +Requires 'Installation tokens: Write'. .PARAMETER Label Installation token label .PARAMETER ExpiresTimestamp @@ -232,7 +264,7 @@ function Remove-FalconInstallToken { .SYNOPSIS Remove installation tokens .DESCRIPTION -Requires 'Installation Tokens: Write'. +Requires 'Installation tokens: Write'. .PARAMETER Id Installation token identifier .LINK @@ -241,7 +273,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconInstallToken [CmdletBinding(DefaultParameterSetName='/installation-tokens/entities/tokens/v1:delete',SupportsShouldProcess)] param( [Parameter(ParameterSetName='/installation-tokens/entities/tokens/v1:delete',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=1)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id diff --git a/Public/intel.ps1 b/Public/intel.ps1 index e6ea5cb2..4c407271 100644 --- a/Public/intel.ps1 +++ b/Public/intel.ps1 @@ -16,6 +16,8 @@ Property and direction to sort results Maximum number of results per request .PARAMETER Fields Specific fields, or a predefined collection name surrounded by two underscores [default: _basic_] +.PARAMETER Include +Include additional information .PARAMETER Offset Position to begin retrieving results .PARAMETER Detailed @@ -29,8 +31,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconActor #> [CmdletBinding(DefaultParameterSetName='/intel/queries/actors/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/intel/entities/actors/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/intel/entities/actors/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [Alias('Ids')] [string[]]$Id, [Parameter(ParameterSetName='/intel/queries/actors/v1:get',Position=1)] @@ -55,6 +57,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconActor [Parameter(ParameterSetName='/intel/entities/actors/v1:get',Position=2)] [Parameter(ParameterSetName='/intel/combined/actors/v1:get',Position=5)] [string[]]$Fields, + [Parameter(ParameterSetName='/intel/queries/actors/v1:get',Position=5)] + [Parameter(ParameterSetName='/intel/combined/actors/v1:get',Position=6)] + [ValidateSet('tactic_and_technique',IgnoreCase=$false)] + [string]$Include, [Parameter(ParameterSetName='/intel/queries/actors/v1:get')] [Parameter(ParameterSetName='/intel/combined/actors/v1:get')] [int32]$Offset, @@ -75,6 +81,135 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconActor [System.Collections.Generic.List[string]]$List = @() } process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} + end { + if ($List) { $PSBoundParameters['Id'] = @($List | Select-Object -Unique) } + if ($Include) { + $Request = Invoke-Falcon @Param -Inputs $PSBoundParameters + if (!$Request.slug) { $Request = $Request | & $MyInvocation.MyCommand.Name | Select-Object id,slug } + @($Request).foreach{ + $Attck = try { [string[]](Get-FalconAttck -Slug $_.slug -EA 0) } catch { [string[]]@() } + if ($Attck -and $PSBoundParameters.Detailed) { + $Attck = try { [object[]]($Attck | Get-FalconAttck -EA 0) } catch { [object[]]@() } + } + $_.PSObject.Properties.Add((New-Object PSNoteProperty('tactic_and_technique',$Attck))) + } + $Request + } else { + Invoke-Falcon @Param -Inputs $PSBoundParameters + } + } +} +function Get-FalconAttck { +<# +.SYNOPSIS +Search for Mitre ATT&CK tactic and technique information related to specific actors +.DESCRIPTION +Requires 'Actors (Falcon Intelligence): Read'. +.PARAMETER Id +Tactic and technique identifier, by actor +.PARAMETER Slug +Actor identifier ('slug') +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconAttck +#> + [CmdletBinding(DefaultParameterSetName='/intel/queries/mitre/v1:get',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/intel/entities/mitre/v1:post',Mandatory,ValueFromPipeline)] + [Alias('ids')] + [string[]]$Id, + [Parameter(ParameterSetName='/intel/queries/mitre/v1:get',Mandatory,Position=1)] + [Alias('actor_id')] + [string]$Slug + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = if ($PSCmdlet.ParameterSetName -eq '/intel/entities/mitre/v1:post') { + @{ Body = @{ root = @('ids') }} + } else { + @{ Query = @('id') } + } + } + [System.Collections.Generic.List[string]]$List = @() + } + process { + if ($Id) { + @($Id).foreach{ $List.Add($_) } + } else { + $PSBoundParameters['id'] = $PSBoundParameters.Slug + [void]$PSBoundParameters.Remove('Slug') + Invoke-Falcon @Param -Inputs $PSBoundParameters + } + } + end { + if ($List) { + $PSBoundParameters['Id'] = @($List | Select-Object -Unique) + Invoke-Falcon @Param -Inputs $PSBoundParameters + } + } +} +function Get-FalconCve { +<# +.SYNOPSIS +Search for Falcon Intelligence CVE reports +.DESCRIPTION +Requires 'Vulnerabilities (Falcon Intelligence): Read'. +.PARAMETER Query +Perform a generic substring search across available fields +.PARAMETER Offset +Position to begin retrieving results +.PARAMETER Sort +Property and direction to sort results +.PARAMETER Limit +Maximum number of results per request +.PARAMETER Filter +Falcon Query Language expression to limit results +.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/Get-FalconCve +#> + [CmdletBinding(DefaultParameterSetName='/intel/queries/vulnerabilities/v1:get',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/intel/entities/vulnerabilities/GET/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] + [Alias('ids')] + [string[]]$Id, + [Parameter(ParameterSetName='/intel/queries/vulnerabilities/v1:get',Position=1)] + [string]$Filter, + [Parameter(ParameterSetName='/intel/queries/vulnerabilities/v1:get',Position=2)] + [Alias('q')] + [string]$Query, + [Parameter(ParameterSetName='/intel/queries/vulnerabilities/v1:get',Position=3)] + [string]$Sort, + [Parameter(ParameterSetName='/intel/queries/vulnerabilities/v1:get',Position=4)] + [int]$Limit, + [Parameter(ParameterSetName='/intel/queries/vulnerabilities/v1:get')] + [string]$Offset, + [Parameter(ParameterSetName='/intel/queries/vulnerabilities/v1:get')] + [switch]$Detailed, + [Parameter(ParameterSetName='/intel/queries/vulnerabilities/v1:get')] + [switch]$All, + [Parameter(ParameterSetName='/intel/queries/vulnerabilities/v1:get')] + [switch]$Total + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ + Body = @{ root = @('ids') } + Query = @('q','offset','sort','limit','filter') + } + } + [System.Collections.Generic.List[string]]$List = @() + } + process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} end { if ($List) { $PSBoundParameters['Id'] = @($List | Select-Object -Unique) } Invoke-Falcon @Param -Inputs $PSBoundParameters @@ -98,6 +233,8 @@ Property and direction to sort results Maximum number of results per request .PARAMETER IncludeDeleted Include previously deleted indicators +.PARAMETER IncludeRelation +Include related indicators .PARAMETER Offset Position to begin retrieving results .PARAMETER Detailed @@ -111,8 +248,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIndicator #> [CmdletBinding(DefaultParameterSetName='/intel/queries/indicators/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/intel/entities/indicators/GET/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/intel/entities/indicators/GET/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [Alias('Ids')] [string[]]$Id, [Parameter(ParameterSetName='/intel/queries/indicators/v1:get',Position=1)] @@ -137,6 +274,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIndicator [Parameter(ParameterSetName='/intel/combined/indicators/v1:get',Position=5)] [Alias('include_deleted')] [boolean]$IncludeDeleted, + [Parameter(ParameterSetName='/intel/queries/indicators/v1:get',Position=6)] + [Parameter(ParameterSetName='/intel/combined/indicators/v1:get',Position=6)] + [Alias('include_relations')] + [boolean]$IncludeRelation, [Parameter(ParameterSetName='/intel/queries/indicators/v1:get')] [Parameter(ParameterSetName='/intel/combined/indicators/v1:get')] [int32]$Offset, @@ -153,7 +294,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIndicator Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName Format = @{ - Query = @('sort','limit','filter','offset','include_deleted','q') + Query = @('sort','limit','filter','offset','include_deleted','q','include_relations') Body = @{ root = @('ids') } } } @@ -196,8 +337,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIntel #> [CmdletBinding(DefaultParameterSetName='/intel/queries/reports/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/intel/entities/reports/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/intel/entities/reports/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [Alias('Ids')] [string[]]$Id, [Parameter(ParameterSetName='/intel/queries/reports/v1:get',Position=1)] @@ -285,8 +426,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconRule #> [CmdletBinding(DefaultParameterSetName='/intel/queries/rules/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/intel/entities/rules/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/intel/entities/rules/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [ValidatePattern('^\d{4,}$')] [Alias('Ids')] [string[]]$Id, @@ -397,7 +538,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Receive-FalconIntel function Receive-FalconRule { <# .SYNOPSIS -Download the most recent ruleset,or a specific ruleset +Download the most recent ruleset, or a specific ruleset .DESCRIPTION Requires 'Rules (Falcon Intelligence): Read'. .PARAMETER Type @@ -421,8 +562,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Receive-FalconRule [Parameter(ParameterSetName='/intel/entities/rules-latest-files/v1:get',Mandatory,Position=2)] [ValidatePattern('\.(gz|gzip|zip)$')] [string]$Path, - [Parameter(ParameterSetName='/intel/entities/rules-files/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=2)] + [Parameter(ParameterSetName='/intel/entities/rules-files/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=2)] [int32]$Id, [Parameter(ParameterSetName='/intel/entities/rules-files/v1:get')] [switch]$Force diff --git a/Public/ioa.ps1 b/Public/ioa.ps1 index aa3f758d..7f5b65ed 100644 --- a/Public/ioa.ps1 +++ b/Public/ioa.ps1 @@ -14,8 +14,10 @@ AWS account identifier Azure subscription identifier .PARAMETER AzureTenantId Azure tenant identifier -.PARAMETER UserIds +.PARAMETER UserId User identifier +.PARAMETER State +Event state .PARAMETER Limit Maximum number of results per request .PARAMETER Offset @@ -51,9 +53,11 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconHorizonIoaEvent [Alias('azure_tenant_id')] [string]$AzureTenantId, [Parameter(ParameterSetName='/ioa/entities/events/v1:get',Position=6)] - [Alias('user_ids')] - [string[]]$UserIds, + [Alias('user_ids','UserIds')] + [string[]]$UserId, [Parameter(ParameterSetName='/ioa/entities/events/v1:get',Position=7)] + [string]$State, + [Parameter(ParameterSetName='/ioa/entities/events/v1:get',Position=8)] [ValidateRange(1,500)] [int32]$Limit, [Parameter(ParameterSetName='/ioa/entities/events/v1:get')] @@ -68,8 +72,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconHorizonIoaEvent Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName Format = @{ - Query = @('cloud_provider','limit','aws_account_id','azure_subscription_id','policy_id', - 'offset','azure_tenant_id','user_ids') + Query = @('cloud_provider','limit','aws_account_id','azure_subscription_id','policy_id','offset', + 'azure_tenant_id','user_ids','state','account_id') } } } @@ -104,6 +108,8 @@ AWS account identifier Azure subscription identifier .PARAMETER AzureTenantId Azure tenant identifier +.PARAMETER State +Event state .LINK https://github.com/crowdstrike/psfalcon/wiki/Get-FalconHorizonIoaUser #> @@ -129,14 +135,16 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconHorizonIoaUser [Parameter(ParameterSetName='/ioa/entities/users/v1:get',ValueFromPipelineByPropertyName,Position=5)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('azure_tenant_id')] - [string]$AzureTenantId + [string]$AzureTenantId, + [Parameter(ParameterSetName='/ioa/entities/users/v1:get',Position=6)] + [string]$State ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName Format = @{ - Query = @('cloud_provider','policy_id','azure_tenant_id','aws_account_id', + Query = @('cloud_provider','policy_id','azure_tenant_id','aws_account_id','state','account_id', 'azure_subscription_id') } } diff --git a/Public/ioarules.ps1 b/Public/ioarules.ps1 index 6beb2e11..58be825d 100644 --- a/Public/ioarules.ps1 +++ b/Public/ioarules.ps1 @@ -160,8 +160,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIoaGroup #> [CmdletBinding(DefaultParameterSetName='/ioarules/queries/rule-groups/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/ioarules/entities/rule-groups/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/ioarules/entities/rule-groups/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -234,8 +234,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIoaPlatform #> [CmdletBinding(DefaultParameterSetName='/ioarules/queries/platforms/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/ioarules/entities/platforms/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/ioarules/entities/platforms/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidateSet('windows','mac','linux',IgnoreCase=$false)] [Alias('Ids')] [string[]]$Id, @@ -294,8 +294,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIoaRule #> [CmdletBinding(DefaultParameterSetName='/ioarules/queries/rules/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/ioarules/entities/rules/GET/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/ioarules/entities/rules/GET/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^\d+$')] [Alias('Ids')] [string[]]$Id, @@ -368,8 +368,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIoaSeverity #> [CmdletBinding(DefaultParameterSetName='/ioarules/queries/pattern-severities/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/ioarules/entities/pattern-severities/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/ioarules/entities/pattern-severities/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidateSet('critical','high','medium','low','informational',IgnoreCase=$false)] [Alias('Ids','pattern_severity')] [string[]]$Id, @@ -422,8 +422,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIoaType #> [CmdletBinding(DefaultParameterSetName='/ioarules/queries/rule-types/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/ioarules/entities/rule-types/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/ioarules/entities/rule-types/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^\d{1,2}$')] [Alias('Ids','ruletype_id')] [string[]]$Id, @@ -595,8 +595,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconIoaGroup param( [Parameter(ParameterSetName='/ioarules/entities/rule-groups/v1:delete',Position=1)] [string]$Comment, - [Parameter(ParameterSetName='/ioarules/entities/rule-groups/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=2)] + [Parameter(ParameterSetName='/ioarules/entities/rule-groups/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id diff --git a/Public/iocs.ps1 b/Public/iocs.ps1 index ec9e484b..b653946a 100644 --- a/Public/iocs.ps1 +++ b/Public/iocs.ps1 @@ -28,6 +28,8 @@ Assign to all host groups Expiration date. When an indicator expires, its action is set to 'no_action' but it remains in your indicator list. .PARAMETER Comment Audit log comment +.PARAMETER FromParent +Inheritance from parent CID .PARAMETER Retrodetect Generate retroactive detections for hosts that have observed the indicator .PARAMETER IgnoreWarning @@ -41,11 +43,9 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconIoc param( [Parameter(ParameterSetName='/iocs/entities/indicators/v1:patch',ValueFromPipelineByPropertyName, Position=1)] - [ValidateSet('no_action','allow','prevent_no_ui','detect','prevent',IgnoreCase=$false)] [string]$Action, [Parameter(ParameterSetName='/iocs/entities/indicators/v1:patch',ValueFromPipelineByPropertyName, Position=2)] - [ValidateSet('android','ios','linux','mac','windows',IgnoreCase=$false)] [Alias('Platforms')] [string[]]$Platform, [Parameter(ParameterSetName='/iocs/entities/indicators/v1:patch',ValueFromPipelineByPropertyName, @@ -54,14 +54,13 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconIoc [string]$Source, [Parameter(ParameterSetName='/iocs/entities/indicators/v1:patch',ValueFromPipelineByPropertyName, Position=4)] - [ValidateSet('informational','low','medium','high','critical',IgnoreCase=$false)] [string]$Severity, [Parameter(ParameterSetName='/iocs/entities/indicators/v1:patch',ValueFromPipelineByPropertyName, Position=5)] [string]$Description, [Parameter(ParameterSetName='/iocs/entities/indicators/v1:patch',ValueFromPipelineByPropertyName, Position=6)] - [Alias('metadata.filename')] + [Alias('metadata')] [string]$Filename, [Parameter(ParameterSetName='/iocs/entities/indicators/v1:patch',ValueFromPipelineByPropertyName, Position=7)] @@ -88,10 +87,14 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconIoc [Parameter(ParameterSetName='/iocs/entities/indicators/v1:patch',ValueFromPipelineByPropertyName, Position=12)] [string]$Comment, - [Parameter(ParameterSetName='/iocs/entities/indicators/v1:patch',Position=13)] + [Parameter(ParameterSetName='/iocs/entities/indicators/v1:patch',ValueFromPipelineByPropertyName, + Position=13)] + [Alias('from_parent')] + [boolean]$FromParent, + [Parameter(ParameterSetName='/iocs/entities/indicators/v1:patch',Position=14)] [Alias('retrodetects')] [boolean]$Retrodetect, - [Parameter(ParameterSetName='/iocs/entities/indicators/v1:patch',Position=14)] + [Parameter(ParameterSetName='/iocs/entities/indicators/v1:patch',Position=15)] [Alias('ignore_warnings','IgnoreWarnings')] [boolean]$IgnoreWarning, [Parameter(ParameterSetName='/iocs/entities/indicators/v1:patch',Mandatory,ValueFromPipelineByPropertyName, @@ -107,13 +110,19 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconIoc Query = @('retrodetects','ignore_warnings') Body = @{ root = @('comment') - indicators = @('id','tags','applied_globally','expiration','description', - 'metadata.filename','source','host_groups','severity','action','platforms','mobile_action') + indicators = @('id','tags','applied_globally','expiration','description','source','action', + 'metadata','host_groups','severity','platforms','mobile_action','from_parent') } } } } - process { Invoke-Falcon @Param -Inputs $PSBoundParameters } + process { + if ($PSBoundParameters.Filename) { + $PSBoundParameters['metadata'] = @{ filename = $PSBoundParameters.Filename } + [void]$PSBoundParameters.Remove('Filename') + } + Invoke-Falcon @Param -Inputs $PSBoundParameters + } } function Get-FalconIoc { <# @@ -129,6 +138,8 @@ Falcon Query Language expression to limit results Property and direction to sort results .PARAMETER Limit Maximum number of results per request +.PARAMETER FromParent +Inheritance from parent CID .PARAMETER Offset Position to begin retrieving results .PARAMETER After @@ -144,8 +155,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIoc #> [CmdletBinding(DefaultParameterSetName='/iocs/queries/indicators/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/iocs/entities/indicators/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/iocs/entities/indicators/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [ValidatePattern('^[A-Fa-f0-9]{64}$')] [Alias('Ids')] [string[]]$Id, @@ -170,6 +181,9 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIoc [Parameter(ParameterSetName='/iocs/combined/indicator/v1:get',Position=3)] [ValidateRange(1,2000)] [int32]$Limit, + [Parameter(ParameterSetName='/iocs/combined/indicator/v1:get',Position=4)] + [Alias('from_parent')] + [boolean]$FromParent, [Parameter(ParameterSetName='/iocs/queries/indicators/v1:get')] [Parameter(ParameterSetName='/iocs/combined/indicator/v1:get')] [int32]$Offset, @@ -188,7 +202,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIoc $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName - Format = @{ Query = @('ids','filter','offset','limit','sort','after') } + Format = @{ Query = @('ids','filter','offset','limit','sort','after','from_parent') } } [System.Collections.Generic.List[string]]$List = @() } @@ -198,6 +212,148 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIoc Invoke-Falcon @Param -Inputs $PSBoundParameters } } +function Get-FalconIocAction { +<# +.SYNOPSIS +Search for custom indicator actions +.DESCRIPTION +Requires 'IOC Manager APIs: Read'. +.PARAMETER Id +Custom indicator action identifier +.PARAMETER Limit +Maximum number of results per request +.PARAMETER Offset +Position to begin retrieving results +.PARAMETER Detailed +Retrieve detailed information +.PARAMETER All +Repeat requests until all available results are retrieved +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIocAction +#> + [CmdletBinding(DefaultParameterSetName='/iocs/queries/actions/v1:get',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/iocs/entities/actions/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] + [Alias('ids')] + [string[]]$Id, + [Parameter(ParameterSetName='/iocs/queries/actions/v1:get',Position=1)] + [int32]$Limit, + [Parameter(ParameterSetName='/iocs/queries/actions/v1:get')] + [int32]$Offset, + [Parameter(ParameterSetName='/iocs/queries/actions/v1:get')] + [switch]$Detailed, + [Parameter(ParameterSetName='/iocs/queries/actions/v1:get')] + [switch]$All + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Query = @('offset','limit','ids') } + } + } + process { Invoke-Falcon @Param -Inputs $PSBoundParameters } +} +function Get-FalconIocPlatform { +<# +.SYNOPSIS +List custom indicator platforms +.DESCRIPTION +Requires 'IOC Manager APIs: Read'. +.PARAMETER Limit +Maximum number of results per request +.PARAMETER Offset +Position to begin retrieving results +.PARAMETER All +Repeat requests until all available results are retrieved +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIocPlatform +#> +[CmdletBinding(DefaultParameterSetName='/iocs/queries/platforms/v1:get',SupportsShouldProcess)] +param( + [Parameter(ParameterSetName='/iocs/queries/platforms/v1:get',Position=1)] + [int32]$Limit, + [Parameter(ParameterSetName='/iocs/queries/platforms/v1:get')] + [int32]$Offset, + [Parameter(ParameterSetName='/iocs/queries/platforms/v1:get')] + [switch]$All +) +begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Query = @('offset','limit') } + } +} +process { Invoke-Falcon @Param -Inputs $PSBoundParameters } +} +function Get-FalconIocSeverity { +<# +.SYNOPSIS +List custom indicator severities +.DESCRIPTION +Requires 'IOC Manager APIs: Read'. +.PARAMETER Limit +Maximum number of results per request +.PARAMETER Offset +Position to begin retrieving results +.PARAMETER All +Repeat requests until all available results are retrieved +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIocSeverity +#> + [CmdletBinding(DefaultParameterSetName='/iocs/queries/severities/v1:get',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/iocs/queries/severities/v1:get',Position=1)] + [int32]$Limit, + [Parameter(ParameterSetName='/iocs/queries/severities/v1:get')] + [int32]$Offset, + [Parameter(ParameterSetName='/iocs/queries/severities/v1:get')] + [switch]$All + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Query = @('offset','limit') } + } + } + process { Invoke-Falcon @Param -Inputs $PSBoundParameters } +} +function Get-FalconIocType { +<# +.SYNOPSIS +List custom indicator types +.DESCRIPTION +Requires 'IOC Manager APIs: Read'. +.PARAMETER Limit +Maximum number of results per request +.PARAMETER Offset +Position to begin retrieving results +.PARAMETER All +Repeat requests until all available results are retrieved +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIocType +#> + [CmdletBinding(DefaultParameterSetName='/iocs/queries/ioc-types/v1:get',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/iocs/queries/ioc-types/v1:get',Position=1)] + [int32]$Limit, + [Parameter(ParameterSetName='/iocs/queries/ioc-types/v1:get')] + [int32]$Offset, + [Parameter(ParameterSetName='/iocs/queries/ioc-types/v1:get')] + [switch]$All + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Query = @('offset','limit') } + } + } + process { Invoke-Falcon @Param -Inputs $PSBoundParameters } +} function New-FalconIoc { <# .SYNOPSIS @@ -261,22 +417,19 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconIoc [Alias('indicators')] [object[]]$Array, [Parameter(ParameterSetName='/iocs/entities/indicators/v1:post',Mandatory,Position=1)] - [ValidateSet('no_action','allow','prevent_no_ui','detect','prevent',IgnoreCase=$false)] [string]$Action, [Parameter(ParameterSetName='/iocs/entities/indicators/v1:post',Mandatory,Position=2)] - [ValidateSet('android','ios','linux','mac','windows',IgnoreCase=$false)] [Alias('platforms')] [string[]]$Platform, [Parameter(ParameterSetName='/iocs/entities/indicators/v1:post',Position=3)] [ValidateRange(1,256)] [string]$Source, [Parameter(ParameterSetName='/iocs/entities/indicators/v1:post',Position=4)] - [ValidateSet('informational','low','medium','high','critical',IgnoreCase=$false)] [string]$Severity, [Parameter(ParameterSetName='/iocs/entities/indicators/v1:post',Position=5)] [string]$Description, [Parameter(ParameterSetName='/iocs/entities/indicators/v1:post',Position=6)] - [Alias('metadata.filename')] + [Alias('metadata')] [string]$Filename, [Parameter(ParameterSetName='/iocs/entities/indicators/v1:post',Position=7)] [Alias('tags')] @@ -307,7 +460,6 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconIoc [Alias('ignore_warnings','IgnoreWarnings')] [boolean]$IgnoreWarning, [Parameter(ParameterSetName='/iocs/entities/indicators/v1:post',Mandatory,Position=15)] - [ValidateSet('domain','ipv4','ipv6','md5','sha256',IgnoreCase=$false)] [string]$Type, [Parameter(ParameterSetName='/iocs/entities/indicators/v1:post',Mandatory,Position=16)] [Alias('indicator')] @@ -321,9 +473,8 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconIoc Query = @('retrodetects','ignore_warnings') Body = @{ root = @('comment','indicators') - indicators = @('tags','applied_globally','expiration','description','value', - 'metadata.filename','type','source','host_groups','severity','action','platforms', - 'mobile_action') + indicators = @('tags','applied_globally','expiration','description','value','metadata','type', + 'source','host_groups','severity','action','platforms','mobile_action') } } } @@ -335,6 +486,10 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconIoc } elseif (!$PSBoundParameters.HostGroup -and !$PSBoundParameters.AppliedGlobally) { throw "'HostGroup' or 'AppliedGlobally' must be provided." } else { + if ($PSBoundParameters.Filename) { + $PSBoundParameters['metadata'] = @{ filename = $PSBoundParameters.Filename } + [void]$PSBoundParameters.Remove('Filename') + } Invoke-Falcon @Param -Inputs $PSBoundParameters } } @@ -357,6 +512,8 @@ Requires 'IOC Manager APIs: Write'. Falcon Query Language expression to find indicators for removal .PARAMETER Comment Audit log comment +.PARAMETER FromParent +Inheritance from parent CID .PARAMETER Id Indicator identifier .LINK @@ -370,8 +527,12 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconIoc [Parameter(ParameterSetName='/iocs/entities/indicators/v1:delete',Position=1)] [Parameter(ParameterSetName='Filter',Position=2)] [string]$Comment, - [Parameter(ParameterSetName='/iocs/entities/indicators/v1:delete',ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=2)] + [Parameter(ParameterSetName='/iocs/entities/indicators/v1:delete',Position=2)] + [Parameter(ParameterSetName='Filter',Position=3)] + [Alias('from_parent')] + [boolean]$FromParent, + [Parameter(ParameterSetName='/iocs/entities/indicators/v1:delete',ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=2)] [ValidatePattern('^[A-Fa-f0-9]{64}$')] [Alias('Ids')] [string[]]$Id @@ -380,7 +541,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconIoc $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = '/iocs/entities/indicators/v1:delete' - Format = @{ Query = @('ids','filter','comment') } + Format = @{ Query = @('ids','filter','comment','from_parent') } } [System.Collections.Generic.List[string]]$List = @() } @@ -399,4 +560,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconIoc Invoke-Falcon @Param -Inputs $PSBoundParameters } } +} +Register-ArgumentCompleter -CommandName New-FalconIoc -ParameterName Type -ScriptBlock {Get-FalconIocType -EA 0} +@('Edit-FalconIoc','New-FalconIoc').foreach{ + Register-ArgumentCompleter -CommandName $_ -ParameterName Action -ScriptBlock {Get-FalconIocAction -EA 0} + Register-ArgumentCompleter -CommandName $_ -ParameterName Platform -ScriptBlock {Get-FalconIocPlatform -EA 0} + Register-ArgumentCompleter -CommandName $_ -ParameterName Severity -ScriptBlock {Get-FalconIocSeverity -EA 0} } \ No newline at end of file diff --git a/Public/kubernetes-protection.ps1 b/Public/kubernetes-protection.ps1 index 1963b332..6d178cfc 100644 --- a/Public/kubernetes-protection.ps1 +++ b/Public/kubernetes-protection.ps1 @@ -17,7 +17,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconContainerAwsAccount [Parameter(ParameterSetName='/kubernetes-protection/entities/accounts/aws/v1:patch',Position=1)] [string]$Region, [Parameter(ParameterSetName='/kubernetes-protection/entities/accounts/aws/v1:patch',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=2)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^\d{12}$')] [Alias('Ids')] [string[]]$Id @@ -38,6 +38,41 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconContainerAwsAccount } } } +function Edit-FalconContainerAzureAccount { +<# +.SYNOPSIS +Modify the client identifier for a Falcon Container Security Azure account +.DESCRIPTION +Requires 'Kubernetes Protection: Write'. +.PARAMETER ClientId +Azure client identifier +.PARAMETER Id +Azure tenant identifier +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconContainerAzureAccount +#> + [CmdletBinding(DefaultParameterSetName='/kubernetes-protection/entities/service-principal/azure/v1:patch', + SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/kubernetes-protection/entities/service-principal/azure/v1:patch',Mandatory, + Position=1)] + [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] + [Alias('client_id')] + [string]$ClientId, + [Parameter(ParameterSetName='/kubernetes-protection/entities/service-principal/azure/v1:patch',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] + [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] + [string]$Id + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Query = @('id','client_id') } + } + } + process { Invoke-Falcon @Param -Inputs $PSBoundParameters } +} function Get-FalconContainerAwsAccount { <# .SYNOPSIS @@ -62,8 +97,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconContainerAwsAccount [CmdletBinding(DefaultParameterSetName='/kubernetes-protection/entities/accounts/aws/v1:get', SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/kubernetes-protection/entities/accounts/aws/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/kubernetes-protection/entities/accounts/aws/v1:get', + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^\d{12}$')] [Alias('Ids')] [string[]]$Id, @@ -93,6 +128,72 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconContainerAwsAccount Invoke-Falcon @Param -Inputs $PSBoundParameters } } +function Get-FalconContainerAzureAccount { +<# +.SYNOPSIS +Search for Falcon Container Security Azure accounts +.DESCRIPTION +Requires 'Kubernetes Protection: Read'. +.PARAMETER Id +Azure tenant identifier +.PARAMETER SubscriptionId +Azure subscription identifier +.PARAMETER Status +Filter by account status +.PARAMETER IsHorizonAcct +Filter by whether an account originates from Horizon or not +.PARAMETER Limit +Maximum number of results per request +.PARAMETER Offset +Position to begin retrieving results +.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/Get-FalconContainerAzureAccount +#> + [CmdletBinding(DefaultParameterSetName='/kubernetes-protection/entities/accounts/azure/v1:get', + SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/kubernetes-protection/entities/accounts/azure/v1:get', + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] + [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] + [Alias('ids')] + [string[]]$Id, + [Parameter(ParameterSetName='/kubernetes-protection/entities/accounts/azure/v1:get',Position=2)] + [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] + [Alias('subscription_id')] + [string[]]$SubscriptionId, + [Parameter(ParameterSetName='/kubernetes-protection/entities/accounts/azure/v1:get',Position=3)] + [ValidateSet('operational','provisioned',IgnoreCase=$false)] + [string]$Status, + [Parameter(ParameterSetName='/kubernetes-protection/entities/accounts/azure/v1:get',Position=4)] + [Alias('is_horizon_acct')] + [boolean]$IsHorizonAcct, + [Parameter(ParameterSetName='/kubernetes-protection/entities/accounts/azure/v1:get',Position=5)] + [int]$Limit, + [Parameter(ParameterSetName='/kubernetes-protection/entities/accounts/azure/v1:get')] + [int]$Offset, + [Parameter(ParameterSetName='/kubernetes-protection/entities/accounts/azure/v1:get')] + [switch]$All, + [Parameter(ParameterSetName='/kubernetes-protection/entities/accounts/azure/v1:get')] + [switch]$Total + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Query = @('ids','status','limit','is_horizon_acct','offset','subscription_id') } + } + [System.Collections.Generic.List[string]]$List = @() + } + process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} + end { + if ($List) { $PSBoundParameters['Id'] = @($List | Select-Object -Unique) } + Invoke-Falcon @Param -Inputs $PSBoundParameters + } +} function Get-FalconContainerCloud { <# .SYNOPSIS @@ -107,8 +208,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconContainerCloud [CmdletBinding(DefaultParameterSetName='/kubernetes-protection/entities/cloud-locations/v1:get', SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/kubernetes-protection/entities/cloud-locations/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/kubernetes-protection/entities/cloud-locations/v1:get', + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidateSet('aws','azure','gcp',IgnoreCase=$false)] [Alias('clouds')] [string[]]$Cloud @@ -160,7 +261,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconContainerCluster SupportsShouldProcess)] param( [Parameter(ParameterSetName='/kubernetes-protection/entities/kubernetes/clusters/v1:get', - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=1)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [Alias('account_ids','Ids')] [string[]]$Id, [Parameter(ParameterSetName='/kubernetes-protection/entities/kubernetes/clusters/v1:get',Position=2)] @@ -194,10 +295,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconContainerCluster } process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} end { - if ($List) { - $PSBoundParameters['Id'] = @($List | Select-Object -Unique) - Invoke-Falcon @Param -Inputs $PSBoundParameters - } + if ($List) { $PSBoundParameters['Id'] = @($List | Select-Object -Unique) } + Invoke-Falcon @Param -Inputs $PSBoundParameters } } function Invoke-FalconContainerScan { @@ -232,7 +331,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconContainerScan function New-FalconContainerAwsAccount { <# .SYNOPSIS -Provision Falcon Container Security accounts +Provision Falcon Container Security AWS accounts .DESCRIPTION Requires 'Kubernetes Protection: Write'. .PARAMETER Region @@ -249,7 +348,7 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconContainerAwsAccount Position=1)] [string]$Region, [Parameter(ParameterSetName='/kubernetes-protection/entities/accounts/aws/v1:post',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=2)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^\d{12}$')] [Alias('account_id')] [string]$Id @@ -263,6 +362,40 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconContainerAwsAccount } process { Invoke-Falcon @Param -Inputs $PSBoundParameters } } +function New-FalconContainerAzureAccount { +<# +.SYNOPSIS +Provision Falcon Container Security Azure accounts +.DESCRIPTION +Requires 'Kubernetes Protection: Write'. +.PARAMETER SubscriptionId +Azure subscription identifier +.PARAMETER TenantId +Azure tenant identifier +.LINK +https://github.com/crowdstrike/psfalcon/wiki/New-FalconContainerAzureAccount +#> + [CmdletBinding(DefaultParameterSetName='/kubernetes-protection/entities/accounts/azure/v1:post', + SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/kubernetes-protection/entities/accounts/azure/v1:post',Position=1)] + [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] + [Alias('subscription_id')] + [string]$SubscriptionId, + [Parameter(ParameterSetName='/kubernetes-protection/entities/accounts/azure/v1:post',Position=2)] + [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] + [Alias('tenant_id')] + [string]$TenantId + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Body = @{ resources = @('subscription_id','tenant_id') }} + } + } + process { Invoke-Falcon @Param -Inputs $PSBoundParameters } +} function New-FalconContainerKey { <# .SYNOPSIS @@ -299,7 +432,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Receive-FalconContainerYaml Position=1)] [string]$Path, [Parameter(ParameterSetName='/kubernetes-protection/entities/integration/agent/v1:get',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=2)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [Alias('cluster_name')] [string]$ClusterName, [Parameter(ParameterSetName='/kubernetes-protection/entities/integration/agent/v1:get')] @@ -344,7 +477,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconContainerAwsAccount SupportsShouldProcess)] param( [Parameter(ParameterSetName='/kubernetes-protection/entities/accounts/aws/v1:delete',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=1)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^\d{12}$')] [Alias('Ids')] [string[]]$Id @@ -364,4 +497,40 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconContainerAwsAccount Invoke-Falcon @Param -Inputs $PSBoundParameters } } +} +function Remove-FalconContainerAzureAccount { +<# +.SYNOPSIS +Remove Falcon Container Security Azure accounts +.DESCRIPTION +Requires 'Kubernetes Protection: Write'. +.PARAMETER Id +Azure subscription identifier +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconContainerAzureAccount +#> + [CmdletBinding(DefaultParameterSetName='/kubernetes-protection/entities/accounts/azure/v1:delete', + SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/kubernetes-protection/entities/accounts/azure/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] + [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] + [Alias('ids')] + [string[]]$Id + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Query = @('ids') } + } + [System.Collections.Generic.List[string]]$List = @() + } + process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} + end { + if ($List) { + $PSBoundParameters['Id'] = @($List | Select-Object -Unique) + Invoke-Falcon @Param -Inputs $PSBoundParameters + } + } } \ No newline at end of file diff --git a/Public/malquery.ps1 b/Public/malquery.ps1 index 96461f69..ca5d17d8 100644 --- a/Public/malquery.ps1 +++ b/Public/malquery.ps1 @@ -11,8 +11,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconMalQuery #> [CmdletBinding(DefaultParameterSetName='/malquery/entities/requests/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/malquery/entities/requests/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/malquery/entities/requests/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('Ids')] [string]$Id @@ -41,7 +41,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconMalQueryQuota $Request = Invoke-Falcon -Endpoint $PSCmdlet.ParameterSetName -RawOutput -EA 0 if ($Request.Result.Content) { (ConvertFrom-Json ($Request.Result.Content).ReadAsStringAsync().Result).meta - } else { + } elseif ($Request) { throw "Unable to retrieve MalQuery quota. Check client permissions." } } @@ -59,8 +59,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconMalQuerySample #> [CmdletBinding(DefaultParameterSetName='/malquery/entities/metadata/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/malquery/entities/metadata/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/malquery/entities/metadata/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] [ValidatePattern('^[A-Fa-f0-9]{64}$')] [Alias('Ids')] [string[]]$Id @@ -96,7 +96,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Group-FalconMalQuerySample SupportsShouldProcess)] param( [Parameter(ParameterSetName='/malquery/entities/samples-multidownload/v1:post',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=1)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[A-Fa-f0-9]{64}$')] [Alias('samples','sample','ids')] [string[]]$Id @@ -244,7 +244,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Receive-FalconMalQuerySample [Parameter(ParameterSetName='/malquery/entities/download-files/v1:get',Mandatory,Position=1)] [string]$Path, [Parameter(ParameterSetName='/malquery/entities/download-files/v1:get',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=2)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^([A-Fa-f0-9]{64}|\w{8}-\w{4}-\w{4}-\w{4}-\w{12})$')] [Alias('Ids')] [string]$Id, @@ -296,10 +296,9 @@ Sha256 hash value .LINK https://github.com/crowdstrike/psfalcon/wiki/Search-FalconMalQueryHash #> - [CmdletBinding(DefaultParameterSetName='/malquery/queries/hunt/v1:post',SupportsShouldProcess)] + [CmdletBinding(SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/malquery/queries/hunt/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[A-Fa-f0-9]{64}$')] [string]$Sha256 ) diff --git a/Public/message-center.ps1 b/Public/message-center.ps1 index 82db4ec4..359d36e4 100644 --- a/Public/message-center.ps1 +++ b/Public/message-center.ps1 @@ -86,21 +86,21 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconCompleteCase Endpoint = $PSCmdlet.ParameterSetName Format = @{ Body = @{ root = @('id','body','detections','incidents') }} } - [System.Collections.Generic.List[string]]$LdtList = @() - [System.Collections.Generic.List[string]]$IncList = @() + [System.Collections.Generic.List[hashtable]]$LdtList = @() + [System.Collections.Generic.List[hashtable]]$IncList = @() } process { if ($DetectionId -or $IncidentId) { - if ($DetectionId) { @($DetectionId).foreach{ $LdtList.Add($_) }} - if ($IncidentId) { @($IncidentId).foreach{ $IncList.Add($_) }} + if ($DetectionId) { @($DetectionId).foreach{ $LdtList.Add(@{ id = $_ }) }} + if ($IncidentId) { @($IncidentId).foreach{ $IncList.Add(@{ id = $_ }) }} } else { Invoke-Falcon @Param -Inputs $PSBoundParameters } } end { if ($LdtList -or $IncList) { - if ($LdtList) { $PSBoundParameters['DetectionId'] = $LdtList | Select-Object -Unique } - if ($IncList) { $PSBoundParameters['IncidentId'] = $IncList | Select-Object -Unique } + if ($LdtList) { $PSBoundParameters['DetectionId'] = $LdtList } + if ($IncList) { $PSBoundParameters['IncidentId'] = $IncList } Invoke-Falcon @Param -Inputs $PSBoundParameters } } @@ -135,7 +135,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconCompleteActivity [CmdletBinding(DefaultParameterSetName='/message-center/queries/case-activities/v1:get',SupportsShouldProcess)] param( [Parameter(ParameterSetName='/message-center/entities/case-activities/GET/v1:post',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName)] + ValueFromPipelineByPropertyName,ValueFromPipeline)] [Alias('Ids')] [string[]]$Id, [Parameter(ParameterSetName='/message-center/queries/case-activities/v1:get',Mandatory,Position=1)] @@ -204,8 +204,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconCompleteCase #> [CmdletBinding(DefaultParameterSetName='/message-center/queries/cases/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/message-center/entities/cases/GET/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/message-center/entities/cases/GET/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [Alias('Ids')] [string[]]$Id, [Parameter(ParameterSetName='/message-center/queries/cases/v1:get',Position=1)] @@ -315,21 +315,21 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconCompleteCase Body = @{ root = @('body','detections','incidents','title','type','user_uuid') } } } - [System.Collections.Generic.List[string]]$LdtList = @() - [System.Collections.Generic.List[string]]$IncList = @() + [System.Collections.Generic.List[hashtable]]$LdtList = @() + [System.Collections.Generic.List[hashtable]]$IncList = @() } process { if ($DetectionId -or $IncidentId) { - if ($DetectionId) { @($DetectionId).foreach{ $LdtList.Add($_) }} - if ($IncidentId) { @($IncidentId).foreach{ $IncList.Add($_) }} + if ($DetectionId) { @($DetectionId).foreach{ $LdtList.Add(@{ id = $_ }) }} + if ($IncidentId) { @($IncidentId).foreach{ $IncList.Add(@{ id = $_ }) }} } else { Invoke-Falcon @Param -Inputs $PSBoundParameters } } end { if ($LdtList -or $IncList) { - if ($LdtList) { $PSBoundParameters['DetectionId'] = $LdtList | Select-Object -Unique } - if ($IncList) { $PSBoundParameters['IncidentId'] = $IncList | Select-Object -Unique } + if ($LdtList) { $PSBoundParameters['DetectionId'] = $LdtList } + if ($IncList) { $PSBoundParameters['IncidentId'] = $IncList } Invoke-Falcon @Param -Inputs $PSBoundParameters } } @@ -354,12 +354,11 @@ https://github.com/crowdstrike/psfalcon/wiki/Receive-FalconCompleteAttachment param( [Parameter(ParameterSetName='/message-center/entities/case-attachment/v1:get',Mandatory,Position=1)] [string]$Path, - [Parameter(ParameterSetName='/message-center/entities/case-attachment/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=2)] + [Parameter(ParameterSetName='/message-center/entities/case-attachment/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [string]$Id, [Parameter(ParameterSetName='/message-center/entities/case-attachment/v1:get')] [switch]$Force - ) begin { $Param = @{ @@ -403,14 +402,16 @@ https://github.com/crowdstrike/psfalcon/wiki/Send-FalconCompleteAttachment SupportsShouldProcess)] param( [Parameter(ParameterSetName='/message-center/entities/case-attachment/v1:post',Mandatory,Position=1)] - [ValidatePattern('\.(bmp|csv|doc|docx|gif|jpg|jpeg|pdf|png|pptx|txt|xls|xlsx)$')] + [ValidatePattern('\.(bmp|csv|doc(x?)|gif|jp(e?)g|pdf|png|ppt(x?)|txt|xls(x?))$')] [ValidateScript({ if (Test-Path $_ -PathType Leaf) { $Leaf = Split-Path $_ -Leaf - if ($Leaf -match '\W') { + if ($Leaf -notmatch '^[a-z0-9-_\.\s]+$') { throw 'Filename contains invalid characters.' - } elseif (((Split-Path $_ -Leaf) -Split '.')[0].Length -gt 255) { + } elseif (($Leaf -Split '.')[0].Length -gt 255) { throw 'Maximum filename length is 255 characters.' + } elseif ((Get-Item $_).Length/15MB -ge 1) { + throw 'Maximum filesize is 15MB.' } else { $true } diff --git a/Public/mobile-enrollment.ps1 b/Public/mobile-enrollment.ps1 deleted file mode 100644 index f9e46440..00000000 --- a/Public/mobile-enrollment.ps1 +++ /dev/null @@ -1,50 +0,0 @@ -function Invoke-FalconMobileAction { -<# -.SYNOPSIS -Trigger on-boarding process for a mobile device -.DESCRIPTION -Requires 'Mobile Enrollment: Write'. -.PARAMETER Name -Action to perform -.PARAMETER ExpiresAt -Expiration time [default: 30 days] -.PARAMETER Email -Email address -.LINK -https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconMobileAction -#> - [CmdletBinding(DefaultParameterSetName='/enrollments/entities/details/v3:post',SupportsShouldProcess)] - param( - [Parameter(ParameterSetName='/enrollments/entities/details/v3:post',Mandatory,Position=1)] - [ValidateSet('enroll','re-enroll',IgnoreCase=$false)] - [Alias('action_name')] - [string]$Name, - [Parameter(ParameterSetName='/enrollments/entities/details/v3:post',Position=2)] - [Alias('expires_at')] - [string]$ExpiresAt, - [Parameter(ParameterSetName='/enrollments/entities/details/v3:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=3)] - [ValidateScript({ - if ((Test-RegexValue $_) -eq 'email') { $true } else { throw "'$_' is not a valid email address." } - })] - [Alias('email_addresses')] - [string[]]$Email - ) - # - begin { - $Param = @{ - Command = $MyInvocation.MyCommand.Name - Endpoint = $PSCmdlet.ParameterSetName - Format = @{ Query = @('action_name'); Body = @{ root = @('email_addresses','expires_at') }} - } - [System.Collections.Generic.List[string]]$List = @() - if (!$PSBoundParameters.ExpiresAt) { $PSBoundParameters.ExpiresAt = Convert-Rfc3339 720 } - } - process { if ($Email) { @($Email).foreach{ $List.Add($_) }}} - end { - if ($List) { - $PSBoundParameters['Email'] = @($List | Select-Object -Unique) - Invoke-Falcon @Param -Inputs $PSBoundParameters - } - } -} \ No newline at end of file diff --git a/Public/mssp.ps1 b/Public/mssp.ps1 index 735616c2..7a8404ed 100644 --- a/Public/mssp.ps1 +++ b/Public/mssp.ps1 @@ -7,7 +7,7 @@ Requires 'Flight Control: Write'. .PARAMETER Id CID group identifier .PARAMETER Cid -CID +Customer identifier .LINK https://github.com/crowdstrike/psfalcon/wiki/Add-FalconCidGroupMember #> @@ -235,10 +235,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconCidGroup #> [CmdletBinding(DefaultParameterSetName='/mssp/queries/cid-groups/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/mssp/entities/cid-groups/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/mssp/entities/cid-groups/v2:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] - [Alias('cid_group_ids','Ids')] + [Alias('ids','cid_group_id')] [string[]]$Id, [Parameter(ParameterSetName='/mssp/queries/cid-groups/v1:get',Position=1)] [string]$Name, @@ -262,7 +262,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconCidGroup $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName - Format = @{ Query = @('cid_group_ids','offset','limit','name','sort') } + Format = @{ Query = @('ids','offset','limit','name','sort') } } [System.Collections.Generic.List[string]]$List = @() } @@ -299,10 +299,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconCidGroupMember #> [CmdletBinding(DefaultParameterSetName='/mssp/queries/cid-group-members/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/mssp/entities/cid-group-members/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/mssp/entities/cid-group-members/v2:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] - [Alias('cid_group_ids','Ids')] + [Alias('ids','cid_group_id')] [string[]]$Id, [Parameter(ParameterSetName='/mssp/queries/cid-group-members/v1:get',Mandatory, ValueFromPipelineByPropertyName,Position=1)] @@ -328,7 +328,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconCidGroupMember $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName - Format = @{ Query = @('cid_group_ids','offset','limit','sort','cid') } + Format = @{ Query = @('ids','offset','limit','sort','cid') } } [System.Collections.Generic.List[string]]$List = @() } @@ -448,8 +448,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconMemberCid #> [CmdletBinding(DefaultParameterSetName='/mssp/queries/children/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/mssp/entities/children/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/mssp/entities/children/GET/v2:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids','child_cid')] [string[]]$Id, @@ -472,7 +472,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconMemberCid $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName - Format = @{ Query = @('sort','ids','offset','limit') } + Format = @{ + Body = @{ root = @('ids') } + Query = @('sort','offset','limit') + } } [System.Collections.Generic.List[string]]$List = @() } @@ -509,10 +512,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconUserGroup #> [CmdletBinding(DefaultParameterSetName='/mssp/queries/user-groups/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/mssp/entities/user-groups/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/mssp/entities/user-groups/v2:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] - [Alias('user_group_ids','user_group_id','Ids')] + [Alias('ids','user_group_id')] [string[]]$Id, [Parameter(ParameterSetName='/mssp/queries/user-groups/v1:get',Position=1)] [string]$Name, @@ -536,7 +539,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconUserGroup $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName - Format = @{ Query = @('sort','offset','user_group_ids','limit','name') } + Format = @{ Query = @('sort','offset','ids','limit','name') } } [System.Collections.Generic.List[string]]$List = @() } @@ -573,10 +576,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconUserGroupMember #> [CmdletBinding(DefaultParameterSetName='/mssp/queries/user-group-members/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/mssp/entities/user-group-members/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/mssp/entities/user-group-members/v2:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] - [Alias('user_group_ids','user_group_id','Ids')] + [Alias('ids','user_group_id')] [string[]]$Id, [Parameter(ParameterSetName='/mssp/queries/user-group-members/v1:get',Mandatory, ValueFromPipelineByPropertyName,Position=1)] @@ -602,7 +605,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconUserGroupMember $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName - Format = @{ Query = @('sort','offset','user_group_ids','limit','user_uuid') } + Format = @{ Query = @('sort','offset','ids','limit','user_uuid') } } [System.Collections.Generic.List[string]]$List = @() } @@ -683,8 +686,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconCidGroup #> [CmdletBinding(DefaultParameterSetName='/mssp/entities/cid-groups/v1:delete',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/mssp/entities/cid-groups/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/mssp/entities/cid-groups/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('cid_group_ids','cid_group_id','Ids')] [string[]]$Id @@ -714,7 +717,7 @@ Requires 'Flight Control: Write'. .PARAMETER Id CID group identifier .PARAMETER Cid -CID +Customer identifier .LINK https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconCidGroupMember #> @@ -814,8 +817,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconUserGroup #> [CmdletBinding(DefaultParameterSetName='/mssp/entities/user-groups/v1:delete',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/mssp/entities/user-groups/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/mssp/entities/user-groups/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('user_group_ids','user_group_id','Ids')] [string[]]$Id @@ -855,8 +858,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconUserGroupMember [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('user_group_id')] [string]$Id, - [Parameter(ParameterSetName='/mssp/entities/user-group-members/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=2)] + [Parameter(ParameterSetName='/mssp/entities/user-group-members/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('user_uuids','uuid','UserIds')] [string[]]$UserId diff --git a/Public/oauth2.ps1 b/Public/oauth2.ps1 index ac5c9ac9..ac91b707 100644 --- a/Public/oauth2.ps1 +++ b/Public/oauth2.ps1 @@ -222,7 +222,9 @@ https://github.com/crowdstrike/psfalcon/wiki/Revoke-FalconToken Write-Result $Request [void]$Script:Falcon.Api.Client.DefaultRequestHeaders.Remove('Authorization') } - @('ClientId','ClientSecret','MemberCid').foreach{ [void]$Script:Falcon.Remove($_) } + @('ClientId','ClientSecret','MemberCid').foreach{ + if ($Script:Falcon.$_) { [void]$Script:Falcon.Remove($_) } + } } } function Test-FalconToken { diff --git a/Public/ods.ps1 b/Public/ods.ps1 new file mode 100644 index 00000000..605c7053 --- /dev/null +++ b/Public/ods.ps1 @@ -0,0 +1,640 @@ +function Set-ScanInteger ([object]$Object) { + @('SensorDetection','SensorPrevention','CloudDetection','CloudPrevention').foreach{ + if ($Object.$_) { + [int]$Object.$_ = switch ($Object.$_) { + # Change machine-learning levels to integer value + 'disabled' { 0 } + 'cautious' { 1 } + 'moderate' { 2 } + 'aggressive' { 3 } + 'extra_aggressive' { 4 } + } + } + } + if ($Object.CpuPriority) { + [int]$Object.CpuPriority = switch ($Object.CpuPriority) { + # Change CPU priority level to integer value + 'up_to_1' { 1 } + 'up_to_25' { 2 } + 'up_to_50' { 3 } + 'up_to_75' { 4 } + 'up_to_100' { 5 } + } + } + if ($Object.Repeat) { + [int]$Object.Repeat = switch ($Object.Repeat) { + # Change interval to integer value + 'never' { 0 } + 'daily' { 1 } + 'weekly' { 7 } + 'every_other_week' { 14 } + 'every_4_weeks' { 28 } + 'monthly' { 30 } + } + } + $Object +} +function Get-FalconScan { +<# +.SYNOPSIS +Search for on-demand or scheduled scan results +.DESCRIPTION +Requires 'On-demand scans (ODS): Read'. +.PARAMETER Id +Scan result 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 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/Get-FalconScan +#> + [CmdletBinding(DefaultParameterSetName='/ods/queries/scans/v1:get',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/ods/entities/scans/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] + [ValidatePattern('^[a-fA-F0-9]{32}$')] + [Alias('ids')] + [string[]]$Id, + [Parameter(ParameterSetName='/ods/queries/scans/v1:get',Position=1)] + [ValidateScript({ Test-FqlStatement $_ })] + [string]$Filter, + [Parameter(ParameterSetName='/ods/queries/scans/v1:get',Position=2)] + [ValidateSet('id|asc','id|desc','initiated_from|asc','initiated_from|desc','description.keyword|asc', + 'description.keyword|desc','filecount.scanned|asc','filecount.scanned|desc','filecount.malicious|asc', + 'filecount.malicious|desc','filecount.quarantined|asc','filecount.quarantined|desc', + 'filecount.skipped|asc','filecount.skipped|desc','affected_hosts_count|asc', + 'affected_hosts_count|desc','status|asc','status|desc','severity|asc','severity|desc', + 'scan_started_on|asc','scan_started_on|desc','scan_completed_on|asc','scan_completed_on|desc', + 'created_on|asc','created_on|desc','created_by|asc','created_by|desc','last_updated|asc', + 'last_updated|desc',IgnoreCase=$false)] + [string]$Sort, + [Parameter(ParameterSetName='/ods/queries/scans/v1:get',Position=3)] + [int32]$Limit, + [Parameter(ParameterSetName='/ods/queries/scans/v1:get')] + [int32]$Offset, + [Parameter(ParameterSetName='/ods/queries/scans/v1:get')] + [switch]$Detailed, + [Parameter(ParameterSetName='/ods/queries/scans/v1:get')] + [switch]$All, + [Parameter(ParameterSetName='/ods/queries/scans/v1:get')] + [switch]$Total + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Query = @('offset','limit','sort','filter','ids') } + } + [System.Collections.Generic.List[string]]$List = @() + } + process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} + end { + if ($List) { $PSBoundParameters['Id'] = @($List | Select-Object -Unique) } + Invoke-Falcon @Param -Inputs $PSBoundParameters + } +} +function Get-FalconScanFile { +<# +.SYNOPSIS +Search for files found by on-demand or scheduled scans +.DESCRIPTION +Requires 'On-demand scans (ODS): Read'. +.PARAMETER Id +Malicious file 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 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/Get-FalconScanFile +#> + [CmdletBinding(DefaultParameterSetName='/ods/queries/malicious-files/v1:get',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/ods/entities/malicious-files/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] + [ValidatePattern('^[a-fA-F0-9]{32}$')] + [Alias('ids')] + [string[]]$Id, + [Parameter(ParameterSetName='/ods/queries/malicious-files/v1:get',Position=1)] + [ValidateScript({ Test-FqlStatement $_ })] + [string]$Filter, + [Parameter(ParameterSetName='/ods/queries/malicious-files/v1:get',Position=2)] + [ValidateSet('id|asc','id|desc','scan_id|asc','scan_id|desc','host_id|asc','host_id|desc', + 'host_scan_id|asc','host_scan_id|desc','filename|asc','filename|desc','hash|asc','hash|desc', + 'pattern_id|asc','pattern_id|desc','severity|asc','severity|desc','last_updated|asc', + 'last_updated|desc',IgnoreCase=$false)] + [string]$Sort, + [Parameter(ParameterSetName='/ods/queries/malicious-files/v1:get',Position=3)] + [int32]$Limit, + [Parameter(ParameterSetName='/ods/queries/malicious-files/v1:get')] + [int32]$Offset, + [Parameter(ParameterSetName='/ods/queries/malicious-files/v1:get')] + [switch]$Detailed, + [Parameter(ParameterSetName='/ods/queries/malicious-files/v1:get')] + [switch]$All, + [Parameter(ParameterSetName='/ods/queries/malicious-files/v1:get')] + [switch]$Total + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Query = @('offset','limit','sort','filter','ids') } + } + [System.Collections.Generic.List[string]]$List = @() + } + process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} + end { + if ($List) { $PSBoundParameters['Id'] = @($List | Select-Object -Unique) } + Invoke-Falcon @Param -Inputs $PSBoundParameters + } +} +function Get-FalconScanHost { +<# +.SYNOPSIS +Search for on-demand or scheduled scan metadata for specific hosts +.DESCRIPTION +Requires 'On-demand scans (ODS): Read'. +.PARAMETER Id +Scanned host metadata 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 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/Get-FalconScanHost +#> + [CmdletBinding(DefaultParameterSetName='/ods/queries/scan-hosts/v1:get',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/ods/entities/scan-hosts/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] + [Alias('ids','scan_host_metadata_id')] + [object[]]$Id, + [Parameter(ParameterSetName='/ods/queries/scan-hosts/v1:get',Position=1)] + [ValidateScript({ Test-FqlStatement $_ })] + [string]$Filter, + [Parameter(ParameterSetName='/ods/queries/scan-hosts/v1:get',Position=2)] + [ValidateSet('id|asc','id|desc','scan_id|asc','scan_id|desc','host_id|asc','host_id|desc', + 'filecount.scanned|asc','filecount.scanned|desc','filecount.malicious|asc','filecount.malicious|desc', + 'filecount.quarantined|asc','filecount.quarantined|desc','filecount.skipped|asc', + 'filecount.skipped|desc','status|asc','status|desc','severity|asc','severity|desc','started_on|asc', + 'started_on|desc','completed_on|asc','completed_on|desc','last_updated|asc','last_updated|desc', + IgnoreCase=$false)] + [string]$Sort, + [Parameter(ParameterSetName='/ods/queries/scan-hosts/v1:get',Position=3)] + [int32]$Limit, + [Parameter(ParameterSetName='/ods/queries/scan-hosts/v1:get')] + [int32]$Offset, + [Parameter(ParameterSetName='/ods/queries/scan-hosts/v1:get')] + [switch]$Detailed, + [Parameter(ParameterSetName='/ods/queries/scan-hosts/v1:get')] + [switch]$All, + [Parameter(ParameterSetName='/ods/queries/scan-hosts/v1:get')] + [switch]$Total + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Query = @('offset','limit','sort','filter','ids') } + } + [System.Collections.Generic.List[string]]$List = @() + } + process { + if ($Id) { + @(Select-Property $Id Id '^[a-fA-F0-9]{32}$' $Param.Command scan_host_metadata_id metadata).foreach{ + if ($_ -is [string]) { $List.Add($_) } else { $PSCmdlet.WriteError($_) } + } + } else { + Invoke-Falcon @Param -Inputs $PSBoundParameters + } + } + end { + if ($List) { + $PSBoundParameters['Id'] = @($List | Select-Object -Unique) + Invoke-Falcon @Param -Inputs $PSBoundParameters + } + } +} +function Get-FalconScheduledScan { +<# +.SYNOPSIS +Search for scheduled scans +.DESCRIPTION +Requires 'On-demand scans (ODS): Read'. +.PARAMETER Id +Scheduled scan 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 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/Get-FalconScheduledScan +#> + [CmdletBinding(DefaultParameterSetName='/ods/queries/scheduled-scans/v1:get',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] + [ValidatePattern('^[a-fA-F0-9]{32}$')] + [Alias('ids')] + [string[]]$Id, + [Parameter(ParameterSetName='/ods/queries/scheduled-scans/v1:get',Position=1)] + [ValidateScript({ Test-FqlStatement $_ })] + [string]$Filter, + [Parameter(ParameterSetName='/ods/queries/scheduled-scans/v1:get',Position=2)] + [ValidateSet('id|asc','id|desc','description.keyword|asc','description.keyword|desc','status|asc', + 'status|desc','schedule.start_timestamp|asc','schedule.start_timestamp|desc','schedule.interval|asc', + 'schedule.interval|desc','created_on|asc','created_on|desc','created_by|asc','created_by|desc', + 'last_updated|asc','last_updated|desc',IgnoreCase=$false)] + [string]$Sort, + [Parameter(ParameterSetName='/ods/queries/scheduled-scans/v1:get',Position=3)] + [int32]$Limit, + [Parameter(ParameterSetName='/ods/queries/scheduled-scans/v1:get')] + [int32]$Offset, + [Parameter(ParameterSetName='/ods/queries/scheduled-scans/v1:get')] + [switch]$Detailed, + [Parameter(ParameterSetName='/ods/queries/scheduled-scans/v1:get')] + [switch]$All, + [Parameter(ParameterSetName='/ods/queries/scheduled-scans/v1:get')] + [switch]$Total + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Query = @('offset','limit','sort','filter','ids') } + } + [System.Collections.Generic.List[string]]$List = @() + } + process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} + end { + if ($List) { $PSBoundParameters['Id'] = @($List | Select-Object -Unique) } + Invoke-Falcon @Param -Inputs $PSBoundParameters + } +} +function New-FalconScheduledScan { +<# +.SYNOPSIS +Create a scheduled scan targeting host groups +.DESCRIPTION +Requires 'On-demand scans (ODS): Write'. +.PARAMETER StartTime +Start time (yyyy-MM-ddThh:mm) +.PARAMETER Repeat +Repetition frequency +.PARAMETER FilePath +File path(s) to scan +.PARAMETER SensorDetection +On-sensor machine-learning detection level +.PARAMETER SensorPrevention +On-sensor machine-learning prevention level +.PARAMETER CloudDetection +Cloud-based machine-learning detection level +.PARAMETER CloudPrevention +Cloud-based machine-learning prevention level +.PARAMETER ScanExclusion +File path(s) to exclude, in glob syntax +.PARAMETER Quarantine +Quarantine malicious files +.PARAMETER MaxFileSize +Maximum file size, in MB +.PARAMETER CpuPriority +Maximum CPU utilization +.PARAMETER EndpointNotification +Show notification to end user +.PARAMETER MaxDuration +Allowable scan duration, in hours +.PARAMETER PauseDuration +Allowable pause duration, in hours +.PARAMETER Description +On-demand scan description +.PARAMETER Id +Host group identifier +.LINK +https://github.com/crowdstrike/psfalcon/wiki/New-FalconScheduledScan +#> + [CmdletBinding(DefaultParameterSetName='/ods/entities/scheduled-scans/v1:post',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:post',Mandatory,Position=1)] + [ValidatePattern('^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}$')] + [string]$StartTime, + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:post',Mandatory,Position=2)] + [ValidateSet('never','daily','weekly','every_other_week','every_4_weeks','monthly',IgnoreCase=$false)] + [string]$Repeat, + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:post',Mandatory,Position=3)] + [Alias('file_paths')] + [string[]]$FilePath, + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:post',Mandatory,Position=4)] + [ValidateSet('disabled','cautious','moderate','aggressive','extra_aggressive',IgnoreCase=$false)] + [Alias('sensor_ml_level_detection')] + [string]$SensorDetection, + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:post',Mandatory,Position=5)] + [ValidateSet('disabled','cautious','moderate','aggressive','extra_aggressive',IgnoreCase=$false)] + [Alias('sensor_ml_level_prevention')] + [string]$SensorPrevention, + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:post',Mandatory,Position=6)] + [ValidateSet('disabled','cautious','moderate','aggressive','extra_aggressive',IgnoreCase=$false)] + [Alias('cloud_ml_level_detection')] + [string]$CloudDetection, + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:post',Mandatory,Position=7)] + [ValidateSet('disabled','cautious','moderate','aggressive','extra_aggressive',IgnoreCase=$false)] + [Alias('cloud_ml_level_prevention')] + [string]$CloudPrevention, + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:post',Position=8)] + [Alias('scan_exclusions')] + [string[]]$ScanExclusion, + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:post',Position=9)] + [boolean]$Quarantine, + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:post',Position=10)] + [Alias('max_file_size')] + [int32]$MaxFileSize, + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:post',Position=11)] + [ValidateSet('up_to_1','up_to_25','up_to_50','up_to_75','up_to_100',IgnoreCase=$false)] + [Alias('cpu_priority')] + [string]$CpuPriority, + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:post',Position=12)] + [Alias('endpoint_notification')] + [boolean]$Notification, + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:post',Position=13)] + [Alias('max_duration')] + [ValidateRange(0,24)] + [int]$MaxDuration, + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:post',Position=14)] + [Alias('pause_duration')] + [ValidateRange(0,24)] + [int]$PauseDuration, + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:post',Position=15)] + [string]$Description, + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=16)] + [ValidatePattern('^[a-fA-F0-9]{32}$')] + [Alias('host_groups')] + [string[]]$Id + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ + Body = @{ + root = @('file_paths','host_groups','max_file_size','max_duration','pause_duration', + 'cloud_ml_level_detection','cloud_ml_level_prevention','sensor_ml_level_detection', + 'sensor_ml_level_prevention','cpu_priority','scan_exclusions','description', + 'schedule','ignored_by_channel_file') + } + } + } + [System.Collections.Generic.List[string]]$List = @() + } + process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} + end { + if ($List) { + $PSBoundParameters['Id'] = @($List | Select-Object -Unique) + $Inputs = Set-ScanInteger $PSBoundParameters + $Inputs['Schedule'] = @{ start_timestamp = $Inputs.StartTime; interval = $Inputs.Repeat } + @('StartTime','Repeat').foreach{ [void]$Inputs.Remove($_) } + Invoke-Falcon @Param -Inputs $Inputs + } + } +} +function Remove-FalconScheduledScan { +<# +.SYNOPSIS +Remove a scheduled scan +.DESCRIPTION +Requires 'On-demand scans (ODS): Write'. +.PARAMETER Id +Scheduled scan identifier +.PARAMETER Filter +Falcon Query Language expression to find scheduled scans for removal +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconScheduledScan +#> + [CmdletBinding(DefaultParameterSetName='/ods/entities/scheduled-scans/v1:delete',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/ods/entities/scheduled-scans/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] + [ValidatePattern('^[a-fA-F0-9]{32}$')] + [Alias('ids')] + [string[]]$Id, + [Parameter(ParameterSetName='Filter',Mandatory)] + [string]$Filter + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = '/ods/entities/scheduled-scans/v1:delete' + Format = @{ Query = @('ids','filter') } + } + [System.Collections.Generic.List[string]]$List = @() + } + process { + if ($Id) { @($Id).foreach{ $List.Add($_) }}} + end { + if ($List) { $PSBoundParameters['Id'] = @($List | Select-Object -Unique) } + Invoke-Falcon @Param -Inputs $PSBoundParameters + } +} +function Start-FalconScan { +<# +.SYNOPSIS +Start an on-demand scan +.DESCRIPTION +Requires 'On-demand scans (ODS): Write'. +.PARAMETER FilePath +File path(s) to scan +.PARAMETER SensorDetection +On-sensor machine-learning detection level +.PARAMETER SensorPrevention +On-sensor machine-learning prevention level +.PARAMETER CloudDetection +Cloud-based machine-learning detection level +.PARAMETER CloudPrevention +Cloud-based machine-learning prevention level +.PARAMETER ScanExclusion +File path(s) to exclude, in glob syntax +.PARAMETER Quarantine +Quarantine malicious files +.PARAMETER MaxFileSize +Maximum file size, in MB +.PARAMETER CpuPriority +Maximum CPU utilization +.PARAMETER EndpointNotification +Show notification to end user +.PARAMETER MaxDuration +Allowable scan duration, in hours +.PARAMETER PauseDuration +Allowable pause duration, in hours +.PARAMETER Description +On-demand scan description +.PARAMETER GroupId +Host Group identifier +.PARAMETER Id +Host identifier +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Start-FalconScan +#> + [CmdletBinding(DefaultParameterSetName='/ods/entities/scans/v1:post',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/ods/entities/scans/v1:post',Mandatory,Position=1)] + [Alias('file_paths')] + [string[]]$FilePath, + [Parameter(ParameterSetName='/ods/entities/scans/v1:post',Mandatory,Position=2)] + [ValidateSet('disabled','cautious','moderate','aggressive','extra_aggressive',IgnoreCase=$false)] + [Alias('sensor_ml_level_detection')] + [string]$SensorDetection, + [Parameter(ParameterSetName='/ods/entities/scans/v1:post',Mandatory,Position=3)] + [ValidateSet('disabled','cautious','moderate','aggressive','extra_aggressive',IgnoreCase=$false)] + [Alias('sensor_ml_level_prevention')] + [string]$SensorPrevention, + [Parameter(ParameterSetName='/ods/entities/scans/v1:post',Mandatory,Position=4)] + [ValidateSet('disabled','cautious','moderate','aggressive','extra_aggressive',IgnoreCase=$false)] + [Alias('cloud_ml_level_detection')] + [string]$CloudDetection, + [Parameter(ParameterSetName='/ods/entities/scans/v1:post',Mandatory,Position=5)] + [ValidateSet('disabled','cautious','moderate','aggressive','extra_aggressive',IgnoreCase=$false)] + [Alias('cloud_ml_level_prevention')] + [string]$CloudPrevention, + [Parameter(ParameterSetName='/ods/entities/scans/v1:post',Position=6)] + [Alias('scan_exclusions')] + [string[]]$ScanExclusion, + [Parameter(ParameterSetName='/ods/entities/scans/v1:post',Position=7)] + [boolean]$Quarantine, + [Parameter(ParameterSetName='/ods/entities/scans/v1:post',Position=8)] + [Alias('max_file_size')] + [int32]$MaxFileSize, + [Parameter(ParameterSetName='/ods/entities/scans/v1:post',Position=9)] + [ValidateSet('up_to_1','up_to_25','up_to_50','up_to_75','up_to_100',IgnoreCase=$false)] + [Alias('cpu_priority')] + [string]$CpuPriority, + [Parameter(ParameterSetName='/ods/entities/scans/v1:post',Position=10)] + [Alias('endpoint_notification')] + [boolean]$Notification, + [Parameter(ParameterSetName='/ods/entities/scans/v1:post',Position=11)] + [ValidateRange(0,24)] + [Alias('max_duration')] + [int]$MaxDuration, + [Parameter(ParameterSetName='/ods/entities/scans/v1:post',Position=12)] + [ValidateRange(0,24)] + [Alias('pause_duration')] + [int]$PauseDuration, + [Parameter(ParameterSetName='/ods/entities/scans/v1:post',Position=13)] + [string]$Description, + [Parameter(ParameterSetName='/ods/entities/scans/v1:post')] + [ValidatePattern('^[a-fA-F0-9]{32}$')] + [Alias('host_groups')] + [string[]]$GroupId, + [Parameter(ParameterSetName='/ods/entities/scans/v1:post',ValueFromPipelineByPropertyName, + ValueFromPipeline)] + [ValidatePattern('^[a-fA-F0-9]{32}$')] + [Alias('hosts','device_id','host_ids','aid')] + [string[]]$Id + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ + Body = @{ + root = @('description','host_groups','scan_exclusions','endpoint_notification','hosts', + 'sensor_ml_level_prevention','max_duration','sensor_ml_level_detection', + 'cloud_ml_level_detection','pause_duration','quarantine','initiated_from', + 'cpu_priority','cloud_ml_level_prevention','file_paths','max_file_size') + } + } + } + [System.Collections.Generic.List[string]]$List = @() + } + process { + if ($Id) { + @($Id).foreach{ $List.Add($_) } + } elseif (!$PSBoundParameters.GroupId) { + throw "At least one host group or host identifier value is required." + } else { + Invoke-Falcon @Param -Inputs (Set-ScanInteger $PSBoundParameters) + } + } + end { + if ($List -or $PSBoundParameters.GroupId) { + if ($List) { $PSBoundParameters['Id'] = @($List | Select-Object -Unique) } + Invoke-Falcon @Param -Inputs (Set-ScanInteger $PSBoundParameters) + } + } +} +function Stop-FalconScan { +<# +.SYNOPSIS +Stop an on-demand scan +.DESCRIPTION +Requires 'On-demand scans (ODS): Write'. +.PARAMETER Id +On-demand scan identifier +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Stop-FalconScan +#> + [CmdletBinding(DefaultParameterSetName='/ods/entities/scan-control-actions/cancel/v1:post', + SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/ods/entities/scan-control-actions/cancel/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] + [ValidatePattern('^[a-fA-F0-9]{32}$')] + [Alias('ids')] + [string[]]$Id + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Body = @{ root = @('ids') }} + } + [System.Collections.Generic.List[string]]$List = @() + } + process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} + end { + if ($List) { + $PSBoundParameters['Id'] = @($List | Select-Object -Unique) + Invoke-Falcon @Param -Inputs $PSBoundParameters + } + } +} \ No newline at end of file diff --git a/Public/policy-device-control.ps1 b/Public/policy-device-control.ps1 index 95f13fac..d212340c 100644 --- a/Public/policy-device-control.ps1 +++ b/Public/policy-device-control.ps1 @@ -15,7 +15,7 @@ Policy description .PARAMETER Setting Policy settings .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Edit-FalconDeviceControlPolicy +https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconDeviceControlPolicy #> [CmdletBinding(DefaultParameterSetName='/policy/entities/device-control/v1:patch',SupportsShouldProcess)] param( @@ -60,8 +60,7 @@ https://github.com/CrowdStrike/psfalcon/wiki/Edit-FalconDeviceControlPolicy } process { if ($Array) { - @($Array).foreach{ - $i = $_ + foreach ($i in $Array) { if ($i.settings.classes.exceptions) { @($i.settings.classes.exceptions).Where({ $_.id }).foreach{ # Remove exception 'id' values from 'settings' object @@ -112,12 +111,12 @@ Repeat requests until all available results are retrieved .PARAMETER Total Display total result count instead of results .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Get-FalconDeviceControlPolicy +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconDeviceControlPolicy #> [CmdletBinding(DefaultParameterSetName='/policy/queries/device-control/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/policy/entities/device-control/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/policy/entities/device-control/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -195,14 +194,14 @@ Repeat requests until all available results are retrieved .PARAMETER Total Display total result count instead of results .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Get-FalconDeviceControlPolicyMember +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconDeviceControlPolicyMember #> [CmdletBinding(DefaultParameterSetName='/policy/queries/device-control-members/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/policy/queries/device-control-members/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] - [Parameter(ParameterSetName='/policy/combined/device-control-members/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/policy/queries/device-control-members/v1:get', + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] + [Parameter(ParameterSetName='/policy/combined/device-control-members/v1:get', + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id, [Parameter(ParameterSetName='/policy/queries/device-control-members/v1:get',Position=2)] @@ -249,7 +248,7 @@ Host group identifier .PARAMETER Id Policy identifier .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Invoke-FalconDeviceControlPolicyAction +https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconDeviceControlPolicyAction #> [CmdletBinding(DefaultParameterSetName='/policy/entities/device-control-actions/v1:post', SupportsShouldProcess)] @@ -262,8 +261,8 @@ https://github.com/CrowdStrike/psfalcon/wiki/Invoke-FalconDeviceControlPolicyAct [Parameter(ParameterSetName='/policy/entities/device-control-actions/v1:post',Position=2)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$GroupId, - [Parameter(ParameterSetName='/policy/entities/device-control-actions/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=3)] + [Parameter(ParameterSetName='/policy/entities/device-control-actions/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id ) @@ -309,7 +308,7 @@ Policy description .PARAMETER Settings Hashtable of policy settings .LINK -https://github.com/CrowdStrike/psfalcon/wiki/New-FalconDeviceControlPolicy +https://github.com/crowdstrike/psfalcon/wiki/New-FalconDeviceControlPolicy #> [CmdletBinding(DefaultParameterSetName='/policy/entities/device-control/v1:post',SupportsShouldProcess)] param( @@ -356,8 +355,7 @@ https://github.com/CrowdStrike/psfalcon/wiki/New-FalconDeviceControlPolicy } process { if ($Array) { - @($Array).foreach{ - $i = $_ + foreach ($i in $Array) { if ($i.settings.classes.exceptions) { @($i.settings.classes.exceptions).Where({ $_.id }).foreach{ # Remove exception 'id' values from 'settings' object @@ -390,12 +388,12 @@ Requires 'Device Control Policies: Write'. .PARAMETER Id Policy identifier .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Remove-FalconDeviceControlPolicy +https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconDeviceControlPolicy #> [CmdletBinding(DefaultParameterSetName='/policy/entities/device-control/v1:delete',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/policy/entities/device-control/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/policy/entities/device-control/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id @@ -430,7 +428,7 @@ Operating system platform .PARAMETER Id Policy identifiers in desired precedence order .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Set-FalconDeviceControlPrecedence +https://github.com/crowdstrike/psfalcon/wiki/Set-FalconDeviceControlPrecedence #> [CmdletBinding(DefaultParameterSetName='/policy/entities/device-control-precedence/v1:post', SupportsShouldProcess)] diff --git a/Public/policy-firewall-management.ps1 b/Public/policy-firewall-management.ps1 index 9c1a1d31..a1312c91 100644 --- a/Public/policy-firewall-management.ps1 +++ b/Public/policy-firewall-management.ps1 @@ -55,8 +55,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconFirewallPolicy } process { if ($Array) { - @($Array).foreach{ - $i = $_ + foreach ($i in $Array) { + # Select allowed fields, when populated [string[]]$Select = @('id','name','description').foreach{ if ($i.$_) { $_ }} $List.Add(($i | Select-Object $Select)) } @@ -102,8 +102,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconFirewallPolicy #> [CmdletBinding(DefaultParameterSetName='/policy/queries/firewall/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/policy/entities/firewall/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/policy/entities/firewall/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -189,10 +189,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconFirewallPolicyMember #> [CmdletBinding(DefaultParameterSetName='/policy/queries/firewall-members/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/policy/queries/firewall-members/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] - [Parameter(ParameterSetName='/policy/combined/firewall-members/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/policy/queries/firewall-members/v1:get',ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] + [Parameter(ParameterSetName='/policy/combined/firewall-members/v1:get',ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id, [Parameter(ParameterSetName='/policy/queries/firewall-members/v1:get',Position=2)] @@ -216,7 +216,6 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconFirewallPolicyMember [switch]$All, [Parameter(ParameterSetName='/policy/queries/firewall-members/v1:get')] [switch]$Total - ) begin { $Param = @{ @@ -251,8 +250,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconFirewallPolicyAction [Parameter(ParameterSetName='/policy/entities/firewall-actions/v1:post',Position=2)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$GroupId, - [Parameter(ParameterSetName='/policy/entities/firewall-actions/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=3)] + [Parameter(ParameterSetName='/policy/entities/firewall-actions/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id ) @@ -371,8 +370,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconFirewallPolicy #> [CmdletBinding(DefaultParameterSetName='/policy/entities/firewall/v1:delete',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/policy/entities/firewall/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/policy/entities/firewall/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id diff --git a/Public/policy-ioa-exclusions.ps1 b/Public/policy-ioa-exclusions.ps1 index 22cf5ce1..617a754e 100644 --- a/Public/policy-ioa-exclusions.ps1 +++ b/Public/policy-ioa-exclusions.ps1 @@ -26,12 +26,12 @@ https://github.com/crowdstrike/psfalcon/wiki/ConvertTo-FalconIoaExclusion [CmdletBinding()] param( [Parameter(Mandatory,ValueFromPipeline,Position=1)] - [System.Object]$Detection + [object]$Detection ) - begin { [System.Collections.Generic.List[object]]$Output = @() } + begin { [System.Collections.Generic.List[PSCustomObject]]$Output = @() } process { - if ($_.behaviors -and $_.device) { - @($_.behaviors).Where({ $_.tactic -notmatch '^(Machine Learning|Malware)$' }).foreach{ + if ($Detection.behaviors -and $Detection.device) { + @($Detection.behaviors).Where({ $_.tactic -notmatch '^(Machine Learning|Malware)$' }).foreach{ $Output.Add(([PSCustomObject]@{ pattern_id = $_.behavior_id pattern_name = $_.display_name @@ -43,7 +43,7 @@ https://github.com/crowdstrike/psfalcon/wiki/ConvertTo-FalconIoaExclusion } } else { foreach ($Property in @('behaviors','device')) { - if (!$_.$Property) { + if (!$Detection.$Property) { throw "[ConvertTo-FalconMlExclusion] Missing required '$Property' property." } } @@ -69,6 +69,10 @@ Host group identifier or 'all' to apply to all hosts Exclusion description .PARAMETER Comment Audit log comment +.PARAMETER PatternId +Indicator of Attack pattern identifier +.PARAMETER PatternName +Indicator of Attack pattern name .PARAMETER Id Exclusion identifier .LINK @@ -97,8 +101,16 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconIoaExclusion [Parameter(ParameterSetName='/policy/entities/ioa-exclusions/v1:patch',ValueFromPipelineByPropertyName, Position=6)] [string]$Comment, + [Parameter(ParameterSetName='/policy/entities/ioa-exclusions/v1:patch',ValueFromPipelineByPropertyName, + Position=7)] + [Alias('pattern_id')] + [string]$PatternId, + [Parameter(ParameterSetName='/policy/entities/ioa-exclusions/v1:patch',ValueFromPipelineByPropertyName, + Position=8)] + [Alias('pattern_name')] + [string]$PatternName, [Parameter(ParameterSetName='/policy/entities/ioa-exclusions/v1:patch',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=7)] + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^([a-fA-F0-9]{32}|all)$')] [string]$Id ) @@ -107,18 +119,25 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconIoaExclusion Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName Format = @{ - Body = @{ root = @('cl_regex','ifn_regex','groups','name','id','description','comment') } + Body = @{ + root = @('cl_regex','ifn_regex','groups','name','id','description','comment','pattern_id', + 'pattern_name') + } } } } process { - if ($PSBoundParameters.GroupId.id) { - # Filter to 'id' if supplied with 'detailed' objects - [string[]]$PSBoundParameters.GroupId = $PSBoundParameters.GroupId.id - } - if ($PSBoundParameters.GroupId) { - @($PSBoundParameters.GroupId).foreach{ - if ($_ -notmatch '^([a-fA-F0-9]{32}|all)$') { throw "'$_' is not a valid Host Group identifier." } + if ($PSCmdlet.ShouldProcess('Edit-FalconIoaExclusion','Test-GroupId')) { + if ($PSBoundParameters.GroupId) { + if ($PSBoundParameters.GroupId.id) { + # Filter to 'id' if supplied with 'detailed' objects + [string[]]$PSBoundParameters.GroupId = $PSBoundParameters.GroupId.id + } + @($PSBoundParameters.GroupId).foreach{ + if ($_ -notmatch '^([a-fA-F0-9]{32}|all)$') { + throw "'$_' is not a valid Host Group identifier." + } + } } } Invoke-Falcon @Param -Inputs $PSBoundParameters @@ -151,8 +170,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconIoaExclusion #> [CmdletBinding(DefaultParameterSetName='/policy/queries/ioa-exclusions/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/policy/entities/ioa-exclusions/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/policy/entities/ioa-exclusions/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -269,6 +288,11 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconIoaExclusion # Filter to 'id' if supplied with 'detailed' objects [string[]]$PSBoundParameters.GroupId = $PSBoundParameters.GroupId.id } + if ($PSBoundParameters.GroupId -eq 'all') { + # Remove 'all' from 'GroupId', and remove 'GroupId' if 'all' was the only value + $PSBoundParameters.GroupId = @($PSBoundParameters.GroupId).Where({ $_ -ne 'all' }) + if ([string]::IsNullOrEmpty($PSBoundParameters.GroupId)) { [void]$PSBoundParameters.Remove('GroupId') } + } if ($PSBoundParameters.GroupId) { @($PSBoundParameters.GroupId).foreach{ if ($_ -notmatch '^[a-fA-F0-9]{32}$') { throw "'$_' is not a valid Host Group identifier." } @@ -294,8 +318,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconIoaExclusion param( [Parameter(ParameterSetName='/policy/entities/ioa-exclusions/v1:delete',Position=1)] [string]$Comment, - [Parameter(ParameterSetName='/policy/entities/ioa-exclusions/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=2)] + [Parameter(ParameterSetName='/policy/entities/ioa-exclusions/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id diff --git a/Public/policy-ml-exclusions.ps1 b/Public/policy-ml-exclusions.ps1 index d74a5401..cd99047d 100644 --- a/Public/policy-ml-exclusions.ps1 +++ b/Public/policy-ml-exclusions.ps1 @@ -22,12 +22,12 @@ https://github.com/crowdstrike/psfalcon/wiki/ConvertTo-FalconMlExclusion [CmdletBinding()] param( [Parameter(Mandatory,ValueFromPipeline,Position=1)] - [System.Object]$Detection + [object]$Detection ) - begin { [System.Collections.Generic.List[object]]$Output = @() } + begin { [System.Collections.Generic.List[PSCustomObject]]$Output = @() } process { - if ($_.behaviors -and $_.device) { - @($_.behaviors).Where({ $_.tactic -match '^(Machine Learning|Malware)$' }).foreach{ + if ($Detection.behaviors -and $Detection.device) { + @($Detection.behaviors).Where({ $_.tactic -match '^(Machine Learning|Malware)$' }).foreach{ $Output.Add(([PSCustomObject]@{ value = $_.filepath -replace '\\Device\\HarddiskVolume\d+\\',$null excluded_from = @('blocking') @@ -37,7 +37,7 @@ https://github.com/crowdstrike/psfalcon/wiki/ConvertTo-FalconMlExclusion } } else { foreach ($Property in @('behaviors','device')) { - if (!$_.$Property) { + if (!$Detection.$Property) { throw "[ConvertTo-FalconMlExclusion] Missing required '$Property' property." } } @@ -87,13 +87,17 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconMlExclusion } } process { - if ($PSBoundParameters.GroupId.id) { - # Filter to 'id' if supplied with 'detailed' objects - [string[]]$PSBoundParameters.GroupId = $PSBoundParameters.GroupId.id - } - if ($PSBoundParameters.GroupId) { - @($PSBoundParameters.GroupId).foreach{ - if ($_ -notmatch '^([a-fA-F0-9]{32}|all)$') { throw "'$_' is not a valid Host Group identifier." } + if ($PSCmdlet.ShouldProcess('Edit-FalconMlExclusion','Test-GroupId')) { + if ($PSBoundParameters.GroupId) { + if ($PSBoundParameters.GroupId.id) { + # Filter to 'id' if supplied with 'detailed' objects + [string[]]$PSBoundParameters.GroupId = $PSBoundParameters.GroupId.id + } + @($PSBoundParameters.GroupId).foreach{ + if ($_ -notmatch '^([a-fA-F0-9]{32}|all)$') { + throw "'$_' is not a valid Host Group identifier." + } + } } } Invoke-Falcon @Param -Inputs $PSBoundParameters @@ -126,8 +130,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconMlExclusion #> [CmdletBinding(DefaultParameterSetName='/policy/queries/ml-exclusions/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/policy/entities/ml-exclusions/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName,Mandatory)] + [Parameter(ParameterSetName='/policy/entities/ml-exclusions/v1:get',ValueFromPipelineByPropertyName, + ValueFromPipeline,Mandatory)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -240,8 +244,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconMlExclusion param( [Parameter(ParameterSetName='/policy/entities/ml-exclusions/v1:delete',Position=1)] [string]$Comment, - [Parameter(ParameterSetName='/policy/entities/ml-exclusions/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=2)] + [Parameter(ParameterSetName='/policy/entities/ml-exclusions/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id diff --git a/Public/policy-prevention.ps1 b/Public/policy-prevention.ps1 index 54d47b23..934f0087 100644 --- a/Public/policy-prevention.ps1 +++ b/Public/policy-prevention.ps1 @@ -60,8 +60,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconPreventionPolicy } process { if ($Array) { - @($Array).foreach{ - $i = $_ + foreach ($i in $Array) { if ($i.prevention_settings.settings) { # Migrate 'prevention_settings' to 'settings' containing required values Set-Property $i settings ($i.prevention_settings.settings | Select-Object id,value) @@ -115,8 +114,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconPreventionPolicy #> [CmdletBinding(DefaultParameterSetName='/policy/queries/prevention/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/policy/entities/prevention/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/policy/entities/prevention/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -199,9 +198,9 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconPreventionPolicyMember [CmdletBinding(DefaultParameterSetName='/policy/queries/prevention-members/v1:get',SupportsShouldProcess)] param( [Parameter(ParameterSetName='/policy/queries/prevention-members/v1:get', - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=1)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [Parameter(ParameterSetName='/policy/combined/prevention-members/v1:get', - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=1)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id, [Parameter(ParameterSetName='/policy/queries/prevention-members/v1:get',Position=2)] @@ -260,8 +259,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconPreventionPolicyAction [Parameter(ParameterSetName='/policy/entities/prevention-actions/v1:post',Position=2)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$GroupId, - [Parameter(ParameterSetName='/policy/entities/prevention-actions/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=3)] + [Parameter(ParameterSetName='/policy/entities/prevention-actions/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id ) @@ -361,8 +360,7 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconPreventionPolicy } process { if ($Array) { - @($Array).foreach{ - $i = $_ + foreach ($i in $Array) { if ($i.prevention_settings.settings) { # Migrate 'prevention_settings' to 'settings' containing required values Set-Property $i settings @(($i.prevention_settings.settings | Select-Object id,value)) @@ -400,8 +398,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconPreventionPolicy #> [CmdletBinding(DefaultParameterSetName='/policy/entities/prevention/v1:delete',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/policy/entities/prevention/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/policy/entities/prevention/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id diff --git a/Public/policy-response.ps1 b/Public/policy-response.ps1 index abdf9d51..bc89dc6b 100644 --- a/Public/policy-response.ps1 +++ b/Public/policy-response.ps1 @@ -60,8 +60,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconResponsePolicy } process { if ($Array) { - @($Array).foreach{ - $i = $_ + foreach ($i in $Array) { if ($i.settings.settings) { # Select required values from 'settings' sub-object $i.settings = $i.settings.settings | Select-Object id,value @@ -114,8 +113,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconResponsePolicy #> [CmdletBinding(DefaultParameterSetName='/policy/queries/response/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/policy/entities/response/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/policy/entities/response/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -197,10 +196,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconResponsePolicyMember #> [CmdletBinding(DefaultParameterSetName='/policy/queries/response-members/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/policy/queries/response-members/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] - [Parameter(ParameterSetName='/policy/combined/response-members/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/policy/queries/response-members/v1:get',ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] + [Parameter(ParameterSetName='/policy/combined/response-members/v1:get',ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id, [Parameter(ParameterSetName='/policy/queries/response-members/v1:get',Position=2)] @@ -258,8 +257,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconResponsePolicyAction [Parameter(ParameterSetName='/policy/entities/response-actions/v1:post',Position=2)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$GroupId, - [Parameter(ParameterSetName='/policy/entities/response-actions/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=3)] + [Parameter(ParameterSetName='/policy/entities/response-actions/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id ) @@ -352,8 +351,7 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconResponsePolicy } process { if ($Array) { - @($Array).foreach{ - $i = $_ + foreach ($i in $Array) { if ($i.settings.settings) { # Select required values from 'settings' sub-object $i.settings = $i.settings.settings | Select-Object id,value @@ -388,8 +386,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconResponsePolicy #> [CmdletBinding(DefaultParameterSetName='/policy/entities/response/v1:delete',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/policy/entities/response/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/policy/entities/response/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id diff --git a/Public/policy-sensor-update.ps1 b/Public/policy-sensor-update.ps1 index c8f4fdc7..6ec4bc25 100644 --- a/Public/policy-sensor-update.ps1 +++ b/Public/policy-sensor-update.ps1 @@ -214,8 +214,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconSensorUpdatePolicy #> [CmdletBinding(DefaultParameterSetName='/policy/queries/sensor-update/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/policy/entities/sensor-update/v2:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/policy/entities/sensor-update/v2:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -297,10 +297,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconSensorUpdatePolicyMember #> [CmdletBinding(DefaultParameterSetName='/policy/queries/sensor-update-members/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/policy/queries/sensor-update-members/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] - [Parameter(ParameterSetName='/policy/combined/sensor-update-members/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/policy/queries/sensor-update-members/v1:get',ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] + [Parameter(ParameterSetName='/policy/combined/sensor-update-members/v1:get', + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id, [Parameter(ParameterSetName='/policy/queries/sensor-update-members/v1:get',Position=2)] @@ -361,7 +361,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconUninstallToken 'serial_number','system_manufacturer','system_product_name','tags',IgnoreCase=$false)] [string[]]$Include, [Parameter(ParameterSetName='/policy/combined/reveal-uninstall-token/v1:post',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=3)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [Alias('device_id','DeviceId')] [ValidatePattern('^([a-fA-F0-9]{32}|MAINTENANCE)$')] [string]$Id @@ -374,13 +374,16 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconUninstallToken } } process { - foreach ($r in (Invoke-Falcon @Param -Inputs $PSBoundParameters)) { - if ($Include) { - # Append properties from 'Include' - $i = Get-FalconHost -Id $r.device_id | Select-Object @($Include + 'device_id') - foreach ($p in $Include) { Set-Property $r $p $i.$p } + if ($Include) { + # Append properties from 'Include' + foreach ($Request in (Invoke-Falcon @Param -Inputs $PSBoundParameters)) { + @($Request | Get-FalconHost -EA 0 | Select-Object @($Include + 'device_id')).foreach{ + @($_.PSObject.Properties).foreach{ Set-Property $Request $_.Name $_.Value } + } + $Request } - $r + } else { + Invoke-Falcon @Param -Inputs $PSBoundParameters } } } @@ -408,8 +411,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconSensorUpdatePolicyActi [Parameter(ParameterSetName='/policy/entities/sensor-update-actions/v1:post',Position=2)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$GroupId, - [Parameter(ParameterSetName='/policy/entities/sensor-update-actions/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=3)] + [Parameter(ParameterSetName='/policy/entities/sensor-update-actions/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id ) @@ -547,8 +550,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconSensorUpdatePolicy #> [CmdletBinding(DefaultParameterSetName='/policy/entities/sensor-update/v1:delete',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/policy/entities/sensor-update/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/policy/entities/sensor-update/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id diff --git a/Public/policy-sv-exclusions.ps1 b/Public/policy-sv-exclusions.ps1 index daeefc79..2feed608 100644 --- a/Public/policy-sv-exclusions.ps1 +++ b/Public/policy-sv-exclusions.ps1 @@ -27,8 +27,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconSvExclusion [Parameter(ParameterSetName='/policy/entities/sv-exclusions/v1:patch',ValueFromPipelineByPropertyName, Position=3)] [string]$Comment, - [Parameter(ParameterSetName='/policy/entities/sv-exclusions/v1:patch',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=4)] + [Parameter(ParameterSetName='/policy/entities/sv-exclusions/v1:patch',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=4)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id ) @@ -40,13 +40,17 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconSvExclusion } } process { - if ($PSBoundParameters.GroupId.id) { - # Filter to 'id' if supplied with 'detailed' objects - [string[]]$PSBoundParameters.GroupId = $PSBoundParameters.GroupId.id - } - if ($PSBoundParameters.GroupId) { - @($PSBoundParameters.GroupId).foreach{ - if ($_ -notmatch '^([a-fA-F0-9]{32}|all)$') { throw "'$_' is not a valid Host Group identifier." } + if ($PSCmdlet.ShouldProcess('Edit-FalconSvExclusion','Test-GroupId')) { + if ($PSBoundParameters.GroupId) { + if ($PSBoundParameters.GroupId.id) { + # Filter to 'id' if supplied with 'detailed' objects + [string[]]$PSBoundParameters.GroupId = $PSBoundParameters.GroupId.id + } + @($PSBoundParameters.GroupId).foreach{ + if ($_ -notmatch '^([a-fA-F0-9]{32}|all)$') { + throw "'$_' is not a valid Host Group identifier." + } + } } } Invoke-Falcon @Param -Inputs $PSBoundParameters @@ -79,8 +83,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconSvExclusion #> [CmdletBinding(DefaultParameterSetName='/policy/queries/sv-exclusions/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/policy/entities/sv-exclusions/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/policy/entities/sv-exclusions/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -183,8 +187,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconSvExclusion param( [Parameter(ParameterSetName='/policy/entities/sv-exclusions/v1:delete',Position=1)] [string]$Comment, - [Parameter(ParameterSetName='/policy/entities/sv-exclusions/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=2)] + [Parameter(ParameterSetName='/policy/entities/sv-exclusions/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [Alias('Ids')] [string[]]$Id ) diff --git a/Public/psf-config.ps1 b/Public/psf-config.ps1 index 076c53e0..a9046a9f 100644 --- a/Public/psf-config.ps1 +++ b/Public/psf-config.ps1 @@ -331,6 +331,26 @@ https://github.com/crowdstrike/psfalcon/wiki/Import-FalconConfig if ($Msg) { Write-Host "[Import-FalconConfig] Imported from $($FilePath): $($Msg -join ', ')." } $Output } + function Invoke-CreateIoc ([object]$Object) { + foreach ($i in ($Object.Value.Import | & "New-Falcon$($Object.Key)")) { + if ($i.id) { + # Track created Ioc + Update-Id $i $Object.Key + Add-Result Created $i $Object.Key + } elseif ($i.type -and $i.value -and $i.message) { + @($Object.Value.Import).Where({ $_.type -eq $i.type -and $_.value -eq $i.value }).foreach{ + # Ignore failed Ioc + Add-Result Ignored $_ $Object.Key -Comment $i.message + } + } + # Remove created and failed Ioc from 'Import' using 'id' value + [string[]]$Remove = @($Object.Value.Import).Where({ $_.type -eq $i.type -and $_.value -eq + $i.value }).id + $Object.Value.Import = @($Object.Value.Import).Where({ $Remove -notcontains $_.id }) + } + # Repeat until 'Import' is empty + if ($Object.Value.Import) { Invoke-CreateIoc $Object } + } function Invoke-PolicyAction ([string]$Type,[string]$Action,[string]$PolicyId,[string]$GroupId) { try { # Perform an action on a policy and output result @@ -426,7 +446,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Import-FalconConfig 'Exists' } elseif ($Item.value -and ($Pair.Value.Cid | Where-Object { $_.value -eq $Item.value })) { 'Exists' - } elseif ($Pair.Value.Cid | Where-Object { $_.name -eq $Item.name }) { + } elseif ($Item.name -and ($Pair.Value.Cid | Where-Object { $_.name -eq $Item.name })) { 'Exists' } if ($Comment -and $ModifyExisting -notcontains $Pair.Key) { @@ -448,16 +468,16 @@ https://github.com/crowdstrike/psfalcon/wiki/Import-FalconConfig foreach ($Item in @($Pair.Value.Import + $Pair.Value.Modify)) { # Update tagged builds with current tagged build versions if ($Item.settings.build -match '^\d+\|') { - [string]$Tag = ($Item.settings.build -split '\|',2)[-1] - [string]$Current = ($Builds | Where-Object { $_.build -like "*|$Tag" -and $_.platform -eq + $Tag = ($Item.settings.build -split '\|',2)[-1] + $Current = ($Builds | Where-Object { $_.build -like "*|$Tag" -and $_.platform -eq $Item.platform_name }).build if ($Item.settings.build -ne $Current) { $Item.settings.build = $Current } } if ($Item.settings.variants) { # Update tagged 'variant' builds with current tagged build versions - @($Item.settings.variants | Where-Object { $_.build }).foreach{ - [string]$Tag = ($_.build -split '\|',2)[-1] - [string]$Current = ($Builds | Where-Object { $_.build -like "*|$Tag" -and + @($Item.settings.variants | Where-Object { $_.build -match '^\d+\|' }).foreach{ + $Tag = ($_.build -split '\|',2)[-1] + $Current = ($Builds | Where-Object { $_.build -like "*|$Tag" -and $_.platform -eq $Item.platform_name }).build if ($_.build -ne $Current) { $_.build = $Current } } @@ -496,11 +516,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Import-FalconConfig } foreach ($Pair in $Config.GetEnumerator().Where({ $_.Key -ne 'FirewallRule' -and $_.Value.Import })) { if ($Pair.Key -eq 'Ioc') { - @($Pair.Value.Import | & "New-Falcon$($Pair.Key)").foreach{ - # Create Ioc - Update-Id $_ $Pair.Key - Add-Result Created $_ $Pair.Key - } + # Create Ioc + Invoke-CreateIoc $Pair } elseif ($Pair.Key -eq 'FirewallGroup') { foreach ($Item in $Pair.Value.Import) { [object]$FwGroup = $Item | Select-Object name,enabled,description,comment,rule_ids diff --git a/Public/psf-devices.ps1 b/Public/psf-devices.ps1 index 07468077..073068e7 100644 --- a/Public/psf-devices.ps1 +++ b/Public/psf-devices.ps1 @@ -48,26 +48,32 @@ https://github.com/crowdstrike/psfalcon/wiki/Find-FalconDuplicate $FilterScript = "$(($Criteria).foreach{ "`$_.$($_)" } -join ' -and ')" } process { - [object[]]$HostArray = if (!$PSBoundParameters.Hosts) { - # Retreive Host details - Get-FalconHost -Detailed -All - } else { - $PSBoundParameters.Hosts - } - if ($HostArray) { - @($Required).foreach{ - if (($HostArray | Get-Member -MemberType NoteProperty).Name -notcontains $_) { - # Verify required properties are present - throw "Missing required property '$_'." - } + if ($PSCmdlet.ShouldProcess('Find-FalconDuplicate','Get-FalconHost')) { + [object[]]$HostArray = if (!$PSBoundParameters.Hosts) { + # Retreive Host details + Get-FalconHost -Detailed -All -EA 0 + } else { + $PSBoundParameters.Hosts } - # Group, sort and output result - $Param = @{ - Object = $HostArray | Select-Object $Required | Where-Object -FilterScript {$FilterScript} - GroupBy = $Criteria + if ($HostArray) { + @($Required).foreach{ + if (($HostArray | Get-Member -MemberType NoteProperty).Name -notcontains $_) { + # Verify required properties are present + throw "Missing required property '$_'." + } + } + $Param = @{ + # Group, sort and output result + Object = $HostArray | Select-Object $Required | Where-Object -FilterScript {$FilterScript} + GroupBy = $Criteria + } + $Output = Group-Selection @Param + if ($Output) { + $Output + } else { + $PSCmdlet.WriteWarning("[Find-FalconDuplicate] No duplicates found.") + } } - $Output = Group-Selection @Param - if ($Output) { $Output } else { $PSCmdlet.WriteWarning("[Find-FalconDuplicate] No duplicates found.") } } } } @@ -76,13 +82,17 @@ function Find-FalconHostname { .SYNOPSIS Find hosts using a list of hostnames .DESCRIPTION -Performs an exact match hostname search in groups of 20. +Perform hostname searches in groups of 20. Requires 'Hosts: Read'. .PARAMETER Array -An array containing one or more hostnames +An array containing hostnames +.PARAMETER Include +Include additional properties +.PARAMETER Partial +Perform a non-exact search .PARAMETER Path -Path to a plaintext file containing hostnames +Path to a plain text file containing hostnames .LINK https://github.com/crowdstrike/psfalcon/wiki/Find-FalconHostname #> @@ -97,6 +107,15 @@ https://github.com/crowdstrike/psfalcon/wiki/Find-FalconHostname } })] [string]$Path, + [Parameter(ParameterSetName='Path',Position=2)] + [Parameter(ParameterSetName='Array',Position=2)] + [ValidateSet('agent_version','cid','external_ip','first_seen','hostname','last_seen','local_ip', + 'mac_address','os_build','os_version','platform_name','product_type','product_type_desc', + 'serial_number','system_manufacturer','system_product_name','tags',IgnoreCase=$false)] + [string[]]$Include, + [Parameter(ParameterSetName='Path')] + [Parameter(ParameterSetName='Array')] + [switch]$Partial, [Parameter(ParameterSetName='Array',Mandatory,ValueFromPipeline)] [string[]]$Array ) @@ -106,6 +125,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Find-FalconHostname } else { [System.Collections.Generic.List[string]]$List = @() } + [string[]]$Select = 'device_id','hostname' + if ($Include) { $Select += $Include } } process { if ($Array) { @($Array).foreach{ $List.Add($_) }}} end { @@ -117,11 +138,14 @@ https://github.com/crowdstrike/psfalcon/wiki/Find-FalconHostname for ($i = 0; $i -lt ($Hostnames | Measure-Object).Count; $i += 20) { [string[]]$TempList = $Hostnames[$i..($i + 19)] [string]$Filter = (@($TempList).foreach{ - if (![string]::IsNullOrEmpty($_)) { "hostname:['$_']" } + if (![string]::IsNullOrEmpty($_)) { + if ($Partial) { "hostname:'$_'" } else { "hostname:['$_']" } + } }) -join ',' - [object[]]$HostList = Get-FalconHost -Filter $Filter -Detailed | Select-Object hostname,device_id + [object[]]$HostList = Get-FalconHost -Filter $Filter -Detailed | Select-Object $Select @($TempList).foreach{ - if ($HostList.hostname -notcontains $_) { + if (($Partial -and $HostList.hostname -notlike "$_*") -or (!$Partial -and + $HostList.hostname -notcontains $_)) { $PSCmdlet.WriteWarning("[Find-FalconHostname] No match found for '$_'.") } } diff --git a/Public/psf-fwmgr.ps1 b/Public/psf-fwmgr.ps1 new file mode 100644 index 00000000..1451e8bf --- /dev/null +++ b/Public/psf-fwmgr.ps1 @@ -0,0 +1,257 @@ +function ConvertTo-FalconFirewallRule { +<# +.SYNOPSIS +Convert firewall rules to be compatible with Falcon Firewall Management +.DESCRIPTION +Ensures that an object (either from the pipeline, or via CSV import) has the required properties to be accepted +as a valid Falcon Firewall Management rule. + +Rules that contain both IPv4 and IPv6 addresses will generate errors, along with any rules that are missing the +required properties defined by the 'Map' parameter. + +Converted rules used with 'New-FalconFirewallGroup' to create groups containing newly converted rules. +.PARAMETER Map +A hashtable containing the following keys with the corresponding CSV column or rule property as the value + +Required: action, description, direction, enabled, local_address, local_port, name, remote_address, remote_port +Optional: image_name, network_location, service_name +.PARAMETER Path +Path to a CSV file containing rules to convert +.PARAMETER Object +An existing rule object to convert +.LINK +https://github.com/crowdstrike/psfalcon/wiki/ConvertTo-FalconFirewallRule +#> + [CmdletBinding()] + [OutputType([PSCustomObject[]])] + param( + [Parameter(ParameterSetName='Pipeline',Mandatory,Position=1)] + [Parameter(ParameterSetName='CSV',Mandatory,Position=1)] + [ValidateScript({ + foreach ($Key in @('action','description','direction','enabled','local_address','local_port','name', + 'remote_address','remote_port')) { + if ($_.Keys -notcontains $Key) { throw "Missing required '$Key' property." } else { $true } + } + })] + [hashtable]$Map, + [Parameter(ParameterSetName='CSV',Mandatory,Position=2)] + [ValidateScript({ + if (Test-Path $_ -PathType Leaf) { + $true + } else { + throw "Cannot find path '$_' because it does not exist or is a directory." + } + })] + [Alias('FullName')] + [string]$Path, + [Parameter(ParameterSetName='Pipeline',Mandatory,ValueFromPipeline)] + [object]$Object + ) + begin { + function Get-RuleAction ([object]$Rule,[hashtable]$Map) { + if ($Rule.($Map.action) -eq 'BLOCK') { 'DENY' } else { $Rule.($Map.action).ToUpper() } + } + function Get-RuleDirection ([object]$Rule,[hashtable]$Map) { + try { [regex]::Match($Rule.($Map.direction),'^(in|out|both)',1).Value.ToUpper() } catch {} + } + function Get-RuleFamily ([object]$Rule,[hashtable]$Map,[string]$Protocol,[string[]]$TypeList) { + if ($Protocol -eq '1') { + # Force 'IP4' when protocol is 'ICMPv4' + 'IP4' + } elseif ($Protocol -eq '58') { + # Force 'IP6' when protocol is 'ICMPv6' + 'IP6' + } else { + # Use unique value from 'TypeList' and default to 'IP4' when 'TypeList' is 'ANY' + [string]$Output = (($TypeList | Select-Object -Unique) -replace 'v',$null -replace 'ANY', + $null).ToUpper() + if ($Output) { ($Output).Trim() } else { 'IP4' } + } + } + function Get-RuleProtocol ([object]$Rule,[hashtable]$Map) { + if ($Rule.($Map.protocol) -match '^(any|\*)$') { + # Use asterisk for 'any' + '*' + } elseif ($Rule.($Map.protocol) -as [int] -is [int]) { + # Use existing integer value + $Rule.($Map.protocol) + } else { + switch ($Rule.($Map.protocol)) { + # Convert expected protocol names to their numerical value + 'icmpv4' { '1' } + 'tcp' { '6' } + 'udp' { '17' } + 'icmpv6' { '58' } + } + } + } + function New-RuleAddress ([string]$String,[hashtable]$Map,[string]$Join,[string]$RuleName) { + foreach ($Address in ($String -split $Join)) { + # Remove excess spaces + [string]$Address = $Address.Trim() + if ($Address -match '^(any|\*)$') { + # Output 'any' address and netmask + [PSCustomObject]@{ address = '*'; netmask = 0 } + } else { + # Check whether address matches ipv4 or ipv6 + [string]$Type = Test-RegexValue ($Address -replace '/\d+$',$null) + [int]$Integer = if ($Address -match '/') { + # Collect netmask from CIDR notation + ($Address -split '/',2)[-1] + $Address = $Address -replace '/\d+$' + } elseif ($Type -eq 'ipv6') { + # Use default for ipv6 address + 128 + } elseif ($Type -eq 'ipv4') { + # Use default for ipv4 address + 32 + } else { + throw "Rule '$RuleName' contains an address that does not match IPv4 or IPv6 pattern. ['$( + $Address)']" + } + # Output object with address and netmask + if ($Address -and $Integer) { [PSCustomObject]@{ address = $Address; netmask = $Integer }} + } + } + } + function New-RuleField ([object]$Rule,[hashtable]$Map,[string]$Join) { + # Create default 'fields' array + [string[]]$Location = if ($Rule.($Map.network_location) -and ($Rule.($Map.network_location) -notmatch + '^(any|\*)$')) { + # Add 'network_location' values + @($Rule.($Map.network_location) -split $Join).foreach{ $_ } + } else { + 'ANY' + } + [PSCustomObject[]]([PSCustomObject]@{ name = 'network_location'; type = 'set'; values = $Location }) + } + function New-RulePort ([string]$String,[string]$Join) { + if ($String -notmatch '^(any|\*)$') { + # Create 'port' objects + @($String -split $Join).foreach{ + if ($_ -match '-') { + # Split ranges into 'start' and 'end' + [int[]]$Range = $_ -split '-',2 + [PSCustomObject]@{ start = $Range[0]; end = $Range[1] } + } else { + # Create separate objects for each value when multiple are provided + [PSCustomObject]@{ start = [int]$_; end = 0 } + } + } + } + } + function Convert-RuleObject ([object]$Rule,[hashtable]$Map) { + # Set RegEx pattern to split port/address strings and create object string for error messaging + [string]$Join = '[;,-]' + try { + [string]$Protocol = Get-RuleProtocol $Rule $Map + if (!$Protocol) { + throw "Rule '$($Rule.($Map.name))' contains unexpected protocol '$($Rule.($Map.protocol))'." + } + [string[]]$TypeList = foreach ($Type in ('local_address','remote_address')) { + @($Rule.($Map.$Type) -split $Join).foreach{ + if ($_.Trim() -match '^(any|\*)$') { + 'ANY' + } else { + # Error when 'local_address' or 'remote_address' does not match ipv4/ipv6 + [string]$Trim = ($_.Trim() -replace '/\d+$',$null) + if (!$Trim) { + throw "Rule '$($Rule.($Map.name))' missing value for required property '$Type'." + } + [string]$Test = Test-RegexValue $Trim + if ($Test -match '^ipv(4|6)$') { + [string]($Test -replace 'v',$null).ToUpper() + } else { + throw "Rule '$($Rule.($Map.name))' contains unexpected $Type '$Trim'." + } + } + } + } + if ($TypeList -contains 'IP4' -and $TypeList -contains 'IP6') { + # Error when rules contain both ipv4 and ipv6 addresses + throw "Rule '$($Rule.($Map.name))' contains both ipv4 and ipv6 addresses." + } else { + foreach ($Name in ('action','address_family','direction')) { + # Set 'action', 'family' and 'direction' + $Value = if ($Name -eq 'address_family') { + Get-RuleFamily $Rule $Map $Protocol $TypeList + } else { + & "Get-Rule$Name" $Rule $Map + } + if ($Name -eq 'address_family' -and $Value -cnotmatch '^IP[4|6]$') { + # Error when unexpected value is provided + throw "Unable to determine $Name for rule '$($Rule.($Map.name))'." + } elseif (($Name -eq 'action' -and $Value -cnotmatch '^(ALLOW|DENY)$') -or + ($Name -eq 'direction' -and $Value -cnotmatch '^(BOTH|IN|OUT)$')) { + throw "Rule '$($Rule.($Map.name))' contains unexpected $Name '$( + $Rule.($Map.$Name))'." + } else { + New-Variable -Name $Name -Value $Value + } + } + @('local_address','remote_address').foreach{ + # Create 'local_address' and 'remote_address' objects + New-Variable -Name $_ -Value ([PSCustomObject[]]( + New-RuleAddress $Rule.($Map.$_) $Map $Join $Rule.($Map.name))) + } + # Construct default 'fields' + [PSCustomObject[]]$Field = New-RuleField $Rule $Map + foreach ($Name in ('image_name','service_name')) { + # Add 'image_name' and 'service_name' to 'fields', when present + if ($Rule.($Map.$Name) -and $Rule.($Map.$Name) -notmatch '^(any|\*)$') { + [string]$Value = if ($Name -eq 'image_name' -and $Rule.($Map.$Name) -notmatch + '\.\w+$') { + # Convert directory paths to glob syntax with a single asterisk + [string]$Glob = $Rule.($Map.$Name) -replace '^\w:\\',$null + if ($Glob -match '\\$') { $Glob,'*' -join $null } else { $Glob,'*' -join '\' } + } else { + $Rule.($Map.$Name) + } + $Field += [PSCustomObject]@{ + name = $Name + type = if ($_ -eq 'image_name') { 'windows_path' } else { 'string' } + value = $Value + } + } + } + # Create rule object + $Output = [PSCustomObject]@{ + action = $action + address_family = $address_family + description = $Rule.($Map.description) + direction = $direction + enabled = if ($Rule.($Map.enabled) -match '$?true') { $true } else { $false } + fields = $Field + name = $Rule.($Map.name) + protocol = $Protocol + local_address = $local_address + remote_address = $remote_address + } + @('local_port','remote_port').foreach{ + # Add 'local_port' and 'remote_port' + New-Variable -Name $_ -Value ([PSCustomObject[]](New-RulePort $Rule.($Map.$_) $Join)) + if ((Get-Variable -Name $_).Value) { + $Output.PSObject.Properties.Add((New-Object PSNoteProperty($_, + (Get-Variable -Name $_).Value))) + } + } + $Output + } + } catch { + throw $_ + } + } + } + process { + if (!$Path) { + # Convert pipeline object into formatted rule + Convert-RuleObject ([PSCustomObject]$Object | Select-Object @($Map.Values)) $Map + } + } + end { + if ($Path) { + # Import CSV and convert rules to expected format + Import-Csv $Path | & $MyInvocation.MyCommand.Name -Map $Map + } + } +} \ No newline at end of file diff --git a/Public/psf-humio.ps1 b/Public/psf-logscale.ps1 similarity index 85% rename from Public/psf-humio.ps1 rename to Public/psf-logscale.ps1 index 40231f60..d086bddd 100644 --- a/Public/psf-humio.ps1 +++ b/Public/psf-logscale.ps1 @@ -1,19 +1,19 @@ function Register-FalconEventCollector { <# .SYNOPSIS -Define Humio ingestion endpoint and token for logging +Define Falcon LogScale ingestion endpoint and token for logging .DESCRIPTION -Once configured, the Humio destination can be used by PSFalcon but the module will not send events to Humio +Once configured, the Falcon LogScale destination can be used by PSFalcon but the module will not send events to Falcon LogScale until 'Enable' options are chosen. 'Remove-FalconEventCollector' can be used to remove a configured destination and stop the transmission of events. .PARAMETER Uri -Humio cloud +Falcon LogScale cloud .PARAMETER Token -Humio ingestion token +Falcon LogScale ingestion token .PARAMETER Enable Define events to send to the collector .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Register-FalconEventCollector +https://github.com/crowdstrike/psfalcon/wiki/Register-FalconEventCollector #> [CmdletBinding()] [OutputType([void])] @@ -44,14 +44,14 @@ https://github.com/CrowdStrike/psfalcon/wiki/Register-FalconEventCollector function Send-FalconEvent { <# .SYNOPSIS -Create Humio events from PSFalcon command results +Create Falcon LogScale events from PSFalcon command results .DESCRIPTION Uses the pre-defined 'Path' and 'Token' values from 'Register-FalconEventCollector' to create events from the output provided by a PSFalcon command. .PARAMETER Object PSFalcon command output .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Send-FalconEvent +https://github.com/crowdstrike/psfalcon/wiki/Send-FalconEvent #> [CmdletBinding()] [OutputType([void])] @@ -67,7 +67,7 @@ https://github.com/CrowdStrike/psfalcon/wiki/Send-FalconEvent process { if ($Object) { @($Object).foreach{ $List.Add($_) }}} end { if (!$Script:Falcon.Api.Collector.Uri -or !$Script:Falcon.Api.Collector.Token) { - throw "Humio destination has not been configured. Try 'Register-FalconEventCollector'." + throw "Falcon LogScale destination has not been configured. Try 'Register-FalconEventCollector'." } elseif ($List) { [object[]]$Events = @($List).foreach{ $Item = @{ timestamp = Get-Date -Format o; attributes = @{}} @@ -102,9 +102,9 @@ https://github.com/CrowdStrike/psfalcon/wiki/Send-FalconEvent function Show-FalconEventCollector { <# .SYNOPSIS -Display existing Humio ingestion endpoint and token +Display existing Falcon LogScale ingestion endpoint and token .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Show-FalconEventCollector +https://github.com/crowdstrike/psfalcon/wiki/Show-FalconEventCollector #> [CmdletBinding()] [OutputType([PSCustomObject])] @@ -116,9 +116,9 @@ https://github.com/CrowdStrike/psfalcon/wiki/Show-FalconEventCollector function Unregister-FalconEventCollector { <# .SYNOPSIS -Remove an existing Humio ingestion endpoint and token +Remove an existing Falcon LogScale ingestion endpoint and token .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Unregister-FalconEventCollector +https://github.com/crowdstrike/psfalcon/wiki/Unregister-FalconEventCollector #> [CmdletBinding()] param() diff --git a/Public/psf-output.ps1 b/Public/psf-output.ps1 index 59e187f8..78812728 100644 --- a/Public/psf-output.ps1 +++ b/Public/psf-output.ps1 @@ -25,7 +25,7 @@ Response object to format .PARAMETER Force Overwrite an existing file when present .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Export-FalconReport +https://github.com/crowdstrike/psfalcon/wiki/Export-FalconReport #> [CmdletBinding()] param( @@ -148,7 +148,7 @@ Message label .PARAMETER Object Response object to format .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Send-FalconWebhook +https://github.com/crowdstrike/psfalcon/wiki/Send-FalconWebhook #> [CmdletBinding()] param( @@ -188,7 +188,7 @@ https://github.com/CrowdStrike/psfalcon/wiki/Send-FalconWebhook } } ,@{ - username = "PSFalcon: $($Script:Falcon.ClientId)" + username = 'PSFalcon',$Script:Falcon.ClientId -join ': ' icon_url = 'https://raw.githubusercontent.com/CrowdStrike/psfalcon/master/icon.png' text = $PSBoundParameters.Label attachments = @( @@ -234,7 +234,7 @@ Show-FalconMap will accept domains, SHA256 hashes, IP addresses and URLs. Invali .PARAMETER Indicator Indicator to display on the Indicator map .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Show-FalconMap +https://github.com/crowdstrike/psfalcon/wiki/Show-FalconMap #> [CmdletBinding(SupportsShouldProcess)] param( @@ -289,7 +289,7 @@ Display information about your PSFalcon module Outputs an object containing module, user and system version information that is helpful for diagnosing problems with the PSFalcon module. .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Show-FalconModule +https://github.com/crowdstrike/psfalcon/wiki/Show-FalconModule #> [CmdletBinding()] param() diff --git a/Public/psf-policies.ps1 b/Public/psf-policies.ps1 index 89e91c74..8e10dc37 100644 --- a/Public/psf-policies.ps1 +++ b/Public/psf-policies.ps1 @@ -7,12 +7,12 @@ Requires 'Prevention Policies: Read'. .PARAMETER Id Policy identifier .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Compare-FalconPreventionPhase +https://github.com/crowdstrike/psfalcon/wiki/Compare-FalconPreventionPhase #> [CmdletBinding(SupportsShouldProcess)] [OutputType([PSCustomObject[]])] param( - [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=1)] + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id ) @@ -23,11 +23,11 @@ https://github.com/CrowdStrike/psfalcon/wiki/Compare-FalconPreventionPhase } process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} end { - if ($List) { + if ($List -and $PSCmdlet.ShouldProcess('Compare-FalconPreventionPhase','Get-FalconPreventionPolicy')) { # Collect detailed policy information for unique identifiers $PolicyList = Get-FalconPreventionPolicy -Id ($List | Select-Object -Unique) -EA 0 | Select-Object id, name,platform_name,prevention_settings | Sort-Object platform_name - $List | Where-Object { $PolicyList.id -notcontains $_ } | ForEach-Object { + @($List).Where({ $PolicyList.id -notcontains $_ }).foreach{ # Generate error when 'id' values were not found Write-Error "'$_' was not found." } @@ -111,13 +111,13 @@ description is not supplied, the description from the existing policy will be us Requires 'Device Control Policies: Read', 'Device Control Policies: Write'. .PARAMETER Name -Policy name +Name for the policy that will be created .PARAMETER Description -Policy description +Description for the policy that will be created .PARAMETER Id -Policy identifier +Identifier of policy to be copied .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Copy-FalconDeviceControlPolicy +https://github.com/crowdstrike/psfalcon/wiki/Copy-FalconDeviceControlPolicy #> [CmdletBinding(SupportsShouldProcess)] param( @@ -125,32 +125,36 @@ https://github.com/CrowdStrike/psfalcon/wiki/Copy-FalconDeviceControlPolicy [string]$Name, [Parameter(Position=2)] [string]$Description, - [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=3)] + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id ) process { - try { - $Policy = Get-FalconDeviceControlPolicy -Id $Id - if ($Policy) { - @('Name','Description').foreach{ if ($PSBoundParameters.$_) { $Policy.$_ = $PSBoundParameters.$_ }} - $Clone = $Policy | New-FalconDeviceControlPolicy - if ($Clone.id) { - $Clone.settings = $Policy.settings - $Clone = $Clone | Edit-FalconDeviceControlPolicy - if ($Clone.enabled -eq $false -and $Policy.enabled -eq $true) { - $Enable = $Clone.id | Invoke-FalconDeviceControlPolicyAction enable - if ($Enable) { - $Enable - } else { - $Clone.enabled = $true - $Clone + if ($PSCmdlet.ShouldProcess('Copy-FalconDeviceControlPolicy','Get-FalconDeviceControlPolicy')) { + try { + $Policy = Get-FalconDeviceControlPolicy -Id $Id + if ($Policy) { + @('Name','Description').foreach{ + if ($PSBoundParameters.$_) { $Policy.$_ = $PSBoundParameters.$_ } + } + $Clone = $Policy | New-FalconDeviceControlPolicy + if ($Clone.id) { + $Clone.settings = $Policy.settings + $Clone = $Clone | Edit-FalconDeviceControlPolicy + if ($Clone.enabled -eq $false -and $Policy.enabled -eq $true) { + $Enable = $Clone.id | Invoke-FalconDeviceControlPolicyAction enable + if ($Enable) { + $Enable + } else { + $Clone.enabled = $true + $Clone + } } } } + } catch { + throw $_ } - } catch { - throw $_ } } } @@ -164,13 +168,13 @@ description is not supplied, the description from the existing policy will be us Requires 'Firewall Management: Read', 'Firewall Management: Write'. .PARAMETER Name -Policy name +Name for the policy that will be created .PARAMETER Description -Policy description +Description for the policy that will be created .PARAMETER Id -Policy identifier +Identifier of policy to be copied .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Copy-FalconFirewallPolicy +https://github.com/crowdstrike/psfalcon/wiki/Copy-FalconFirewallPolicy #> [CmdletBinding(SupportsShouldProcess)] param( @@ -178,39 +182,43 @@ https://github.com/CrowdStrike/psfalcon/wiki/Copy-FalconFirewallPolicy [string]$Name, [Parameter(Position=2)] [string]$Description, - [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=3)] + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id ) process { - try { - $Policy = Get-FalconFirewallPolicy -Id $Id -Include settings - if ($Policy) { - @('Name','Description').foreach{ if ($PSBoundParameters.$_) { $Policy.$_ = $PSBoundParameters.$_ }} + if ($PSCmdlet.ShouldProcess('Copy-FalconFirewallPolicy','Get-FalconFirewallPolicy')) { + try { + $Policy = Get-FalconFirewallPolicy -Id $Id -Include settings if ($Policy) { - $Clone = $Policy | New-FalconFirewallPolicy - if ($Clone.id) { - if ($Policy.settings) { - $Policy.settings.policy_id = $Clone.id - $Settings = $Policy.settings | Edit-FalconFirewallSetting - if ($Settings) { $Settings = Get-FalconFirewallSetting -Id $Clone.id } - } - if ($Clone.enabled -eq $false -and $Policy.enabled -eq $true) { - $Enable = $Clone.id | Invoke-FalconFirewallPolicyAction enable - if ($Enable) { - Set-Property $Enable settings $Settings - $Enable - } else { - $Clone.enabled = $true - Set-Property $Clone settings $Settings - $Clone + @('Name','Description').foreach{ + if ($PSBoundParameters.$_) { $Policy.$_ = $PSBoundParameters.$_ } + } + if ($Policy) { + $Clone = $Policy | New-FalconFirewallPolicy + if ($Clone.id) { + if ($Policy.settings) { + $Policy.settings.policy_id = $Clone.id + $Settings = $Policy.settings | Edit-FalconFirewallSetting + if ($Settings) { $Settings = Get-FalconFirewallSetting -Id $Clone.id } + } + if ($Clone.enabled -eq $false -and $Policy.enabled -eq $true) { + $Enable = $Clone.id | Invoke-FalconFirewallPolicyAction enable + if ($Enable) { + Set-Property $Enable settings $Settings + $Enable + } else { + $Clone.enabled = $true + Set-Property $Clone settings $Settings + $Clone + } } } } } + } catch { + throw $_ } - } catch { - throw $_ } } } @@ -224,13 +232,13 @@ supplied, the description from the existing policy will be used. Requires 'Prevention Policies: Read', 'Prevention Policies: Write'. .PARAMETER Name -Policy name +Name for the policy that will be created .PARAMETER Description -Policy description +Description for the policy that will be created .PARAMETER Id -Policy identifier +Identifier of policy to be copied .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Copy-FalconPreventionPolicy +https://github.com/crowdstrike/psfalcon/wiki/Copy-FalconPreventionPolicy #> [CmdletBinding(SupportsShouldProcess)] param( @@ -238,32 +246,36 @@ https://github.com/CrowdStrike/psfalcon/wiki/Copy-FalconPreventionPolicy [string]$Name, [Parameter(Position=2)] [string]$Description, - [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=3)] + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id ) process { - try { - $Policy = Get-FalconPreventionPolicy -Id $Id - if ($Policy) { - @('Name','Description').foreach{ if ($PSBoundParameters.$_) { $Policy.$_ = $PSBoundParameters.$_ }} - $Clone = $Policy | New-FalconPreventionPolicy - if ($Clone.id) { - $Clone.prevention_settings = $Policy.prevention_settings - $Clone = $Clone | Edit-FalconPreventionPolicy - if ($Clone.enabled -eq $false -and $Policy.enabled -eq $true) { - $Enable = $Clone.id | Invoke-FalconPreventionPolicyAction enable - if ($Enable) { - $Enable - } else { - $Clone.enabled = $true - $Clone + if ($PSCmdlet.ShouldProcess('Copy-FalconPreventionPolicy','Get-FalconPreventionPolicy')) { + try { + $Policy = Get-FalconPreventionPolicy -Id $Id + if ($Policy) { + @('Name','Description').foreach{ + if ($PSBoundParameters.$_) { $Policy.$_ = $PSBoundParameters.$_ } + } + $Clone = $Policy | New-FalconPreventionPolicy + if ($Clone.id) { + $Clone.prevention_settings = $Policy.prevention_settings + $Clone = $Clone | Edit-FalconPreventionPolicy + if ($Clone.enabled -eq $false -and $Policy.enabled -eq $true) { + $Enable = $Clone.id | Invoke-FalconPreventionPolicyAction enable + if ($Enable) { + $Enable + } else { + $Clone.enabled = $true + $Clone + } } } } + } catch { + throw $_ } - } catch { - throw $_ } } } @@ -277,13 +289,13 @@ is not supplied, the description from the existing policy will be used. Requires 'Response Policies: Read', 'Response Policies: Write'. .PARAMETER Name -Policy name +Name for the policy that will be created .PARAMETER Description -Policy description +Description for the policy that will be created .PARAMETER Id -Policy identifier +Identifier of policy to be copied .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Copy-FalconResponsePolicy +https://github.com/crowdstrike/psfalcon/wiki/Copy-FalconResponsePolicy #> [CmdletBinding(SupportsShouldProcess)] param( @@ -291,32 +303,36 @@ https://github.com/CrowdStrike/psfalcon/wiki/Copy-FalconResponsePolicy [string]$Name, [Parameter(Position=2)] [string]$Description, - [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=3)] + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id ) process { - try { - $Policy = Get-FalconResponsePolicy -Id $Id - if ($Policy) { - @('Name','Description').foreach{ if ($PSBoundParameters.$_) { $Policy.$_ = $PSBoundParameters.$_ }} - $Clone = $Policy | New-FalconResponsePolicy - if ($Clone.id) { - $Clone.settings = $Policy.settings - $Clone = $Clone | Edit-FalconResponsePolicy - if ($Clone.enabled -eq $false -and $Policy.enabled -eq $true) { - $Enable = $Clone.id | Invoke-FalconResponsePolicyAction enable - if ($Enable) { - $Enable - } else { - $Clone.enabled = $true - $Clone + if ($PSCmdlet.ShouldProcess('Copy-FalconResponsePolicy','Get-FalconResponsePolicy')) { + try { + $Policy = Get-FalconResponsePolicy -Id $Id + if ($Policy) { + @('Name','Description').foreach{ + if ($PSBoundParameters.$_) { $Policy.$_ = $PSBoundParameters.$_ } + } + $Clone = $Policy | New-FalconResponsePolicy + if ($Clone.id) { + $Clone.settings = $Policy.settings + $Clone = $Clone | Edit-FalconResponsePolicy + if ($Clone.enabled -eq $false -and $Policy.enabled -eq $true) { + $Enable = $Clone.id | Invoke-FalconResponsePolicyAction enable + if ($Enable) { + $Enable + } else { + $Clone.enabled = $true + $Clone + } } } } + } catch { + throw $_ } - } catch { - throw $_ } } } @@ -330,13 +346,13 @@ not supplied, the description from the existing policy will be used. Requires 'Sensor Update Policies: Read', 'Sensor Update Policies: Write'. .PARAMETER Name -Policy name +Name for the policy that will be created .PARAMETER Description -Policy description +Description for the policy that will be created .PARAMETER Id -Policy identifier +Identifier of policy to be copied .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Copy-FalconSensorUpdatePolicy +https://github.com/crowdstrike/psfalcon/wiki/Copy-FalconSensorUpdatePolicy #> [CmdletBinding(SupportsShouldProcess)] param( @@ -344,32 +360,36 @@ https://github.com/CrowdStrike/psfalcon/wiki/Copy-FalconSensorUpdatePolicy [string]$Name, [Parameter(Position=2)] [string]$Description, - [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=3)] + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id ) process { - try { - $Policy = Get-FalconSensorUpdatePolicy -Id $Id - if ($Policy) { - @('Name','Description').foreach{ if ($PSBoundParameters.$_) { $Policy.$_ = $PSBoundParameters.$_ }} - $Clone = $Policy | New-FalconSensorUpdatePolicy - if ($Clone.id) { - $Clone.settings = $Policy.settings - $Clone = $Clone | Edit-FalconSensorUpdatePolicy - if ($Clone.enabled -eq $false -and $Policy.enabled -eq $true) { - $Enable = $Clone.id | Invoke-FalconSensorUpdatePolicyAction enable - if ($Enable) { - $Enable - } else { - $Clone.enabled = $true - $Clone + if ($PSCmdlet.ShouldProcess('Copy-FalconSensorUpdatePolicy','Get-FalconSensorUpdatePolicy')) { + try { + $Policy = Get-FalconSensorUpdatePolicy -Id $Id + if ($Policy) { + @('Name','Description').foreach{ + if ($PSBoundParameters.$_) { $Policy.$_ = $PSBoundParameters.$_ } + } + $Clone = $Policy | New-FalconSensorUpdatePolicy + if ($Clone.id) { + $Clone.settings = $Policy.settings + $Clone = $Clone | Edit-FalconSensorUpdatePolicy + if ($Clone.enabled -eq $false -and $Policy.enabled -eq $true) { + $Enable = $Clone.id | Invoke-FalconSensorUpdatePolicyAction enable + if ($Enable) { + $Enable + } else { + $Clone.enabled = $true + $Clone + } } } } + } catch { + throw $_ } - } catch { - throw $_ } } } \ No newline at end of file diff --git a/Public/psf-real-time-response.ps1 b/Public/psf-real-time-response.ps1 index ccd471d6..fec1890d 100644 --- a/Public/psf-real-time-response.ps1 +++ b/Public/psf-real-time-response.ps1 @@ -198,7 +198,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconDeploy [Parameter(ParameterSetName='GroupId_File',Position=3)] [Parameter(ParameterSetName='HostId_Archive',Position=4)] [Parameter(ParameterSetName='GroupId_Archive',Position=4)] - [ValidateRange(1,600)] + [ValidateRange(30,600)] [int32]$Timeout, [Parameter(ParameterSetName='HostId_File',Position=4)] [Parameter(ParameterSetName='GroupId_File',Position=4)] @@ -218,8 +218,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconDeploy [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('id')] [string]$GroupId, - [Parameter(ParameterSetName='HostId_File',Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] - [Parameter(ParameterSetName='HostId_Archive',Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='HostId_File',Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline)] + [Parameter(ParameterSetName='HostId_Archive',Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('HostIds','device_id','host_ids','aid')] [string[]]$HostId @@ -358,11 +358,15 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconDeploy # Check for existing 'CloudFile' and upload 'LocalFile' if chosen if (Test-Path $FilePath -PathType Leaf) { Update-CloudFile $PutFile $FilePath } try { - # Force a base timeout of 30 to ensure a batch session + # Force a base timeout of 30 if (!$Timeout) { $Timeout = 30 } for ($i = 0; $i -lt ($Hosts | Measure-Object).Count; $i += 1000) { - # Start Real-time Response sessions in groups of 1,000 with 'Timeout' to force batch - $Param = @{ Id = @($Hosts[$i..($i + 999)].device_id); Timeout = $Timeout } + # Start Real-time Response sessions in groups of 1,000 with 'HostTimeout' to force batch + $Param = @{ + Id = @($Hosts[$i..($i + 999)].device_id) + Timeout = $Timeout + HostTimeout = ($Timeout - 5) + } if ($QueueOffline) { $Param['QueueOffline'] = $QueueOffline } $Session = Start-FalconSession @Param [string[]]$SessionIds = if ($Session.batch_id) { @@ -544,7 +548,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconRtr [Parameter(ParameterSetName='GroupId',Mandatory)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$GroupId, - [Parameter(ParameterSetName='HostId',Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='HostId',Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('device_id','host_ids','aid','HostIds')] [string[]]$HostId @@ -585,12 +589,12 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconRtr } } } - # Force a base timeout of 30 to ensure a batch session + # Force a base timeout of 30 if (!$Timeout) { $Timeout = 30 } for ($i = 0; $i -lt ($Hosts | Measure-Object).Count; $i += 10000) { # Start batch Real-time Response session in groups of 10,000 $Output = $Hosts[$i..($i + 9999)] - $Init = @{ Id = $Output.aid; Timeout = $Timeout } + $Init = @{ Id = $Output.aid; Timeout = $Timeout; HostTimeout = ($Timeout - 5) } if ($QueueOffline) { $Init['QueueOffline'] = $QueueOffline } $InitReq = Start-FalconSession @Init if ($InitReq.batch_id -or $InitReq.session_id) { @@ -605,7 +609,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconRtr } # Determine PSFalcon command, execute and capture result [string]$Invoke = Get-RtrCommand $Command - $Cmd = @{ Command = $Command; Timeout = $Timeout } + $Cmd = @{ Command = $Command; Timeout = $Timeout; HostTimeout = ($Timeout - 5) } if ($Argument) { $Cmd['Argument'] = $Argument } if ($QueueOffline -ne $true) { $Cmd['Wait'] = $true } $CmdReq = $InitReq | & $Invoke @Cmd @@ -628,9 +632,4 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconRtr } } } -$Register = @{ - CommandName = 'Invoke-FalconRtr' - ParameterName = 'Command' - ScriptBlock = { Get-RtrCommand } -} -Register-ArgumentCompleter @Register \ No newline at end of file +Register-ArgumentCompleter -CommandName Invoke-FalconRtr -ParameterName Command -ScriptBlock {Get-RtrCommand} \ No newline at end of file diff --git a/Public/psf-sensors.ps1 b/Public/psf-sensors.ps1 index 66b01f29..68ad3c67 100644 --- a/Public/psf-sensors.ps1 +++ b/Public/psf-sensors.ps1 @@ -31,7 +31,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Add-FalconSensorTag [string[]]$Tag, [Parameter(Position=2)] [boolean]$QueueOffline, - [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=3)] + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids','device_id','host_ids','aid')] [string[]]$Id @@ -194,7 +194,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconSensorTag param( [Parameter(Position=1)] [boolean]$QueueOffline, - [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=2)] + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids','device_id','host_ids','aid')] [string[]]$Id @@ -319,7 +319,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconSensorTag [string[]]$Tag, [Parameter(Position=2)] [boolean]$QueueOffline, - [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=3)] + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids','device_id','host_ids','aid')] [string[]]$Id @@ -494,12 +494,12 @@ https://github.com/crowdstrike/psfalcon/wiki/Uninstall-FalconSensor param( [Parameter(Position=1)] [boolean]$QueueOffline, - [Parameter(ParameterSetName='/policy/combined/reveal-uninstall-token/v1:post',Position=2)] + [Parameter(Position=2)] [ValidateSet('agent_version','cid','external_ip','first_seen','hostname','last_seen','local_ip', 'mac_address','os_build','os_version','platform_name','product_type','product_type_desc', 'serial_number','system_manufacturer','system_product_name','tags',IgnoreCase=$false)] [string[]]$Include, - [Parameter(Mandatory,ValueFromPipeline,ValueFromPipelineByPropertyName,Position=3)] + [Parameter(Mandatory,ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('HostId','device_id','host_ids','aid')] [string]$Id diff --git a/Public/quarantine.ps1 b/Public/quarantine.ps1 index b07b9123..34d4105a 100644 --- a/Public/quarantine.ps1 +++ b/Public/quarantine.ps1 @@ -23,12 +23,12 @@ Repeat requests until all available results are retrieved .PARAMETER Total Display total result count instead of results .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Get-FalconQuarantine +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconQuarantine #> [CmdletBinding(DefaultParameterSetName='/quarantine/queries/quarantined-files/v1:get',SupportsShouldProcess)] param( [Parameter(ParameterSetName='/quarantine/entities/quarantined-files/GET/v1:post',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName)] + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}_[A-Fa-f0-9]{64}$')] [Alias('Ids')] [string[]]$Id, @@ -89,7 +89,7 @@ Audit log comment .PARAMETER Id Quarantined file identifier .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Invoke-FalconQuarantineAction +https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconQuarantineAction #> [CmdletBinding(DefaultParameterSetName='/quarantine/entities/quarantined-files/v1:patch', SupportsShouldProcess)] @@ -107,8 +107,8 @@ https://github.com/CrowdStrike/psfalcon/wiki/Invoke-FalconQuarantineAction [Parameter(ParameterSetName='/quarantine/entities/quarantined-files/v1:patch',Position=2)] [Parameter(ParameterSetName='/quarantine/queries/quarantined-files/v1:patch',Position=4)] [string]$Comment, - [Parameter(ParameterSetName='/quarantine/entities/quarantined-files/v1:patch',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=3)] + [Parameter(ParameterSetName='/quarantine/entities/quarantined-files/v1:patch',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{32}_[A-Fa-f0-9]{64}$')] [Alias('Ids')] [string[]]$Id @@ -137,7 +137,7 @@ Requires 'Quarantined Files: Write'. .PARAMETER Filter Falcon Query Language statement .LINK -https://github.com/CrowdStrike/psfalcon/wiki/Test-FalconQuarantineAction +https://github.com/crowdstrike/psfalcon/wiki/Test-FalconQuarantineAction #> [CmdletBinding(DefaultParameterSetName='/quarantine/aggregates/action-update-count/v1:get', SupportsShouldProcess)] diff --git a/Public/real-time-response.ps1 b/Public/real-time-response.ps1 index f9838672..f0889e61 100644 --- a/Public/real-time-response.ps1 +++ b/Public/real-time-response.ps1 @@ -24,7 +24,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Confirm-FalconAdminCommand [Alias('sequence_id')] [int32]$SequenceId, [Parameter(ParameterSetName='/real-time-response/entities/admin-command/v1:get',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=2)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('cloud_request_id','task_id')] [string]$CloudRequestId @@ -63,8 +63,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Confirm-FalconCommand [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)] + [Parameter(ParameterSetName='/real-time-response/entities/command/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('cloud_request_id','task_id')] [string]$CloudRequestId @@ -88,7 +88,7 @@ Requires 'Real Time Response: Write'. .PARAMETER SessionId Session identifier .PARAMETER Timeout -Length of time to wait for a result, in seconds +Length of time to wait for a result, in seconds [default: 30] .PARAMETER BatchGetCmdReqId Batch 'get' command identifier .LINK @@ -103,7 +103,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Confirm-FalconGetFile [Alias('session_id')] [string]$SessionId, [Parameter(ParameterSetName='/real-time-response/combined/batch-get-command/v1:get',Position=1)] - [ValidateRange(30,600)] + [ValidateRange(1,600)] [int32]$Timeout, [Parameter(ParameterSetName='/real-time-response/combined/batch-get-command/v1:get',Mandatory, ValueFromPipelineByPropertyName)] @@ -164,7 +164,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Confirm-FalconResponderCommand [Alias('sequence_id')] [int32]$SequenceId, [Parameter(ParameterSetName='/real-time-response/entities/active-responder-command/v1:get',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=2)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('cloud_request_id','task_id')] [string]$CloudRequestId @@ -273,8 +273,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconPutFile #> [CmdletBinding(DefaultParameterSetName='/real-time-response/queries/put-files/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/real-time-response/entities/put-files/v2:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/real-time-response/entities/put-files/v2:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}_[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -340,8 +340,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconScript #> [CmdletBinding(DefaultParameterSetName='/real-time-response/queries/scripts/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/real-time-response/entities/scripts/v2:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/real-time-response/entities/scripts/v2:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}_[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -415,9 +415,9 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconSession [CmdletBinding(DefaultParameterSetName='/real-time-response/queries/sessions/v1:get',SupportsShouldProcess)] param( [Parameter(ParameterSetName='/real-time-response/entities/queued-sessions/GET/v1:post',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName)] + ValueFromPipelineByPropertyName,ValueFromPipeline)] [Parameter(ParameterSetName='/real-time-response/entities/sessions/GET/v1:post',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName)] + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('Ids')] [string[]]$Id, @@ -439,7 +439,6 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconSession [switch]$All, [Parameter(ParameterSetName='/real-time-response/queries/sessions/v1:get')] [switch]$Total - ) begin { $Param = @{ @@ -474,10 +473,12 @@ Requires 'Real Time Response (Admin): Write'. Real-time Response command .PARAMETER Argument Arguments to include with the command -.PARAMETER Timeout -Length of time to wait for a result, in seconds .PARAMETER OptionalHostId Restrict execution to specific host identifiers +.PARAMETER Timeout +Length of time to wait for a result, in seconds [default: 30] +.PARAMETER HostTimeout +Length of time to wait for a result from target host(s), in seconds .PARAMETER SessionId Session identifier .PARAMETER BatchId @@ -506,12 +507,16 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconAdminCommand [Alias('Arguments')] [string]$Argument, [Parameter(ParameterSetName='/real-time-response/combined/batch-admin-command/v1:post',Position=3)] - [ValidateRange(30,600)] - [int32]$Timeout, - [Parameter(ParameterSetName='/real-time-response/combined/batch-admin-command/v1:post',Position=4)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('optional_hosts','OptionalHostIds')] [string[]]$OptionalHostId, + [Parameter(ParameterSetName='/real-time-response/combined/batch-admin-command/v1:post',Position=4)] + [ValidateRange(1,600)] + [int32]$Timeout, + [Parameter(ParameterSetName='/real-time-response/combined/batch-admin-command/v1:post',Position=5)] + [ValidateRange(1,600)] + [Alias('host_timeout_duration')] + [int32]$HostTimeout, [Parameter(ParameterSetName='/real-time-response/entities/admin-command/v1:post',Mandatory, ValueFromPipelineByPropertyName)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] @@ -530,7 +535,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconAdminCommand $Param = @{ Command = $MyInvocation.MyCommand.Name Format = @{ - Query = @('timeout') + Query = @('timeout','host_timeout_duration') Body = @{ root = @('session_id','base_command','command_string','optional_hosts','batch_id') } } } @@ -556,31 +561,37 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconAdminCommand } elseif ($PSBoundParameters.SessionId) { '/real-time-response/entities/admin-command/v1:post' } - $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 $Wait) { - 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-FalconAdminCommand + if ($Endpoint) { + if ($PSBoundParameters.HostTimeout) { + # Add 's' to denote seconds for 'host_timeout_duration' + $PSBoundParameters.HostTimeout = $PSBoundParameters.HostTimeout,'s' -join $null + } + $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 $Wait) { + 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-FalconAdminCommand + } } + $Result + } else { + $_ } - $Result - } else { - $_ } } } @@ -600,10 +611,12 @@ of 60 seconds. Requires 'Real Time Response: Write'. .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 Timeout +Length of time to wait for a result, in seconds [default: 30] +.PARAMETER HostTimeout +Length of time to wait for a result from target host(s), in seconds .PARAMETER BatchId Batch session identifier .PARAMETER Wait @@ -618,14 +631,18 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconBatchGet [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('^[a-fA-F0-9]{32}$')] [Alias('optional_hosts','OptionalHostIds')] [string[]]$OptionalHostId, + [Parameter(ParameterSetName='/real-time-response/combined/batch-get-command/v1:post',Position=3)] + [ValidateRange(1,600)] + [int32]$Timeout, + [Parameter(ParameterSetName='/real-time-response/combined/batch-get-command/v1:post',Position=4)] + [ValidateRange(1,600)] + [Alias('host_timeout_duration')] + [int32]$HostTimeout, [Parameter(ParameterSetName='/real-time-response/combined/batch-get-command/v1:post',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=4)] + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('batch_id')] [string]$BatchId, @@ -637,7 +654,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconBatchGet Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName Format = @{ - Query = @('timeout') + Query = @('timeout','host_timeout_duration') Body = @{ root = @('batch_id','file_path','optional_hosts') } } } @@ -646,6 +663,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconBatchGet process { if ($OptionalHostId) { @($OptionalHostId).foreach{ $List.Add($_) }}} end { if ($List) { $PSBoundParameters['OptionalHostId'] = @($List | Select-Object -Unique) } + if ($PSBoundParameters.HostTimeout) { + # Add 's' to denote seconds for 'host_timeout_duration' + $PSBoundParameters.HostTimeout = $PSBoundParameters.HostTimeout,'s' -join $null + } @(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 @@ -702,7 +723,9 @@ 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 +Length of time to wait for a result, in seconds [default: 30] +.PARAMETER HostTimeout +Length of time to wait for a result from target host(s), in seconds .PARAMETER SessionId Session identifier .PARAMETER BatchId @@ -731,8 +754,12 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconCommand [Alias('optional_hosts','OptionalHostIds')] [string[]]$OptionalHostId, [Parameter(ParameterSetName='/real-time-response/combined/batch-command/v1:post',Position=4)] - [ValidateRange(30,600)] + [ValidateRange(1,600)] [int32]$Timeout, + [Parameter(ParameterSetName='/real-time-response/combined/batch-command/v1:post',Position=5)] + [ValidateRange(1,600)] + [Alias('host_timeout_duration')] + [int32]$HostTimeout, [Parameter(ParameterSetName='/real-time-response/entities/command/v1:post',Mandatory, ValueFromPipelineByPropertyName)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] @@ -751,7 +778,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconCommand $Param = @{ Command = $MyInvocation.MyCommand.Name Format = @{ - Query = @('timeout') + Query = @('timeout','host_timeout_duration') Body = @{ root = @('session_id','base_command','command_string','optional_hosts','batch_id') } } } @@ -767,6 +794,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconCommand '/real-time-response/entities/command/v1:post' } if ($Endpoint) { + if ($PSBoundParameters.HostTimeout) { + # Add 's' to denote seconds for 'host_timeout_duration' + $PSBoundParameters.HostTimeout = $PSBoundParameters.HostTimeout,'s' -join $null + } $PSBoundParameters['command_string'] = if ($PSBoundParameters.Argument) { # Join 'Command' and 'Argument' into 'command_string' @($PSBoundParameters.Command,$PSBoundParameters.Argument) -join ' ' @@ -812,7 +843,9 @@ 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 +Length of time to wait for a result, in seconds [default: 30] +.PARAMETER HostTimeout +Length of time to wait for a result from target host(s), in seconds .PARAMETER SessionId Session identifier .PARAMETER BatchId @@ -848,8 +881,13 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconResponderCommand [string[]]$OptionalHostId, [Parameter(ParameterSetName='/real-time-response/combined/batch-active-responder-command/v1:post', Position=4)] - [ValidateRange(30,600)] + [ValidateRange(1,600)] [int32]$Timeout, + [Parameter(ParameterSetName='/real-time-response/combined/batch-active-responder-command/v1:post', + Position=5)] + [ValidateRange(1,600)] + [Alias('host_timeout_duration')] + [int32]$HostTimeout, [Parameter(ParameterSetName='/real-time-response/entities/active-responder-command/v1:post',Mandatory, ValueFromPipelineByPropertyName)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] @@ -868,7 +906,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconResponderCommand $Param = @{ Command = $MyInvocation.MyCommand.Name Format = @{ - Query = @('timeout') + Query = @('timeout','host_timeout_duration') Body = @{ root = @('session_id','base_command','command_string','optional_hosts','batch_id') } } } @@ -895,6 +933,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconResponderCommand '/real-time-response/entities/active-responder-command/v1:post' } if ($Endpoint) { + if ($PSBoundParameters.HostTimeout) { + # Add 's' to denote seconds for 'host_timeout_duration' + $PSBoundParameters.HostTimeout = $PSBoundParameters.HostTimeout,'s' -join $null + } $PSBoundParameters['command_string'] = if ($PSBoundParameters.Argument) { # Join 'Command' and 'Argument' into 'command_string' @($PSBoundParameters.Command,$PSBoundParameters.Argument) -join ' ' @@ -1083,7 +1125,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconPutFile SupportsShouldProcess)] param( [Parameter(ParameterSetName='/real-time-response/entities/put-files/v1:delete',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=1)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}_[a-fA-F0-9]{32}$')] [Alias('Ids')] [string]$Id @@ -1110,8 +1152,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconScript #> [CmdletBinding(DefaultParameterSetName='/real-time-response/entities/scripts/v1:delete',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/real-time-response/entities/scripts/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/real-time-response/entities/scripts/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}_[a-fA-F0-9]{32}$')] [Alias('Ids')] [string]$Id @@ -1139,8 +1181,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconSession [CmdletBinding(DefaultParameterSetName='/real-time-response/entities/sessions/v1:delete', SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/real-time-response/entities/sessions/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/real-time-response/entities/sessions/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('session_id')] [string]$Id @@ -1280,10 +1322,12 @@ and 'Invoke-FalconBatchGet'. Requires 'Real Time Response: Read'. .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 Timeout +Length of time to wait for a result, in seconds [default: 30] +.PARAMETER HostTimeout +Length of time to wait for a result from target host(s), in seconds .PARAMETER Id Host identifier .LINK @@ -1297,15 +1341,20 @@ https://github.com/crowdstrike/psfalcon/wiki/Start-FalconSession [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('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('existing_batch_id')] [string]$ExistingBatchId, + [Parameter(ParameterSetName='/real-time-response/combined/batch-init-session/v1:post',Position=3)] + [Parameter(ParameterSetName='/real-time-response/entities/sessions/v1:post',Position=2)] + [ValidateRange(1,600)] + [int32]$Timeout, + [Parameter(ParameterSetName='/real-time-response/combined/batch-init-session/v1:post',Position=4)] + [ValidateRange(1,600)] + [Alias('host_timeout_duration')] + [int32]$HostTimeout, [Parameter(ParameterSetName='/real-time-response/entities/sessions/v1:post',Mandatory)] [Parameter(ParameterSetName='/real-time-response/combined/batch-init-session/v1:post',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName)] + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [ValidateLength(1,10000)] [Alias('host_ids','device_id','device_ids','aid','HostId','HostIds')] @@ -1315,7 +1364,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Start-FalconSession $Param = @{ Command = $MyInvocation.MyCommand.Name Format = @{ - Query = @('timeout') + Query = @('timeout','host_timeout_duration') Body = @{ root = @('existing_batch_id','host_ids','queue_offline','device_id') } } } @@ -1326,10 +1375,14 @@ https://github.com/crowdstrike/psfalcon/wiki/Start-FalconSession if ($List) { # Verify 'Endpoint' using BatchId/SessionId and select hosts [void]$PSBoundParameters.Remove('Id') - $Endpoint = if ($List.Count -eq 1 -and !$Timeout -and !$ExistingBatchId) { + $Endpoint = if ($List.Count -eq 1 -and !$HostTimeout -and !$ExistingBatchId) { $PSBoundParameters['device_id'] = $List[0] '/real-time-response/entities/sessions/v1:post' } else { + if ($PSBoundParameters.HostTimeout) { + # Add 's' to denote seconds for 'host_timeout_duration' + $PSBoundParameters.HostTimeout = $PSBoundParameters.HostTimeout,'s' -join $null + } $PSBoundParameters['host_ids'] = @($List | Select-Object -Unique) '/real-time-response/combined/batch-init-session/v1:post' } @@ -1363,17 +1416,17 @@ function Update-FalconSession { .SYNOPSIS Refresh a single-host or batch Real-time Response session to prevent expiration .DESCRIPTION -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 +Real-time Response sessions expire after 5 minutes by default. Any commands that were issued to a session that +take longer than 5 minutes will not return results without refreshing the session to keep it alive until the command process completes. Requires 'Real Time Response: Read'. .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 identifier(s) to remove from a batch Real-time Response session +.PARAMETER Timeout +Length of time to wait for a result, in seconds [default: 30] .PARAMETER HostId Host identifier, for a single-host session .PARAMETER BatchId @@ -1389,14 +1442,14 @@ https://github.com/crowdstrike/psfalcon/wiki/Update-FalconSession [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('^[a-fA-F0-9]{32}$')] [Alias('hosts_to_remove','HostsToRemove')] [string[]]$HostToRemove, + [Parameter(ParameterSetName='/real-time-response/combined/batch-refresh-session/v1:post',Position=3)] + [ValidateRange(1,600)] + [int32]$Timeout, [Parameter(ParameterSetName='/real-time-response/entities/refresh-session/v1:post',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName)] + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('device_id','host_ids','aid')] [string]$HostId, diff --git a/Public/recon.ps1 b/Public/recon.ps1 index 42128714..194c7c30 100644 --- a/Public/recon.ps1 +++ b/Public/recon.ps1 @@ -10,6 +10,10 @@ Action frequency Email address .PARAMETER Status Action status +.PARAMETER ContentFormat +Email format +.PARAMETER TriggerMatchless +Send email when no matches are found .PARAMETER Id Action identifier .LINK @@ -34,15 +38,25 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconReconAction [string]$Status, [Parameter(ParameterSetName='/recon/entities/actions/v1:patch',Mandatory,ValueFromPipelineByPropertyName, Position=4)] + [ValidateSet('standard','enhanced',IgnoreCase=$false)] + [Alias('content_format')] + [string]$ContentFormat, + [Parameter(ParameterSetName='/recon/entities/actions/v1:patch',Mandatory,ValueFromPipelineByPropertyName, + Position=5)] + [Alias('trigger_matchless')] + [boolean]$TriggerMatchless, + [Parameter(ParameterSetName='/recon/entities/actions/v1:patch',Mandatory,ValueFromPipelineByPropertyName, + Position=6)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [string]$Id - ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName - Format = @{ Body = @{ root = @('recipients','id','status','frequency') }} + Format = @{ + Body = @{ root = @('id','frequency','trigger_matchless','recipients','status','content_format') } + } } [System.Collections.Generic.List[string]] $List = @() } @@ -108,17 +122,17 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconReconNotification begin { $Param = @{ Command = $MyInvocation.MyCommand.Name - Endpoint = '/recon/entities/notifications/v1' + Endpoint = '/recon/entities/notifications/v1:patch' Format = @{ Body = @{ root = @('assigned_to_uuid','id','status','raw_array') }} } [System.Collections.Generic.List[object]]$List = @() } process { if ($Array) { - @($Array).foreach{ + foreach ($i in $Array) { # Select allowed fields, when populated [string[]]$Select = @('id','assigned_to_uuid','status').foreach{ if ($i.$_) { $_ }} - $List.Add(($_ | Select-Object $Select)) + $List.Add(($i | Select-Object $Select)) } } else { Invoke-Falcon @Param -Inputs $PSBoundParameters @@ -151,6 +165,10 @@ Monitoring rule filter Monitoring rule priority .PARAMETER Permission Permission level [public: 'All Intel users', private: 'Recon Admins'] +.PARAMETER BreachMonitoring +Monitor for breach data +.PARAMETER SubstringMatching +Monitor for substring matches .LINK https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconReconRule #> @@ -186,22 +204,36 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconReconRule [Parameter(ParameterSetName='/recon/entities/rules/v1:patch',Mandatory,Position=5)] [ValidateSet('private','public',IgnoreCase=$false)] [Alias('permissions')] - [string]$Permission + [string]$Permission, + [Parameter(ParameterSetName='/recon/entities/rules/v1:patch',Position=6)] + [Alias('breach_monitoring_enabled')] + [boolean]$BreachMonitoring, + [Parameter(ParameterSetName='/recon/entities/rules/v1:patch',Position=7)] + [Alias('substring_matching_enabled')] + [boolean]$SubstringMatching ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = '/recon/entities/rules/v1:patch' - Format = @{ Body = @{ root = @('permissions','priority','name','id','filter','raw_array') }} + Format = @{ + Body = @{ + root = @('permissions','priority','name','id','filter','raw_array','breach_monitoring_enabled', + 'substring_matching_enabled') + } + } } [System.Collections.Generic.List[object]]$List = @() } process { if ($Array) { - @($Array).foreach{ + foreach ($i in $Array) { # Select allowed fields, when populated - [string[]]$Select = @('permissions','priority','name','id','filter').foreach{ if ($i.$_) { $_ }} - $List.Add(($_ | Select-Object $Select)) + [string[]]$Select = @('permissions','priority','name','filter','breach_monitoring_enabled', + 'substring_match_enabled','id').foreach{ + if ($null -ne $i.$_) { $_ } + } + $List.Add(($i | Select-Object $Select)) } } else { Invoke-Falcon @Param -Inputs $PSBoundParameters @@ -245,8 +277,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconReconAction #> [CmdletBinding(DefaultParameterSetName='/recon/queries/actions/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/recon/entities/actions/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/recon/entities/actions/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('Ids')] [string[]]$Id, @@ -283,6 +315,40 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconReconAction Invoke-Falcon @Param -Inputs $PSBoundParameters } } +function Get-FalconReconExport { +<# +.SYNOPSIS +Return status of Falcon Intelligence Recon export jobs +.DESCRIPTION +Requires 'Monitoring rules (Falcon Intelligence Recon): Read'. +.PARAMETER Id +Recon export job identifier +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconReconExport +#> + [CmdletBinding(DefaultParameterSetName='/recon/entities/exports/v1:get',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/recon/entities/exports/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] + [Alias('ids')] + [string[]]$Id + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Query = @('ids') } + } + [System.Collections.Generic.List[string]]$List = @() + } + process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} + end { + if ($List) { + $PSBoundParameters['Id'] = @($List | Select-Object -Unique) + Invoke-Falcon @Param -Inputs $PSBoundParameters + } + } +} function Get-FalconReconNotification { <# .SYNOPSIS @@ -318,14 +384,14 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconReconNotification #> [CmdletBinding(DefaultParameterSetName='/recon/queries/notifications/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/recon/entities/notifications/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] - [Parameter(ParameterSetName='/recon/entities/notifications-detailed/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] - [Parameter(ParameterSetName='/recon/entities/notifications-translated/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/recon/entities/notifications/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] + [Parameter(ParameterSetName='/recon/entities/notifications-detailed/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] + [Parameter(ParameterSetName='/recon/entities/notifications-translated/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [Parameter(ParameterSetName='/recon/entities/notifications-detailed-translated/v1:get',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName)] + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^\w{76}$')] [Alias('Ids')] [string[]]$Id, @@ -371,6 +437,73 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconReconNotification Invoke-Falcon @Param -Inputs $PSBoundParameters } } +function Get-FalconReconRecord { +<# +.SYNOPSIS +Search for Falcon Intelligence Recon exposed data record notifications +.DESCRIPTION +Requires 'Monitoring rules (Falcon Intelligence Recon): Read'. +.PARAMETER Id +Exposed data record identifier +.PARAMETER Filter +Falcon Query Language expression to limit results +.PARAMETER Query +Perform a generic substring search across available fields +.PARAMETER Sort +Property and direction to sort results +.PARAMETER Limit +Maximum number of results per request +.PARAMETER Offset +Position to begin retrieving results +.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/Get-FalconReconRecord +#> + [CmdletBinding(DefaultParameterSetName='/recon/queries/notifications-exposed-data-records/v1:get', + SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/recon/entities/notifications-exposed-data-records/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] + [ValidatePattern('^\w{76}$')] + [Alias('ids')] + [string[]]$Id, + [Parameter(ParameterSetName='/recon/queries/notifications-exposed-data-records/v1:get',Position=1)] + [string]$Filter, + [Parameter(ParameterSetName='/recon/queries/notifications-exposed-data-records/v1:get',Position=2)] + [Alias('q')] + [string]$Query, + [Parameter(ParameterSetName='/recon/queries/notifications-exposed-data-records/v1:get',Position=3)] + [string]$Sort, + [Parameter(ParameterSetName='/recon/queries/notifications-exposed-data-records/v1:get',Position=4)] + [int]$Limit, + [Parameter(ParameterSetName='/recon/queries/notifications-exposed-data-records/v1:get')] + [int]$Offset, + [Parameter(ParameterSetName='/recon/queries/notifications-exposed-data-records/v1:get')] + [switch]$Detailed, + [Parameter(ParameterSetName='/recon/queries/notifications-exposed-data-records/v1:get')] + [switch]$All, + [Parameter(ParameterSetName='/recon/queries/notifications-exposed-data-records/v1:get')] + [switch]$Total + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Query = @('q','offset','sort','limit','filter','ids') } + } + [System.Collections.Generic.List[string]]$List = @() + } + process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} + end { + if ($List) { $PSBoundParameters['Id'] = @($List | Select-Object -Unique) } + Invoke-Falcon @Param -Inputs $PSBoundParameters + } +} function Get-FalconReconRule { <# .SYNOPSIS @@ -400,8 +533,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconReconRule #> [CmdletBinding(DefaultParameterSetName='/recon/queries/rules/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/recon/entities/rules/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/recon/entities/rules/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('Ids')] [string[]]$Id, @@ -471,6 +604,74 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconReconRulePreview } process { Invoke-Falcon @Param -Inputs $PSBoundParameters } } +function Invoke-FalconReconExport { +<# +.SYNOPSIS +Initiate a Falcon Intelligence Recon export job +.DESCRIPTION +Requires 'Monitoring rules (Falcon Intelligence Recon): Write'. +.PARAMETER Array +An array of jobs to submit in a single request +.PARAMETER Entity +Entity type +.PARAMETER Filter +Falcon Query Language expression to limit results +.PARAMETER Sort +Property and direction to sort results +.PARAMETER ExportType +Export file format +.PARAMETER HumanReadable +Use property names that match the Falcon UI +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconReconExport +#> + [CmdletBinding(DefaultParameterSetName='/recon/entities/exports/v1:post',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/recon/entities/exports/v1:post',Mandatory,Position=1)] + [ValidateSet('notification-exposed-data-record',IgnoreCase=$false)] + [string]$Entity, + [Parameter(ParameterSetName='/recon/entities/exports/v1:post',Mandatory,Position=2)] + [string]$Filter, + [Parameter(ParameterSetName='/recon/entities/exports/v1:post',Mandatory,Position=3)] + [ValidateSet('author|asc','author|desc','author_id|asc','author_id|desc','cid|asc','cid|desc', + 'created_date|asc','created_date|desc','credentials_domain|asc','credentials_domain|desc', + 'credentials_ip|asc','credentials_ip|desc','display_name|asc','display_name|desc','domain|asc', + 'domain|desc','email|asc','email|desc','email_domain|asc','email_domain|desc','exposure_date|asc', + 'exposure_date|desc','file.complete_data_set|asc','file.complete_data_set|desc', + 'financial.bank_account|asc','financial.bank_account|desc','financial.credit_card|asc', + 'financial.credit_card|desc','financial.crypto_currency_addresses|asc', + 'financial.crypto_currency_addresses|desc','hash_type|asc','hash_type|desc','id|asc','id|desc', + 'impacted_domain|asc','impacted_domain|desc','impacted_ip|asc','impacted_ip|desc', + 'location.country_code|asc','location.country_code|desc','location.postal_code|asc', + 'location.postal_code|desc','login_id|asc','login_id|desc','notification_id|asc', + 'notification_id|desc','phone_number|asc','phone_number|desc','rule.id|asc','rule.id|desc', + 'rule.topic|asc','rule.topic|desc','site|asc','site|desc','site_id|asc','site_id|desc', + 'social.aim_id|asc','social.aim_id|desc','social.facebook_id|asc','social.facebook_id|desc', + 'social.icq_id|asc','social.icq_id|desc','social.instagram_id|asc','social.instagram_id|desc', + 'social.msn_id|asc','social.msn_id|desc','social.skype_id|asc','social.skype_id|desc', + 'social.twitter_id|asc','social.twitter_id|desc','social.vk_id|asc','social.vk_id|desc', + 'social.vk_token|asc','social.vk_token|desc','source_category|asc','source_category|desc', + 'user_id|asc','user_id|desc','user_ip|asc','user_ip|desc','user_name|asc','user_name|desc', + 'user_uuid|asc','user_uuid|desc',IgnoreCase=$false)] + [string]$Sort, + [Parameter(ParameterSetName='/recon/entities/exports/v1:post',Mandatory,Position=4)] + [ValidateSet('csv','json',IgnoreCase=$false)] + [Alias('export_type')] + [string]$ExportType, + [Parameter(ParameterSetName='/recon/entities/exports/v1:post',Mandatory,Position=5)] + [Alias('human_readable')] + [boolean]$HumanReadable + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Body = @{ root = @('filter','sort','entity','human_readable','export_type') }} + BodyArray = $true + } + } + process { Invoke-Falcon @Param -Inputs $PSBoundParameters } +} function New-FalconReconAction { <# .SYNOPSIS @@ -485,6 +686,10 @@ Notification type Notification frequency .PARAMETER Recipient Notification recipient +.PARAMETER ContentFormat +Email format +.PARAMETER TriggerMatchless +Send email when no matches are found .LINK https://github.com/crowdstrike/psfalcon/wiki/New-FalconReconAction #> @@ -509,7 +714,17 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconReconAction if ((Test-RegexValue $_) -eq 'email') { $true } else { throw "'$_' is not a valid email address." } })] [Alias('Recipients','uid')] - [string[]]$Recipient + [string[]]$Recipient, + [Parameter(ParameterSetName='/recon/entities/actions/v1:post',ValueFromPipelineByPropertyName, + Position=5)] + [ValidateSet('standard','enhanced',IgnoreCase=$false)] + [Alias('content_format')] + [string]$ContentFormat, + [Parameter(ParameterSetName='/recon/entities/actions/v1:post',ValueFromPipelineByPropertyName, + Position=6)] + [Alias('trigger_matchless')] + [boolean]$TriggerMatchless + ) begin { $Param = @{ @@ -518,7 +733,7 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconReconAction Format = @{ Body = @{ root = @('rule_id') - actions = @('recipients','type','frequency') + actions = @('type','trigger_matchless','recipients','frequency','content_format') } } } @@ -552,6 +767,10 @@ Falcon Query Language expression to limit results Monitoring rule priority .PARAMETER Permission Permission level [public: 'All Intel users', private: 'Recon Admins'] +.PARAMETER BreachMonitoring +Monitor for breach data +.PARAMETER SubstringMatching +Monitor for substring matches .LINK https://github.com/crowdstrike/psfalcon/wiki/New-FalconReconRule #> @@ -587,22 +806,36 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconReconRule [Parameter(ParameterSetName='/recon/entities/rules/v1:post',Mandatory,Position=5)] [ValidateSet('private','public',IgnoreCase=$false)] [Alias('permissions')] - [string]$Permission + [string]$Permission, + [Parameter(ParameterSetName='/recon/entities/rules/v1:post',Position=6)] + [Alias('breach_monitoring_enabled')] + [boolean]$BreachMonitoring, + [Parameter(ParameterSetName='/recon/entities/rules/v1:post',Position=7)] + [Alias('substring_matching_enabled')] + [boolean]$SubstringMatching ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = '/recon/entities/rules/v1:post' - Format = @{ Body = @{ root = @('permissions','priority','name','filter','topic','raw_array') }} + Format = @{ + Body = @{ + root = @('filter','permissions','topic','name','breach_monitoring_enabled', + 'substring_matching_enabled','priority','raw_array') + } + } } [System.Collections.Generic.List[object]]$List = @() } process { if ($Array) { - @($Array).foreach{ + foreach ($i in $Array) { # Select allowed fields, when populated - [string[]]$Select = @('permissions','priority','name','filter','topic').foreach{ if ($i.$_) { $_ }} - $List.Add(($_ | Select-Object $Select)) + [string[]]$Select = @('permissions','priority','name','filter','topic', + 'breach_monitoring_enabled','substring_match_enabled').foreach{ + if ($null -ne $i.$_) { $_ } + } + $List.Add(($i | Select-Object $Select)) } } else { Invoke-Falcon @Param -Inputs $PSBoundParameters @@ -617,6 +850,51 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconReconRule } } } +function Receive-FalconReconExport { +<# +.SYNOPSIS +Download a Falcon Intelligence Recon export +.DESCRIPTION +Requires 'Monitoring rules (Falcon Intelligence Recon): Read'. +.PARAMETER Path +Destination path +.PARAMETER Id +Recon export job identifier +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Receive-FalconReconExport +#> + [CmdletBinding(DefaultParameterSetName='/recon/entities/export-files/v1:get',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/recon/entities/export-files/v1:get',Mandatory,Position=1)] + [string]$Path, + [Parameter(ParameterSetName='/recon/entities/export-files/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] + [string]$Id + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ + Outfile = 'path' + Query = @('id') + } + Headers = @{ Accept = 'application/octet-stream' } + } + } + process { + $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 + } else { + Invoke-Falcon @Param -Inputs $PSBoundParameters + } + } + } +} function Remove-FalconReconAction { <# .SYNOPSIS @@ -630,8 +908,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconReconAction #> [CmdletBinding(DefaultParameterSetName='/recon/entities/actions/v1:delete',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/recon/entities/actions/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/recon/entities/actions/v1:delete',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [string]$Id ) @@ -644,6 +922,40 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconReconAction } process { Invoke-Falcon @Param -Inputs $PSBoundParameters } } +function Remove-FalconReconExport { +<# +.SYNOPSIS +Remove a Falcon Intelligence Recon export job +.DESCRIPTION +Requires 'Monitoring rules (Falcon Intelligence Recon): Write'. +.PARAMETER Id +Recon export job identifier +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconReconExport +#> + [CmdletBinding(DefaultParameterSetName='/recon/entities/exports/v1:delete',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/recon/entities/exports/v1:delete',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] + [Alias('ids')] + [string[]]$Id + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Query = @('ids') } + } + [System.Collections.Generic.List[string]]$List = @() + } + process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} + end { + if ($List) { + $PSBoundParameters['Id'] = @($List | Select-Object -Unique) + Invoke-Falcon @Param -Inputs $PSBoundParameters + } + } +} function Remove-FalconReconNotification { <# .SYNOPSIS @@ -657,8 +969,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconReconNotification #> [CmdletBinding(DefaultParameterSetName='/recon/entities/notifications/v1:delete',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/recon/entities/notifications/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/recon/entities/notifications/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^\w{76}$')] [Alias('Ids')] [string[]]$Id @@ -692,8 +1004,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconReconRule #> [CmdletBinding(DefaultParameterSetName='/recon/entities/rules/v1:delete',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/recon/entities/rules/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/recon/entities/rules/v1:delete',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('Ids')] [string[]]$Id diff --git a/Public/reports.ps1 b/Public/reports.ps1 index e5baa60e..88420a7a 100644 --- a/Public/reports.ps1 +++ b/Public/reports.ps1 @@ -29,10 +29,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconScheduledReport #> [CmdletBinding(DefaultParameterSetName='/reports/queries/scheduled-reports/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/reports/entities/scheduled-reports/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] - [Parameter(ParameterSetName='/reports/entities/report-executions/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/reports/entities/scheduled-reports/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] + [Parameter(ParameterSetName='/reports/entities/report-executions/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -111,7 +111,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconScheduledReport SupportsShouldProcess)] param( [Parameter(ParameterSetName='/reports/entities/scheduled-reports/execution/v1:post',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=1)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id ) @@ -151,7 +151,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Receive-FalconScheduledReport [Alias('result_metadata','last_execution')] [object]$Path, [Parameter(ParameterSetName='/reports/entities/report-executions-download/v1:get',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=2)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids')] [string]$Id, @@ -212,7 +212,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Redo-FalconScheduledReport SupportsShouldProcess)] param( [Parameter(ParameterSetName='/reports/entities/report-executions-retry/v1:post',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=1)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Id ) diff --git a/Public/samples.ps1 b/Public/samples.ps1 index ee1d132b..8715be54 100644 --- a/Public/samples.ps1 +++ b/Public/samples.ps1 @@ -11,8 +11,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconSample #> [CmdletBinding(DefaultParameterSetName='/samples/queries/samples/GET/v1:post',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/samples/queries/samples/GET/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/samples/queries/samples/GET/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[A-Fa-f0-9]{64}$')] [Alias('sha256s','sha256','Ids')] [string[]]$Id @@ -57,8 +57,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Receive-FalconSample [Parameter(ParameterSetName='/samples/entities/samples/v3:get',Position=2)] [Alias('password_protected')] [boolean]$PasswordProtected, - [Parameter(ParameterSetName='/samples/entities/samples/v3:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=3)] + [Parameter(ParameterSetName='/samples/entities/samples/v3:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=3)] [ValidatePattern('^[A-Fa-f0-9]{64}$')] [Alias('Ids')] [string]$Id, @@ -102,8 +102,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconSample #> [CmdletBinding(DefaultParameterSetName='/samples/entities/samples/v3:delete',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/samples/entities/samples/v3:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/samples/entities/samples/v3:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[A-Fa-f0-9]{64}$')] [Alias('Ids')] [string]$Id @@ -125,14 +125,14 @@ Upload a sample file A successful upload will provide a 'sha256' value that can be used in submissions to the Falcon Sandbox or Falcon QuickScan. -Maximum file size is 256MB. ZIP archives will automatically redirect to the archive submission API. +Maximum file size is 256MB. ZIP and 7z archives will automatically redirect to 'Send-FalconSampleArchive'. Requires 'Sample Uploads: Write'. .PARAMETER IsConfidential Prohibit sample from being displayed in MalQuery [default: True] .PARAMETER Comment -Sample comment -.PARAMETER FileName +Audit log comment +.PARAMETER Name File name .PARAMETER Path Path to local file @@ -148,10 +148,10 @@ https://github.com/crowdstrike/psfalcon/wiki/Send-FalconSample [string]$Comment, [Parameter(ParameterSetName='/samples/entities/samples/v3:post',ValueFromPipelineByPropertyName, Position=3)] - [Alias('file_name','name')] - [string]$FileName, + [Alias('file_name','FileName')] + [string]$Name, [Parameter(ParameterSetName='/samples/entities/samples/v3:post',Mandatory, - ValueFromPipelineByPropertyName)] + ValueFromPipelineByPropertyName,Position=4)] [ValidateScript({ if (Test-Path $_ -PathType Leaf) { $true @@ -168,20 +168,19 @@ https://github.com/crowdstrike/psfalcon/wiki/Send-FalconSample Endpoint = $PSCmdlet.ParameterSetName Headers = @{ ContentType = 'application/octet-stream' } Format = @{ - Query = @('comment','file_name','is_confidential','name') + Query = @('comment','file_name','is_confidential') Body = @{ root = @('body') } } } } process { - if (!$PSBoundParameters.FileName) { - $PSBoundParameters['FileName'] = [System.IO.Path]::GetFileName($PSBoundParameters.Path) + if (!$PSBoundParameters.Name) { + $PSBoundParameters['Name'] = [System.IO.Path]::GetFileName($PSBoundParameters.Path) } - if ($PSBoundParameters.FileName -match '\.zip$') { - $Param.Endpoint = '/archives/entities/archives/v1:post' - $PSBoundParameters['name'] = $PSBoundParameters.FileName - [void]$PSBoundParameters.Remove('FileName') + if ($PSBoundParameters.Path -match '\.(7z|zip)$') { + Send-FalconSampleArchive @PSBoundParameters + } else { + Invoke-Falcon @Param -Inputs $PSBoundParameters } - Invoke-Falcon @Param -Inputs $PSBoundParameters } } \ No newline at end of file diff --git a/Public/scanner.ps1 b/Public/scanner.ps1 index 9282983c..07ec96f4 100644 --- a/Public/scanner.ps1 +++ b/Public/scanner.ps1 @@ -25,8 +25,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconQuickScan #> [CmdletBinding(DefaultParameterSetName='/scanner/queries/scans/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/scanner/entities/scans/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/scanner/entities/scans/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}_[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -76,7 +76,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconQuickScanQuota $Request = Invoke-Falcon -Endpoint $PSCmdlet.ParameterSetName -RawOutput -EA 0 if ($Request.Result.Content) { (ConvertFrom-Json ($Request.Result.Content).ReadAsStringAsync().Result).meta.quota - } else { + } elseif ($Request) { throw "Unable to retrieve QuickScan quota. Check client permissions." } } @@ -99,8 +99,8 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconQuickScan #> [CmdletBinding(DefaultParameterSetName='/scanner/entities/scans/v1:post',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/scanner/entities/scans/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/scanner/entities/scans/v1:post',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] [ValidatePattern('^[A-Fa-f0-9]{64}$')] [Alias('samples','Ids','sha256')] [string[]]$Id diff --git a/Public/sensors.ps1 b/Public/sensors.ps1 index 29944363..80b38495 100644 --- a/Public/sensors.ps1 +++ b/Public/sensors.ps1 @@ -40,8 +40,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconInstaller #> [CmdletBinding(DefaultParameterSetName='/sensors/queries/installers/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/sensors/entities/installers/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/sensors/entities/installers/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[A-Fa-f0-9]{64}$')] [Alias('Ids')] [string[]]$Id, @@ -132,8 +132,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Receive-FalconInstaller ValueFromPipelineByPropertyName,Position=1)] [Alias('name')] [string]$Path, - [Parameter(ParameterSetName='/sensors/entities/download-installer/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=2)] + [Parameter(ParameterSetName='/sensors/entities/download-installer/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=2)] [ValidatePattern('^[A-Fa-f0-9]{64}$')] [Alias('sha256')] [string]$Id, diff --git a/Public/settings-discover.ps1 b/Public/settings-discover.ps1 new file mode 100644 index 00000000..34770db9 --- /dev/null +++ b/Public/settings-discover.ps1 @@ -0,0 +1,44 @@ +function Get-FalconDiscoverAwsScript { +<# +.SYNOPSIS +Generate a bulk registration script for Falcon Discover +.DESCRIPTION +Requires 'AWS Accounts: Read'. +.PARAMETER OrganizationId +AWS organization identifier +.PARAMETER AccountType +Account type, when registering AWS commercial account in a Gov environment +.PARAMETER SingleAccount +Provide static script for a single AWS account +.PARAMETER Delete + +.LINK +https://github.com/crowdstrike/psfalcon/wiki/Get-FalconDiscoverAwsScript +#> + [CmdletBinding(DefaultParameterSetName='/settings-discover/entities/gen/scripts/v1:get',SupportsShouldProcess)] + param( + [Parameter(ParameterSetName='/settings-discover/entities/gen/scripts/v1:get',Position=1, + ValueFromPipelineByPropertyName)] + [ValidatePattern('^o-[0-9a-z]{10,32}$')] + [Alias('organization-id','organization_id')] + [string]$OrganizationId, + [Parameter(ParameterSetName='/settings-discover/entities/gen/scripts/v1:get',Position=2, + ValueFromPipelineByPropertyName)] + [ValidateSet('commercial','gov',IgnoreCase=$false)] + [Alias('account_type')] + [string]$AccountType, + [Parameter(ParameterSetName='/settings-discover/entities/gen/scripts/v1:get',Position=3)] + [Alias('single_account')] + [boolean]$SingleAccount, + [Parameter(ParameterSetName='/settings-discover/entities/gen/scripts/v1:get',Position=4)] + [boolean]$Delete + ) + begin { + $Param = @{ + Command = $MyInvocation.MyCommand.Name + Endpoint = $PSCmdlet.ParameterSetName + Format = @{ Query = @('delete','organization-id','account_type','single_account') } + } + } + process { Invoke-Falcon @Param -Inputs $PSBoundParameters } +} \ No newline at end of file diff --git a/Public/settings.ps1 b/Public/settings.ps1 index 639d5375..b1c04d08 100644 --- a/Public/settings.ps1 +++ b/Public/settings.ps1 @@ -8,6 +8,12 @@ Requires 'CSPM Registration: Write'. Severity level .PARAMETER Enabled Policy enablement status +.PARAMETER Region +Cloud region +.PARAMETER TagExcluded + +.PARAMETER AccountId +Account identifier .PARAMETER Id Policy identifier .LINK @@ -22,8 +28,20 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconHorizonPolicy [Parameter(ParameterSetName='/settings/entities/policy/v1:patch',Mandatory,ValueFromPipelineByPropertyName, Position=2)] [boolean]$Enabled, - [Parameter(ParameterSetName='/settings/entities/policy/v1:patch',Mandatory,ValueFromPipelineByPropertyName, + [Parameter(ParameterSetName='/settings/entities/policy/v1:patch',ValueFromPipelineByPropertyName, Position=3)] + [Alias('regions')] + [string[]]$Region, + [Parameter(ParameterSetName='/settings/entities/policy/v1:patch',ValueFromPipelineByPropertyName, + Position=4)] + [Alias('tag_excluded')] + [boolean]$TagExcluded, + [Parameter(ParameterSetName='/settings/entities/policy/v1:patch',ValueFromPipelineByPropertyName, + Position=5)] + [Alias('account_id')] + [string]$AccountId, + [Parameter(ParameterSetName='/settings/entities/policy/v1:patch',Mandatory, + ValueFromPipelineByPropertyName)] [Alias('policy_id','PolicyId')] [int32]$Id ) @@ -31,7 +49,9 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconHorizonPolicy $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName - Format = @{ Body = @{ resources = @('severity','policy_id','enabled') }} + Format = @{ + Body = @{ resources = @('enabled','policy_id','regions','account_id','severity','tag_excluded') } + } } } process { Invoke-Falcon @Param -Inputs $PSBoundParameters } @@ -46,6 +66,8 @@ Requires 'CSPM Registration: Write'. Scan interval .PARAMETER CloudPlatform Cloud platform +.PARAMETER NextScanTimestamp +Next scan timestamp (RFC3339) .LINK https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconHorizonSchedule #> @@ -60,13 +82,17 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconHorizonSchedule Position=2)] [ValidateSet('aws','azure','gcp',IgnoreCase=$false)] [Alias('cloud_platform','cloud_provider')] - [string]$CloudPlatform + [string]$CloudPlatform, + [Parameter(ParameterSetName='/settings/scan-schedule/v1:post',ValueFromPipelineByPropertyName,Position=3)] + [ValidatePattern('^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}Z$')] + [Alias('next_scan_timestamp')] + [string]$NextScanTimestamp ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName - Format = @{ Body = @{ resources = @('cloud_platform','scan_schedule') }} + Format = @{ Body = @{ resources = @('cloud_platform','scan_schedule','next_scan_timestamp') }} } } process { Invoke-Falcon @Param -Inputs $PSBoundParameters } @@ -92,8 +118,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconHorizonPolicy #> [CmdletBinding(DefaultParameterSetName='/settings/entities/policy/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/settings/entities/policy-details/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName,Mandatory)] + [Parameter(ParameterSetName='/settings/entities/policy-details/v1:get',ValueFromPipelineByPropertyName, + ValueFromPipeline,Mandatory)] [ValidatePattern('^\d+$')] [Alias('Ids','policy_id')] [int32[]]$Id, @@ -145,8 +171,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconHorizonSchedule #> [CmdletBinding(DefaultParameterSetName='/settings/scan-schedule/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/settings/scan-schedule/v1:get',ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/settings/scan-schedule/v1:get',Mandatory,ValueFromPipelineByPropertyName, + ValueFromPipeline,Position=1)] [ValidateSet('aws','azure','gcp',IgnoreCase=$false)] [Alias('cloud-platform','cloud_platform','cloud_provider')] [string[]]$CloudPlatform @@ -159,9 +185,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconHorizonSchedule } [System.Collections.Generic.List[string]]$List = @() } - process { - if ($CloudPlatform) { @($CloudPlatform).foreach{ $List.Add($_) }} - } + process { if ($CloudPlatform) { @($CloudPlatform).foreach{ $List.Add($_) }}} end { if ($List) { $PSBoundParameters['CloudPlatform'] = @($List | Select-Object -Unique) diff --git a/Public/spotlight.ps1 b/Public/spotlight.ps1 index 68be43e9..469028ee 100644 --- a/Public/spotlight.ps1 +++ b/Public/spotlight.ps1 @@ -11,8 +11,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconRemediation #> [CmdletBinding(DefaultParameterSetName='/spotlight/entities/remediations/v2:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/spotlight/entities/remediations/v2:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/spotlight/entities/remediations/v2:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [Alias('Ids')] [object[]]$Id ) @@ -76,8 +76,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconVulnerability #> [CmdletBinding(DefaultParameterSetName='/spotlight/queries/vulnerabilities/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/spotlight/entities/vulnerabilities/v2:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/spotlight/entities/vulnerabilities/v2:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [ValidatePattern('^[a-fA-F0-9]{32}_[a-fA-F0-9]{32}$')] [Alias('Ids')] [string[]]$Id, @@ -149,8 +149,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconVulnerabilityLogic #> [CmdletBinding(DefaultParameterSetName='/spotlight/queries/evaluation-logic/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/spotlight/entities/evaluation-logic/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName)] + [Parameter(ParameterSetName='/spotlight/entities/evaluation-logic/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline)] [Alias('Ids','apps')] [object[]]$Id, [Parameter(ParameterSetName='/spotlight/queries/evaluation-logic/v1:get',Mandatory,Position=1)] diff --git a/Public/ti.ps1 b/Public/ti.ps1 index 49af9b94..0c8dfe61 100644 Binary files a/Public/ti.ps1 and b/Public/ti.ps1 differ diff --git a/Public/user-management.ps1 b/Public/user-management.ps1 index c07403b8..bae07a54 100644 --- a/Public/user-management.ps1 +++ b/Public/user-management.ps1 @@ -6,57 +6,42 @@ Assign roles to users Requires 'User Management: Write'. .PARAMETER UserId User identifier -.PARAMETER Id -User role .PARAMETER Cid Customer identifier +.PARAMETER Id +User role .LINK https://github.com/crowdstrike/psfalcon/wiki/Add-FalconRole #> - [CmdletBinding(DefaultParameterSetName='/user-roles/entities/user-roles/v1:post',SupportsShouldProcess)] + [CmdletBinding(DefaultParameterSetName='/user-management/entities/user-role-actions/v1:post', + SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/user-roles/entities/user-roles/v1:post',Mandatory, - ValueFromPipelineByPropertyName,Position=1)] [Parameter(ParameterSetName='/user-management/entities/user-role-actions/v1:post',Mandatory, ValueFromPipelineByPropertyName,Position=1)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('uuid','user_uuid')] [string]$UserId, - [Parameter(ParameterSetName='/user-roles/entities/user-roles/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=2)] - [Parameter(ParameterSetName='/user-management/entities/user-role-actions/v1:post',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=2)] - [Alias('Ids','roles')] - [string[]]$Id, [Parameter(ParameterSetName='/user-management/entities/user-role-actions/v1:post',Mandatory, - ValueFromPipelineByPropertyName,Position=3)] - [string]$Cid + ValueFromPipelineByPropertyName,Position=2)] + [string]$Cid, + [Parameter(ParameterSetName='/user-management/entities/user-role-actions/v1:post',Mandatory,Position=3)] + [Alias('role_ids','Ids')] + [string[]]$Id ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName - Format = if ($PSCmdlet.ParameterSetName -eq '/user-management/entities/user-role-actions/v1:post') { - @{ Body = @{ root = @('cid','uuid','action','role_ids') }} - } else { - @{ Query = @('user_uuid'); Body = @{ root = @('roleIds') }} - } + Format = @{ Body = @{ root = @('cid','uuid','action','role_ids') }} } [System.Collections.Generic.List[string]]$List = @() } - process { - if ($Id) { @($Id).foreach{ $List.Add($_) }} - } + process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} end { if ($List) { - if ($PSCmdlet.ParameterSetName -eq '/user-management/entities/user-role-actions/v1:post') { - $PSBoundParameters['role_ids'] = @($List | Select-Object -Unique) - $PSBoundParameters['uuid'] = $PSBoundParameters.UserId - $PSBoundParameters['action'] = 'grant' - } else { - $PSBoundParameters['roleIds'] = @($List | Select-Object -Unique) - $PSBoundParameters['user_uuid'] = $PSBoundParameters.UserId - } + $PSBoundParameters['role_ids'] = @($List | Select-Object -Unique) + $PSBoundParameters['uuid'] = $PSBoundParameters.UserId + $PSBoundParameters['action'] = 'grant' [void]$PSBoundParameters.Remove('Id') [void]$PSBoundParameters.Remove('UserId') Invoke-Falcon @Param -Inputs $PSBoundParameters @@ -86,8 +71,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Edit-FalconUser [Parameter(ParameterSetName='/user-management/entities/users/v1:patch',Position=2)] [Alias('last_name')] [string]$LastName, - [Parameter(ParameterSetName='/user-management/entities/users/v1:patch',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=3)] + [Parameter(ParameterSetName='/user-management/entities/users/v1:patch',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=3)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('user_uuid','uuid')] [string]$Id @@ -116,7 +101,6 @@ Role identifier User identifier .PARAMETER Cid Customer identifier - .PARAMETER Detailed Retrieve detailed information .LINK @@ -125,18 +109,20 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconRole [CmdletBinding(DefaultParameterSetName='/user-management/queries/roles/v1:get', SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/user-management/entities/roles/v1:get',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] - [Alias('ids')] + [Parameter(ParameterSetName='/user-management/entities/roles/v1:get',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] + [Alias('ids','roles')] [string[]]$Id, - [Parameter(ParameterSetName='/user-management/combined/user-roles/v1:get',Mandatory,Position=1)] - [Alias('user_uuid','uuid')] - [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] - [string]$UserId, [Parameter(ParameterSetName='/user-management/queries/roles/v1:get',Position=1)] [Parameter(ParameterSetName='/user-management/combined/user-roles/v1:get',Position=2)] + [Parameter(ParameterSetName='/user-management/entities/roles/v1:get',Position=2)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [string]$Cid, + [Parameter(ParameterSetName='/user-management/queries/roles/v1:get',Position=2)] + [Parameter(ParameterSetName='/user-management/combined/user-roles/v1:get',Mandatory,Position=1)] + [Alias('user_uuid','uuid')] + [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] + [string]$UserId, [Parameter(ParameterSetName='/user-management/combined/user-roles/v1:get',Position=3)] [string]$Filter, [Parameter(ParameterSetName='/user-management/combined/user-roles/v1:get',Position=4)] @@ -151,8 +137,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconRole [Parameter(ParameterSetName='/user-management/combined/user-roles/v1:get',Position=7)] [Alias('direct_only')] [boolean]$DirectOnly, - [Parameter(ParameterSetName='/user-management/queries/roles/v1:get')] - [Parameter(ParameterSetName='/user-roles/queries/user-role-ids-by-cid/v1:get')] + [Parameter(ParameterSetName='/user-management/combined/user-roles/v1:get',Mandatory)] [switch]$Detailed ) begin { @@ -171,7 +156,11 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconRole } elseif ($_ -match '^[a-fA-F0-9]{32}$') { Get-FalconRole -Cid $_ } else { - $List.Add($_) + if ($_ -notmatch '^\w+') { + Write-Error "'$_' is not a valid user role." + } else { + $List.Add($_) + } } } } else { @@ -203,17 +192,21 @@ Property and direction to sort results Maximum number of results per request .PARAMETER Username Username -.PARAMETER Detailed -Retrieve detailed information .PARAMETER Include Include additional properties +.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/Get-FalconUser #> [CmdletBinding(DefaultParameterSetName='/user-management/queries/users/v1:get',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/user-management/entities/users/GET/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/user-management/entities/users/GET/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('ids','uuid')] [string[]]$Id, @@ -235,13 +228,17 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconUser [Alias('uid','Usernames')] [string[]]$Username, [Parameter(ParameterSetName='/user-management/queries/users/v1:get')] - [Parameter(ParameterSetName='Username')] - [switch]$Detailed, - [Parameter(ParameterSetName='/user-management/queries/users/v1:get')] [Parameter(ParameterSetName='/user-management/entities/users/GET/v1:post')] [Parameter(ParameterSetName='Username')] [ValidateSet('roles',IgnoreCase=$false)] - [string[]]$Include + [string[]]$Include, + [Parameter(ParameterSetName='/user-management/queries/users/v1:get')] + [Parameter(ParameterSetName='Username')] + [switch]$Detailed, + [Parameter(ParameterSetName='/user-management/queries/users/v1:get')] + [switch]$All, + [Parameter(ParameterSetName='/user-management/queries/users/v1:get')] + [switch]$Total ) begin { $Param = @{ @@ -251,6 +248,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconUser Body = @{ root = @('ids') } Query = @('filter','sort','limit','offset','uid') } + Max = 100 } [System.Collections.Generic.List[string]]$List = @() } @@ -302,6 +300,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Invoke-FalconUserAction param( [Parameter(ParameterSetName='/user-management/entities/user-actions/v1:post',Mandatory,Position=1)] [ValidateSet('reset_password','reset_2fa',IgnoreCase=$false)] + [Alias('action_name')] [string]$Name, [Parameter(ParameterSetName='/user-management/entities/user-actions/v1:post',Mandatory,Position=2)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] @@ -349,8 +348,8 @@ https://github.com/crowdstrike/psfalcon/wiki/New-FalconUser #> [CmdletBinding(DefaultParameterSetName='/user-management/entities/users/v1:post',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/user-management/entities/users/v1:post',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/user-management/entities/users/v1:post',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidateScript({ if ((Test-RegexValue $_) -eq 'email') { $true } else { throw "'$_' is not a valid email address." } })] @@ -396,57 +395,42 @@ Remove roles from a user Requires 'User Management: Write'. .PARAMETER UserId User identifier -.PARAMETER Id -User role .PARAMETER Cid Customer identifier +.PARAMETER Id +User role .LINK https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconRole #> - [CmdletBinding(DefaultParameterSetName='/user-roles/entities/user-roles/v1:delete',SupportsShouldProcess)] + [CmdletBinding(DefaultParameterSetName='/user-management/entities/user-role-actions/v1:post', + SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/user-roles/entities/user-roles/v1:delete',Mandatory, - ValueFromPipelineByPropertyName,Position=1)] [Parameter(ParameterSetName='/user-management/entities/user-role-actions/v1:post',Mandatory, ValueFromPipelineByPropertyName,Position=1)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('uuid','user_uuid')] [string]$UserId, - [Parameter(ParameterSetName='/user-roles/entities/user-roles/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=2)] - [Parameter(ParameterSetName='/user-management/entities/user-role-actions/v1:post',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=2)] - [Alias('roleIds','Ids','roles')] - [string[]]$Id, [Parameter(ParameterSetName='/user-management/entities/user-role-actions/v1:post',Mandatory, - ValueFromPipelineByPropertyName,Position=3)] - [string]$Cid + ValueFromPipelineByPropertyName,Position=2)] + [string]$Cid, + [Parameter(ParameterSetName='/user-management/entities/user-role-actions/v1:post',Mandatory,Position=3)] + [Alias('role_ids','Ids')] + [string[]]$Id ) begin { $Param = @{ Command = $MyInvocation.MyCommand.Name Endpoint = $PSCmdlet.ParameterSetName - Format = if ($PSCmdlet.ParameterSetName -eq '/user-management/entities/user-role-actions/v1:post') { - @{ Body = @{ root = @('cid','uuid','action','role_ids') }} - } else { - @{ Query = @('user_uuid','ids') } - } + Format = @{ Body = @{ root = @('cid','uuid','action','role_ids') }} } [System.Collections.Generic.List[string]]$List = @() } - process { - if ($Id) { @($Id).foreach{ $List.Add($_) }} - } + process { if ($Id) { @($Id).foreach{ $List.Add($_) }}} end { if ($List) { - if ($PSCmdlet.ParameterSetName -eq '/user-management/entities/user-role-actions/v1:post') { - $PSBoundParameters['role_ids'] = @($List | Select-Object -Unique) - $PSBoundParameters['uuid'] = $PSBoundParameters.UserId - $PSBoundParameters['action'] = 'revoke' - } else { - $PSBoundParameters['Ids'] = @($List | Select-Object -Unique) - $PSBoundParameters['user_uuid'] = $PSBoundParameters.UserId - } + $PSBoundParameters['role_ids'] = @($List | Select-Object -Unique) + $PSBoundParameters['uuid'] = $PSBoundParameters.UserId + $PSBoundParameters['action'] = 'revoke' [void]$PSBoundParameters.Remove('Id') [void]$PSBoundParameters.Remove('UserId') Invoke-Falcon @Param -Inputs $PSBoundParameters @@ -466,8 +450,8 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconUser #> [CmdletBinding(DefaultParameterSetName='/user-management/entities/users/v1:delete',SupportsShouldProcess)] param( - [Parameter(ParameterSetName='/user-management/entities/users/v1:delete',Mandatory,ValueFromPipeline, - ValueFromPipelineByPropertyName,Position=1)] + [Parameter(ParameterSetName='/user-management/entities/users/v1:delete',Mandatory, + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}$')] [Alias('user_uuid','uuid')] [string]$Id @@ -481,11 +465,6 @@ https://github.com/crowdstrike/psfalcon/wiki/Remove-FalconUser } process { Invoke-Falcon @Param -Inputs $PSBoundParameters } } -@('Add-FalconRole','Remove-FalconRole').foreach{ - $Register = @{ - CommandName = $_ - ParameterName = 'Id' - ScriptBlock = { Get-FalconRole -EA 0 } - } - Register-ArgumentCompleter @Register +@('Add-FalconRole','Get-FalconRole','Remove-FalconRole').foreach{ + Register-ArgumentCompleter -CommandName $_ -ParameterName 'Id' -ScriptBlock { Get-FalconRole -EA 0 } } \ No newline at end of file diff --git a/Public/zero-trust-assessment.ps1 b/Public/zero-trust-assessment.ps1 index 0142da47..de6e8c8f 100644 --- a/Public/zero-trust-assessment.ps1 +++ b/Public/zero-trust-assessment.ps1 @@ -12,7 +12,7 @@ https://github.com/crowdstrike/psfalcon/wiki/Get-FalconZta [CmdletBinding(DefaultParameterSetName='/zero-trust-assessment/entities/audit/v1:get',SupportsShouldProcess)] param( [Parameter(ParameterSetName='/zero-trust-assessment/entities/assessments/v1:get',Mandatory, - ValueFromPipeline,ValueFromPipelineByPropertyName,Position=1)] + ValueFromPipelineByPropertyName,ValueFromPipeline,Position=1)] [ValidatePattern('^[a-fA-F0-9]{32}$')] [Alias('Ids','device_id','host_ids','aid')] [string[]]$Id