PSWordPress.psm1

function Join-UriQuery { 
    <#
    .SYNOPSIS
    Provides ability to join two Url paths together including advanced querying
 
    .DESCRIPTION
    Provides ability to join two Url paths together including advanced querying which is useful for RestAPI/GraphApi calls
 
    .PARAMETER BaseUri
    Primary Url to merge
 
    .PARAMETER RelativeOrAbsoluteUri
    Additional path to merge with primary url (optional)
 
    .PARAMETER QueryParameter
    Parameters and their values in form of hashtable
 
    .PARAMETER EscapeUriString
    If set, will escape the url string
 
    .EXAMPLE
    Join-UriQuery -BaseUri 'https://evotec.xyz/' -RelativeOrAbsoluteUri '/wp-json/wp/v2/posts' -QueryParameter @{
        page = 1
        per_page = 20
        search = 'SearchString'
    }
 
    .EXAMPLE
    Join-UriQuery -BaseUri 'https://evotec.xyz/wp-json/wp/v2/posts' -QueryParameter @{
        page = 1
        per_page = 20
        search = 'SearchString'
    }
 
    .EXAMPLE
    Join-UriQuery -BaseUri 'https://evotec.xyz' -RelativeOrAbsoluteUri '/wp-json/wp/v2/posts'
 
    .NOTES
    General notes
    #>

    [alias('Join-UrlQuery')]
    [CmdletBinding()]
    param (
        [parameter(Mandatory)][uri] $BaseUri,
        [parameter(Mandatory = $false)][uri] $RelativeOrAbsoluteUri,
        [Parameter()][System.Collections.IDictionary] $QueryParameter,
        [alias('EscapeUrlString')][switch] $EscapeUriString
    )
    Begin {
        Add-Type -AssemblyName System.Web
    }
    Process {

        if ($BaseUri -and $RelativeOrAbsoluteUri) {
            $Url = Join-Uri -BaseUri $BaseUri -RelativeOrAbsoluteUri $RelativeOrAbsoluteUri
        }
        else {
            $Url = $BaseUri
        }

        if ($QueryParameter) {
            $Collection = [System.Web.HttpUtility]::ParseQueryString([String]::Empty)
            foreach ($key in $QueryParameter.Keys) {
                $Collection.Add($key, $QueryParameter.$key)
            }
        }

        $uriRequest = [System.UriBuilder] $Url
        if ($Collection) {
            $uriRequest.Query = $Collection.ToString()
        }
        if (-not $EscapeUriString) {
            $uriRequest.Uri.AbsoluteUri
        }
        else {
            [System.Uri]::EscapeUriString($uriRequest.Uri.AbsoluteUri)
        }
    }
}
function Remove-EmptyValue { 
    <#
    .SYNOPSIS
    Removes empty values from a hashtable recursively.
 
    .DESCRIPTION
    This function removes empty values from a given hashtable. It can be used to clean up a hashtable by removing keys with null, empty string, empty array, or empty dictionary values. The function supports recursive removal of empty values.
 
    .PARAMETER Hashtable
    The hashtable from which empty values will be removed.
 
    .PARAMETER ExcludeParameter
    An array of keys to exclude from the removal process.
 
    .PARAMETER Recursive
    Indicates whether to recursively remove empty values from nested hashtables.
 
    .PARAMETER Rerun
    Specifies the number of times to rerun the removal process recursively.
 
    .PARAMETER DoNotRemoveNull
    If specified, null values will not be removed.
 
    .PARAMETER DoNotRemoveEmpty
    If specified, empty string values will not be removed.
 
    .PARAMETER DoNotRemoveEmptyArray
    If specified, empty array values will not be removed.
 
    .PARAMETER DoNotRemoveEmptyDictionary
    If specified, empty dictionary values will not be removed.
 
    .EXAMPLE
    $hashtable = @{
        'Key1' = '';
        'Key2' = $null;
        'Key3' = @();
        'Key4' = @{}
    }
    Remove-EmptyValue -Hashtable $hashtable -Recursive
 
    Description
    -----------
    This example removes empty values from the $hashtable recursively.
 
    #>

    [alias('Remove-EmptyValues')]
    [CmdletBinding()]
    param(
        [alias('Splat', 'IDictionary')][Parameter(Mandatory)][System.Collections.IDictionary] $Hashtable,
        [string[]] $ExcludeParameter,
        [switch] $Recursive,
        [int] $Rerun,
        [switch] $DoNotRemoveNull,
        [switch] $DoNotRemoveEmpty,
        [switch] $DoNotRemoveEmptyArray,
        [switch] $DoNotRemoveEmptyDictionary
    )
    foreach ($Key in [string[]] $Hashtable.Keys) {
        if ($Key -notin $ExcludeParameter) {
            if ($Recursive) {
                if ($Hashtable[$Key] -is [System.Collections.IDictionary]) {
                    if ($Hashtable[$Key].Count -eq 0) {
                        if (-not $DoNotRemoveEmptyDictionary) {
                            $Hashtable.Remove($Key)
                        }
                    }
                    else {
                        Remove-EmptyValue -Hashtable $Hashtable[$Key] -Recursive:$Recursive
                    }
                }
                else {
                    if (-not $DoNotRemoveNull -and $null -eq $Hashtable[$Key]) {
                        $Hashtable.Remove($Key)
                    }
                    elseif (-not $DoNotRemoveEmpty -and $Hashtable[$Key] -is [string] -and $Hashtable[$Key] -eq '') {
                        $Hashtable.Remove($Key)
                    }
                    elseif (-not $DoNotRemoveEmptyArray -and $Hashtable[$Key] -is [System.Collections.IList] -and $Hashtable[$Key].Count -eq 0) {
                        $Hashtable.Remove($Key)
                    }
                }
            }
            else {
                if (-not $DoNotRemoveNull -and $null -eq $Hashtable[$Key]) {
                    $Hashtable.Remove($Key)
                }
                elseif (-not $DoNotRemoveEmpty -and $Hashtable[$Key] -is [string] -and $Hashtable[$Key] -eq '') {
                    $Hashtable.Remove($Key)
                }
                elseif (-not $DoNotRemoveEmptyArray -and $Hashtable[$Key] -is [System.Collections.IList] -and $Hashtable[$Key].Count -eq 0) {
                    $Hashtable.Remove($Key)
                }
            }
        }
    }
    if ($Rerun) {
        for ($i = 0; $i -lt $Rerun; $i++) {
            Remove-EmptyValue -Hashtable $Hashtable -Recursive:$Recursive
        }
    }
}
function Join-Uri { 
    <#
    .SYNOPSIS
    Provides ability to join two Url paths together
 
    .DESCRIPTION
    Provides ability to join two Url paths together
 
    .PARAMETER BaseUri
    Primary Url to merge
 
    .PARAMETER RelativeOrAbsoluteUri
    Additional path to merge with primary url
 
    .EXAMPLE
    Join-Uri 'https://evotec.xyz/' '/wp-json/wp/v2/posts'
 
    .EXAMPLE
    Join-Uri 'https://evotec.xyz/' 'wp-json/wp/v2/posts'
 
    .EXAMPLE
    Join-Uri -BaseUri 'https://evotec.xyz/' -RelativeOrAbsoluteUri '/wp-json/wp/v2/posts'
 
    .EXAMPLE
    Join-Uri -BaseUri 'https://evotec.xyz/test/' -RelativeOrAbsoluteUri '/wp-json/wp/v2/posts'
 
    .NOTES
    General notes
    #>

    [alias('Join-Url')]
    [cmdletBinding()]
    param(
        [parameter(Mandatory)][uri] $BaseUri,
        [parameter(Mandatory)][uri] $RelativeOrAbsoluteUri
    )

    return ($BaseUri.OriginalString.TrimEnd('/') + "/" + $RelativeOrAbsoluteUri.OriginalString.TrimStart('/'))
}
function Invoke-WordpressRestApi {
    [cmdletBinding(SupportsShouldProcess)]
    param(
        [alias('PrimaryUri')][uri] $BaseUri,
        [alias('Uri')][uri] $RelativeOrAbsoluteUri,
        [System.Collections.IDictionary] $QueryParameter,
        [alias('Authorization')][System.Collections.IDictionary] $Headers,
        [validateset('GET', 'DELETE', 'POST', 'PATCH')][string] $Method = 'GET',
        [string] $ContentType = "application/json; charset=UTF-8",
        [System.Collections.IDictionary] $Body,
        [switch] $FullUri
    )

    if ($Authorization.Error) {
        Write-Warning "Invoke-WordpressRestApi - Authorization error. Skipping."
        return
    }
    $RestSplat = @{
        Headers     = $Headers
        Method      = $Method
        ContentType = $ContentType
        Body        = $Body | ConvertTo-Json -Depth 5
    }
    Remove-EmptyValue -Hashtable $RestSplat

    if ($FullUri) {
        $RestSplat.Uri = $PrimaryUri
    }
    else {
        $RestSplat.Uri = Join-UriQuery -QueryParameter $QueryParameter -BaseUri $BaseUri -RelativeOrAbsoluteUri $RelativeOrAbsoluteUri
    }
    $TempProgressPreference = $ProgressPreference
    $ProgressPreference = 'SilentlyContinue'
    if ($PSCmdlet.ShouldProcess("$($RestSplat.Uri)", "Invoking query with $Method")) {
        try {
            Write-Verbose -Message "Invoke-WordpressRestApi - Querying $($RestSplat.Uri) method $Method"
            if ($Method -eq 'GET') {
                if (-not ($QueryParameter.Contains('page'))) {
                    $AllResults = @()
                    $Page = 1
                    do {
                        $CurrentQuery = $QueryParameter + @{ page = $Page }
                        $RestSplat.Uri = Join-UriQuery -QueryParameter $CurrentQuery -BaseUri $BaseUri -RelativeOrAbsoluteUri $RelativeOrAbsoluteUri
                        $Response = Invoke-WebRequest @RestSplat -Verbose:$false
                        $Result = $Response.Content | ConvertFrom-Json
                        $AllResults += $Result
                        if (-not $TotalPages) {
                            $TotalPages = [int]$Response.Headers['X-WP-TotalPages']
                            #Write-Verbose "Invoke-WordpressRestApi - Total pages to retrieve: $TotalPages"
                        }
                        Write-Verbose "Invoke-WordpressRestApi - Querying $($RestSplat.Uri) method $Method [Retrieved page $Page of $TotalPages]"
                        $Page++
                    } while ($Page -le $TotalPages)
                    $ProgressPreference = $TempProgressPreference
                    return $AllResults
                }
                else {
                    $Response = Invoke-WebRequest @RestSplat -Verbose:$false
                    $ProgressPreference = $TempProgressPreference
                    $Result = $Response.Content | ConvertFrom-Json
                    return $Result
                }
            }
            else {
                $Response = Invoke-WebRequest @RestSplat -Verbose:$false
                $ProgressPreference = $TempProgressPreference
                $Result = [PSCustomObject]@{
                    Body    = $Response.Content | ConvertFrom-Json
                    Headers = $Response.Headers
                }
                if ($Method -eq 'GET' -or $Method -eq 'POST') {
                    return $Result
                }
                else {
                    return $true
                }
            }
        }
        catch {
            $RestError = $_.ErrorDetails.Message
            if ($RestError) {
                try {
                    $ErrorMessage = ConvertFrom-Json -InputObject $RestError
                    $ErrorMy = -join ('JSON Error:' , $ErrorMessage.error.code, ' ', $ErrorMessage.error.message, ' Additional Error: ', $_.Exception.Message)
                    Write-Warning $ErrorMy
                }
                catch {
                    Write-Warning $_.Exception.Message
                }
            }
            else {
                Write-Warning $_.Exception.Message
            }
            if ($Method -ne 'GET', 'POST') {
                return $false
            }
        }
    }
}
function Connect-Wordpress {
    [cmdletBinding(DefaultParameterSetName = 'Password')]
    param(
        [Parameter(ParameterSetName = 'ClearText')]
        [Parameter(ParameterSetName = 'EncryptedPassword')]
        [string] $UserName,
        [Parameter(ParameterSetName = 'ClearText')]
        [string] $Password,
        [Parameter(ParameterSetName = 'EncryptedPassword')]
        [string] $EncryptedPassword,

        [Parameter(ParameterSetName = 'EncryptedPassword')]
        [Parameter(ParameterSetName = 'ClearText')]
        [Parameter(ParameterSetName = 'Password')]
        [alias('Uri')][Uri] $Url,
        [Parameter(ParameterSetName = 'Password')]
        [pscredential] $Credential
    )
    if ($UserName -and $EncryptedPassword) {
        $UserNameApi = $UserName
        $TempPassword = ConvertTo-SecureString -String $EncryptedPassword
        $Credentials = [System.Management.Automation.PSCredential]::new($UserNameApi, $TempPassword)
        $PasswordApi = $Credentials.GetNetworkCredential().Password
    }
    elseif ($Username -and $Password) {
        $UserNameApi = $UserName
        $PasswordApi = $Password
    }
    elseif ($Credential) {
        $UserNameApi = $Credential.UserName
        $PasswordApi = $Credential.GetNetworkCredential().Password
    }
    $Authorization = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("$UserNameApi`:$PasswordApi")))
    $Auth = @{
        Header = @{
            Authorization = -join ("Basic ", $Authorization)
        }
        Url    = $Url
    }
    $Auth
}
function Get-WordPressCategory {
    [cmdletBinding(DefaultParameterSetName = 'List')]
    param(
        [Parameter(ParameterSetName = 'List', Mandatory)]
        [Parameter(ParameterSetName = 'Id', Mandatory)]
        [System.Collections.IDictionary] $Authorization,

        [Parameter(ParameterSetName = 'Id')][int[]] $Id,
        [Parameter(ParameterSetName = 'List')][int] $Page,
        [Parameter(ParameterSetName = 'List')][int] $RecordsPerPage,
        [Parameter(ParameterSetName = 'List')][string] $Search,
        [Parameter(ParameterSetName = 'List')][string] $Exclude,
        [Parameter(ParameterSetName = 'List')][string] $Include,
        [Parameter(ParameterSetName = 'List')][string] $Slug,
        [Parameter(ParameterSetName = 'List')][string] $Parent,
        [Parameter(ParameterSetName = 'List')][string] $Post,
        [Parameter(ParameterSetName = 'List')][ValidateSet('view', 'embed', 'edit')][string] $Context,
        [Parameter(ParameterSetName = 'List')][ValidateSet('asc', 'desc')][string] $Order,
        [Parameter(ParameterSetName = 'List')][ValidateSet('id', 'include', 'name', 'slug', 'include_slugs', 'term_group', 'description', 'count')][string] $OrderBy,
        [switch] $HideUnused
    )
    if ($Id) {
        foreach ($I in $Id) {
            Invoke-WordpressRestApi -PrimaryUri $Authorization.Url -Uri "wp-json/wp/v2/categories/$I" -Headers $Authorization.Header -QueryParameter @{}
        }
    }
    else {
        $QueryParameters = [ordered] @{
            context = $Context
            search  = $Search
            include = $Include
            exclude = $Exclude
            order   = $Order
            orderby = $OrderBy
            slug    = $Slug
            tags    = $Tags
            parent  = $Parent
            post    = $Post
        }
        if ($HideUnused) {
            $QueryParameters['hide_empty'] = $HideUnused.IsPresent
        }
        if ($Page) {
            $QueryParameters['page'] = $Page
        }
        if ($RecordsPerPage) {
            $QueryParameters['per_page'] = $RecordsPerPage
        }
        Remove-EmptyValue -Hashtable $QueryParameters
        Invoke-WordpressRestApi -PrimaryUri $Authorization.Url -Uri 'wp-json/wp/v2/categories' -QueryParameter $QueryParameters -Headers $Authorization.Header
    }
}
function Get-WordPressPage {
    [cmdletBinding(DefaultParameterSetName = 'List')]
    param(
        [Parameter(ParameterSetName = 'List', Mandatory)]
        [Parameter(ParameterSetName = 'Id', Mandatory)]
        [System.Collections.IDictionary] $Authorization,

        [Parameter(ParameterSetName = 'Id')][int] $Id,

        [Parameter(ParameterSetName = 'Id')]
        [Parameter(ParameterSetName = 'List')]
        [ValidateSet('edit', 'view')][string[]] $Context,
        [Parameter(ParameterSetName = 'List')][int] $Include,
        [Parameter(ParameterSetName = 'List')][int] $Exclude,
        [Parameter(ParameterSetName = 'List')][int] $Page,
        [Parameter(ParameterSetName = 'List')][int] $RecordsPerPage,
        [Parameter(ParameterSetName = 'List')][string] $Search,
        [Parameter(ParameterSetName = 'List')][string] $Author,
        [Parameter(ParameterSetName = 'List')][string] $ExcludeAuthor,
        [ValidateSet('publish', 'future', 'draft', 'pending', 'private')][Parameter(ParameterSetName = 'List')][string[]] $Status,
        [Parameter(ParameterSetName = 'List')][string] $Slug,
        [Parameter(ParameterSetName = 'List')][int[]] $Tags,
        [Parameter(ParameterSetName = 'List')][int[]] $ExcludeTags,
        [Parameter(ParameterSetName = 'List')][int[]] $Categories,
        [Parameter(ParameterSetName = 'List')][int[]] $ExcludeCategories,
        [Parameter(ParameterSetName = 'List')][ValidateSet('asc', 'desc')][string] $Order,
        [Parameter(ParameterSetName = 'List')][ValidateSet('author', 'date', 'id', 'include', 'modified', 'parent', 'relevance', 'slug', 'include_slugs', 'title')][string] $OrderBy
    )

    if ($Id) {
        Invoke-WordpressRestApi -PrimaryUri $Authorization.Url -Uri "wp-json/wp/v2/pages/$id" -Headers $Authorization.Header -QueryParameter @{}
    }
    else {
        $QueryParameters = [ordered] @{
            search         = $Search
            author         = $Author
            author_exclude = $ExcludeAuthor
            status         = $Status
            order          = $Order
            orderby        = $OrderBy
            slug           = $Slug
            context        = $Context
        }
        if ($Tags) {
            $QueryParameters['tags'] = $Tags
        }
        if ($Categories) {
            $QueryParameters['categories'] = $Categories
        }
        if ($ExcludeTags) {
            $QueryParameters['tags_exclude'] = $ExludeTags
        }
        if ($ExcludeCategories) {
            $QueryParameters['categories_exclude'] = $ExcludeCategories
        }
        if ($Include) {
            $QueryParameters['include'] = $Include
        }
        if ($Exclude) {
            $QueryParameters['exclude'] = $Exclude
        }
        if ($Page) {
            $QueryParameters['page'] = $Page
        }
        if ($RecordsPerPage) {
            $QueryParameters['per_page'] = $RecordsPerPage
        }
        Remove-EmptyValue -Hashtable $QueryParameters
        Invoke-WordpressRestApi -PrimaryUri $Authorization.Url -Uri 'wp-json/wp/v2/pages' -QueryParameter $QueryParameters -Headers $Authorization.Header
    }
}
function Get-WordPressPost {
    [cmdletBinding(DefaultParameterSetName = 'List')]
    param(
        [Parameter(ParameterSetName = 'List', Mandatory)]
        [Parameter(ParameterSetName = 'Id', Mandatory)]
        [System.Collections.IDictionary] $Authorization,

        [Parameter(ParameterSetName = 'Id')][int] $Id,

        [Parameter(ParameterSetName = 'Id')]
        [Parameter(ParameterSetName = 'List')]
        [ValidateSet('edit', 'view')][string[]] $Context,

        [Parameter(ParameterSetName = 'List')][int] $Include,
        [Parameter(ParameterSetName = 'List')][int] $Exclude,
        [Parameter(ParameterSetName = 'List')][int] $Page,
        [Parameter(ParameterSetName = 'List')][int] $RecordsPerPage,
        [Parameter(ParameterSetName = 'List')][string] $Search,
        [Parameter(ParameterSetName = 'List')][string] $Author,
        [Parameter(ParameterSetName = 'List')][string] $ExcludeAuthor,
        [ValidateSet('publish', 'future', 'draft', 'pending', 'private')][Parameter(ParameterSetName = 'List')][string[]] $Status,
        [Parameter(ParameterSetName = 'List')][string] $Slug,
        [Parameter(ParameterSetName = 'List')][int[]] $Tags,
        [Parameter(ParameterSetName = 'List')][int[]] $ExcludeTags,
        [Parameter(ParameterSetName = 'List')][int[]] $Categories,
        [Parameter(ParameterSetName = 'List')][int[]] $ExcludeCategories,
        [Parameter(ParameterSetName = 'List')][ValidateSet('asc', 'desc')][string] $Order,
        [Parameter(ParameterSetName = 'List')][ValidateSet('author', 'date', 'id', 'include', 'modified', 'parent', 'relevance', 'slug', 'include_slugs', 'title')][string] $OrderBy
    )

    if ($Id) {
        Invoke-WordpressRestApi -PrimaryUri $Authorization.Url -Uri "wp-json/wp/v2/posts/$id" -Headers $Authorization.Header -QueryParameter @{}
    }
    else {
        $QueryParameters = [ordered] @{
            search         = $Search
            author         = $Author
            author_exclude = $ExcludeAuthor
            status         = $Status
            order          = $Order
            orderby        = $OrderBy
            slug           = $Slug
            context        = $Context
        }
        if ($Tags) {
            $QueryParameters['tags'] = $Tags
        }
        if ($Categories) {
            $QueryParameters['categories'] = $Categories
        }
        if ($ExcludeTags) {
            $QueryParameters['tags_exclude'] = $ExludeTags
        }
        if ($ExcludeCategories) {
            $QueryParameters['categories_exclude'] = $ExcludeCategories
        }
        if ($Include) {
            $QueryParameters['include'] = $Include
        }
        if ($Exclude) {
            $QueryParameters['exclude'] = $Exclude
        }
        if ($Page) {
            $QueryParameters['page'] = $Page
        }
        if ($RecordsPerPage) {
            $QueryParameters['per_page'] = $RecordsPerPage
        }
        Remove-EmptyValue -Hashtable $QueryParameters
        Invoke-WordpressRestApi -PrimaryUri $Authorization.Url -Uri 'wp-json/wp/v2/posts' -QueryParameter $QueryParameters -Headers $Authorization.Header
    }
}
function Get-WordPressSetting {
    [cmdletBinding()]
    param(
        [Parameter(Mandatory)][System.Collections.IDictionary] $Authorization
    )
    $QueryParameters = [ordered] @{
    }
    Remove-EmptyValue -Hashtable $QueryParameters
    Invoke-WordpressRestApi -PrimaryUri $Authorization.Url -Uri 'wp-json/wp/v2/settings' -QueryParameter $QueryParameters -Headers $Authorization.Header
}
function Get-WordPressTag {
    [cmdletBinding(DefaultParameterSetName = 'List')]
    param(
        [Parameter(ParameterSetName = 'List', Mandatory)]
        [Parameter(ParameterSetName = 'Id', Mandatory)]
        [System.Collections.IDictionary] $Authorization,

        [Parameter(ParameterSetName = 'Id')][int[]] $Id,
        [Parameter(ParameterSetName = 'List')][int] $Page,
        [Parameter(ParameterSetName = 'List')][int] $RecordsPerPage,
        [Parameter(ParameterSetName = 'List')][string] $Search,
        [Parameter(ParameterSetName = 'List')][string] $Exclude,
        [Parameter(ParameterSetName = 'List')][string] $Include,
        [Parameter(ParameterSetName = 'List')][string] $Slug,
        [Parameter(ParameterSetName = 'List')][string] $Parent,
        [Parameter(ParameterSetName = 'List')][string] $Post,
        [Parameter(ParameterSetName = 'List')][ValidateSet('view', 'embed', 'edit')][string] $Context,
        [Parameter(ParameterSetName = 'List')][ValidateSet('asc', 'desc')][string] $Order,
        [Parameter(ParameterSetName = 'List')][ValidateSet('id', 'include', 'name', 'slug', 'include_slugs', 'term_group', 'description', 'count')][string] $OrderBy,
        [Parameter(ParameterSetName = 'List')][switch] $HideUnused
    )
    if ($Id) {
        foreach ($I in $Id) {
            Invoke-WordpressRestApi -PrimaryUri $Authorization.Url -Uri "wp-json/wp/v2/tags/$I" -Headers $Authorization.Header -QueryParameter @{}
        }
    }
    else {
        $QueryParameters = [ordered] @{
            context = $Context
            search  = $Search
            include = $Include
            exclude = $Exclude
            order   = $Order
            orderby = $OrderBy
            slug    = $Slug
            tags    = $Tags
            parent  = $Parent
            post    = $Post
        }
        if ($HideUnused) {
            $QueryParameters['hide_empty'] = $HideUnused.IsPresent
        }
        if ($Page) {
            $QueryParameters['page'] = $Page
        }
        if ($RecordsPerPage) {
            $QueryParameters['per_page'] = $RecordsPerPage
        }
        Remove-EmptyValue -Hashtable $QueryParameters
        Invoke-WordpressRestApi -PrimaryUri $Authorization.Url -Uri 'wp-json/wp/v2/tags' -QueryParameter $QueryParameters -Headers $Authorization.Header
    }
}
function New-WordPressPage {
    [cmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory)][System.Collections.IDictionary] $Authorization,
        [string] $Date,
        [string] $Slug,
        [ValidateSet('publish', 'future', 'draft', 'pending', 'private')][string] $Status,
        [string] $Title,
        [int] $Parent,
        [string] $Password,
        [string] $Content,
        [int] $Author,
        [string] $Excerpt,
        [int] $FeaturedMedia,
        [ValidateSet('open', 'closed')][string] $CommentStatus,
        [ValidateSet('open', 'closed')][string] $PingStatus,
        [string] $Meta,
        [string] $Template,
        [int] $MenuOrder
    )
    $QueryParameters = [ordered] @{
        title          = $Title
        date           = $Date
        slug           = $Slug
        status         = $Status
        password       = $Password
        #content = $Content
        excerpt        = $Excerpt
        comment_status = $CommentStatus
        ping_status    = $PingStatus
        meta           = $Meta
        template       = $Template
    }
    if ($Parent) {
        $QueryParameters['parent'] = $Parent
    }
    if ($FeaturedMedia) {
        $QueryParameters['featured_media'] = $FeaturedMedia
    }
    if ($Author) {
        $QueryParameters['author'] = $Author
    }
    if ($MenuOrder) {
        $QueryParameters['menu_order'] = $MenuOrder
    }
    $BodyParameters = [ordered] @{
        content = $Content
    }
    Remove-EmptyValue -Hashtable $BodyParameters
    Remove-EmptyValue -Hashtable $QueryParameters
    if ($QueryParameters.Keys.Count -gt 0 -or $BodyParameters.Keys.Count -gt 0) {
        $invokeWordpressRestApiSplat = @{
            PrimaryUri     = $Authorization.Url
            Uri            = 'wp-json/wp/v2/pages'
            QueryParameter = $QueryParameters
            Headers        = $Authorization.Header
            Method         = 'POST'
            Body           = $BodyParameters
        }

        Invoke-WordpressRestApi @invokeWordpressRestApiSplat
    }
    else {
        Write-Warning "New-WordPressPage - parameters not provided. Skipping."
    }
}
function New-WordPressPost {
    [cmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory)][System.Collections.IDictionary] $Authorization,
        [string] $Date,
        [string] $Slug,
        [ValidateSet('publish', 'future', 'draft', 'pending', 'private')][string] $Status,
        [string] $Title,
        [string] $Password,
        [string] $Content,
        [int] $Author,
        [string] $Excerpt,
        [int] $FeaturedMedia,
        [ValidateSet('open', 'closed')][string] $CommentStatus,
        [ValidateSet('open', 'closed')][string] $PingStatus,
        [ValidateSet('standard', 'aside', 'chat', 'gallery', 'link', 'image', 'quote', 'status', 'video', 'audio')][string] $Format,
        [string] $Meta,
        [nullable[bool]] $Sticky,
        [int[]] $Tags,
        [int[]] $Categories

    )
    $QueryParameters = [ordered] @{
        title          = $Title
        date           = $Date
        slug           = $Slug
        status         = $Status
        password       = $Password
        #content = $Content
        excerpt        = $Excerpt
        comment_status = $CommentStatus
        ping_status    = $PingStatus
        format         = $Format
        meta           = $Meta
    }

    if ($Tags) {
        $QueryParameters['tags'] = $Tags
    }
    if ($Categories) {
        $QueryParameters['categories'] = $Categories
    }
    if ($FeaturedMedia) {
        $QueryParameters['featured_media'] = $FeaturedMedia
    }
    if ($Author) {
        $QueryParameters['author'] = $Author
    }
    $BodyParameters = [ordered] @{
        content = $Content
    }
    Remove-EmptyValue -Hashtable $BodyParameters
    Remove-EmptyValue -Hashtable $QueryParameters
    if ($QueryParameters.Keys.Count -gt 0 -or $BodyParameters.Keys.Count -gt 0) {
        $invokeWordpressRestApiSplat = @{
            PrimaryUri     = $Authorization.Url
            Uri            = 'wp-json/wp/v2/posts'
            QueryParameter = $QueryParameters
            Headers        = $Authorization.Header
            Method         = 'POST'
            Body           = $BodyParameters
        }

        Invoke-WordpressRestApi @invokeWordpressRestApiSplat
    }
    else {
        Write-Warning "New-WordPressPost - parameters not provided. Skipping."
    }
}
function Remove-WordPressPage {
    [cmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory)][System.Collections.IDictionary] $Authorization,
        [Parameter(Mandatory)][int] $Id,
        [switch] $Force
    )
    $QueryParameters = [ordered] @{}
    if ($Force) {
        $QueryParameters['force'] = $Force.IsPresent
    }
    Invoke-WordpressRestApi -PrimaryUri $Authorization.Url -Uri "wp-json/wp/v2/pages/$Id" -QueryParameter $QueryParameters -Headers $Authorization.Header -Method DELETE
}
function Remove-WordPressPost {
    [cmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory)][System.Collections.IDictionary] $Authorization,
        [Parameter(Mandatory)][int] $Id,
        [switch] $Force
    )
    $QueryParameters = [ordered] @{}
    if ($Force) {
        $QueryParameters['force'] = $Force.IsPresent
    }
    Invoke-WordpressRestApi -PrimaryUri $Authorization.Url -Uri "wp-json/wp/v2/posts/$Id" -QueryParameter $QueryParameters -Headers $Authorization.Header -Method DELETE
}
function Set-WordPressPage {
    [cmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory)][System.Collections.IDictionary] $Authorization,
        [Parameter(Mandatory)][int] $Id,
        [string] $Date,
        [string] $Slug,
        [ValidateSet('publish', 'future', 'draft', 'pending', 'private')][string] $Status,
        [string] $Title,
        [int] $Parent,
        [string] $Password,
        [string] $Content,
        [int] $Author,
        [string] $Excerpt,
        [int] $FeaturedMedia,
        [ValidateSet('open', 'closed')][string] $CommentStatus,
        [ValidateSet('open', 'closed')][string] $PingStatus,
        [string] $Meta,
        [string] $Template,
        [int] $MenuOrder
    )
    $QueryParameters = [ordered] @{
        title          = $Title
        date           = $Date
        slug           = $Slug
        status         = $Status
        password       = $Password
        #content = $Content
        excerpt        = $Excerpt
        comment_status = $CommentStatus
        ping_status    = $PingStatus
        meta           = $Meta
        template       = $Template
    }
    $BodyParameters = [ordered] @{
        content = $Content
    }
    Remove-EmptyValue -Hashtable $BodyParameters
    if ($Parent) {
        $QueryParameters['parent'] = $Parent
    }
    if ($FeaturedMedia) {
        $QueryParameters['featured_media'] = $FeaturedMedia
    }
    if ($Author) {
        $QueryParameters['author'] = $Author
    }
    if ($MenuOrder) {
        $QueryParameters['menu_order'] = $MenuOrder
    }
    Remove-EmptyValue -Hashtable $QueryParameters
    if ($QueryParameters.Keys.Count -gt 0 -or $BodyParameters.Keys.Count -gt 0) {
        $invokeWordpressRestApiSplat = @{
            PrimaryUri     = $Authorization.Url
            Uri            = "wp-json/wp/v2/pages/$Id"
            QueryParameter = $QueryParameters
            Headers        = $Authorization.Header
            Method         = 'POST'
            Body           = $BodyParameters
        }

        Invoke-WordpressRestApi @invokeWordpressRestApiSplat
    }
    else {
        Write-Warning "Set-WordPressPage - parameters not provided. Skipping."
    }
}
function Set-WordPressPost {
    [cmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory)][System.Collections.IDictionary] $Authorization,
        [Parameter(Mandatory)][int] $Id,
        [string] $Date,
        [string] $Slug,
        [ValidateSet('publish', 'future', 'draft', 'pending', 'private')][string] $Status,
        [string] $Title,
        [string] $Password,
        [string] $Content,
        [int] $Author,
        [string] $Excerpt,
        [int] $FeaturedMedia,
        [ValidateSet('open', 'closed')][string] $CommentStatus,
        [ValidateSet('open', 'closed')][string] $PingStatus,
        [ValidateSet('standard', 'aside', 'chat', 'gallery', 'link', 'image', 'quote', 'status', 'video', 'audio')][string] $Format,
        [string] $Meta,
        [nullable[bool]] $Sticky,
        [int[]] $Tags,
        [int[]] $Categories

    )
    $QueryParameters = [ordered] @{
        title          = $Title
        date           = $Date
        slug           = $Slug
        status         = $Status
        password       = $Password
        #content = $Content
        excerpt        = $Excerpt
        comment_status = $CommentStatus
        ping_status    = $PingStatus
        format         = $Format
        meta           = $Meta
    }
    $BodyParameters = [ordered] @{
        content = $Content
    }
    Remove-EmptyValue -Hashtable $BodyParameters
    if ($Tags) {
        $QueryParameters['tags'] = $Tags
    }
    if ($Categories) {
        $QueryParameters['categories'] = $Categories
    }
    if ($FeaturedMedia) {
        $QueryParameters['featured_media'] = $FeaturedMedia
    }
    if ($Author) {
        $QueryParameters['author'] = $Author
    }
    Remove-EmptyValue -Hashtable $QueryParameters
    if ($QueryParameters.Keys.Count -gt 0 -or $BodyParameters.Keys.Count -gt 0) {
        $invokeWordpressRestApiSplat = @{
            PrimaryUri     = $Authorization.Url
            Uri            = "wp-json/wp/v2/posts/$Id"
            Body           = $BodyParameters
            Headers        = $Authorization.Header
            Method         = 'POST'
            QueryParameter = $QueryParameters
        }

        Invoke-WordpressRestApi @invokeWordpressRestApiSplat
    }
    else {
        Write-Warning "Set-WordPressPost - parameters not provided. Skipping."
    }
}
function Set-WordPressSetting {
    [cmdletBinding(SupportsShouldProcess)]
    param(
        [Parameter(Mandatory)][System.Collections.IDictionary] $Authorization,
        [string] $Title,
        [string] $Description,
        [string] $Url,
        [string] $Email,
        [string] $TimeZone,
        [string] $DateFormat,
        [string] $TimeFormat,
        [string] $StartOfWeek,
        [string] $Language,
        [int] $PostsPerPage,
        [int] $DefaultCategory,
        [int] $DefaultPostFormat,
        [nullable[bool]] $UseSmiles,
        [ValidateSet('open', 'closed')][string] $DefaultPingStatus,
        [ValidateSet('open', 'closed')][string] $DefaultCommentStatus
    )
    $QueryParameters = [ordered] @{
        title                  = $Title
        description            = $Description
        url                    = $Url
        email                  = $Email
        timezone               = $TimeZone
        date_format            = $DateFormat
        time_format            = $TimeFormat
        start_of_week          = $StartOfWeek
        language               = $Language
        default_comment_status = $DefaultPingStatus
        default_ping_status    = $DefaultCommentStatus
    }
    if ($null -ne $UseSmiles) {
        $QueryParameters['use_smiles'] = $UseSmiles
    }
    if ($DefaultCategory) {
        $QueryParameters['posts_per_page'] = $PostsPerPage
    }
    if ($PostsPerPage) {
        $QueryParameters['default_category'] = $DefaultCategory
    }
    if ($DefaultPostFormat) {
        $QueryParameters['default_post_format'] = $DefaultPostFormat
    }
    Remove-EmptyValue -Hashtable $QueryParameters
    if ($QueryParameters.Keys.Count -gt 0) {
        Invoke-WordpressRestApi -PrimaryUri $Authorization.Url -Uri 'wp-json/wp/v2/settings' -QueryParameter $QueryParameters -Headers $Authorization.Header -Method POST
    }
    else {
        Write-Warning "Set-WordPressSetting - parameters not provided. Skipping."
    }
}


# Export functions and aliases as required
Export-ModuleMember -Function @('Connect-Wordpress', 'Get-WordPressCategory', 'Get-WordPressPage', 'Get-WordPressPost', 'Get-WordPressSetting', 'Get-WordPressTag', 'New-WordPressPage', 'New-WordPressPost', 'Remove-WordPressPage', 'Remove-WordPressPost', 'Set-WordPressPage', 'Set-WordPressPost', 'Set-WordPressSetting') -Alias @()