ZabbixPS.psm1

$Script:PSModuleRoot = $PSScriptRoot
$Script:ModuleName = "ZabbixPS"
$Script:AppDataPath = [Environment]::GetFolderPath('ApplicationData')
$Script:ModuleDataRoot = (Join-Path -Path $Script:AppDataPath -ChildPath $Script:ModuleName)
$Script:ZabbixModuleDataPath = (Join-Path -Path $Script:ModuleDataRoot -ChildPath "ModuleData.json")
if (-not (Test-Path $Script:ModuleDataRoot)) {New-Item -ItemType Directory -Path $Script:ModuleDataRoot -Force}
# Imported from [D:\a\1\s\ZabbixPS\Private]
# New-ZBXRestBody.ps1
function New-ZBXRestBody
{
    <#
    .SYNOPSIS
 
    Returns the correct API body for a Zabbix API call.
 
    .DESCRIPTION
 
    Intended as an internal function for returning the body of an API call where the params may change
 
    .PARAMETER Method
 
    The Zabbix API method used in the call
 
    .PARAMETER ApiVersion
 
    Specifies the API Version being used
 
    .PARAMETER Param
 
    A hashtable of Zabbix specific filters for the specific method
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    Hashtable. RestMethod Body.
 
    .EXAMPLE
 
    Dynamically generates the body for an API call.
 
    New-ZBXRestBody -Method 'event.problem' -API $ApiVersion -Params $params
 
    #>

    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Method,

        [Parameter(Mandatory)]
        [string]
        $ApiVersion,

        [Parameter(Mandatory)]
        [hashtable]
        $Params

    )

    process
    {
        #todo create some validation for the params
        #to make sure they match the methods for the Zabbix API
        $body = @{
            method  = $Method
            jsonrpc = $ApiVersion
            id      = 1

            params  = $Params
        }

        $body
    }

}
# Imported from [D:\a\1\s\ZabbixPS\Public]
# Confirm-ZBXEvent.ps1
function Confirm-ZBXEvent
{
    <#
    .SYNOPSIS
 
    Changes the status of an Event
 
    .DESCRIPTION
 
    Changes the acknowledgement of an Event
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER EventId
 
    IDs of the events to acknowledge.
 
    .PARAMETER Action
 
    Event update action(s). This is bitmask field (under the hood), any combination of text values is acceptable.
 
    Possible values:
    1 - close problem;
    2 - acknowledge event;
    4 - add message;
    8 - change severity.
 
    .PARAMETER Message
 
    Text of the message.
    Required, if action contains 'add message' flag.
 
    .PARAMETER Severity
 
    New severity for events.
    Required, if action contains 'change severity' flag.
 
    Possible values:
    0 - notclassified;
    1 - information;
    2 - warning;
    3 - average;
    4 - high;
    5 - disaster.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject.
 
 
    .EXAMPLE
 
    Acknowledges a event.
 
    Confirm-ZBXEvent TBD
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/event/get
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter(Mandatory)]
        [Alias('eventids')]
        [string[]]
        $EventId,

        [Parameter(Mandatory)]
        [Alias('action')]
        [ValidateSet('CloseProblem','Acknowledge','AddMessage','ChangeSeverity')]
        [string[]]
        $AcknowledgeAction,

        [Parameter()]
        [Alias('message')]
        [string]
        $AcknowledgeMessage,

        [Parameter()]
        [Alias('severity')]
        [ValidateSet('NotClassified','Information','Warning','Average','High','Disaster')]
        [string]
        $NewSeverity
    )

    begin
    {
        if ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession)
            {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }
        $ActionValues = @{
            'CloseProblem'   = 1
            'Acknowledge'    = 2
            'AddMessage'     = 4
            'ChangeSeverity' = 8
        }
        $SeverityValues = @{
            'NotClassified' = 0
            'Information'   = 1
            'Warning'       = 2
            'Average'       = 3
            'High'          = 4
            'Disaster'      = 5
        }
        $SessionParameters = @('Uri','Credential','Proxy','ProxyCredential','Session')
        $CommonParameters = $(([System.Management.Automation.PSCmdlet]::CommonParameters,[System.Management.Automation.PSCmdlet]::OptionalCommonParameters) | ForEach-Object {$PSItem})
    }

    process
    {

        $params  = @{}

        #Dynamically adds any bound parameters that are used for the conditions
        foreach ($Parameter in $PSBoundParameters.GetEnumerator()) {
            if ($Parameter.key -notin $SessionParameters -and $Parameter.key -notin $CommonParameters) {
                #uses the hardcoded Alias of the parameter as the API friendly param
                $apiParam = $MyInvocation.MyCommand.Parameters[$Parameter.key].Aliases[0]
                switch ($apiParam) {
                    'action'   { [int]$total = 0
                                 foreach ($value in $parameter.Value) {
                                    $total = $total + [int]$ActionValues[$value]
                                 }
                                 $apiValue = $total
                                 break
                               }
                    'severity' { $apiValue = $SeverityValues[$Parameter.Value]; break }
                    default    { $apiValue = $Parameter.Value }
                }

                $params[$apiParam] = $apiValue

            }
        }

        $body = New-ZBXRestBody -Method 'event.acknowledge' -API $ApiVersion -Params $params


        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy)
        {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

}
# Format-ZBXTags.ps1
function Format-ZBXTags
{
    <#
    .SYNOPSIS
 
    Formats an array of tags.
 
    .DESCRIPTION
 
    Formats an array of tags.
 
    .PARAMETER Tags
 
    A comma sperated list of tags.
    'Key1:Value1', 'Key2:Value2'
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject, formatted Zabbix tags.
 
    .EXAMPLE
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    Param
    (
        [Parameter(Mandatory)]
        [string[]]
        $Tags
    )

    begin
    {

    }

    process
    {
        $formattedTags = Foreach ($tag in $Tags)
        {
            $split = $tag.split(':')
            @{
                tag      = $split[0]
                operator = 0
                value    = $split[-1]
            }
        }
        return $formattedTags
    }

    end
    {
    }
}
# Get-ZBXAction.ps1
function Get-ZBXAction
{
    <#
    .SYNOPSIS
 
    Returns a Zabbix action.
 
    .DESCRIPTION
 
    Returns a Zabbix action.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER ActionId
 
    Return only actions with the given IDs.
 
    .PARAMETER GroupId
 
    Return only actions that use the given host groups in action conditions.
 
    .PARAMETER HostId
 
    Return only actions that use the given hosts in action conditions.
 
    .PARAMETER TriggerId
 
    Return only actions that use the given triggers in action conditions.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix action.
 
    .EXAMPLE
 
    Returns all Zabbix actions.
 
    Get-ZBXAction
 
    .EXAMPLE
 
    Returns Zabbix Action with the Action name of 'myAction'.
 
    Get-ZBXAction -Name 'myAction'
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/action/get
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    [Alias("gzac")]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter()]
        [string[]]
        $ActionId,

        [Parameter()]
        [string[]]
        $GroupId,

        [Parameter()]
        [string[]]
        $HostId,

        [Parameter()]
        [string[]]
        $TriggerId
    )

    begin
    {
        if ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession)
            {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }
    }

    process
    {
        $body = @{
            method  = 'action.get'
            jsonrpc = $ApiVersion
            id      = 1

            params  = @{
                output                   = 'extend'
                selectOperations         = 'extend'
                selectRecoveryOperations = 'extend'
                selectFilter             = 'extend'
            }
        }
        if ($ActionId)
        {
            $body.params.actionids = $ActionId
        }
        if ($GroupId)
        {
            $body.params.groupids = $GroupId
        }
        if ($HostId)
        {
            $body.params.hostids = $HostId
        }
        if ($TriggerId)
        {
            $body.params.triggerids = $TriggerId
        }
        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy)
        {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        return Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

    end
    {
    }
}
# Get-ZBXAlert.ps1
function Get-ZBXAlert
{
    <#
    .SYNOPSIS
 
    Returns a Zabbix alert.
 
    .DESCRIPTION
 
    Returns a Zabbix alert.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER AlertId
 
    Return only alerts with the given IDs.
 
    .PARAMETER ActionId
 
    Return only alerts generated by the given actions.
 
    .PARAMETER EventId
 
    Return only alerts generated by the given events.
 
    .PARAMETER GroupId
 
    Return only alerts that use the given host groups in alert conditions.
 
    .PARAMETER HostId
 
    Return only alerts that use the given hosts in alert conditions.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix alert.
 
    .EXAMPLE
 
    Returns all Zabbix alerts.
 
    Get-ZBXAlert
 
    .EXAMPLE
 
    Returns Zabbix Alert with the Alert name of 'myAlert'.
 
    Get-ZBXAlert -Name 'myAlert'
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/alert/get
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    [Alias("gzal")]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter()]
        [string[]]
        $AlertId,

        [Parameter()]
        [string[]]
        $ActionId,

        [Parameter()]
        [string[]]
        $EventId,

        [Parameter()]
        [string[]]
        $GroupId,

        [Parameter()]
        [string[]]
        $HostId
    )

    begin
    {
        if ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession)
            {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }
    }

    process
    {
        $body = @{
            method  = 'alert.get'
            jsonrpc = $ApiVersion
            id      = 1

            params  = @{
                output                   = 'extend'
            }
        }
        if ($AlertId)
        {
            $body.params.alertids = $AlertId
        }
        if ($ActionId)
        {
            $body.params.actionids = $ActionId
        }
        if ($EventId)
        {
            $body.params.eventids = $EventId
        }
        if ($GroupId)
        {
            $body.params.groupids = $GroupId
        }
        if ($HostId)
        {
            $body.params.hostids = $HostId
        }
        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy)
        {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        return Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

    end
    {
    }
}
# Get-ZBXApplication.ps1
function Get-ZBXApplication
{
    <#
    .SYNOPSIS
 
    Returns a Zabbix application.
 
    .DESCRIPTION
 
    Returns a Zabbix application.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER ApplicationId
 
    Return only applications with the given IDs.
 
    .PARAMETER GroupId
 
    Return only applications that use the given host groups in application conditions.
 
    .PARAMETER HostId
 
    Return only applications that use the given hosts in application conditions.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix application.
 
    .EXAMPLE
 
    Returns all Zabbix applications.
 
    Get-ZBXApplication
 
    .EXAMPLE
 
    Returns Zabbix Application with the Application name of 'myApplication'.
 
    Get-ZBXApplication -Name 'myApplication'
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/application/get
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    [Alias("gzapp")]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter()]
        [string[]]
        $ApplicationId,

        [Parameter()]
        [string[]]
        $GroupId,

        [Parameter()]
        [string[]]
        $HostId
    )

    begin
    {
        if ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession)
            {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }
    }

    process
    {
        $body = @{
            method  = 'application.get'
            jsonrpc = $ApiVersion
            id      = 1

            params  = @{
                output                   = 'extend'
            }
        }
        if ($ApplicationId)
        {
            $body.params.applicationids = $ApplicationId
        }
        if ($GroupId)
        {
            $body.params.groupids = $GroupId
        }
        if ($HostId)
        {
            $body.params.hostids = $HostId
        }
        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy)
        {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        return Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

    end
    {
    }
}
# Get-ZBXEvent.ps1
function Get-ZBXEvent
{
    <#
    .SYNOPSIS
 
    Returns a Zabbix event.
 
    .DESCRIPTION
 
    Returns a Zabbix event.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER EventId
 
    Return only events with the given IDs.
 
    .PARAMETER GroupId
 
    Return only events that use the given host groups in event conditions.
 
    .PARAMETER HostId
 
    Return only events that use the given hosts in event conditions.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix event.
 
    .EXAMPLE
 
    Returns all Zabbix events.
 
    Get-ZBXEvent
 
    .EXAMPLE
 
    Returns Zabbix Event with the Event name of 'myEvent'.
 
    Get-ZBXEvent -Name 'myEvent'
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/event/get
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    [Alias("gze")]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter()]
        [string[]]
        $EventId,

        [Parameter()]
        [string[]]
        $GroupId,

        [Parameter()]
        [string[]]
        $HostId
    )

    begin
    {
        if ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession)
            {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }
    }

    process
    {
        $body = @{
            method  = 'event.get'
            jsonrpc = $ApiVersion
            id      = 1

            params  = @{
                output                = 'extend'
                select_acknowledges   = 'extend'
                selectTags            = 'extend'
                selectSuppressionData = 'extend'
                selectHosts           = 'extend'
            }
        }
        if ($EventId)
        {
            $body.params.eventids = $EventId
        }
        if ($GroupId)
        {
            $body.params.groupids = $GroupId
        }
        if ($HostId)
        {
            $body.params.hostids = $HostId
        }
        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy)
        {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        return Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

    end
    {
    }
}
# Get-ZBXGraph.ps1
function Get-ZBXGraph
{
    <#
    .SYNOPSIS
 
    Returns a Zabbix graph.
 
    .DESCRIPTION
 
    Returns a Zabbix graph.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER GraphId
 
    Return only graphs with the given IDs.
 
    .PARAMETER GroupId
 
    Return only graphs that use the given host groups in graph conditions.
 
    .PARAMETER HostId
 
    Return only graphs that use the given hosts in graph conditions.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix graph.
 
    .EXAMPLE
 
    Returns all Zabbix graphs.
 
    Get-ZBXGraph
 
    .EXAMPLE
 
    Returns Zabbix Graph with the Graph name of 'myGraph'.
 
    Get-ZBXGraph -Name 'myGraph'
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/graph/get
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    [Alias("gzgph")]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter()]
        [string[]]
        $GraphId,

        [Parameter()]
        [string[]]
        $GroupId,

        [Parameter()]
        [string[]]
        $HostId
    )

    begin
    {
        if ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession)
            {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }
    }

    process
    {
        $body = @{
            method  = 'graph.get'
            jsonrpc = $ApiVersion
            id      = 1

            params  = @{
                output                   = 'extend'
            }
        }
        if ($GraphId)
        {
            $body.params.graphids = $GraphId
        }
        if ($GroupId)
        {
            $body.params.groupids = $GroupId
        }
        if ($HostId)
        {
            $body.params.hostids = $HostId
        }
        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy)
        {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        return Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

    end
    {
    }
}
# Get-ZBXHistory.ps1
function Get-ZBXHistory
{
    <#
    .SYNOPSIS
 
    Returns a Zabbix history.
 
    .DESCRIPTION
 
    Returns a Zabbix history.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER History
 
    History object types to return.
    0 - numeric float;
    1 - character;
    2 - log;
    3 - numeric unsigned;
    4 - text.
 
    Default: 3.
 
    .PARAMETER GroupId
 
    Return only historys that use the given host groups in history conditions.
 
    .PARAMETER ItemId
 
    Return only history from the given items.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix history.
 
    .EXAMPLE
 
    Returns all Zabbix historys.
 
    Get-ZBXHistory
 
    .EXAMPLE
 
    Returns Zabbix History with the History name of 'myHistory'.
 
    Get-ZBXHistory -Name 'myHistory'
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/history/get
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    [Alias("gzhist")]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter()]
        [ValidateSet(0, 1, 2, 3, 4)]
        [int]
        $History = 3,

        [Parameter()]
        [string[]]
        $GroupId,

        [Parameter()]
        [string[]]
        $ItemId
    )

    begin
    {
        if ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession)
            {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }
    }

    process
    {
        $body = @{
            method  = 'history.get'
            jsonrpc = $ApiVersion
            id      = 1

            params  = @{
                output  = 'extend'
                history = $History
            }
        }
        if ($GroupId)
        {
            $body.params.groupids = $GroupId
        }
        if ($ItemId)
        {
            $body.params.itemids = $ItemId
        }
        $invokeZabbixRestMethodSplat = @{
            Body         = $body
            Uri          = $Uri
            Credential   = $Credential
            ApiVersion   = $ApiVersion
            ErrorAction  = 'Stop'
        }
        if ($Proxy)
        {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        return Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

    end
    {
    }
}
# Get-ZBXHost.ps1
function Get-ZBXHost
{
    <#
    .SYNOPSIS
 
    Returns a Zabbix host.
 
    .DESCRIPTION
 
    Returns a Zabbix host.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER Name
 
    The name of the host.
 
    .PARAMETER HostId
 
    Return only hosts with the given IDs.
 
    .PARAMETER GroupId
 
    Return only hosts that use the given host groups in host conditions.
 
    .PARAMETER ApplicationId
 
    Return only hosts that have the given applications.
 
    .PARAMETER DserviceId
 
    Return only hosts that are related to the given discovered services.
 
    .PARAMETER GraphId
 
    Return only hosts that have the given graphs.
 
    .PARAMETER InterfaceId
 
    Return only hosts that use the given interfaces.
 
    .PARAMETER ItemId
 
    Return only hosts that have the given items.
 
    .PARAMETER MaintenanceId
 
    Return only hosts that are affected by the given maintenances.
 
    .PARAMETER TemplateId
 
    Return only hosts that are linked to the given templates.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix host.
 
    .EXAMPLE
 
    Returns all Zabbix hosts.
 
    Get-ZBXHost
 
    .EXAMPLE
 
    Returns Zabbix Host with the Host name of 'myHost'.
 
    Get-ZBXHost -Name 'myHost'
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/host/get
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter()]
        [string[]]
        $Name,

        [Parameter()]
        [string[]]
        $HostId,

        [Parameter()]
        [string[]]
        $GroupId,

        [Parameter()]
        [string[]]
        $ApplicationId,

        [Parameter()]
        [string[]]
        $DserviceId,

        [Parameter()]
        [string[]]
        $GraphId,

        [Parameter()]
        [string[]]
        $InterfaceId,

        [Parameter()]
        [string[]]
        $ItemId,

        [Parameter()]
        [string[]]
        $MaintenanceId,

        [Parameter()]
        [string[]]
        $TemplateId
    )

    begin
    {
        if ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession)
            {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }
    }

    process
    {
        $body = @{
            method  = 'host.get'
            jsonrpc = $ApiVersion
            id      = 1
            sortfield = 'name'
            params  = @{
                output                   = 'extend'
                selectParentTemplates = @(
                    "templateid",
                    "name"
                )
                selectInterfaces = @(
                    "interfaceid",
                    "ip",
                    "port"
                )
                selectHttpTests = @(
                    "httptestid",
                    "name",
                    "steps"
                )
                selectTriggers = @(
                    "triggerid",
                    "description"
                )
                selectApplications = @(
                    "applicationid"
                    "name"
                )
                selectGraphs = @(
                    "graphid"
                    "name"
                )
                selectMacros = @(
                    "hostmacroid"
                    "macro"
                    "value"
                )
                selectScreens = @(
                    "screenid"
                    "name"
                )
                selectInventory = @(
                    "name"
                    "type"
                    "os"
                )
            }
        }
        if ($Name)
        {
            $body.params.filter = @{
                host = $Name
            }
        }
        if ($HostId)
        {
            $body.params.hostids = $HostId
        }
        if ($GroupId)
        {
            $body.params.groupids = $GroupId
        }
        if ($ApplicationId)
        {
            $body.params.applicationids = $ApplicationId
        }
        if ($DserviceId)
        {
            $body.params.dserviceids = $DserviceId
        }
        if ($GraphId)
        {
            $body.params.graphids = $GraphId
        }
        if ($InterfaceId)
        {
            $body.params.interfaceids = $InterfaceId
        }
        if ($ItemId)
        {
            $body.params.itemids = $ItemId
        }
        if ($MaintenanceId)
        {
            $body.params.maintenanceids = $MaintenanceId
        }
        if ($TemplateId)
        {
            $body.params.templateids = $TemplateId
        }
        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy)
        {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        return Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

    end
    {
    }
}
# Get-ZBXHostGroup.ps1
function Get-ZBXHostGroup
{
    <#
    .SYNOPSIS
 
    Returns a Zabbix host group.
 
    .DESCRIPTION
 
    Returns a Zabbix host group.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER Name
 
    The name of the group.
 
    .PARAMETER GroupId
 
    Return only host group that use the given host groups in hostgroup conditions.
 
    .PARAMETER MaintenanceId
 
    Return only host groups that are affected by the given maintenances.
 
    .PARAMETER TemplateId
 
    Return only host groups that contain the given templates.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix hostgroup.
 
    .EXAMPLE
 
    Returns all Zabbix host group.
 
    Get-ZBXHostGroup
 
    .EXAMPLE
 
    Returns Zabbix HostGroup with the HostGroup name of 'myHostGroup'.
 
    Get-ZBXHostGroup -Name 'myHostGroup'
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/hostgroup/get
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    [Alias("gzhg", "Get-ZBXGroup")]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter()]
        [string[]]
        $Name,

        [Parameter()]
        [string[]]
        $GroupId,

        [Parameter()]
        [string[]]
        $HostId,

        [Parameter()]
        [string[]]
        $MaintenanceId,

        [Parameter()]
        [string[]]
        $TemplateId
    )

    begin
    {
        if ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession)
            {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }
    }

    process
    {
        $body = @{
            method  = 'hostgroup.get'
            jsonrpc = $ApiVersion
            id      = 1

            params  = @{
                output          = 'extend'
                selectHosts     = @(
                    "hostid",
                    "host"
                )
                selectTemplates = @(
                    "templateid",
                    "name"
                )
            }
        }
        if ($Name)
        {
            $body.params.filter = @{
                name = $Name
            }
        }
        if ($GroupId)
        {
            $body.params.groupids = $GroupId
        }
        if ($HostId)
        {
            $body.params.hostids = $HostId
        }
        if ($MaintenanceId)
        {
            $body.params.maintenanceids = $MaintenanceId
        }
        if ($TemplateId)
        {
            $body.params.templateids = $TemplateId
        }
        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy)
        {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        return Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

    end
    {
    }
}
# Get-ZBXMaintenance.ps1
function Get-ZBXMaintenance
{
    <#
    .SYNOPSIS
 
    Gets a Zabbix maintenance period.
 
    .DESCRIPTION
 
    Gets a Zabbix maintenance period.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER Name
 
    The maintenance name.
 
    .PARAMETER Id
 
    The maintenance id.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    None, does not support output.
 
    .EXAMPLE
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/maintenance/delete
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    [Alias("gzm")]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter()]
        [string]
        $Name,

        [Parameter()]
        [string]
        $Id
    )

    begin
    {
        if ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession)
            {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }
    }

    process
    {
        $body = @{
            method  = 'maintenance.get'
            jsonrpc = $ApiVersion
            id      = 1

            params  = @{
                output            = "extend"
                selectGroups      = "extend"
                selectHosts       = "extend"
                selectTimeperiods = "extend"
            }
        }
        if ($Name)
        {
            $body.params.filter = @{
                name = $Name
            }
        }
        if ($Id)
        {
            $body.params.maintenanceids = $Id
        }
        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy)
        {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        return Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

    end
    {
    }
}
# Get-ZBXProblem.ps1
function Get-ZBXProblem
{
    <#
    .SYNOPSIS
 
    Returns a Zabbix Problem.
 
    .DESCRIPTION
 
    Returns a Zabbix Problem.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER EventId
 
    Return only problems with the given IDs.
 
    .PARAMETER GroupId
 
    Return only problems that use the given host groups in problems conditions.
 
    .PARAMETER HostId
 
    Return only problems that use the given hosts in problems conditions.
 
    .PARAMETER ObjectId
 
    Return only problems that have the given ObjectId in problems conditions.
 
    .PARAMETER ApplicationId
 
    Return only problems that have the given ApplicationId in problems conditions.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix problems.
 
    .EXAMPLE
 
    Returns all Zabbix Problems.
 
    Get-ZBXProblem
 
    .EXAMPLE
 
    Returns Zabbix Problem from the HostID 10084.
 
    Get-ZBXProblem -Session $Session -HostId 10084
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/event/get
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter()]
        [Alias('eventids')]
        [string[]]
        $EventId,

        [Parameter()]
        [Alias('groupids')]
        [string[]]
        $GroupId,

        [Parameter()]
        [Alias('hostids')]
        [string[]]
        $HostId,

        [Parameter()]
        [Alias('objectids')]
        [string[]]
        $ObjectId,

        [Parameter()]
        [Alias('applicationids')]
        [string[]]
        $ApplicationId,

        [Parameter()]
        [Alias('acknowledged')]
        [ValidateSet('true','false')]
        [string]
        $AcknowledgedProblem,

        [Parameter()]
        [Alias('suppressed')]
        [ValidateSet('true','false')]
        [string]
        $SuppressedProblem
    )

    begin
    {
        if ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession)
            {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }

        $SessionParameters = @('Uri','Credential','Proxy','ProxyCredential','Session')
        $CommonParameters = $(([System.Management.Automation.PSCmdlet]::CommonParameters,[System.Management.Automation.PSCmdlet]::OptionalCommonParameters) | ForEach-Object {$PSItem})
    }

    process
    {

        $params  = @{
            output                = 'extend'
            select_acknowledges   = 'extend'
            selectTags            = 'extend'
        }

        #Dynamically adds any bound parameters that are used for the conditions
        foreach ($Parameter in $PSBoundParameters.GetEnumerator()){
            if ($Parameter.key -notin $SessionParameters -and $Parameter.key -notin $CommonParameters) {
                #uses the hardcoded Alias of the parameter as the API friendly param
                $apiParam = $MyInvocation.MyCommand.Parameters[$Parameter.key].Aliases[0]
                if ($Parameter.Value -in @('true','false')) {
                    $params[$apiParam] = [system.convert]::ToBoolean($Parameter.Value)
                } else {
                    $params[$apiParam] = $Parameter.Value
                }
            }
        }

        $body = New-ZBXRestBody -Method 'problem.get' -API $ApiVersion -Params $params


        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy)
        {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

}
# Get-ZBXSession.ps1
function Get-ZBXSession
{
    <#
    .SYNOPSIS
 
    Returns Zabbix session data.
 
    .DESCRIPTION
 
    Returns Zabbix session data that has been stored in the users local application data.
    Use Save-ZBXSession to persist the session data to disk.
    The sensetive data is returned encrypted.
 
    .PARAMETER Id
 
    Session id.
 
    .PARAMETER Name
 
    The friendly name of the session.
 
    .PARAMETER Path
 
    The path where session data will be stored, defaults to $Script:ZabbixModuleDataPath.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix session.
 
    .EXAMPLE
 
    Returns all Zabbix sessions from disk and memory.
 
    Get-ZBXSession
 
    .EXAMPLE
 
    Returns Zabbix session with the session name of 'myFirstSession'.
 
    Get-ZBXSession -Name 'myFirstSession'
 
    .LINK
 
    Zabbix documentation:
    https://www.zabbix.com/documentation/4.2/manual/api
 
    New-ZBXSession
    Save-ZBXSession
    Remove-ZBXSession
    Initialize-ZBXSession
    #>

    [CmdletBinding()]
    param
    (
        [Parameter(ValueFromPipeline,
            ValueFromPipelineByPropertyName)]
        [string]
        $Name,

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

        [Parameter()]
        [string]
        $Path = $Script:ZabbixModuleDataPath
    )
    begin
    {

    }
    process
    {
        # Process memory sessions
        $_sessions = @()
        if ($null -ne $Global:_ZabbixSessions)
        {
            foreach ($_memSession in $Global:_ZabbixSessions)
            {
                $_sessions += $_memSession
            }
        }

        # Process saved sessions
        if (Test-Path $Path)
        {
            $data = Get-Content -Path $Path -Raw | ConvertFrom-Json
            foreach ($_data in $data.SessionData)
            {
                $_object = New-Object -TypeName PSCustomObject -Property @{
                    Id         = $_data.Id
                    Uri        = $_data.Uri
                    Name       = $_data.Name
                    ApiVersion = $_data.ApiVersion
                    Saved      = $_data.Saved
                }
                if ($_data.Credential)
                {
                    $_psCredentialObject = [pscredential]::new($_data.Credential.Username, ($_data.Credential.Password | ConvertTo-SecureString))
                    $_object | Add-Member -NotePropertyName 'Credential' -NotePropertyValue $_psCredentialObject
                }
                if ($_data.Proxy)
                {
                    $_object | Add-Member -NotePropertyName 'Proxy' -NotePropertyValue $_data.Proxy
                }
                if ($_data.ProxyCredential)
                {
                    $_psProxyCredentialObject = [pscredential]::new($_data.ProxyCredential.Username, ($_data.ProxyCredential.Password | ConvertTo-SecureString))
                    $_object | Add-Member -NotePropertyName 'ProxyCredential' -NotePropertyValue $_psProxyCredentialObject
                }
                $_sessions += $_object
            }
        }
        if ($PSCmdlet.ParameterSetName -eq 'ById')
        {
            $_sessions = $_sessions | Where-Object { $PSItem.Id -eq $Id }
        }
        if ($Name)
        {
            $_sessions = $_sessions | Where-Object { $PSItem.Name -eq $Name }
        }
        if ($_sessions)
        {
            return $_sessions        
        }
        else
        {
            Write-Error "[$($MyInvocation.MyCommand.Name)]: Unable to locate a ZabbixPS session."
        }
    }
    end
    {

    }
}
# Get-ZBXTemplate.ps1
function Get-ZBXTemplate
{
    <#
    .SYNOPSIS
 
    Returns a Zabbix Template.
 
    .DESCRIPTION
 
    Returns a Zabbix Template.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER TemplateId
 
    Return only Templates with the given IDs.
 
    .PARAMETER GroupId
 
    Return only Templates that use the given host groups in the search conditions.
 
    .PARAMETER HostId
 
    Return only Templates that use the given hosts in the search conditions.
 
    .PARAMETER ParentTemplateId
 
    Return the children Templates of the Parent Templates that is given in the search conditions.
 
    .PARAMETER TreiggerId
 
    Return only Templates that have the given ApplicationId in Templates conditions.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix Templates.
 
    .EXAMPLE
 
    Returns all Zabbix Templates.
 
    Get-ZBXTemplate
 
    .EXAMPLE
 
    Returns Zabbix Template from the HostID 10084.
 
    Get-ZBXTemplate -Session $Session -HostId 10084
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/event/get
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter()]
        [Alias('templateids')]
        [string[]]
        $TemplateId,

        [Parameter()]
        [Alias('groupids')]
        [string[]]
        $GroupId,

        [Parameter()]
        [Alias('hostids')]
        [string[]]
        $HostId,

        [Parameter()]
        [Alias('parentTemplateids')]
        [string[]]
        $ParentTemplateId,

        [Parameter()]
        [Alias('triggerids')]
        [string[]]
        $TriggerId
    )

    begin
    {
        if ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession)
            {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }

        $SessionParameters = @('Uri','Credential','Proxy','ProxyCredential','Session')
        $CommonParameters = $(([System.Management.Automation.PSCmdlet]::CommonParameters,[System.Management.Automation.PSCmdlet]::OptionalCommonParameters) | ForEach-Object {$PSItem})
    }

    process
    {

        $params  = @{
            output                = 'extend'
            selectTags            = 'extend'
            selectGroups          = 'extend'
        }

        #Dynamically adds any bound parameters that are used for the conditions
        foreach ($Parameter in $PSBoundParameters.GetEnumerator()){
            if ($Parameter.key -notin $SessionParameters -and $Parameter.key -notin $CommonParameters) {
                #uses the hardcoded Alias of the parameter as the API friendly param
                $apiParam = $MyInvocation.MyCommand.Parameters[$Parameter.key].Aliases[0]
                $params[$apiParam] = $Parameter.Value
            }
        }

        $body = New-ZBXRestBody -Method 'template.get' -API $ApiVersion -Params $params


        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy)
        {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

}
# Get-ZBXTrigger.ps1
function Get-ZBXTrigger
{
    <#
    .SYNOPSIS
 
    Returns a Zabbix Trigger.
 
    .DESCRIPTION
 
    Returns a Zabbix Trigger.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER TriggerId
 
    Return only Triggers with the given IDs.
 
    .PARAMETER GroupId
 
    Return only Triggers that use the given host groups.
 
    .PARAMETER HostId
 
    Return only Triggers that use the given hosts.
 
    .PARAMETER TemplateId
 
    Return only Triggers that belong to given templates.
 
    .PARAMETER ApplicationId
 
    Return only triggers that contain items from the given applications.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix Triggers.
 
    .EXAMPLE
 
    Returns all Zabbix Triggers.
 
    Get-ZBXTrigger
 
    .EXAMPLE
 
    Returns Zabbix Trigger from the HostID 10084.
 
    Get-ZBXTrigger -Session $Session -HostId 10084
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/event/get
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter()]
        [Alias('triggerids')]
        [string[]]
        $TriggerId,

        [Parameter()]
        [Alias('groupids')]
        [string[]]
        $GroupId,

        [Parameter()]
        [Alias('hostids')]
        [string[]]
        $HostId,

        [Parameter()]
        [Alias('templateids')]
        [string[]]
        $TemplateId,

        [Parameter()]
        [Alias('applicationids')]
        [string[]]
        $ApplicationId
    )

    begin
    {
        if ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession)
            {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }

        $SessionParameters = @('Uri','Credential','Proxy','ProxyCredential','Session')
        $CommonParameters = $(([System.Management.Automation.PSCmdlet]::CommonParameters,[System.Management.Automation.PSCmdlet]::OptionalCommonParameters) | ForEach-Object {$PSItem})
    }

    process
    {

        $params  = @{
            output                = 'extend'
            selectTags            = 'extend'
        }

        #Dynamically adds any bound parameters that are used for the conditions
        foreach ($Parameter in $PSBoundParameters.GetEnumerator()){
            if ($Parameter.key -notin $SessionParameters -and $Parameter.key -notin $CommonParameters) {
                #uses the hardcoded Alias of the parameter as the API friendly param
                $apiParam = $MyInvocation.MyCommand.Parameters[$Parameter.key].Aliases[0]
                $params[$apiParam] = $Parameter.Value
            }
        }

        $body = New-ZBXRestBody -Method 'trigger.get' -API $ApiVersion -Params $params


        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy)
        {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

}
# Get-ZBXUser.ps1
function Get-ZBXUser {
    <#
    .SYNOPSIS
 
    Returns a Zabbix User.
 
    .DESCRIPTION
 
    Returns a Zabbix User.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER UserID
 
    Return only users with the given IDs.
 
    .PARAMETER GroupId
 
    Return only users that belong to the given user groups.
 
    .PARAMETER MediaID
 
    Return only users that use the given media.
 
    .PARAMETER MediaTypeID
 
    Return only users that use the given media types.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix User.
 
    .EXAMPLE
 
    Returns all Zabbix Users.
 
    Get-ZBXUser
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/user/get
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter()]
        [Alias('userids')]
        [string[]]
        $UserID,

        [Parameter()]
        [Alias('usrgrpids')]
        [string[]]
        $GroupID,

        [Parameter()]
        [Alias('mediaids')]
        [string[]]
        $MediaID,

        [Parameter()]
        [Alias('mediatypeids')]
        [string[]]
        $MediaTypeID
    )

    begin {
        if ($PSCmdlet.ParameterSetName -eq 'BySession') {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession) {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }

        $SessionParameters = @('Uri', 'Credential', 'Proxy', 'ProxyCredential', 'Session')
        $CommonParameters = $(([System.Management.Automation.PSCmdlet]::CommonParameters, [System.Management.Automation.PSCmdlet]::OptionalCommonParameters) | ForEach-Object { $PSItem })
    }

    process {

        $params = @{
            output           = 'extend'
            selectMedias     = 'extend'
            selectMediatypes = 'extend'
            selectUsrgrps    = 'extend'
        }

        #Dynamically adds any bound parameters that are used for the conditions
        foreach ($Parameter in $PSBoundParameters.GetEnumerator()) {
            if ($Parameter.key -notin $SessionParameters -and $Parameter.key -notin $CommonParameters) {
                #uses the hardcoded Alias of the parameter as the API friendly param
                $apiParam = $MyInvocation.MyCommand.Parameters[$Parameter.key].Aliases[0]
                $params[$apiParam] = $Parameter.Value
            }
        }

        $body = New-ZBXRestBody -Method 'user.get' -API $ApiVersion -Params $params


        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy) {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential) {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

}
# Get-ZBXUserGroup.ps1
function Get-ZBXUserGroup {
    <#
    .SYNOPSIS
 
    Returns a Zabbix UserGroup.
 
    .DESCRIPTION
 
    Returns a Zabbix UserGroup.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER UserID
 
    Return only user groups that contain the given users.
 
    .PARAMETER GroupId
 
    Return only user groups with the given IDs.
 
    .PARAMETER GroupStatus
 
    Return only user groups with the given status.
 
    .PARAMETER AuthMethod
 
    Return only user groups with the given frontend authentication method.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix User.
 
    .EXAMPLE
 
    Returns all Zabbix Users.
 
    Get-ZBXUserGroup
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/usergroup/get
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter()]
        [Alias('userids')]
        [string[]]
        $UserID,

        [Parameter()]
        [Alias('usrgrpids')]
        [string[]]
        $GroupID,

        [Parameter()]
        [Alias('status')]
        [ValidateSet('Enable', 'Disabled')]
        [string]
        $GroupStatus,

        [Parameter()]
        [Alias('with_gui_access')]
        [ValidateSet('Default', 'Internal', 'LDAP', 'Disabled')]
        [string]
        $AuthMethod
    )

    begin {
        if ($PSCmdlet.ParameterSetName -eq 'BySession') {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession) {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }
        $GroupStatusValues = @{
            'Enabled'  = 0
            'Disabled' = 1
        }
        $AuthMethodValues = @{
            'Default'  = 0
            'Internal' = 1
            'LDAP'     = 2
            'Disabled' = 3
        }
        $SessionParameters = @('Uri', 'Credential', 'Proxy', 'ProxyCredential', 'Session')
        $CommonParameters = $(([System.Management.Automation.PSCmdlet]::CommonParameters, [System.Management.Automation.PSCmdlet]::OptionalCommonParameters) | ForEach-Object { $PSItem })
    }

    process {

        $params = @{
            output      = 'extend'
            selectUsers = 'extend'
        }

        #Dynamically adds any bound parameters that are used for the conditions
        foreach ($Parameter in $PSBoundParameters.GetEnumerator()) {
            if ($Parameter.key -notin $SessionParameters -and $Parameter.key -notin $CommonParameters) {
                #uses the hardcoded Alias of the parameter as the API friendly param
                $apiParam = $MyInvocation.MyCommand.Parameters[$Parameter.key].Aliases[0]
                switch ($apiParam) {
                    'status' { $apiValue = $GroupStatusValues[$Parameter.Value]; break }
                    'with_gui_access' { $apiValue = $AuthMethodValues[$Parameter.Value]; break }
                    default { $apiValue = $Parameter.Value }
                }
                $params[$apiParam] = $apiValue
            }
        }

        $body = New-ZBXRestBody -Method 'usergroup.get' -API $ApiVersion -Params $params


        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy) {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential) {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

}
# Initialize-ZBXSession.ps1
function Initialize-ZBXSession
{
    <#
    .SYNOPSIS
 
    Logs into the Zabbix instance and returns an authentication token.
 
    .DESCRIPTION
 
    Logs into the Zabbix instance and returns an authentication token.
 
    .PARAMETER Uri
 
    The zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER ApiVersion
 
    Version of the api to use, defaults to 2.0.
 
    .PARAMETER Path
 
    The path where module data will be stored, defaults to $Script:ZabbixModuleDataPath.
 
    .PARAMETER Session
 
    The name of the Zabbix session.
 
    .PARAMETER Force
 
    Forces an update to the authorization token.
 
    .INPUTS
 
    None. Does not support pipeline.
 
    .OUTPUTS
 
    None. Does not support output.
 
    .EXAMPLE
 
 
    .LINK
 
    Zabbix documentation:
    https://www.zabbix.com/documentation/4.2/manual/api
 
    New-ZBXSession
    Get-ZBXSession
    Save-ZBXSession
    Remove-ZBXSession
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByName')]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByName')]
        [uri]
        $Uri,

        [Parameter(Mandatory,
            ParameterSetName = 'ByName')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByName')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByName')]
        [pscredential]
        $ProxyCredential,

        [Parameter(ParameterSetName = 'ByName')]
        [string]
        $ApiVersion = '2.0',

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter()]
        [string]
        $Path = $Script:ZabbixModuleDataPath,

        [Parameter()]
        [switch]
        $Force
    )
    begin
    {
        if ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession)
            {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }
    }
    process
    {
        if ($Global:_ZabbixAuthenticationToken -and (-not($Force.IsPresent)))
        {
            Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Defaulting to `$Global:_ZabbixAuthenticationToken"
            return $Global:_ZabbixAuthenticationToken
        }
        else
        {
            $body = @{
                jsonrpc = $ApiVersion
                method  = 'user.login'
                params  = @{
                    user     = $Credential.Username
                    password = $Credential.GetNetworkCredential().password
                }
                id      = 1
                auth    = $null
            }
            $invokeRestMethodSplat = @{
                ContentType     = 'application/json'
                Method          = 'POST'
                UseBasicParsing = $true
                Uri             = $Uri.AbsoluteUri
                Body            = $body | ConvertTo-Json -Depth 20
            }
            if ($Proxy)
            {
                $invokeRestMethodSplat.Proxy = $Proxy
                if ($ProxyCredential)
                {
                    $invokeRestMethodSplat.ProxyCredential = $ProxyCredential
                }
                else
                {
                    $invokeRestMethodSplat.ProxyUseDefaultCredentials = $true
                }
            }
            Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Requesting an authentication token"
            try
            {
                $results = Invoke-RestMethod @invokeRestMethodSplat
            }
            catch
            {
                If ($PSitem -match 'File not found')
                {
                    Write-Error "[$($MyInvocation.MyCommand.Name)]: Unable to locate the Zabbix api at: [$Uri], is this the correct uri? See: https://www.zabbix.com/documentation/4.2/manual/api for more information." -ErrorAction 'Stop'
                }
            }
            If ($results.result)
            {
                $Global:_ZabbixAuthenticationToken = $results.result
                return $Global:_ZabbixAuthenticationToken
            }
        }
    }
    end
    {

    }
}

# Invoke-ZBXRestMethod.ps1
function Invoke-ZBXRestMethod
{
    <#
    .SYNOPSIS
 
    Invokes a Zabbix rest method.
 
    .DESCRIPTION
 
    Invokes Zabbix rest method.
 
    .PARAMETER Body
 
    Specifies the body of the request. The body is the content of the request that follows the headers.
 
    .PARAMETER Uri
 
    Specifies the Uniform Resource Identifier (URI) of the Internet resource to which the web request is sent. This parameter supports HTTP, HTTPS, FTP, and FILE values.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to send the request. The default is the Personal Access Token if it is defined, otherwise it is the current user.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Path
 
    The directory to output files to.
 
    .OUTPUTS
 
    System.Int64, System.String, System.Xml.XmlDocument, The output of the cmdlet depends upon the format of the content that is retrieved.
 
    .OUTPUTS
 
    PSObject, If the request returns JSON strings, Invoke-RestMethod returns a PSObject that represents the strings.
 
    .EXAMPLE
 
    .LINK
 
    Zabbix documentation:
    https://www.zabbix.com/documentation/4.2/manual/api
    #>

    [CmdletBinding()]
    Param
    (
        [Parameter(Mandatory)]
        [psobject]
        $Body,

        [Parameter(Mandatory)]
        [uri]
        $Uri,

        [Parameter(Mandatory)]
        [pscredential]
        $Credential,

        [Parameter()]
        [string]
        $Proxy,

        [Parameter()]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory)]
        [string]
        $ApiVersion,

        [Parameter()]
        [string]
        $Path
    )

    begin
    {

    }

    process
    {
        $initializeZabbixSessionSplat = @{
            Uri        = $Uri
            Credential = $Credential
            ApiVersion = $ApiVersion
        }
        if ($Proxy)
        {
            $initializeZabbixSessionSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $initializeZabbixSessionSplat.ProxyCredential = $ProxyCredential
            }
        }
        $Body.auth = Initialize-ZBXSession @initializeZabbixSessionSplat
        $bodyJson = $Body | ConvertTo-Json -Depth 20
        $invokeRestMethodSplat = @{
            ContentType     = 'application/json'
            Method          = 'POST'
            UseBasicParsing = $true
            Uri             = $Uri.AbsoluteUri
            Body            = $bodyJson
        }
        if ($Proxy)
        {
            $invokeRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $invokeRestMethodSplat.ProxyCredential = $ProxyCredential
            }
            else
            {
                $invokeRestMethodSplat.ProxyUseDefaultCredentials = $true
            }
        }
        if ($Path)
        {
            $invokeRestMethodSplat.OutFile = $Path
        }
        Write-Verbose "[$($MyInvocation.MyCommand.Name)]: Invoking Zabbix rest method: [$bodyJson]"
        try
        {
            $results = Invoke-RestMethod @invokeRestMethodSplat
        }
        catch
        {
            If ($PSitem -match 'File not found')
            {
                Write-Error "[$($MyInvocation.MyCommand.Name)]: Unable to locate the Zabbix api at: [$Uri], is this the correct uri? See: https://www.zabbix.com/documentation/4.2/manual/api for more information." -ErrorAction 'Stop'
            }
            else
            {
                $PSitem | Write-Error
            }
        }
        if ($results.result)
        {
            return $results.result
        }
        elseif ($results.error)
        {
            Write-Error -Exception $results.error.message -Message $results.error.data -ErrorId $results.error.code
        }
    }

    end
    {
    }
}

# New-ZBXMaintenance.ps1
function New-ZBXMaintenance
{
    <#
    .SYNOPSIS
 
    Creates a new Zabbix maintenance period.
 
    .DESCRIPTION
 
    Creates a new Zabbix maintenance period.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER Name
 
    The case sensitive maintenance name.
 
    .PARAMETER Description
 
    The maintenance description.
 
    .PARAMETER GroupId
 
    The id of the group.
    Can be retrieved with Get-ZBXGroup.
 
    .PARAMETER HostId
 
    The id of the host.
    Can be retrieved with Get-ZBXHost.
 
    .PARAMETER Type
 
    The maintenance type, defaults to 0.
    0 - data collection
    1 - without data collection
 
    .PARAMETER ActiveSince
 
    The maintenance start time.
 
    .PARAMETER ActiveTill
 
    The maintenance end time.
 
    .PARAMETER Tags
 
    A comma sperated list of tags.
    'Key1:Value1', 'Key2:Value2'
 
    .PARAMETER TpType
 
    The maintenance time period's type, defaults to 0.
    0 - one time only
    2 - daily
    3 - weekly
    4 - monthly
 
    .PARAMETER TpStartTime
 
    The maintenance time period's start time in seconds. Required for daily, weekly and monthly periods.
 
    .PARAMETER TpStartDate
 
    The maintenance time period's start date. Required only for one time period, defaults to current date.
 
    .PARAMETER TpEvery
 
    For daily and weekly periods every defines day or week intervals at which the maintenance must come into effect.
 
    For monthly periods every defines the week of the month when the maintenance must come into effect.
    Possible values:
    1 - first week;
    2 - second week;
    3 - third week;
    4 - fourth week;
    5 - last week.
     
    .PARAMETER TpDay
 
    Day of the month when the maintenance must come into effect
    Required only for monthly time periods
 
    .PARAMETER TpDayOfWeek
 
    Days of the week when the maintenance must come into effect.
    Used for weekly and monthly time periods. Required only for weekly time periods
    Days are stored in binary form with each bit representing the corresponding day.
    4 - equals 100 in binary and means, that maintenance will be enabled on Wednesday
 
    .PARAMETER TpMonth
 
    Months when the maintenance must come into effect.
    Required only for monthly time periods.
    Months are stored in binary form with each bit representing the corresponding month.
    5 - equals 101 in binary and means, that maintenance will be enabled in January and March
 
    .PARAMETER TpPeriod
 
    The maintenance time period's period/duration in seconds.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject, Zabbix maintenance period.
 
    .EXAMPLE
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/maintenance/create
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    [Alias("nzm")]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter(Mandatory)]
        [string]
        $Name,

        [Parameter()]
        [string]
        $Description,

        [Parameter()]
        [string[]]
        $GroupId,

        [Parameter()]
        [string[]]
        $HostId,

        [Parameter()]
        [int]
        $Type = 0,

        [Parameter()]
        [datetime]
        $ActiveSince,

        [Parameter()]
        [datetime]
        $ActiveTill,

        [Parameter()]
        [string[]]
        $Tags,

        [Parameter()]
        [int]
        $TpType = 0,

        [Parameter()]
        [int]
        $TpStartTime,

        [Parameter()]
        [datetime]
        $TpStartDate,

        [Parameter()]
        [int]
        $TpDay,

        [Parameter()]
        [int]
        $TpEvery,

        [Parameter()]
        [int]
        $TpDayOfWeek,

        [Parameter()]
        [int]
        $TpMonth,

        [Parameter()]
        [int]
        $TpPeriod
    )

    begin
    {
        if ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession)
            {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }
    }

    process
    {
        $body = @{
            method  = 'maintenance.create'
            jsonrpc = $ApiVersion
            id      = 1

            params  = @{
                name             = $Name
                description      = $Description
                active_since     = [Math]::Floor([decimal](Get-Date($ActiveSince).ToUniversalTime()-UFormat "%s"))
                active_till      = [Math]::Floor([decimal](Get-Date($ActiveTill).ToUniversalTime()-UFormat "%s"))
                maintenance_type = $Type
                timeperiods      = @(
                    @{
                        timeperiod_type = $TpType
                        start_date      = [Math]::Floor([decimal](Get-Date($TpStartDate).ToUniversalTime()-UFormat "%s"))
                        period          = $TpPeriod

                        start_time      = $TpStartTime
                        month           = $TpMonth
                        dayofweek       = $TpDayOfWeek
                        day             = $TpDay
                    }
                )
            }
        }
        if ($TpEvery)
        {
            $body.params.timeperiods.every = $TpEvery
        }
        if ($GroupId)
        {
            $body.params.groupids = $GroupId
        }
        if ($HostId)
        {
            $body.params.hostids = $HostId
        }
        if ($Tags)
        {
            $body.params.tags = (Format-ZBXTags -Tags $Tags)
        }
        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy)
        {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        return Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

    end
    {
    }
}
# New-ZBXSession.ps1
function New-ZBXSession
{
    <#
    .SYNOPSIS
 
    Creates a new Zabbix session.
 
    .DESCRIPTION
 
    Creates a new Zabbix session.
    Use Save-ZBXSession to persist the session data to disk.
    Save the session to a variable to pass the session to other functions.
 
    .PARAMETER Name
 
    The friendly name of the session.
 
    .PARAMETER Uri
 
    The zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER ApiVersion
 
    Version of the api to use, defaults to 2.0.
 
    .PARAMETER Path
 
    The path where module data will be stored, defaults to $Script:ZabbixModuleDataPath.
 
    .INPUTS
 
    None. Does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix session
 
    .EXAMPLE
 
    Creates a session with the name of 'myZabbixInstance' returning it to the $session variable.
 
    $session = New-ZBXSession -Uri 'http://myCompany/zabbix/api_jsonrpc.php' -Credential $creds -Name myZabbixInstance
 
    .LINK
 
    Zabbix documentation:
    https://www.zabbix.com/documentation/4.2/manual/api
 
    Remove-ZBXSession
    Get-ZBXSession
    Save-ZBXSession
    Initialize-ZBXSession
    #>

    [CmdletBinding()]
    [Alias("Connect-ZBX","czab")]
    param
    (
        [Parameter(Mandatory)]
        [string]
        $Name,

        [Parameter(Mandatory)]
        [uri]
        $Uri,

        [Parameter(Mandatory)]
        [pscredential]
        $Credential,

        [Parameter()]
        [string]
        $Proxy,

        [Parameter()]
        [pscredential]
        $ProxyCredential,

        [Parameter()]
        [string]
        $ApiVersion = '2.0',

        [Parameter()]
        [string]
        $Path = $Script:ZabbixModuleDataPath
    )
    begin
    {

    }
    process
    {
        [int] $_sessionIdcount = (Get-ZBXSession -ErrorAction 'SilentlyContinue' | Sort-Object -Property 'Id' | Select-Object -Last 1 -ExpandProperty 'Id') + 1
        $_session = New-Object -TypeName PSCustomObject -Property @{
            Uri        = $Uri
            Name       = $Name
            Id         = $_sessionIdcount
            Credential = $Credential
            ApiVersion = $ApiVersion
        }
        if ($Proxy)
        {
            $_session | Add-Member -NotePropertyName 'Proxy' -NotePropertyValue $Proxy
        }
        if ($ProxyCredential)
        {
            $_session | Add-Member -NotePropertyName 'ProxyCredential' -NotePropertyValue $ProxyCredential
        }
        if ($null -eq $Global:_ZabbixSessions)
        {
            $Global:_ZabbixSessions = @()
        }
        $Global:_ZabbixSessions += $_session
        return $_session
    }
    end
    {

    }
}

# New-ZBXUser.ps1
function New-ZBXUser {
    <#
    .SYNOPSIS
 
    Creates a Zabbix User.
 
    .DESCRIPTION
 
    Creates a Zabbix User.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER Username
 
    User Alias
 
    .PARAMETER Password
 
    User's password. Can be omitted if user is added only to groups that have LDAP access.
 
    .PARAMETER GroupId
 
    User groups to add the user to. Must be the GroupID
 
    .PARAMETER UserMedia
 
    Medias to create for the user. This parameter takes a Hashtable of values.
 
    @{
        mediatypeid = 0|1|2|3
        sendto = @('EmailAddress@example.com') # other media types are single string
        active = 0|1
        severity = 63| #binary combination of severity default shown
        period = 1-7,00:00-24:00 # days and times
    }
 
    .PARAMETER AdditionalOptions
 
    This parameter takes a Hashtable of values to provied userObject values
 
    @{
        alias = jdoe
        autologin = 0|1 #disable|enable
        autologout = 15m # timeframe
        lang = en_GB # language for user
        name = Jane
        refresh = 30s
        rows_per_page = 50
        surname = Doe
        theme = default|blue-theme|dark-theme
        type = 1|2|3 # ZabbixUser|Zabbix Admin| Zabbix Super Admin
        url = htpps://zabbix/devices.php # Page after logging in
        #UserMedia Options can also be included
    }
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix User.
 
    .EXAMPLE
 
    Adds the LDAP user jdoe to an LDAP group
 
    New-ZBXUser -Username jdoe -GroupID 15
 
    .EXAMPLE
 
    Adds the local user jcool with additional options
 
    $AdditionalOptions = @{name='Joe';surname='Cool';autologin=0;autologout="30m";lang='en_US';refresh='60s';rows_per_page=100;theme='dark-theme';type=3;}
    New-ZBXUser -Session $session -Username jcool -Password (Read-Host -AsSecureString) -GroupID 7 -AdditionalOptions $AdditionalOptions
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/user/create
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter(Mandatory)]
        [Alias('alias')]
        [string]
        $Username,

        [Parameter()]
        [Alias('passwd')]
        [securestring]
        $Password,

        [Parameter()]
        [Alias('usrgrps')]
        [int]
        $GroupID,

        [Parameter()]
        [hashtable]
        $UserMedia,

        [Parameter()]
        [hashtable]
        $AdditionalOptions
    )

    begin {
        if ($PSCmdlet.ParameterSetName -eq 'BySession') {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession) {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }

        #These Enums create an easy way to lookup supported API keys
        enum validMediaOptions {
            mediatypeid; sendto; active; severity; period;
        }
        enum validOptions {
            alias; autologin; autologout; lang; name; refresh; rows_per_page; surname; theme;
            type; url; mediatypeid; sendto; active; severity; period;
        }
        $params = @{ }
        $SessionParameters = @('Uri', 'Credential', 'Proxy', 'ProxyCredential', 'Session')
        $CommonParameters = $(([System.Management.Automation.PSCmdlet]::CommonParameters, [System.Management.Automation.PSCmdlet]::OptionalCommonParameters) | ForEach-Object { $PSItem })
    }

    process {
        #Dynamically adds any bound parameters that are used for the conditions
        foreach ($Parameter in $PSBoundParameters.GetEnumerator()) {
            if ($Parameter.key -notin $SessionParameters -and $Parameter.key -notin $CommonParameters) {
                #uses the hardcoded Alias of the parameter as the API friendly param
                $apiParam = $MyInvocation.MyCommand.Parameters[$Parameter.key].Aliases[0]
                if ($null -ne $apiParam) {
                    switch ($apiParam) {
                        'passwd' { $apiValue = ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password))); break }
                        'usrgrps' { $apiValue = @(@{"usrgrpid" = $Parameter.value }); break }
                        default { $apiValue = $Parameter.Value }
                    }
                    $params[$apiParam] = $apiValue
                }
            }
        }
        if ($PSBoundParameters.ContainsKey('UserMedia')) {
            foreach ($Options in $UserMedia.GetEnumerator()) {
                #Validates that the
                if ([validMediaOptions].getEnumNames().Contains("$($Options.key)")) {
                    $params["user_medias"] = @{"$($Options.key)" = $($Options.value) }
                } else {
                    Write-Warning "$($Options.key) is not part of the supported options; See help for valid options"
                }
            }
        }
        if ($PSBoundParameters.ContainsKey('AdditionalOptions')) {
            foreach ($Options in $AdditionalOptions.GetEnumerator()) {
                if ([validOptions].getEnumNames().Contains("$($Options.key)")) {
                    #Ensures that if someone uses AdditionalOptions for everything
                    if ([validMediaOptions].getEnumNames().Contains("$($Options.key)")) {
                        $params["user_medias"] = @{"$($Options.key)" = $($Options.value) }
                    } else {
                        $params[$($Options.key)] = $Options.value
                    }
                } else {
                    Write-Warning "$($Options.key) is not part of the supported options; See help for valid options"
                }
            }
        }

        $body = New-ZBXRestBody -Method 'user.create' -API $ApiVersion -Params $params


        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy) {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential) {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }
}
# Remove-ZBXAction.ps1
function Remove-ZBXAction
{
    <#
    .SYNOPSIS
 
    Removes a Zabbix action.
 
    .DESCRIPTION
 
    Removes a Zabbix action.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER Id
 
    The action id.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject, action ids that were removed.
 
    .EXAMPLE
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/action/delete
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter(Mandatory)]
        [int]
        $Id
    )

    begin
    {
        if ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession)
            {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }
    }

    process
    {
        $body = @{
            method  = 'action.delete'
            jsonrpc = $ApiVersion
            id      = 1

            params  = @($Id)
        }
        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy)
        {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        return Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

    end
    {
    }
}
# Remove-ZBXMaintenance.ps1
function Remove-ZBXMaintenance
{
    <#
    .SYNOPSIS
 
    Removes a Zabbix maintenance period.
 
    .DESCRIPTION
 
    Removes a Zabbix maintenance period.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER Id
 
    The maintenance id.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject, maintenance ids that were removed.
 
    .EXAMPLE
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/maintenance/delete
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    [Alias("rzm")]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter(Mandatory)]
        [int]
        $Id
    )

    begin
    {
        if ($PSCmdlet.ParameterSetName -eq 'BySession')
        {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession)
            {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }
    }

    process
    {
        $body = @{
            method  = 'maintenance.delete'
            jsonrpc = $ApiVersion
            id      = 1

            params  = @($Id)
        }
        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy)
        {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential)
            {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        return Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }

    end
    {
    }
}
# Remove-ZBXSession.ps1
function Remove-ZBXSession
{
    <#
    .SYNOPSIS
 
    Removes a Zabbix session.
 
    .DESCRIPTION
 
    Removes a Zabbix session.
    If the session is saved, it will be removed from the saved sessions as well.
 
    .PARAMETER Id
 
    Session id.
 
    .PARAMETER Path
 
    The path where module data will be stored, defaults to $Script:ZabbixModuleDataPath.
 
    .INPUTS
 
    PSObject. Get-ZBXSession
 
    .OUTPUTS
 
    None. Does not supply output.
 
    .EXAMPLE
 
    Deletes a Zabbix session with the id of '2'.
 
    Remove-ZBXSession -Id 2
 
    .EXAMPLE
 
    Deletes all AP sessions in memory and stored on disk.
 
    Remove-ZBXSession
 
    .LINK
 
    Zabbix documentation:
    https://www.zabbix.com/documentation/4.2/manual/api
 
    New-ZBXSession
    Get-ZBXSession
    Save-ZBXSession
    Initialize-ZBXSession
    #>

    [CmdletBinding()]
    [Alias("rzsess","dzsess")]
    param
    (
        [Parameter(Mandatory,
            ValueFromPipelineByPropertyName)]
        [int]
        $Id,

        [Parameter()]
        [string]
        $Path = $Script:ZabbixModuleDataPath
    )
    begin
    {

    }
    process
    {
        $sessions = Get-ZBXSession -Id $Id
        foreach ($session in $sessions)
        {
            if ($session.Saved -eq $true)
            {
                $newData = @{SessionData = @() }
                $data = Get-Content -Path $Path -Raw | ConvertFrom-Json
                foreach ($_data in $data.SessionData)
                {
                    if ($_data.Id -eq $session.Id)
                    {
                        Continue
                    }
                    else
                    {
                        $newData.SessionData += $_data
                    }
                }
                $newData | ConvertTo-Json -Depth 5 | Out-File -FilePath $Path
            }
            $Global:_ZabbixSessions = $Global:_ZabbixSessions | Where-Object { $PSItem.Id -ne $session.Id }
        }
    }
    end
    {

    }
}

# Remove-ZBXUser.ps1
function Remove-ZBXUser {
    <#
    .SYNOPSIS
 
    Removes a Zabbix User.
 
    .DESCRIPTION
 
    Removes a Zabbix User.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER UserID
 
    IDs of users to delete.
 
    .PARAMETER Force
 
    Suppresses prompt.
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix User.
 
    .EXAMPLE
 
    Removes the user whose id is 7
 
    Remove-ZBXUser -UserID 7
 
    .EXAMPLE
 
    Removes the users without prompting for confirmation
 
    Remove-ZBXUser -UserID 7,8 -Force
 
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/user/delete
    #>

    [CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High', DefaultParameterSetName = 'ByCredential')]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter(Mandatory)]
        [int[]]
        $UserId,

        [Parameter()]
        [switch]
        $Force
    )

    begin {
        if ($PSCmdlet.ParameterSetName -eq 'BySession') {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession) {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }

        $params = @{ }
        $SessionParameters = @('Uri', 'Credential', 'Proxy', 'ProxyCredential', 'Session')
        $CommonParameters = $(([System.Management.Automation.PSCmdlet]::CommonParameters, [System.Management.Automation.PSCmdlet]::OptionalCommonParameters) | ForEach-Object { $PSItem })
    }

    process {
        #This method only takes an array of ids, so needs a blank hashtable to get the basic body
        $params = @{ }
        $body = New-ZBXRestBody -Method 'user.delete' -API $ApiVersion -Params $params
        $body.params = @($UserId)

        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy) {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential) {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        #Get the frendly name of the user
        $getUserSplat = $invokeZabbixRestMethodSplat.Clone()
        $getUserSplat.Remove('body')
        $getUserSplat.Remove('apiversion')
        $userName = Get-ZBXUser @getUserSplat -UserID $UserId
        $userName = $userName.alias -join ' '

        if ($Force -or $PSCmdlet.ShouldContinue("About to remove $userName", "Would you like to continue?" )) {
            Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
        }
    }
}
# Save-ZBXSession.ps1
function Save-ZBXSession
{
    <#
    .SYNOPSIS
 
    Saves a Zabbix session disk.
 
    .DESCRIPTION
 
    Saves a Zabbix session disk.
    The sensetive data is encrypted and stored in the users local application data.
    These saved sessions will be available next time the module is imported.
 
    .PARAMETER Session
 
    Zabbix session, created by New-ZBXSession.
 
    .PARAMETER Path
 
    The path where session data will be stored, defaults to $Script:ZabbixModuleDataPath.
 
    .PARAMETER PassThru
 
    Returns the saved session object.
 
    .INPUTS
 
    PSbject. Get-ZBXSession, New-ZBXSession
 
    .OUTPUTS
 
    None. Save-ZBXSession does not generate any output.
 
    .EXAMPLE
 
    Creates a session with the name of 'myZabbixInstance' saving it to disk.
 
    New-ZBXSession -Uri 'http://myCompany/zabbix/api_jsonrpc.php' -Credential $creds -Name myZabbixInstance | Save-ZBXSession
 
    .LINK
 
    Zabbix documentation:
    https://www.zabbix.com/documentation/4.2/manual/api
 
    New-ZBXSession
    Get-ZBXSession
    Remove-ZBXSession
    Initialize-ZBXSession
    #>

    [CmdletBinding()]
    param
    (
        [Parameter(Mandatory,
            ValueFromPipeline)]
        [object]
        $Session,

        [Parameter()]
        [string]
        $Path = $Script:ZabbixModuleDataPath
    )
    begin
    {
        if (-not(Test-Path $Path))
        {
            $data = @{SessionData = @() }
        }
        else
        {
            $data = Get-Content -Path $Path -Raw | ConvertFrom-Json
        }
    }
    process
    {
        if ($data.SessionData.Id -notcontains $session.Id)
        {
            $_object = @{
                Id         = $Session.Id
                Name       = $Session.Name
                Uri        = $Session.Uri
                ApiVersion = $Session.ApiVersion
                Saved      = $true
            }
            if ($Session.Credential)
            {
                $_credentialObject = @{
                    Username = $Session.Credential.UserName
                    Password = ($Session.Credential.GetNetworkCredential().SecurePassword | ConvertFrom-SecureString)
                }
                $_object.Credential = $_credentialObject
            }
            if ($Session.Proxy)
            {
                $_object.Proxy = $Session.Proxy
            }
            if ($Session.ProxyCredential)
            {
                $_proxyCredentialObject = @{
                    Username = $Session.ProxyCredential.UserName
                    Password = ($Session.ProxyCredential.GetNetworkCredential().SecurePassword | ConvertFrom-SecureString)
                }
                $_object.ProxyCredential = $_proxyCredentialObject
            }
            $data.SessionData += $_object
            $session | Remove-ZBXSession -Path $Path
        }
    }
    end
    {
        $data | ConvertTo-Json -Depth 5 | Out-File -FilePath $Path
        Write-Verbose "[$($MyInvocation.MyCommand.Name)]: [$Name]: Session data has been stored at [$Path]"
    }
}

# Update-ZBXUser.ps1
function Update-ZBXUser {
    <#
    .SYNOPSIS
 
    Updates a Zabbix User.
 
    .DESCRIPTION
 
    Updates a Zabbix User.
 
    .PARAMETER Uri
 
    The Zabbix instance uri.
 
    .PARAMETER Credential
 
    Specifies a user account that has permission to the project.
 
    .PARAMETER Proxy
 
    Use a proxy server for the request, rather than connecting directly to the Internet resource. Enter the URI of a network proxy server.
 
    .PARAMETER ProxyCredential
 
    Specifie a user account that has permission to use the proxy server that is specified by the -Proxy parameter. The default is the current user.
 
    .PARAMETER Session
 
    ZabbixPS session, created by New-ZBXSession.
 
    .PARAMETER UserIDToUpdate
 
    User ID
 
    .PARAMETER Password
 
    User's password. Can be empty string if user belongs to or is moved only to groups that have LDAP access.
 
    .PARAMETER GroupId
 
    User groups to replace existing user groups. Must be the ID
 
    .PARAMETER UserMedia
 
    Medias to replace existing medias. This parameter takes a Hashtable of values.
 
    @{
        mediatypeid = 0|1|2|3
        sendto = @('EmailAddress@example.com') # other media types are single string
        active = 0|1
        severity = 63| #binary combination of severity default shown
        period = 1-7,00:00-24:00 # days and times
    }
 
    .PARAMETER AdditionalOptions
 
    This parameter takes a Hashtable of values to provied userObject values
 
    @{
        alias = jdoe
        autologin = 0|1 #disable|enable
        autologout = 15m # timeframe
        lang = en_GB # language for user
        name = Jane
        refresh = 30s
        rows_per_page = 50
        surname = Doe
        theme = default|blue-theme|dark-theme
        type = 1|2|3 # ZabbixUser|Zabbix Admin| Zabbix Super Admin
        url = htpps://zabbix/devices.php # Page after logging in
        #UserMedia Options can also be included
    }
 
    .INPUTS
 
    None, does not support pipeline.
 
    .OUTPUTS
 
    PSObject. Zabbix User.
 
    .EXAMPLE
 
    Adds the LDAP user jdoe to an LDAP group
 
    Update-ZBXUser -UserIDToUpdate 12 -GroupID 16
 
    .EXAMPLE
 
    Adds the local user jdoe with additional options
 
    $AdditionalOptions = @{name='Joe';surname='Doe';Alias='jdoe'}
    Update-ZBXUser -Session $session -UserIDToUpdate 15 -AdditionalOptions $AdditionalOptions
    .LINK
 
    https://www.zabbix.com/documentation/4.2/manual/api/reference/user/create
    #>

    [CmdletBinding(DefaultParameterSetName = 'ByCredential')]
    param
    (
        [Parameter(Mandatory,
            ParameterSetName = 'ByCredential')]
        [uri]
        $Uri,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $Credential,

        [Parameter(ParameterSetName = 'ByCredential')]
        [string]
        $Proxy,

        [Parameter(ParameterSetName = 'ByCredential')]
        [pscredential]
        $ProxyCredential,

        [Parameter(Mandatory,
            ParameterSetName = 'BySession')]
        [object]
        $Session,

        [Parameter(Mandatory)]
        [Alias('userid')]
        [string]
        $UserIDToUpdate,

        [Parameter()]
        [Alias('passwd')]
        [securestring]
        $Password,

        [Parameter()]
        [Alias('usrgrps')]
        [int]
        $GroupID,

        [Parameter()]
        [hashtable]
        $UserMedia,

        [Parameter()]
        [hashtable]
        $AdditionalOptions
    )

    begin {
        if ($PSCmdlet.ParameterSetName -eq 'BySession') {
            $currentSession = $Session | Get-ZBXSession -ErrorAction 'Stop' | Select-Object -First 1
            if ($currentSession) {
                $Uri = $currentSession.Uri
                $Credential = $currentSession.Credential
                $Proxy = $currentSession.Proxy
                $ProxyCredential = $currentSession.ProxyCredential
                $ApiVersion = $currentSession.ApiVersion
            }
        }

        #These Enums create an easy way to lookup supported API keys
        enum validMediaOptions {
            mediatypeid; sendto; active; severity; period;
        }
        enum validOptions {
            alias; autologin; autologout; lang; name; refresh; rows_per_page; surname; theme;
            type; url; mediatypeid; sendto; active; severity; period;
        }
        $params = @{ }
        $SessionParameters = @('Uri', 'Credential', 'Proxy', 'ProxyCredential', 'Session')
        $CommonParameters = $(([System.Management.Automation.PSCmdlet]::CommonParameters, [System.Management.Automation.PSCmdlet]::OptionalCommonParameters) | ForEach-Object { $PSItem })
    }

    process {
        #Dynamically adds any bound parameters that are used for the conditions
        foreach ($Parameter in $PSBoundParameters.GetEnumerator()) {
            if ($Parameter.key -notin $SessionParameters -and $Parameter.key -notin $CommonParameters) {
                #uses the hardcoded Alias of the parameter as the API friendly param
                $apiParam = $MyInvocation.MyCommand.Parameters[$Parameter.key].Aliases[0]
                if ($null -ne $apiParam) {
                    switch ($apiParam) {
                        'passwd' { $apiValue = ([System.Runtime.InteropServices.Marshal]::PtrToStringAuto([System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($Password))); break }
                        'usrgrps' { $apiValue = @(@{"usrgrpid" = $($Parameter.value) }); break }
                        default { $apiValue = $Parameter.Value }
                    }
                    $params[$apiParam] = $apiValue
                }
            }
        }
        if ($PSBoundParameters.ContainsKey('UserMedia')) {
            foreach ($Options in $UserMedia.GetEnumerator()) {
                #Validates that the
                if ([validMediaOptions].getEnumNames().Contains("$($Options.key)")) {
                    $params["user_medias"] = @{"$($Options.key)" = $($Options.value) }
                } else {
                    Write-Warning "$($Options.key) is not part of the supported options; See help for valid options"
                }
            }
        }
        if ($PSBoundParameters.ContainsKey('AdditionalOptions')) {
            foreach ($Options in $AdditionalOptions.GetEnumerator()) {
                if ([validOptions].getEnumNames().Contains("$($Options.key)")) {
                    #Ensures that if someone uses AdditionalOptions for everything
                    if ([validMediaOptions].getEnumNames().Contains("$($Options.key)")) {
                        $params["user_medias"] = @{"$($Options.key)" = $($Options.value) }
                    } else {
                        $params[$($Options.key)] = $Options.value
                    }
                } else {
                    Write-Warning "$($Options.key) is not part of the supported options; See help for valid options"
                }
            }
        }

        $body = New-ZBXRestBody -Method 'user.update' -API $ApiVersion -Params $params


        $invokeZabbixRestMethodSplat = @{
            Body        = $body
            Uri         = $Uri
            Credential  = $Credential
            ApiVersion  = $ApiVersion
            ErrorAction = 'Stop'
        }
        if ($Proxy) {
            $invokeZabbixRestMethodSplat.Proxy = $Proxy
            if ($ProxyCredential) {
                $invokeZabbixRestMethodSplat.ProxyCredential = $ProxyCredential
            }
        }
        Invoke-ZBXRestMethod @invokeZabbixRestMethodSplat
    }
}
# Imported from [D:\a\1\s\ZabbixPS\Tests]