Public/Policies/New-FleetPolicy.ps1
|
function New-FleetPolicy { <# .SYNOPSIS Creates a new policy in FleetDM .DESCRIPTION Creates a new policy in FleetDM. Policies are compliance rules that are regularly checked on hosts. .PARAMETER Name The name of the policy .PARAMETER Query The SQL query that defines the policy check. Should return 1 row for compliant hosts. .PARAMETER Description A description of what the policy checks .PARAMETER Resolution Steps to resolve the issue when the policy fails .PARAMETER Platform The platform this policy applies to (windows, linux, darwin, chrome, or all) .PARAMETER FleetId Fleet Premium. Creates the policy on this fleet instead of as a global policy. .PARAMETER Critical Fleet Premium. Marks the policy as critical. .PARAMETER CalendarEventsEnabled Fleet Premium. Enables calendar maintenance events when this fleet policy fails. Requires FleetId. .PARAMETER SoftwareTitleId Fleet Premium. Installs this software title when the fleet policy fails. Requires FleetId. .PARAMETER ScriptId Fleet Premium. Runs this script when the fleet policy fails. Requires FleetId. .PARAMETER LabelIncludeAny Fleet Premium. Hosts must match one of these label names. .NOTES FleetId, Critical, calendar events, software install automation, script automation, and label targeting require Fleet Premium. https://fleetdm.com/docs/rest-api/rest-api#create-policy https://fleetdm.com/docs/rest-api/rest-api#create-fleet-level-policy .EXAMPLE New-FleetPolicy -Name "Firewall Enabled" -Query "SELECT 1 FROM windows_firewall WHERE enabled = 1;" Creates a basic policy to check if Windows Firewall is enabled .EXAMPLE $params = @{ Name = "FileVault Enabled" Query = "SELECT 1 FROM filevault_status WHERE status = 'on';" Description = "Ensures FileVault disk encryption is enabled" Resolution = "Enable FileVault in System Preferences > Security & Privacy" Platform = "darwin" } New-FleetPolicy @params Creates a comprehensive macOS policy with all details .EXAMPLE Import-Csv policies.csv | ForEach-Object { New-FleetPolicy -Name $_.Name -Query $_.Query -Description $_.Description } Bulk creates policies from a CSV file .LINK https://fleetdm.com/docs/using-fleet/rest-api#create-policy #> [CmdletBinding(SupportsShouldProcess)] param( [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Name, [Parameter(Mandatory)] [ValidateNotNullOrEmpty()] [string]$Query, [Parameter()] [string]$Description, [Parameter()] [string]$Resolution, [Parameter()] [ValidateSet('windows', 'linux', 'darwin', 'chrome', 'all')] [string]$Platform = 'all', [ValidateRange(0, [int]::MaxValue)] [int]$FleetId, [switch]$Critical, [bool]$CalendarEventsEnabled, [ValidateRange(1, [int]::MaxValue)] [int]$SoftwareTitleId, [ValidateRange(1, [int]::MaxValue)] [int]$ScriptId, [string[]]$LabelIncludeAny ) process { # Build the request body $body = @{ name = $Name query = $Query } # Add optional parameters if provided if ($PSBoundParameters.ContainsKey('Description')) { $body['description'] = $Description } if ($PSBoundParameters.ContainsKey('Resolution')) { $body['resolution'] = $Resolution } # Handle platform parameter - API expects empty string for 'all' if ($Platform -eq 'all') { $body['platform'] = '' } else { $body['platform'] = $Platform } $automationOnGlobal = -not $PSBoundParameters.ContainsKey('FleetId') -and ( $PSBoundParameters.ContainsKey('CalendarEventsEnabled') -or $PSBoundParameters.ContainsKey('SoftwareTitleId') -or $PSBoundParameters.ContainsKey('ScriptId') ) if ($automationOnGlobal) { throw "CalendarEventsEnabled, SoftwareTitleId, and ScriptId are fleet policy automations and require -FleetId. https://fleetdm.com/docs/rest-api/rest-api#create-fleet-level-policy" } if ($PSBoundParameters.ContainsKey('Critical')) { $body['critical'] = [bool]$Critical } if ($PSBoundParameters.ContainsKey('CalendarEventsEnabled')) { $body['calendar_events_enabled'] = [bool]$CalendarEventsEnabled } if ($PSBoundParameters.ContainsKey('SoftwareTitleId')) { $body['software_title_id'] = $SoftwareTitleId } if ($PSBoundParameters.ContainsKey('ScriptId')) { $body['script_id'] = $ScriptId } if ($LabelIncludeAny) { $body['labels_include_any'] = @($LabelIncludeAny) } $endpoint = if ($PSBoundParameters.ContainsKey('FleetId')) { "fleets/$FleetId/policies" } else { "global/policies" } $targetDescription = if ($PSBoundParameters.ContainsKey('FleetId')) { "fleet $FleetId policy '$Name'" } else { "global policy '$Name'" } Write-Verbose "Creating new policy: $Name" Write-Verbose "Platform: $Platform" Write-Verbose "Query: $Query" if ($PSCmdlet.ShouldProcess($targetDescription, 'Create')) { try { $result = Invoke-FleetDMRequest -Endpoint $endpoint -Method POST -Body $body if ($result.policy) { # Add custom type for formatting $result.policy.PSObject.TypeNames.Insert(0, 'FleetDM.Policy') # Add calculated properties if host counts are available $result.policy = Add-FleetPolicyCalculatedProperties -Policy $result.policy Write-Verbose "Successfully created policy '$Name' (ID: $($result.policy.id))" return $result.policy } else { Write-Warning "Policy creation succeeded but no policy data was returned" } } catch { if ($_.Exception.Message -like "*already exists*") { Write-Error "A policy with the name '$Name' already exists" } else { throw $_ } } } } } |