Public/New-FsArticle.ps1
Function New-FsArticle { <# .SYNOPSIS Creates a new Solution Article in FreshService .DESCRIPTION The New-FsArticle function creates a new solution article in your FreshService domain. Supports creating articles with HTML content, external URLs, attachments, and secondary languages. .EXAMPLE New-FsArticle -Title "How to Reset Password" -Description "<p>Steps to reset password...</p>" -FolderID 2 -CategoryID 2 Creates a new article with HTML content .EXAMPLE New-FsArticle -Title "External Guide" -Url "https://example.com/guide" -FolderID 2 -CategoryID 2 Creates a new article linking to external URL .EXAMPLE New-FsArticle -Title "Guide with Files" -Description "<p>See attachments...</p>" -FolderID 2 -CategoryID 2 -Attachments @("C:\file1.pdf", "C:\file2.jpg") Creates a new article with file attachments .EXAMPLE New-FsArticle -Title "French Version" -Description "<p>Contenu français...</p>" -FolderID 2 -CategoryID 2 -Language "fr" -ParentID 1 Creates a secondary language version of an existing article .PARAMETER Title The title of the article (required) .PARAMETER Description The HTML description/content of the article (required for HTML articles) .PARAMETER Url External URL for the article (mutually exclusive with Description) .PARAMETER FolderID The folder ID where the article will be created (required) .PARAMETER CategoryID The category ID for the article (required) .PARAMETER Attachments Array of file paths to attach to the article .PARAMETER Language Language code for secondary language articles (e.g., "fr", "es", "de") .PARAMETER ParentID ID of the primary language article (required when Language is specified) .PARAMETER Status The status of the article (Draft, Published) .PARAMETER ArticleType The type of article (Permanent, Workaround) .PARAMETER AgentID The ID of the agent creating the article .PARAMETER Keywords Array of keywords for the article .PARAMETER Tags Array of tags for the article .PARAMETER ReviewDate Review date for the article .PARAMETER WorkspaceID The workspace ID (defaults to 3 for MSPs) .INPUTS String, Int, Array .OUTPUTS PSCustomObject .NOTES Requires FreshService API connection .LINK https://api.freshservice.com/v2/#create_solution_article #> [CmdletBinding(DefaultParameterSetName = 'HTMLContent')] Param( [Parameter(Mandatory=$true, Position=0, ParameterSetName='HTMLContent')] [Parameter(Mandatory=$true, Position=0, ParameterSetName='ExternalURL')] [Parameter(Mandatory=$true, Position=0, ParameterSetName='WithAttachments')] [Parameter(Mandatory=$true, Position=0, ParameterSetName='SecondaryLanguage')] [String]$Title, [Parameter(Mandatory=$true, Position=1, ParameterSetName='HTMLContent')] [Parameter(Mandatory=$true, Position=1, ParameterSetName='WithAttachments')] [Parameter(Mandatory=$true, Position=1, ParameterSetName='SecondaryLanguage')] [String]$Description, [Parameter(Mandatory=$true, Position=1, ParameterSetName='ExternalURL')] [String]$Url, [Parameter(Mandatory=$true, Position=2)] [Int]$FolderID, [Parameter(Mandatory=$true, Position=3)] [Int]$CategoryID, [Parameter(Mandatory=$true, ParameterSetName='WithAttachments')] [String[]]$Attachments, [Parameter(Mandatory=$true, ParameterSetName='SecondaryLanguage')] [String]$Language, [Parameter(Mandatory=$true, ParameterSetName='SecondaryLanguage')] [Int]$ParentID, [Parameter(Mandatory=$false)] [ValidateSet("Draft","Published")] [String]$Status = "Published", [Parameter(Mandatory=$false)] [ValidateSet("Permanent","Workaround")] [String]$ArticleType = "Permanent", [Parameter(Mandatory=$false)] [Int]$AgentID, [Parameter(Mandatory=$false)] [String[]]$Keywords, [Parameter(Mandatory=$false)] [String[]]$Tags, [Parameter(Mandatory=$false)] [DateTime]$ReviewDate, [Parameter(Mandatory=$false)] [Int]$WorkspaceID = 3 ) Begin { Write-Verbose -Message "Starting $($MyInvocation.InvocationName) with $($PsCmdlet.ParameterSetName) parameterset..." Write-Verbose -Message "Parameters are $($PSBoundParameters | Select-Object -Property *)" Connect-FreshServiceAPI $StatusInt = $null switch ($Status) { Draft {$StatusInt = 1} Published {$StatusInt = 2} } $ArticleTypeInt = $null switch ($ArticleType) { Permanent {$ArticleTypeInt = 1} Workaround {$ArticleTypeInt = 2} } # Check for file attachments parameter set $UseMultipartForm = $PSCmdlet.ParameterSetName -eq 'WithAttachments' } Process { if ($UseMultipartForm) { # Handle multipart form data for attachments $FormData = @{} if ($Title) { $FormData['title'] = $Title } if ($Description) { $FormData['description'] = $Description } if ($FolderID) { $FormData['folder_id'] = $FolderID.ToString() } if ($CategoryID) { $FormData['category_id'] = $CategoryID.ToString() } if ($StatusInt) { $FormData['status'] = $StatusInt.ToString() } if ($ArticleTypeInt) { $FormData['article_type'] = $ArticleTypeInt.ToString() } if ($AgentID) { $FormData['agent_id'] = $AgentID.ToString() } if ($WorkspaceID) { $FormData['workspace_id'] = $WorkspaceID.ToString() } if ($Keywords) { for ($i = 0; $i -lt $Keywords.Count; $i++) { $FormData["keywords[$i]"] = $Keywords[$i] } } if ($Tags) { for ($i = 0; $i -lt $Tags.Count; $i++) { $FormData["tags[$i]"] = $Tags[$i] } } if ($ReviewDate) { $FormData['review_date'] = $ReviewDate.ToString('yyyy-MM-ddTHH:mm:ssZ') } # Add file attachments $Files = @{} for ($i = 0; $i -lt $Attachments.Count; $i++) { if (Test-Path $Attachments[$i]) { $Files["attachments[$i]"] = $Attachments[$i] } else { Write-Warning "File not found: $($Attachments[$i])" } } # Use multipart form request (this would need to be implemented in Get-FreshServiceAPIResult) Write-Verbose -Message "Creating article with attachments using multipart form data" # Note: This requires enhancing Get-FreshServiceAPIResult to handle multipart form data # For now, we'll fall back to JSON method and warn about attachments Write-Warning "Attachment support requires multipart form implementation. Creating article without attachments." } # Standard JSON method for all parameter sets $Attributes = @{} if ($Title) { $Attributes.Add('title', $($Title)) } if ($Description) { $Attributes.Add('description', $($Description)) } if ($Url) { $Attributes.Add('url', $($Url)) } if ($FolderID) { $Attributes.Add('folder_id', $($FolderID)) } if ($CategoryID) { $Attributes.Add('category_id', $($CategoryID)) } if ($StatusInt) { $Attributes.Add('status', $($StatusInt)) } if ($ArticleTypeInt) { $Attributes.Add('article_type', $($ArticleTypeInt)) } if ($AgentID) { $Attributes.Add('agent_id', $($AgentID)) } if ($Keywords) { $Attributes.Add('keywords', $($Keywords)) } if ($Tags) { $Attributes.Add('tags', $($Tags)) } if ($ReviewDate) { $Attributes.Add('review_date', $($ReviewDate.ToString('yyyy-MM-ddTHH:mm:ssZ'))) } if ($WorkspaceID) { $Attributes.Add('workspace_id', $($WorkspaceID)) } if ($Language) { $Attributes.Add('language', $($Language)) } if ($ParentID) { $Attributes.Add('parent_id', $($ParentID)) } $Body = $Attributes | ConvertTo-Json Write-Verbose -Message "Request body: $Body" Get-FreshServiceAPIResult -APIEndpoint "$($Script:APIURL)/solutions/articles" -Body $Body -Method 'POST' } End { Write-Verbose -Message "Ending $($MyInvocation.InvocationName)..." } } |