diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json new file mode 100644 index 0000000..68ec9b6 --- /dev/null +++ b/.devcontainer/devcontainer.json @@ -0,0 +1,44 @@ +// For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: +// https://github.com/microsoft/vscode-dev-containers/tree/v0.194.3/containers/docker-existing-docker-compose +// If you want to run as a non-root user in the container, see .devcontainer/docker-compose.yml. +{ + "name": "Existing Docker Compose (Extend)", + + // Update the 'dockerComposeFile' list if you have more compose files or use different names. + // The .devcontainer/docker-compose.yml file contains any overrides you need/want to make. + "dockerComposeFile": [ + "../docker-compose.yml", + "docker-compose.yml" + ], + + // The 'service' property is the name of the service for the container that VS Code should + // use. Update this value and .devcontainer/docker-compose.yml to the real service name. + "service": "pszabbix", + + // The optional 'workspaceFolder' property is the path VS Code should open by default when + // connected. This is typically a file mount in .devcontainer/docker-compose.yml + "workspaceFolder": "/workspace", + + // Set *default* container specific settings.json values on container create. + "settings": {}, + + // Add the IDs of extensions you want installed when the container is created. + "extensions": [ + "ms-vscode.powershell", + ] + + // Use 'forwardPorts' to make a list of ports inside the container available locally. + // "forwardPorts": [], + + // Uncomment the next line if you want start specific services in your Docker Compose config. + // "runServices": [], + + // Uncomment the next line if you want to keep your containers running after VS Code shuts down. + // "shutdownAction": "none", + + // Uncomment the next line to run commands after the container is created - for example installing curl. + // "postCreateCommand": "apt-get update && apt-get install -y curl", + + // Uncomment to connect as a non-root user if you've added one. See https://aka.ms/vscode-remote/containers/non-root. + // "remoteUser": "vscode" +} diff --git a/.devcontainer/docker-compose.yml b/.devcontainer/docker-compose.yml new file mode 100644 index 0000000..b1bfb44 --- /dev/null +++ b/.devcontainer/docker-compose.yml @@ -0,0 +1,38 @@ +version: '3.9' +services: + # Update this to the name of the service you want to work with in your docker-compose.yml file + pszabbix: + # If you want add a non-root user to your Dockerfile, you can use the "remoteUser" + # property in devcontainer.json to cause VS Code its sub-processes (terminals, tasks, + # debugging) to execute as the user. Uncomment the next line if you want the entire + # container to run as this user instead. Note that, on Linux, you may need to + # ensure the UID and GID of the container user you create matches your local user. + # See https://aka.ms/vscode-remote/containers/non-root for details. + # + # user: vscode + + # Uncomment if you want to override the service's Dockerfile to one in the .devcontainer + # folder. Note that the path of the Dockerfile and context is relative to the *primary* + # docker-compose.yml file (the first in the devcontainer.json "dockerComposeFile" + # array). The sample below assumes your primary file is in the root of your project. + # + # build: + # context: . + # dockerfile: .devcontainer/Dockerfile + + volumes: + # Update this to wherever you want VS Code to mount the folder of your project + - .:/workspace:cached + + # Uncomment the next line to use Docker from inside the container. See https://aka.ms/vscode-remote/samples/docker-from-docker-compose for details. + # - /var/run/docker.sock:/var/run/docker.sock + + # Uncomment the next four lines if you will use a ptrace-based debugger like C++, Go, and Rust. + # cap_add: + # - SYS_PTRACE + # security_opt: + # - seccomp:unconfined + + # Overrides default command so things don't shut down after the process ends. + command: /bin/sh -c "while sleep 1000; do :; done" + diff --git a/.devcontainer/pscoredev.Dockerfile b/.devcontainer/pscoredev.Dockerfile new file mode 100644 index 0000000..0e4d06c --- /dev/null +++ b/.devcontainer/pscoredev.Dockerfile @@ -0,0 +1,3 @@ +FROM mcr.microsoft.com/powershell:ubuntu-18.04 +RUN pwsh -noprofile -noninteractive -c 'Install-Module PowershellGet -Scope AllUsers -Force' +RUN pwsh -noprofile -noninteractive -c 'Install-Module Pester,PSFramework -Scope AllUsers -Force' diff --git a/PSZabbix.Tests.ps1 b/PSZabbix.Tests.ps1 deleted file mode 100644 index 22e70f3..0000000 --- a/PSZabbix.Tests.ps1 +++ /dev/null @@ -1,575 +0,0 @@ -[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")] -param() - -$here = Split-Path -Parent $MyInvocation.MyCommand.Path -$sut = (Split-Path -Leaf $MyInvocation.MyCommand.Path).Replace(".Tests.", ".").Replace(".ps1", ".psm1") - -$global:baseUrl = "http://tools/zabbix/api_jsonrpc.php" -$secpasswd = ConvertTo-SecureString "zabbix" -AsPlainText -Force -$global:admin = New-Object System.Management.Automation.PSCredential ("Admin", $secpasswd) - -$wrongsecpasswd = ConvertTo-SecureString "wrong" -AsPlainText -Force -$global:admin2 = New-Object System.Management.Automation.PSCredential ("Admin", $wrongsecpasswd) - -Import-Module $here/$sut -Force - -InModuleScope PSZabbix { - $s = New-ApiSession $baseUrl $global:admin -silent - - Describe "New-ApiSession" { - $session = New-ApiSession $baseUrl $admin -silent - - It "connects to zabbix and returns a non-empty session object" { - $session | should Not Be $null - $session["Uri"] | should Not Be $null - $session["Auth"] | should Not Be $null - } - - It "fails when URL is wrong" { - {New-ApiSession "http://localhost:12345/zabbix" $admin} | Should Throw - } -Skip - - It "fails when login/password is wrong" { - {New-ApiSession $baseUrl $admin2} | Should Throw - } - } - - Describe "New-Host" { - It "can create an enabled host from explicit ID parameters" { - $h = New-Host -Name "pestertesthost$(Get-Random)" -HostGroupId 2 -TemplateId 10108 -Dns localhost - $h | should not be $null - $h.status | should be 0 - } - It "can create an disabled host from explicit ID parameters" { - $h = New-Host -Name "pestertesthost$(Get-Random)" -HostGroupId 2 -TemplateId 10108 -Dns localhost -status disabled - $h | should not be $null - $h.status | should be 1 - } - } - - Describe "Get-Host" { - It "can return all hosts" { - Get-Host | Should Not BeNullOrEmpty - } - It "can filter by name with wildcard (explicit parameter)" { - Get-Host "pestertesthost*" | Should Not BeNullOrEmpty - Get-Host "pestertesthostXXX*" | Should BeNullOrEmpty - } - It "can filter by ID (explicit parameter)" { - $h = (Get-Host "pestertesthost*")[0] - (Get-Host -Id $h.hostid).host | Should Be $h.host - } - It "can filter by group membership (explicit parameter)" { - $h = (Get-Host "pestertesthost*")[0] - (Get-Host -Id $h.hostid -HostGroupId 2).host | Should Be $h.host - } - } - - Describe "Remove-Host" { - It "can delete from one explicit ID parameter" { - New-Host -Name "pestertesthostrem" -HostGroupId 2 -TemplateId 10108 -Dns localhost -errorAction silentlycontinue - $h = Get-Host pestertesthostrem - remove-Host $h.hostid | should be $h.hostid - } - It "can delete from multiple explicit ID parameters" { - $h1 = New-Host -Name "pestertesthostrem" -HostGroupId 2 -TemplateId 10108 -Dns localhost - $h2 = New-Host -Name "pestertesthostrem2" -HostGroupId 2 -TemplateId 10108 -Dns localhost -errorAction silentlycontinue - remove-Host $h1.hostid,$h2.hostid | should be @($h1.hostid, $h2.hostid) - } - It "can delete from multiple piped IDs" { - $h1 = New-Host -Name "pestertesthostrem" -HostGroupId 2 -TemplateId 10108 -Dns localhost - $h2 = New-Host -Name "pestertesthostrem2" -HostGroupId 2 -TemplateId 10108 -Dns localhost - $h1.hostid,$h2.hostid | remove-Host | should be @($h1.hostid, $h2.hostid) - } - It "can delete from one piped object parameter" { - $h = New-Host -Name "pestertesthostrem" -HostGroupId 2 -TemplateId 10108 -Dns localhost - $h | remove-Host | should be $h.hostid - } - It "can delete from multiple piped objects" { - $h1 = New-Host -Name "pestertesthostrem" -HostGroupId 2 -TemplateId 10108 -Dns localhost - $h2 = New-Host -Name "pestertesthostrem2" -HostGroupId 2 -TemplateId 10108 -Dns localhost - $h1,$h2 | remove-Host | should be @($h1.hostid, $h2.hostid) - } - } - - Describe "Disable-Host" { - New-Host -Name "pestertesthost1" -HostGroupId 2 -TemplateId 10108 -Dns localhost -errorAction silentlycontinue - New-Host -Name "pestertesthost2" -HostGroupId 2 -TemplateId 10108 -Dns localhost -errorAction silentlycontinue - $h1 = get-host pestertesthost1 - $h2 = get-host pestertesthost2 - - It "can enable multiple piped objects" { - $h1,$h2 | Disable-host | should be @($h1.hostid, $h2.hostid) - (get-host pestertesthost1).status | should be 1 - } - It "can enable multiple piped IDs" { - $h1.hostid,$h2.hostid | Disable-host | should be @($h1.hostid, $h2.hostid) - (get-host pestertesthost1).status | should be 1 - } - It "can enable multiple explicit parameter IDs" { - Disable-host $h1.hostid,$h2.hostid | should be @($h1.hostid, $h2.hostid) - (get-host pestertesthost1).status | should be 1 - } - } - - Describe "Enable-Host" { - New-Host -Name "pestertesthost1" -HostGroupId 2 -TemplateId 10108 -Dns localhost -errorAction silentlycontinue - New-Host -Name "pestertesthost2" -HostGroupId 2 -TemplateId 10108 -Dns localhost -errorAction silentlycontinue - $h1 = get-host pestertesthost1 - $h2 = get-host pestertesthost2 - - It "can enable multiple piped objects" { - $h1,$h2 | enable-host | should be @($h1.hostid, $h2.hostid) - (get-host pestertesthost1).status | should be 0 - } - It "can enable multiple piped IDs" { - $h1.hostid,$h2.hostid | enable-host | should be @($h1.hostid, $h2.hostid) - (get-host pestertesthost1).status | should be 0 - } - It "can enable multiple explicit parameter IDs" { - enable-host $h1.hostid,$h2.hostid | should be @($h1.hostid, $h2.hostid) - (get-host pestertesthost1).status | should be 0 - } - } - - Describe "Add-HostGroupMembership" { - New-Host -Name "pestertesthost1" -HostGroupId 2 -TemplateId 10108 -Dns localhost -errorAction silentlycontinue - New-Host -Name "pestertesthost2" -HostGroupId 2 -TemplateId 10108 -Dns localhost -errorAction silentlycontinue - $h1 = get-host pestertesthost1 - $h2 = get-host pestertesthost2 - New-HostGroup "pestertest1" -errorAction silentlycontinue - New-HostGroup "pestertest2" -errorAction silentlycontinue - $g1 = get-HostGroup pestertest1 - $g2 = get-HostGroup pestertest2 - - It "adds a set of groups given as a parameter to multiple piped hosts" { - $h1,$h2 | Add-HostGroupMembership $g1,$g2 - (get-HostGroup pestertest1).hosts.Count | should be 2 - } - } - - Describe "Remove-HostGroupMembership" { - New-Host -Name "pestertesthost1" -HostGroupId 2 -TemplateId 10108 -Dns localhost -errorAction silentlycontinue - New-Host -Name "pestertesthost2" -HostGroupId 2 -TemplateId 10108 -Dns localhost -errorAction silentlycontinue - $h1 = get-host pestertesthost1 - $h2 = get-host pestertesthost2 - New-HostGroup "pestertest1" -errorAction silentlycontinue - New-HostGroup "pestertest2" -errorAction silentlycontinue - $g1 = get-HostGroup pestertest1 - $g2 = get-HostGroup pestertest2 - - It "removes a set of groups given as a parameter to multiple piped hosts" { - $h1,$h2 | Remove-HostGroupMembership $g1,$g2 - (get-HostGroup pestertest1).hosts.Count | should be 0 - } - } - - Describe "Get-Template" { - It "can return all templates" { - Get-Template | Should Not BeNullOrEmpty - } - It "can filter by name with wildcard (explicit parameter)" { - Get-Template "Template OS Lin*" | Should Not BeNullOrEmpty - Get-Template "XXXXXXXXXXXXXX" | Should BeNullOrEmpty - } - It "can filter by ID (explicit parameter)" { - $h = (Get-Template "Template OS Lin*")[0] - (Get-Template -Id $h.templateid).host | Should Be $h.host - } - } - - Describe "New-HostGroup" { - It "creates a new group with explicit name parameter" { - $g = New-HostGroup "pestertest$(Get-Random)","pestertest$(Get-Random)" - $g.count | should be 2 - $g[0].name | should match "pestertest" - } - It "creates a new group with piped names" { - $g = "pestertest$(Get-Random)","pestertest$(Get-Random)" | New-HostGroup - $g.count | should be 2 - $g[0].name | should match "pestertest" - } - It "creates a new group with piped objects" { - $g = (New-Object -TypeName PSCustomObject -Property @{name = "pestertest$(Get-Random)"}),(New-Object -TypeName PSCustomObject -Property @{name = "pestertest$(Get-Random)"}) | New-HostGroup - $g.count | should be 2 - $g[0].name | should match "pestertest" - } - } - - Describe "Get-HostGroup" { - It "can return all groups" { - Get-HostGroup | Should Not BeNullOrEmpty - } - It "can filter by name with wildcard (explicit parameter)" { - Get-HostGroup "pestertest*" | Should Not BeNullOrEmpty - Get-HostGroup "XXXXXXXXXXXXXX" | Should BeNullOrEmpty - } - It "can filter by ID (explicit parameter)" { - $h = (Get-HostGroup "pestertest*")[0] - (Get-HostGroup -Id $h.groupid).name | Should Be $h.name - } - } - - Describe "Remove-HostGroup" { - It "can delete from one explicit ID parameter" { - New-HostGroup -Name "pestertestrem" -errorAction silentlycontinue - $h = Get-HostGroup pestertestrem - remove-HostGroup $h.groupid | should be $h.groupid - Get-HostGroup pestertestrem | should Throw - } - It "can delete from multiple explicit ID parameters" { - $h1 = New-HostGroup -Name "pestertestrem" - $h2 = New-HostGroup -Name "pestertestrem2" -errorAction silentlycontinue - $h2 = get-Hostgroup pestertestrem2 - remove-Hostgroup $h1.groupid,$h2.groupid | should be @($h1.groupid, $h2.groupid) - Get-HostGroup pestertestrem | should Throw - Get-HostGroup pestertestrem2 | should Throw - } - It "can delete from multiple piped IDs" { - $h1 = New-HostGroup -Name "pestertestrem" - $h2 = New-HostGroup -Name "pestertestrem2" - $h1.groupid,$h2.groupid | remove-Hostgroup | should be @($h1.groupid, $h2.groupid) - } - It "can delete from one piped object parameter" { - $h = New-HostGroup -Name "pestertestrem" - $h | remove-Hostgroup | should be $h.groupid - } - It "can delete from multiple piped objects" { - $h1 = New-HostGroup -Name "pestertestrem" - $h2 = New-HostGroup -Name "pestertestrem2" - $h1,$h2 | remove-Hostgroup | should be @($h1.groupid, $h2.groupid) - } - } - - Describe "Get-UserGroup" { - It "can return all groups" { - Get-UserGroup | Should Not BeNullOrEmpty - } - It "can filter by name with wildcard (explicit parameter)" { - Get-UserGroup "Zabbix*" | Should Not BeNullOrEmpty - Get-UserGroup "XXXXXXXXXXXXXX" | Should BeNullOrEmpty - } - It "can filter by ID (explicit parameter)" { - $h = (Get-UserGroup "Zabbix*")[0] - (Get-UserGroup -Id $h.usrgrpid).name | Should Be $h.name - } - } - - Describe "New-UserGroup" { - It "creates a new group with explicit name parameter" { - $g = New-UserGroup "pestertest$(Get-Random)","pestertest$(Get-Random)" - $g.count | should be 2 - $g[0].name | should match "pestertest" - } - It "creates a new group with piped names" { - $g = "pestertest$(Get-Random)","pestertest$(Get-Random)" | New-UserGroup - $g.count | should be 2 - $g[0].name | should match "pestertest" - } - It "creates a new group with piped objects" { - $g = (New-Object -TypeName PSCustomObject -Property @{name = "pestertest$(Get-Random)"}),(New-Object -TypeName PSCustomObject -Property @{name = "pestertest$(Get-Random)"}) | New-UserGroup - $g.count | should be 2 - $g[0].name | should match "pestertest" - } - } - - Describe "Remove-UserGroup" { - It "can delete from one explicit ID parameter" { - New-UserGroup -Name "pestertestrem" -errorAction silentlycontinue - $h = Get-UserGroup pestertestrem - Remove-UserGroup $h.usrgrpid | should be $h.usrgrpid - Get-UserGroup pestertestrem | should Throw - } - It "can delete from multiple explicit ID parameters" { - $h1 = New-UserGroup -Name "pestertestrem" - $h2 = New-UserGroup -Name "pestertestrem2" -errorAction silentlycontinue - $h2 = get-Usergroup pestertestrem2 - remove-usergroup $h1.usrgrpid,$h2.usrgrpid | should be @($h1.usrgrpid, $h2.usrgrpid) - Get-UserGroup pestertestrem | should Throw - Get-UserGroup pestertestrem2 | should Throw - } - It "can delete from multiple piped IDs" { - $h1 = New-UserGroup -Name "pestertestrem" - $h2 = New-UserGroup -Name "pestertestrem2" - $h1.usrgrpid,$h2.usrgrpid | remove-usergroup | should be @($h1.usrgrpid, $h2.usrgrpid) - } - It "can delete from one piped object parameter" { - $h = New-UserGroup -Name "pestertestrem" - $h | remove-Usergroup | should be $h.usrgrpid - } - It "can delete from multiple piped objects" { - $h1 = New-UserGroup -Name "pestertestrem" - $h2 = New-UserGroup -Name "pestertestrem2" - $h1,$h2 | remove-Usergroup | should be @($h1.usrgrpid, $h2.usrgrpid) - } - } - - Describe "Get-User" { - It "can return all users" { - Get-User | Should Not BeNullOrEmpty - } - It "can filter by name with wildcard (explicit parameter)" { - Get-User "Admi*" | Should Not BeNullOrEmpty - Get-User "XXXXXXXXXXXXXX" | Should BeNullOrEmpty - } - It "can filter by ID (explicit parameter)" { - $h = (Get-User "Admin")[0] - (Get-User -Id $h.userid).alias | Should Be $h.alias - } - } - - Describe "New-User" { - It "creates a new user with explicit parameters" { - $g = @(New-User -Alias "pestertest$(get-random)" -name "marsu" -UserGroupId 8) - $g.count | should be 1 - $g[0].name | should match "marsu" - } - It "creates a new user from another user (copy)" { - $u = @(New-User -Alias "pestertest$(get-random)" -name "marsu" -UserGroupId 8) - $g = $u | new-user -alias "pestertest$(get-random)" - $g.userid | should Not Be $null - $g.name | should match "marsu" - $g.usrgrps.usrgrpid | should be 8 - } - } - - Describe "Remove-User" { - It "can delete from one explicit ID parameter" { - New-User -Alias "pestertestrem" -UserGroupId 8 -errorAction silentlycontinue - $h = Get-User pestertestrem - Remove-User $h.userid | should be $h.userid - Get-User pestertestrem | should Throw - } - It "can delete from multiple explicit ID parameters" { - $h1 = New-User -Alias "pestertestrem" -UserGroupId 8 - $h2 = New-User -Alias "pestertestrem2" -UserGroupId 8 -errorAction silentlycontinue - $h2 = get-User pestertestrem2 - remove-user $h1.userid,$h2.userid | should be @($h1.userid, $h2.userid) - Get-User pestertestrem | should Throw - Get-User pestertestrem2 | should Throw - } - It "can delete from multiple piped IDs" { - $h1 = New-User -Alias "pestertestrem" -UserGroupId 8 - $h2 = New-User -Alias "pestertestrem2" -UserGroupId 8 - $h1.userid,$h2.userid | remove-user | should be @($h1.userid, $h2.userid) - } - It "can delete from one piped object parameter" { - $h = New-User -Alias "pestertestrem" -UserGroupId 8 - $h | remove-User | should be $h.userid - } - It "can delete from multiple piped objects" { - $h1 = New-User -Alias "pestertestrem" -UserGroupId 8 - $h2 = New-User -Alias "pestertestrem2" -UserGroupId 8 - $h1,$h2 | remove-User | should be @($h1.userid, $h2.userid) - } - } - - Describe "Add-UserGroupMembership" { - It "can add two user groups (explicit parameter) to piped users" { - Get-User "pester*" | remove-User - Get-UserGroup "pester*" | remove-UserGroup - - $g1 = New-UserGroup -Name "pestertestmembers" - $g2 = New-UserGroup -Name "pestertestmembers2" - $g1 = get-Usergroup pestertestmembers - $g2 = get-Usergroup pestertestmembers2 - - $u1 = New-User -Alias "pestertestrem" -UserGroupId 8 - $u2 = New-User -Alias "pestertestrem2" -UserGroupId 8 - $u1 = get-User pestertestrem - $u2 = get-User pestertestrem2 - - $u1,$u2 | Add-UserGroupMembership $g1,$g2 | should be @($u1.userid, $u2.userid) - $u1 = get-User pestertestrem - $u2 = get-User pestertestrem2 - $u1.usrgrps | select -ExpandProperty usrgrpid | Should Be @(8, $g1.usrgrpid, $g2.usrgrpid) - } - It "same with ID instead of objects" { - Get-User "pester*" | remove-User - Get-UserGroup "pester*" | remove-UserGroup - - $g1 = New-UserGroup -Name "pestertestmembers3" - $g2 = New-UserGroup -Name "pestertestmembers4" - $g1 = get-Usergroup pestertestmembers3 - $g2 = get-Usergroup pestertestmembers4 - - $u1 = New-User -Alias "pestertestrem3" -UserGroupId 8 - $u2 = New-User -Alias "pestertestrem4" -UserGroupId 8 - $u1 = get-User pestertestrem3 - $u2 = get-User pestertestrem4 - - $u1.userid,$u2.userid | Add-UserGroupMembership $g1.usrgrpid,$g2.usrgrpid | should be @($u1.userid, $u2.userid) - $u1 = get-User pestertestrem3 - $u2 = get-User pestertestrem4 - $u1.usrgrps | select -ExpandProperty usrgrpid | Should Be @(8, $g1.usrgrpid, $g2.usrgrpid) - } - } - - Describe "Remove-UserGroupMembership" { - It "can remove two user groups (explicit parameter) to piped users" { - Get-User "pester*" | remove-User - Get-UserGroup "pester*" | remove-UserGroup - - $g1 = New-UserGroup -Name "pestertestmembers" - $g2 = New-UserGroup -Name "pestertestmembers2" - $g1 = get-Usergroup pestertestmembers - $g2 = get-Usergroup pestertestmembers2 - - $u1 = New-User -Alias "pestertestrem" -UserGroupId 8 - $u2 = New-User -Alias "pestertestrem2" -UserGroupId 8 - $u1 = get-User pestertestrem - $u2 = get-User pestertestrem2 - - $u1,$u2 | Add-UserGroupMembership $g1,$g2 | should be @($u1.userid, $u2.userid) - $u1,$u2 | Remove-UserGroupMembership $g1,$g2 | should be @($u1.userid, $u2.userid) - $u1 = get-User pestertestrem - $u2 = get-User pestertestrem2 - $u1.usrgrps | select -ExpandProperty usrgrpid | Should Be @(8) - } - It "same with ID instead of objects" { - Get-User "pester*" | remove-User - Get-UserGroup "pester*" | remove-UserGroup - - $g1 = New-UserGroup -Name "pestertestmembers3" - $g2 = New-UserGroup -Name "pestertestmembers4" - $g1 = get-Usergroup pestertestmembers3 - $g2 = get-Usergroup pestertestmembers4 - - $u1 = New-User -Alias "pestertestrem3" -UserGroupId 8 - $u2 = New-User -Alias "pestertestrem4" -UserGroupId 8 - $u1 = get-User pestertestrem3 - $u2 = get-User pestertestrem4 - - $u1.userid,$u2.userid | Add-UserGroupMembership $g1.usrgrpid,$g2.usrgrpid | should be @($u1.userid, $u2.userid) - $u1 = get-User pestertestrem3 - $u2 = get-User pestertestrem4 - $u1.usrgrps | select -ExpandProperty usrgrpid | Should Be @(8, $g1.usrgrpid, $g2.usrgrpid) - $u1.userid,$u2.userid | Remove-UserGroupMembership $g1.usrgrpid,$g2.usrgrpid | should be @($u1.userid, $u2.userid) - $u1 = get-User pestertestrem3 - $u2 = get-User pestertestrem4 - $u1.usrgrps | select -ExpandProperty usrgrpid | Should Be @(8) - } - } - - Describe "Add-UserGroupPermission" { - It "can add a Read permission to two piped user groups on two host groups" { - Get-HostGroup "pester*" | remove-HostGroup - Get-UserGroup "pester*" | remove-UserGroup - - New-UserGroup -Name "pestertest1","pestertest2" - $ug1 = get-Usergroup pestertest1 - $ug2 = get-Usergroup pestertest2 - - New-HostGroup "pestertest1","pestertest2" - $hg1 = get-HostGroup pestertest1 - $hg2 = get-HostGroup pestertest2 - - $ug1,$ug2 | Add-UserGroupPermission $hg1,$hg2 ReadWrite | should be @($ug1.usrgrpid, $ug2.usrgrpid) - $ug1 = get-Usergroup pestertest1 - $ug2 = get-Usergroup pestertest2 - $ug1.rights | select -ExpandProperty id | Should Be @($hg1.groupid, $hg2.groupid) - $ug1.rights | select -ExpandProperty permission | Should Be @(3, 3) - } - It "can alter and clear permissions on a host group without touching permissions on other groups" { - $ug1 = get-Usergroup pestertest1 - $ug2 = get-Usergroup pestertest2 - $hg1 = get-HostGroup pestertest1 - $hg2 = get-HostGroup pestertest2 - - # Sanity check - $ug1.rights | select -ExpandProperty id | Should Be @($hg1.groupid, $hg2.groupid) - $ug1.rights | select -ExpandProperty permission | Should Be @(3, 3) - - # Set HG1 RO. - $ug1,$ug2 | Add-UserGroupPermission $hg1 ReadOnly | should be @($ug1.usrgrpid, $ug2.usrgrpid) - $ug1 = get-Usergroup pestertest1 - $ug2 = get-Usergroup pestertest2 - $ug1.rights | select -ExpandProperty id | Should Be @($hg1.groupid, $hg2.groupid) - $ug1.rights | select -ExpandProperty permission | Should Be @(2, 3) - - # Clear HG1 - $ug1,$ug2 | Add-UserGroupPermission $hg1 Clear | should be @($ug1.usrgrpid, $ug2.usrgrpid) - $ug1 = get-Usergroup pestertest1 - $ug2 = get-Usergroup pestertest2 - $ug1.rights | select -ExpandProperty id | Should Be @($hg2.groupid) - $ug1.rights | select -ExpandProperty permission | Should Be @(3) - } - } - - Describe "Get-MediaType" { - It "can return all types" { - Get-MediaType | Should Not BeNullOrEmpty - } - It "can filter by technical media type" { - Get-MediaType -type Email | Should Not BeNullOrEmpty - Get-MediaType -type EzTexting | Should BeNullOrEmpty - } - } - - Describe "Add-UserMail" { - It "can add a mail to a user without mail" { - $u = @(New-User -Alias "pestertestmedia$(get-random)" -name "marsu" -UserGroupId 8)[0] - $u | Add-UserMail toto1@company.com | Should Not BeNullOrEmpty - } - It "can add a mail with specific severity filter" { - $u = @(New-User -Alias "pestertestmedia$(get-random)" -name "marsu" -UserGroupId 8)[0] - $u | Add-UserMail toto1@company.com Information,Warning | Should Not BeNullOrEmpty - } - } - - Describe "Get-Media" { - It "can return all media" { - Get-Media | Should Not BeNullOrEmpty - } - - It "can filter by media type" { - Get-Media -MediaTypeId (Get-MediaType -Type email).mediatypeid | Should Not BeNullOrEmpty - } - - It "can filter actions used by certain users" { - Get-Media -UserId @(Get-User -Name "pestertestmedia*")[0].userid | Should Not BeNullOrEmpty - Get-Media -UserId @(Get-User -Name "Admin")[0].userid | Should BeNullOrEmpty - } - } - - Describe "Remove-Media" { - It "can remove piped media" { - Get-Media | Remove-Media | Should Not BeNullOrEmpty - Get-Media | Should BeNullOrEmpty - Get-User -Name "pestertestmedia*" | Remove-User > $null - } - } - - Describe "Disable-UserGroup" { - New-UserGroup -Name "pestertestenable1" -errorAction silentlycontinue - $h1 = get-usergroup pestertestenable1 - - It "can disable multiple piped objects" { - $h1 | Disable-UserGroup | should be @($h1.usrgrpid) - [int](get-usergroup pestertestenable1).users_status | should be 1 - } - } - - Describe "Enable-UserGroup" { - New-UserGroup -Name "pestertestenable1" -errorAction silentlycontinue - $h1 = get-usergroup pestertestenable1 - - It "can enable multiple piped objects" { - $h1 | Enable-UserGroup | should be @($h1.usrgrpid) - [int](get-usergroup pestertestenable1).users_status | should be 0 - } - } - - Describe "Update-Host" { - $name = "pestertesthost$(Get-Random)" - Get-Host -name "perster*" | remove-host - Get-Host -name "newname" | remove-host - $h = New-Host -Name $name -HostGroupId 2 -TemplateId 10108 -Dns localhost -errorAction silentlycontinue - - It "can update the name of a host" { - $h.name = "newname" - $h | update-host - get-host -id $h.hostid | select -ExpandProperty name | should be "newname" - } - } -} \ No newline at end of file diff --git a/PSZabbix.psd1 b/PSZabbix.psd1 index 5064c93..da4b4dc 100644 Binary files a/PSZabbix.psd1 and b/PSZabbix.psd1 differ diff --git a/PSZabbix.psm1 b/PSZabbix.psm1 index 25502b1..dc1d0c8 100644 --- a/PSZabbix.psm1 +++ b/PSZabbix.psm1 @@ -1,2151 +1,15 @@ $ErrorActionPreference = "Stop" $latestSession = $null +$Private = @( Get-ChildItem -Path $PSScriptRoot/src/Private/*.ps1 -ErrorAction SilentlyContinue ) +$Public = @( Get-ChildItem -Path $PSScriptRoot/src/Public/*.ps1 -ErrorAction SilentlyContinue ) -################################################################################ -## INTERNAL HELPERS -################################################################################ - -function New-JsonrpcRequest($method, $params, $auth = $null) -{ - if ($params.output -eq $null -and $method -like "*.get") - { - $params["output"] = "extend" - } - - return ConvertTo-Json @{ - jsonrpc = "2.0" - method = $method - params = $params - id = 1 - auth = $auth - } -Depth 20 -} - - -function Get-ApiVersion($Session) -{ - $r = Invoke-RestMethod -Uri $session.Uri -Method Post -ContentType "application/json" -Body (new-JsonrpcRequest "apiinfo.version" @{}) - $r.result -} - -function New-ApiSession -{ - <# - .SYNOPSIS - Create a new authenticated session which can be used to call the Zabbix REST API. - - .DESCRIPTION - It must be called all other functions. It returns the actual session object, but usually - this object is not needed as the module caches and reuses the latest successful session. - - The validity of the credentials is checked and an error is thrown if not. - - .INPUTS - This function does not take pipe input. - - .OUTPUTS - The session object. - - .EXAMPLE - PS> New-ZbxApiSession "http://myserver/zabbix/api_jsonrpc.php" (Get-Credentials MyAdminLogin) - Name Value - ---- ----- - Auth 2cce0ad0fac0a5da348fdb70ae9b233b - Uri http://myserver/zabbix/api_jsonrpc.php - WARNING : Connected to Zabbix version 3.2.1 - #> - param( - # The Zabbix REST endpoint. It should be like "http://myserver/zabbix/api_jsonrpc.php". - [uri] $ApiUri, - - # The credentials used to authenticate. Use Get-Credential to create this object. - [PSCredential]$auth, - - # If this switch is used, the information message "connected to..." will not be displayed. - [switch]$Silent - ) - $r = Invoke-RestMethod -Uri $ApiUri -Method Post -ContentType "application/json" -Body (new-JsonrpcRequest "user.login" @{user = $auth.UserName; password = $auth.GetNetworkCredential().Password}) - if ($r -eq $null -or $r.result -eq $null -or [string]::IsNullOrWhiteSpace($r.result)) - { - Write-Error -Message "Session could not be opened" - } - $script:latestSession = @{Uri = $ApiUri; Auth = $r.result} - $script:latestSession - - $ver = Get-ApiVersion -Session $script:latestSession - $vers = $ver.split(".") - if ( ($vers[0] -lt 2) -or ($vers[0] -eq 2 -and $vers[1] -lt 4)) - { - Write-Warning "PSZabbix has not been tested with this version of Zabbix ${ver}. Tested version are >= 2.4. It should still work but be warned." - } - if (-not $Silent) - { - Write-Warning "Connected to Zabbix version ${ver}" - } -} - - -function Invoke-ZabbixApi($session, $method, $parameters = @{}) -{ - if ($session -eq $null) { $session = $latestSession } - if ($session -eq $null) - { - Write-Error -Message "No session is opened. Call New-ZabbixApiSession before or pass a previously retrieved session object as a parameter." - return - } - - $r = Invoke-RestMethod -Uri $session.Uri -Method Post -ContentType "application/json" -Body (new-JsonrpcRequest $method $parameters $session.Auth) - if ($r.error -ne $null) - { - Write-Error -Message "$($r.error.message) $($r.error.data)" -ErrorId $r.error.code - } - else - { - return $r.result - } -} - - - -################################################################################ -## HOSTS -################################################################################ - -Add-Type -TypeDefinition @" - public enum ZbxStatus - { - Enabled = 0, - Disabled = 1 - } -"@ - - -function Get-Host -{ - <# - .SYNOPSIS - Retrieve and filter hosts. - - .DESCRIPTION - Query all hosts (not templates) with basic filters, or get all hosts. - - .INPUTS - This function does not take pipe input. - - .OUTPUTS - The ZabbixHost objects corresponding to the filter. - - .EXAMPLE - PS> Get-ZbxHost - hostid host name status - ------ ---- ---- ------ - 10084 Zabbix server Zabbix server Enabled - 10105 Agent Mongo 1 Agent Mongo 1 Enabled - - .EXAMPLE - PS> Get-ZbxHost -Id 10084 - hostid host name status - ------ ---- ---- ------ - 10084 Zabbix server Zabbix server Enabled - - .EXAMPLE - PS> Get-ZbxHost "Agent*" - hostid host name status - ------ ---- ---- ------ - 10105 Agent Mongo 1 Agent Mongo 1 Enabled - 10106 Agent Mongo 2 Agent Mongo 2 Enabled - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$False)][Alias("HostId")] - # Only retrieve the items with the given ID(s). - [int[]] $Id, - - [Parameter(Mandatory=$False)] - # Only retrieve items which belong to the given group(s). - [int[]] $HostGroupId, - - [Parameter(Mandatory=$False, Position=0)][Alias("HostName")] - # Filter by hostname. Accepts wildcard. - [string] $Name - ) - $prms = @{search= @{}; searchWildcardsEnabled = 1; selectInterfaces = @("interfaceid", "ip", "dns"); selectParentTemplates = 1} - if ($Id.Length -gt 0) {$prms["hostids"] = $Id} - if ($HostGroupId.Length -gt 0) {$prms["groupids"] = $GroupId} - if ($Name -ne $null) {$prms["search"]["name"] = $Name} - Invoke-ZabbixApi $session "host.get" $prms |% {$_.status = [ZbxStatus]$_.status; $_.hostid = [int]$_.hostid; $_.PSTypeNames.Insert(0,"ZabbixHost"); $_} -} - - -function New-Host -{ - <# - .SYNOPSIS - Create a new host. - - .DESCRIPTION - Create a new host. - - .INPUTS - This function does not take pipe input. - - .OUTPUTS - The ZabbixHost object created. - - .EXAMPLE - PS> New-ZbxHost -Name "mynewhostname$(Get-Random)" -HostGroupId 2 -TemplateId 10108 -Dns localhost - hostid host name status - ------ ---- ---- ------ - 10084 mynewhostname321 mynewhostname Enabled - - .NOTES - Contrary to other New-* functions inside this module, this method does not take pipe input. - This is inconsistent and needs to be changed. - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [parameter(Mandatory=$true)][Alias("HostName")] - # The name of the new host (not the visible name) - [string] $Name, - - [parameter(Mandatory=$false)][Alias("DisplayName")] - # The name as displayed in the interface. Defaults to Name. - [string] $VisibleName, - - [parameter(Mandatory=$false)] - # A description of the new host. - [string] $Description = $null, - - [parameter(Mandatory=$true, ParameterSetName="Ids")] - # The groups the new host should belong to. - [int[]] $HostGroupId, - - [parameter(Mandatory=$true, ParameterSetName="Objects")] - # The groups the new host should belong to. - [PSCustomObject[]] $HostGroup, - - [parameter(Mandatory=$true, ParameterSetName="Ids")] - # The templates the new host should belong to. - [int[]] $TemplateId, - - [parameter(Mandatory=$true, ParameterSetName="Objects")] - # The templates the new host should belong to. - [PSCustomObject[]] $Template, - - [parameter(Mandatory=$false)] - # An optional map of inventory properties - $Inventory = @{}, - - [parameter(Mandatory=$true)] - # The DNS or IP address to use to contact the host - [string] $Dns, - - [parameter(Mandatory=$false)] - # The port to use to use to contact the host. Default is 10050. - [int] $Port = 10050, - - [parameter(Mandatory=$false)] - # Should the newly created host be enabled? Default is true. - [ZbxStatus] $Status = [ZbxStatus]::Enabled, - - [parameter(Mandatory=$false)] - # The ID of the proxy to use. Default is no proxy. - [int] $ProxyId - ) - - $isIp = 0 - try { [ipaddress]$Dns; $isIp = 1} catch {} - - if ($Hostgroupid -ne $null) - { - $HostGroup = @() - $HostGroupId |% { $HostGroup += @{"groupid" = $_} } - } - if ($TemplateId -ne $null) - { - $Template = @() - $TemplateId |% { $Template += @{"templateid" = $_} } - } - - $prms = @{ - host = $Name - name = if ([string]::IsNullOrWhiteSpace($VisibleName)) { $null } else { $VisibleName } - description = $Description - interfaces = @( @{ - type = 1 - main = 1 - useip = $isIp - dns = if ($isIp -eq 1) { "" } else { $Dns } - ip = if ($isIp -eq 0) { "" } else { $Dns } - port = $Port - }) - groups = $HostGroup - templates = $Template - inventory_mode = 0 - inventory = $Inventory - status = [int]$Status - proxy_hostid = if ($ProxyId -eq $null) { "" } else { $ProxyId } - } - - $r = Invoke-ZabbixApi $session "host.create" $prms - Get-Host -session $s -Id $r.hostids -} - - -function Remove-Host -{ - <# - .SYNOPSIS - Remove one or more hosts from Zabbix. - - .DESCRIPTION - Removal is immediate. - - .INPUTS - This function accepts ZabbixHost objects or host IDs from the pipe. Equivalent to using -HostId parameter. - - .OUTPUTS - The ID of the removed objects. - - .EXAMPLE - Remove all hosts - PS> Get-ZbxHost | Remove-ZbxHost - 10084 - 10085 - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)][ValidateNotNullOrEmpty()][Alias("Id")] - # The ID of one or more hosts to remove. You can also pipe a ZabbixHost object or any object with a hostid or id property. - [int[]]$HostId - ) - - begin - { - $prms = @() - } - process - { - $prms += $HostId - } - end - { - if ($prms.Count -eq 0) { return } - Invoke-ZabbixApi $session "host.delete" $prms | select -ExpandProperty hostids - } -} - - -function Enable-Host -{ - <# - .SYNOPSIS - Enable one or more hosts from Zabbix. - - .DESCRIPTION - Simple change of the status of the host. Idempotent. - - .INPUTS - This function accepts ZabbixHost objects or host IDs from the pipe. Equivalent to using -HostId parameter. - - .OUTPUTS - The ID of the changed objects. - - .EXAMPLE - Enable all hosts - PS> Get-ZbxHost | Enable-ZbxHost - 10084 - 10085 - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true, Position=0)][Alias("Id", "Host")] - # The ID of one or more hosts to enable. You can also pipe a ZabbixHost object or any object with a hostid or id property. - [int[]]$HostId - ) - begin - { - $ids = @() - } - Process - { - $HostId |% {$ids += @{hostid = $_}} - } - end - { - if ($ids.Count -eq 0) { return } - Invoke-ZabbixApi $session "host.massupdate" @{hosts=$ids; status=0} | select -ExpandProperty hostids - } -} - - -function Disable-Host -{ - <# - .SYNOPSIS - Disable one or more hosts from Zabbix. - - .DESCRIPTION - Simple change of the status of the host. Idempotent. - - .INPUTS - This function accepts ZabbixHost objects or host IDs from the pipe. Equivalent to using -HostId parameter. - - .OUTPUTS - The ID of the changed objects. - - .EXAMPLE - Disable all hosts - PS> Get-ZbxHost | Disable-ZbxHost - 10084 - 10085 - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true, Position=0)][Alias("Id", "Host")] - # The ID of one or more hosts to disable. You can also pipe a ZabbixHost object or any object with a hostid or id property. - [int[]]$HostId - ) - begin - { - $ids = @() - } - Process - { - $HostId |% {$ids += @{hostid = $_}} - } - end - { - if ($ids.Count -eq 0) { return } - Invoke-ZabbixApi $session "host.massupdate" @{hosts=$ids; status=1} | select -ExpandProperty hostids - } -} - - -function Add-HostGroupMembership -{ - <# - .SYNOPSIS - Make a host (or multiple hosts) member of one or more host groups. - - .DESCRIPTION - This is additional: existing membership to other groups are not changed. - - .INPUTS - This function accepts ZabbixHost objects from the pipe. Equivalent to using -Host parameter. - - .OUTPUTS - The ID of the changed objects. - - .EXAMPLE - PS> Get-ZbxHost | Add-ZbxHostGroupMembership (Get-ZbxGroup group1),(Get-ZbxGroup group2) - 10084 - 10085 - - Add two groups to all hosts - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=1)][ValidateScript({ $_.PSObject.TypeNames[0] -eq 'ZabbixHost'})][ValidateNotNullOrEmpty()] - # The host or hostid to add to the hostgroup. - [PSCustomObject[]]$Host, - - [Parameter(Mandatory=$true, Position=0)][ValidateNotNullOrEmpty()] - # The Host is added to this list of one or more hostgroups. - [PSCustomObject[]]$HostGroup - ) - begin - { - $grpids = @($HostGroup |% {@{groupid = $_.groupid}} ) - $prms = @{hosts = @(); groups = $grpids} - } - process - { - $prms["hosts"] += $Host.hostid - } - end - { - Invoke-ZabbixApi $session "host.massadd" $prms | select -ExpandProperty hostids - } -} - - -function Remove-HostGroupMembership -{ - <# - .SYNOPSIS - Remove a host (or multiple hosts) as a member of one or more host groups. - - .DESCRIPTION - This is additional: existing membership to other groups are not changed. - - .INPUTS - This function accepts ZabbixHost objects from the pipe. Equivalent to using -Host parameter. - - .OUTPUTS - The ID of the changed objects. - - .EXAMPLE - PS> Get-ZbxHost | Remove-ZbxHostGroupMembership (Get-ZbxGroup group1),(Get-ZbxGroup group2) - 10084 - 10085 - - Make sure no host is member of two specified groups. - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=1)][ValidateScript({ $_.PSObject.TypeNames[0] -eq 'ZabbixHost'})][ValidateNotNullOrEmpty()] - # The host or hostid to remove from the hostgroup(s). - [PSCustomObject[]]$Host, - - [Parameter(Mandatory=$true, Position=0)][ValidateNotNullOrEmpty()][ValidateScript({ $_.PSObject.TypeNames[0] -eq 'ZabbixGroup'})] - # The Host is removed from this list of one or more hostgroups. - [PSCustomObject[]]$HostGroup - ) - begin - { - $grpids = @($HostGroup |% {$_.groupid} ) - $prms = @{hostids = @(); groupids = $grpids} - } - process - { - $prms["hostids"] += $Host.hostid - } - end - { - Invoke-ZabbixApi $session "host.massremove" $prms | select -ExpandProperty hostids - } -} - - -function Update-Host -{ - <# - .SYNOPSIS - Update the attributes of one or more existing Zabbix Hosts. - - .DESCRIPTION - Please note that this method actually updates all attributes of the host, even if they were not changed. - - This is first and foremost made to update direct attributes. To update linked linked objects like templates or interfaces, it is often more practical to use the dedicated cmdlets. - - .INPUTS - This function accepts ZabbixHost objects, on pipe or as argument. - - .OUTPUTS - The ID of the changed objects. - - .EXAMPLE - Sets a new description for all hosts. - PS> Get-ZbxHost |% { $_.name = "toto"; $_ } | Update-ZbxHost - 10084 - 10085 - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)] - [ValidateScript({ $_.PSObject.TypeNames[0] -eq 'ZabbixHost'})][ValidateNotNullOrEmpty()] - # One or more hosts to update. - [PSObject[]]$Host - ) - begin - { - $Hosts = @() - } - process - { - $Hosts += $Host - } - end - { - if ($Hosts.Count -eq 0) { return } - Invoke-ZabbixApi $session "host.update" $Hosts | select -ExpandProperty hostids - } -} - - -################################################################################ -## TEMPLATES -################################################################################ - -function Get-Template -{ - <# - .SYNOPSIS - Retrieve and filter templates. - - .DESCRIPTION - Query all templates (not hosts) with basic filters, or get all templates. - - .INPUTS - This function does not take pipe input. - - .OUTPUTS - The ZabbixTemplate objects corresponding to the filter. - - .EXAMPLE - PS> Get-ZbxHost - templateid name description - ---------- ---- ----------- - 10001 Template OS Linux - 10047 Template App Zabbix Server - 10048 Template App Zabbix Proxy - 10050 Template App Zabbix Agent - - .EXAMPLE - PS> Get-ZbxHost -Id 10001 - templateid name description - ---------- ---- ----------- - 10001 Template OS Linux - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$False)][Alias("TemplateId")] - # Only retrieve the template with the given ID. - [int[]] $Id, - - [Parameter(Mandatory=$False)] - # Only retrieve remplates which belong to the given group(s). - [int[]] $GroupId, - - [Parameter(Mandatory=$False)] - # Only retrieve templates which are linked to the given hosts - [int[]] $HostId, - - [Parameter(Mandatory=$False)] - # Only retrieve templates which are children of the given parent template(s) - [int[]] $ParentId, - - [Parameter(Mandatory=$False, Position=0)][Alias("TemplateName")] - # Filter by name. Accepts wildcard. - [string] $Name - ) - $prms = @{search= @{}; searchWildcardsEnabled=1} - if ($Id.Length -gt 0) {$prms["templateids"] = $Id} - if ($GroupId.Length -gt 0) {$prms["groupids"] = $GroupId} - if ($HostId.Length -gt 0) {$prms["hostids"] = $HostId} - if ($Name -ne $null) {$prms["search"]["name"] = $Name} - Invoke-ZabbixApi $session "template.get" $prms |% {$_.templateid = [int]$_.templateid; $_.PSTypeNames.Insert(0,"ZabbixTemplate"); $_} -} - - -function Remove-Template -{ - <# - .SYNOPSIS - Remove one or more templates from Zabbix. - - .DESCRIPTION - Removal is immediate. - - .INPUTS - This function accepts ZabbixTemplate objects or template IDs from the pipe. Equivalent to using -TemplateId parameter. - - .OUTPUTS - The ID of the removed objects. - - .EXAMPLE - Remove all templates - PS> Get-ZbxTemplate | Remove-ZbxTemplate - 10084 - 10085 - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)][ValidateNotNullOrEmpty()][Alias("Template")] - # The templates to remove. Either template objects (with a templateid property) or directly IDs. - [int[]]$TemplateId - ) - - begin - { - $prms = @() - } - process - { - $prms += $TemplateId - } - end - { - if ($prms.Count -eq 0) { return } - Invoke-ZabbixApi $session "template.delete" $prms | select -ExpandProperty templateids - } -} - - - -################################################################################ -## HOST GROUPS -################################################################################ - -#region host groups -function Get-HostGroup -{ - <# - .SYNOPSIS - Retrieve and filter host groups. - - .DESCRIPTION - Query all host groups with basic filters, or get all host groups. - - .INPUTS - This function does not take pipe input. - - .OUTPUTS - The ZabbixHostGroup objects corresponding to the filter. - - .EXAMPLE - PS> Get-ZbxHostGroup "Linux*" - groupid internal flags name - ------- -------- ----- ---- - 1 0 0 Linux Group 1 - 2 0 0 Linux Group 2 - - .EXAMPLE - PS> Get-ZbxHostGroup - groupid internal flags name - ------- -------- ----- ---- - 1 0 0 Templates - 2 0 0 Linux servers - 4 0 0 Zabbix servers - - .EXAMPLE - PS> Get-ZbxHostGroup -Id 1 - groupid internal flags name - ------- -------- ----- ---- - 1 0 0 Templates - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$False)] - # Only retrieve the groups with the given ID(s) - [int[]] $Id, - - [Parameter(Mandatory=$False)] - # Only retrieve the groups which contain the given host(s) - [int[]] $HostId, - - [Parameter(Mandatory=$False, Position=0)][Alias("GroupName")] - # Filter by name. Accepts wildcard. - [string] $Name - ) - $prms = @{search= @{}; searchWildcardsEnabled = 1; selectHosts = 1} - if ($HostId.Length -gt 0) {$prms["hostids"] = $HostId} - if ($Id.Length -gt 0) {$prms["groupids"] = $Id} - if ($Name -ne $null) {$prms["search"]["name"] = $Name} - Invoke-ZabbixApi $session "hostgroup.get" $prms |% {$_.groupid = [int]$_.groupid; $_.PSTypeNames.Insert(0,"ZabbixGroup"); $_} -} - - -function New-HostGroup -{ - <# - .SYNOPSIS - Create a new host group. - - .DESCRIPTION - Create a new host group. - - .INPUTS - This function accepts a ZabbixHostGroup as pipe input, or any object which properties map the function parameters. - - .OUTPUTS - The ZabbixHostGroup object created. - - .EXAMPLE - PS> New-ZbxHostGroup "newgroupname1","newgroupname2" - groupid internal flags name - ------- -------- ----- ---- - 13 0 0 newgroupname1 - 14 0 0 newgroupname2 - - .EXAMPLE - PS> "newgroupname1","newgroupname2" | New-ZbxHostGroup - groupid internal flags name - ------- -------- ----- ---- - 13 0 0 newgroupname1 - 14 0 0 newgroupname2 - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)][ValidateNotNullOrEmpty()][Alias("HostGroupName")] - # The name of the new group (one or more separated by commas) - [string[]] $Name - ) - begin - { - $prms = @() - } - process - { - $Name |% { $prms += @{name = $_} } - } - end - { - if ($prms.Count -eq 0) { return } - $r = Invoke-ZabbixApi $session "hostgroup.create" $prms - Get-HostGroup -Session $s -Id $r.groupids - } -} - - -function Remove-HostGroup -{ - <# - .SYNOPSIS - Remove one or more host groups from Zabbix. - - .DESCRIPTION - Removal is immediate. - - .INPUTS - This function accepts ZabbixHostGroup objects or host group IDs from the pipe. Equivalent to using -HostGroupId parameter. - - .OUTPUTS - The ID of the removed objects. - - .EXAMPLE - Remove all groups - PS> Get-ZbxHostGroup | Remove-ZbxHostGroup - 10084 - 10085 - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)][ValidateNotNullOrEmpty()][Alias("Id", "GroupId")] - # ID of one or more groups to remove. You can also pipe in objects with an "ID" of "groupid" property. - [int[]]$HostGroupId - ) - - begin - { - $prms = @() - } - process - { - $prms += $HostGroupId - } - end - { - if ($prms.Count -eq 0) { return } - Invoke-ZabbixApi $session "hostgroup.delete" $prms | select -ExpandProperty groupids - } -} -#endregion - - - -################################################################################ -## USER GROUPS -################################################################################ - -Add-Type -TypeDefinition @" - public enum ZbxGuiAccess - { - WithDefaultAuthenticationMethod = 0, - WithInternalAuthentication = 1, - Disabled = 2 - } -"@ - - -function Get-UserGroup -{ - <# - .SYNOPSIS - Retrieve and filter user groups. - - .DESCRIPTION - Query all user groups with basic filters, or get all user groups. - - .INPUTS - This function does not take pipe input. - - .OUTPUTS - The ZabbixUserGroup objects corresponding to the filter. - - .EXAMPLE - PS> Get-ZbxUserGroup "*admin*" - usrgrpid count name - -------- ----- ---- - 7 1 Zabbix administrators - - .EXAMPLE - PS> Get-ZbxUserGroup - usrgrpid count name - -------- ----- ---- - 7 1 Zabbix administrators - 8 4 Guests - 9 0 Disabled - - .EXAMPLE - PS> Get-ZbxUserGroup -Id 7 - usrgrpid count name - -------- ----- ---- - 7 1 Zabbix administrators - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$False)][Alias("UserGroupId", "UsrGrpId")] - # Only retrieve the usergroup with the given ID - [int[]] $Id, - - [Parameter(Mandatory=$False)] - # Only retrieve groups which contain the given users - [int[]] $UserId, - - [Parameter(Mandatory=$False, Position=0)][Alias("UserGroupName")] - # Filter by name. Accepts wildcard. - [string] $Name - ) - $prms = @{searchWildcardsEnabled=1; selectUsers= 1; selectRights = 1; search= @{}} - if ($Id.Length -gt 0) {$prms["usrgrpids"] = $Id} - if ($UserId.Length -gt 0) {$prms["userids"] = $UserId} - if ($Name -ne $null) {$prms["search"]["name"] = $Name} - Invoke-ZabbixApi $session "usergroup.get" $prms |% {$_.usrgrpid = [int]$_.usrgrpid; $_.users_status = [ZbxStatus]$_.users_status; $_.debug_mode = [ZbxStatus]$_.debug_mode; $_.PSTypeNames.Insert(0,"ZabbixUserGroup"); $_} -} - - -function New-UserGroup -{ - <# - .SYNOPSIS - Create a new user group. - - .DESCRIPTION - Create a new user group. - - .INPUTS - This function accepts a ZabbixUserGroup as pipe input, or any object which properties map the function parameters. - - .OUTPUTS - The ZabbixUserGroup object created. - - .EXAMPLE - PS> New-ZbxUserGroup "newgroupname1","newgroupname2" - usrgrpid count name - -------- ----- ---- - 7 1 newgroupname1 - 8 1 newgroupname2 - - .EXAMPLE - PS> "newgroupname1","newgroupname2" | New-ZbxUserGroup - usrgrpid count name - -------- ----- ---- - 7 1 newgroupname1 - 8 1 newgroupname2 - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)][ValidateNotNullOrEmpty()][Alias("UserGroupName")] - # The name of the new group (one or more separated by commas) - [string[]] $Name, - - [Parameter(Mandatory=$false)] - # Status of the new group. Default is enabled. - $Status = [ZbxStatus]::Enabled, - - [Parameter(Mandatory=$false)] - # If members have access to the GUI. Default is WithDefaultAuthenticationMethod. - $GuiAccess = [ZbxGuiAccess]::WithDefaultAuthenticationMethod - ) - begin - { - $prms = @() - } - process - { - $Name |% { $prms += @{name = $_; gui_access = [int]$GuiAccess; users_status = [int]$Status} } - } - end - { - if ($prms.Count -eq 0) { return } - $r = Invoke-ZabbixApi $session "usergroup.create" $prms - Get-UserGroup -Session $s -Id $r.usrgrpids - } -} - - -function Remove-UserGroup -{ - <# - .SYNOPSIS - Remove one or more user groups from Zabbix. - - .DESCRIPTION - Removal is immediate. - - .INPUTS - This function accepts ZabbixUserGroup objects or user group IDs from the pipe. Equivalent to using -UserGroupId parameter. - - .OUTPUTS - The ID of the removed objects. - - .EXAMPLE - Remove all groups - PS> Get-ZbxUserGroup | Remove-ZbxUserGroup - 10084 - 10085 - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)][ValidateNotNullOrEmpty()][Alias("UsrGrpId", "UserGroup", "Id")] - # Id of one or more groups to remove. You can also pipe in objects with an "Id" of "usrgrpid" property. - [int[]]$UserGroupId - ) - - begin - { - $prms = @() - } - process - { - $prms += $UserGroupId - } - end - { - if ($prms.Count -eq 0) { return } - Invoke-ZabbixApi $session "usergroup.delete" $prms | select -ExpandProperty usrgrpids - } -} - - -Add-Type -TypeDefinition @" - public enum ZbxPermission - { - Clear = -1, - Deny = 0, - ReadOnly = 2, - ReadWrite = 3 - } -"@ - - -function Add-UserGroupPermission -{ - <# - .SYNOPSIS - Set permissions for user groups on host groups. - - .DESCRIPTION - Add, modify or remove permissions granted to one or more user groups on one or more host groups. - This is idempotent. - This is additional: existing permissions on host groups not mentionned in -HostGroup are not modified. - - .INPUTS - This function accepts ZabbixUserGroup objects from the pipe. Equivalent to using -UserGroup parameter. - - .OUTPUTS - The ID of the modified objects. - - .EXAMPLE - PS> $usergroup11,$usergroup2 | Add-ZbxUserGroupPermission $hostgroup1,$hostgroup2 ReadWrite - 10084 - 10085 - - .NOTES - There is no Remove-UserGroupPermission, as this method with -Permission Clear actually removes a permission. - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$true, Position=0)][ValidateScript({ $_.groupid -ne $null})][ValidateNotNullOrEmpty()] - # The host group(s) to add to the user group. - [PSCustomObject[]]$HostGroup, - - [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=2)][ValidateScript({ $_.usrgrpid -ne $null})][ValidateNotNullOrEmpty()] - # The user groups to add permissions to. Can come from the pipe. - [PSCustomObject[]]$UserGroup, - - [Parameter(Mandatory=$true, Position=1)] - # The permission to grant on the specified groups. "Clear" means any rule concerning these groups will be removed from the user groups. - [ZbxPermission] $Permission - ) - begin - { - $newRights = if ($Permission -eq [ZbxPermission]::Clear) {@()} else {@($HostGroup |% {@{id = $_.groupid; permission = [int]$Permission}} )} - $HostGroupIds = @($HostGroup | select -ExpandProperty groupid) - $usrgrpids = @() - $prms = @() - } - process - { - $usrgrpids += $UserGroup.usrgrpid - } - end - { - # Note: there is no usergroup.massremove verb in the API. And the usergroup.massadd method cannot update existing permissions. - # So we have to use the normal "update" verb. To do so we need to collect existing permissions and alter them. - # This is done in "end" and not in "process" so as to make a single GET API request to fetch existing rights - much faster. - - if ($usrgrpids.Count -eq 0) { return } - - foreach ($usergroup in (Get-UserGroup -Id $usrgrpids)) - { - # First filter existing permissions - do not touch permissions which are not about the $HostGroups - $rights = @() - foreach($right in $usergroup.rights) - { - if (-not($right.id -in $HostGroupIds)) - { - $rights += $right - } - } - # Then add permissions for $HostGroups - $rights += $newRights - - # Finaly create the update object - $prms += @{usrgrpid = $usergroup.usrgrpid; rights = $rights} - } - - Invoke-ZabbixApi $session "usergroup.update" $prms | select -ExpandProperty usrgrpids - } -} - - -function Enable-UserGroup -{ - <# - .SYNOPSIS - Enable one or more user groups. - - .DESCRIPTION - Simple change of the status of the group. Idempotent. - - .INPUTS - This function accepts ZabbixuserGroup objects or user group IDs from the pipe. Equivalent to using -UserGroupId parameter. - - .OUTPUTS - The ID of the changed objects. - - .EXAMPLE - Enable all user groups - PS> Get-ZbxUserGroup | Enable-ZbxUserGroup - 10084 - 10085 - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true, Position=0)][Alias("Id", "UserGroup", "GroupId", "UsrGrpId")] - # The ID of one or more user groups to enable. You can also pipe a ZabbixUserGroup object or any object with a usrgrpid or id property. - [int[]]$UserGroupId - ) - begin - { - $ids = @() - } - Process - { - $ids += $UserGroupId - } - end - { - if ($ids.Count -eq 0) { return } - Invoke-ZabbixApi $session "usergroup.massupdate" @{usrgrpids=$ids; users_status=0} | select -ExpandProperty usrgrpids - } -} - - -function Disable-UserGroup -{ - <# - .SYNOPSIS - Disable one or more user groups. - - .DESCRIPTION - Simple change of the status of the group. Idempotent. - - .INPUTS - This function accepts ZabbixuserGroup objects or user group IDs from the pipe. Equivalent to using -UserGroupId parameter. - - .OUTPUTS - The ID of the changed objects. - - .EXAMPLE - Disable all user groups - PS> Get-ZbxUserGroup | Disable-ZbxUserGroup - 10084 - 10085 - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true, Position=0)][Alias("Id", "UserGroup", "GroupId", "UsrGrpId")] - # The ID of one or more user groups to disable. You can also pipe a ZabbixUserGroup object or any object with a usrgrpid or id property. - [int[]]$UserGroupId - ) - begin - { - $ids = @() - } - Process - { - $ids += $UserGroupId - } - end - { - if ($ids.Count -eq 0) { return } - Invoke-ZabbixApi $session "usergroup.massupdate" @{usrgrpids=$ids; users_status=1} | select -ExpandProperty usrgrpids - } -} - - - -################################################################################ -## USERS -################################################################################ - -function Get-User -{ - <# - .SYNOPSIS - Retrieve and filter users. - - .DESCRIPTION - Query all users with basic filters, or get all users. - - .INPUTS - This function does not take pipe input. - - .OUTPUTS - The ZabbixUser objects corresponding to the filter. - - .EXAMPLE - PS> Get-ZbxUser "marsu*" - userid alias name surname usrgrpsnames - ------ ----- ---- ------- ------------ - 1 marsu1 Zabbix Administrator Zabbix administrators - 2 marsu2 Guests - - .EXAMPLE - PS> Get-ZbxUser - userid alias name surname usrgrpsnames - ------ ----- ---- ------- ------------ - 1 Admin Zabbix Administrator Zabbix administrators - 2 guest Guests - - .EXAMPLE - PS> Get-ZbxUser -Id 1 - userid alias name surname usrgrpsnames - ------ ----- ---- ------- ------------ - 1 Admin Zabbix Administrator Zabbix administrators - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$False, ValueFromPipelineByPropertyName=$true)][Alias("UserId")] - # Only retrieve the user with the given ID - [int[]] $Id, - - [Parameter(Mandatory=$False, ValueFromPipelineByPropertyName=$true )][Alias("UsergrpId")] - # Only retrieve users which belong to these user groups - [int[]] $UserGroupId, - - [Parameter(Mandatory=$False, Position=0)][Alias("UserName")] - # Filter by name. Accepts wildcard. - [string] $Name - ) - $prms = @{selectUsrgrps = "extend"; getAccess = 1; search= @{}; searchWildcardsEnabled = 1} - if ($Id.Length -gt 0) {$prms["userids"] = $Id} - if ($UserGroupId.Length -gt 0) {$prms["usrgrpids"] = $UserGroupId} - if ($Name -ne $null) {$prms["search"]["alias"] = $Name} - Invoke-ZabbixApi $session "user.get" $prms |% {$_.userid = [int]$_.userid; $_.PSTypeNames.Insert(0,"ZabbixUser"); $_} -} - - -Add-Type -TypeDefinition @" - public enum ZbxUserType - { - User = 1, - Admin, - SuperAdmin - } -"@ - - -function New-User -{ - <# - .SYNOPSIS - Create a new user. - - .DESCRIPTION - Create a new user. - - .INPUTS - This function accepts a ZabbixUser as pipe input, or any object which properties map the function parameters. - - .OUTPUTS - The ZabbixUser object created. - - .EXAMPLE - PS> New-ZbxUser -Alias "login1" -name "marsu" -UserGroupId (get-zbxgroup "GROUPNAME*").id - userid alias name surname usrgrpsnames - ------ ----- ---- ------- ------------ - 19 login1 marsu GROUPNAME1,GROUPNAME2,GROUPNAME3 - - Create a user from scratch. - - .EXAMPLE - PS> $u = New-ZbxUser -Alias "login1" -name "marsu" -UserGroupId (get-zbxgroup "GROUPNAME*").id - PS> $u | new-user -alias "login2" - userid alias name surname usrgrpsnames - ------ ----- ---- ------- ------------ - 20 login2 marsu GROUPNAME1,GROUPNAME2,GROUPNAME3 - - Copy a user. - #> - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingUserNameAndPassWordParams", "")] - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")] - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$true, ParameterSetName = "login_withgroupid")] - [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$true, ParameterSetName = "login_withgroupobject")] - [Alias("Login")] - # Login of the new user. Must be unique. - [string] $Alias, - - [Parameter(Mandatory=$False, ValueFromPipelineByPropertyName=$true, ParameterSetName = "login_withgroupid")] - [Parameter(Mandatory=$False, ValueFromPipelineByPropertyName=$true, ParameterSetName = "login_withgroupobject")] - [Alias("Pwd", "passwd")] - # Password of the new user. If not specified, a long random string is used (useful if authenticated - # against a LDAP, as in that case the internal Zabbix password is not used). - [string] $Password = $null, - - [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$true, ParameterSetName = "pscred_withgroupid")] - [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$true, ParameterSetName = "pscred_withgroupobject")] - # A Credential (from Get-Credential or other source) object containing both login and password for the new user. - [PSCredential][System.Management.Automation.Credential()] $Credential, - - [Parameter(Mandatory=$False, ValueFromPipelineByPropertyName=$true)] - # Display name of the new user. If not given, the Alias is used. - [string] $Name, - - [Parameter(Mandatory=$False, ValueFromPipelineByPropertyName=$true )] - # Type of user. Default is simple user. - [ZbxUserType] $UserType = [ZbxUserType]::User, - - [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$true, ParameterSetName = "login_withgroupid")] - [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$true, ParameterSetName = "pscred_withgroupid")] - [ValidateNotNullOrEmpty()][Alias("UsrGrpId")] - # The ID of the groups the new user belongs to. - [int[]] $UserGroupId, - - [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$true, ParameterSetName = "login_withgroupobject")] - [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$true, ParameterSetName = "pscred_withgroupobject")] - [ValidateNotNullOrEmpty()][ValidateScript({ $_.usrgrpid -ne $null})] - [Alias("UsrGrps")] - # The groups the new user belongs to. - [object[]] $UserGroup, - - [Parameter(Mandatory=$False)] - # Mail adress to send alerts to - [string] $MailAddress, - - [Parameter(Mandatory=$False)] - # A severity mask for alerts. Only used if $MailAdress is specified. Default is Disaster,High - [ZbxSeverity] $AlertOn = [ZbxSeverity]::Disaster -bor [ZbxSeverity]::High - ) - - begin - { - $prms = @() - $media = @() - if ($MailAddress -ne $null) - { - $media += @{ - mediatypeid = @(Get-MediaType -Type email)[0].mediatypeid - sendto = $MailAddress - active = [int][ZbxStatus]::Enabled - severity = $AlertOn - period = "1-7,00:00-24:00" - } - } - } - process - { - $usergrps = @() - if ($PSCmdlet.ParameterSetName -in "login_withgroupid", "pscred_withgroupid") - { - $UserGroupId |% { $usergrps += @{usrgrpid = $_} } - } - else - { - $usergrps += $UserGroup - } - - if ($PSCmdlet.ParameterSetName -in "pscred_withgroupid", "pscred_withgroupobject") - { - $Alias = $Credential.GetNetworkCredential().UserName - $Pp = $Credential.GetNetworkCredential().Password - } - - $prms += @{ - alias = $Alias - name = if ($Name -ne $null) { $Name } else {$Alias} - type = [int]$UserType - passwd = if ($Password -ne $null) {$Password} else { "" + (Get-Random -Maximum ([long]::MaxValue)) } - usrgrps = $usergrps - user_medias = $media - } - } - end - { - if ($prms.Count -eq 0) { return } - $id = Invoke-ZabbixApi $session "user.create" $prms - Get-User -Session $Session -Id $id.userids - } -} - - -function Remove-User -{ - <# - .SYNOPSIS - Remove one or more users from Zabbix. - - .DESCRIPTION - Removal is immediate. - - .INPUTS - This function accepts ZabbixUser objects or user IDs from the pipe. Equivalent to using -UserId parameter. - - .OUTPUTS - The ID of the removed objects. - - .EXAMPLE - Remove all users - PS> Get-ZbxUser | Remove-ZbxUser - 10084 - 10085 - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$True, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)][ValidateNotNullOrEmpty()][Alias("User", "Id")] - # One or more users to remove. Either user objects (with a userid property) or directly IDs. - [int[]] $UserId - ) - - Begin - { - $prms = @() - } - process - { - $prms += $UserId - } - end - { - if ($prms.Count -eq 0) { return } - Invoke-ZabbixApi $session "user.delete" $prms | select -ExpandProperty userids - } -} - - -function Add-UserGroupMembership -{ - <# - .SYNOPSIS - Make a user (or multiple users) member of one or more user groups. - - .DESCRIPTION - This is additional: existing membership to other groups are not changed. - - .INPUTS - This function accepts ZabbixUser objects or user IDs from the pipe. Equivalent to using -UserId parameter. - - .OUTPUTS - The ID of the changed objects. - - .EXAMPLE - PS> Get-ZbxUser | Add-ZbxUserGroupMembership (Get-ZbxUserGroup group1),(Get-ZbxUserGroup group2) - 10084 - 10085 - - Add two groups to all users. - - .NOTES - Very slow when modifying many users as there is no "mass update" API for this operation in Zabbix. - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$True, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)][Alias("Id", "User")] - [ValidateNotNullOrEmpty()] - # User to add to the group - [int[]] $UserId, - - [Parameter(Mandatory=$True, ParameterSetName="Objects", Position=0)][ValidateScript({ $_.usrgrpid -ne $null})] - # Group to add the user to - [PSCustomObject[]] $UserGroup, - - [Parameter(Mandatory=$True, ParameterSetName="Ids",Position=0)] - # Group to add the user to - [int[]] $UserGroupId - ) - - begin - { - $prms = @() - $groupids = @() - if ($PSCmdlet.ParameterSetName -eq "Objects") - { - $UserGroup |% { $groupids += $_.usrgrpid} - } - else - { - $groupids += $UserGroupId - } - } - process - { - foreach ($uid in $UserId) - { - $User = Get-User -session $s -id $uid - $grps = @() - $existingGid = @($User.usrgrps.usrgrpid) - $addedGid = @() - - foreach ($gid in $groupids) - { - if (-not ($gid -in $existingGid)) - { - $addedGid += $gid - } - } - - if ($addedGid.count -eq 0) - { - # already in requested groups - continue - } - - $addedGid += $existingGid - foreach($gid in $addedGid) - { - $grps += @{usrgrpid = $gid} - } - - $prms = @{ - userid = $User.userid - usrgrps = $grps - } - # Sad, but not mass API. - Invoke-ZabbixApi $session "user.update" $prms | select -ExpandProperty userids - } - } -} - - -function Remove-UserGroupMembership -{ - <# - .SYNOPSIS - Remove a user (or multiple users) as a member of one or more user groups. - - .DESCRIPTION - This is additional: existing membership to other groups are not changed. - - .INPUTS - This function accepts ZabbixUser objects or user IDs from the pipe. Equivalent to using -UserId parameter. - - .OUTPUTS - The ID of the changed objects. - - .EXAMPLE - PS> Get-ZbxUser | Remove-ZbxUserGroupMembership (Get-ZbxUserGroup group1),(Get-ZbxUserGroup group2) - 10084 - 10085 - - Make sure no user is member of two specified groups. - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$True, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)][Alias("Id", "User")] - [ValidateNotNullOrEmpty()] - # User to remove from the groups - [int[]] $UserId, - - [Parameter(Mandatory=$True, ParameterSetName="Objects", Position=0)][ValidateScript({ $_.usrgrpid -ne $null})] - # Groups to remove the users from - [PSCustomObject[]] $UserGroup, - - [Parameter(Mandatory=$True, ParameterSetName="Ids",Position=0)] - # Groups to remove the users from - [int[]] $UserGroupId - ) - - begin - { - $prms = @() - $groupids = @() - if ($PSCmdlet.ParameterSetName -eq "Objects") - { - $UserGroup |% { $groupids += $_.usrgrpid} - } - else - { - $groupids += $UserGroupId - } - } - process - { - foreach ($uid in $UserId) - { - $User = Get-User -session $s -id $uid - $grps = @() - $existingGid = @($User.usrgrps.usrgrpid) - $removedGid = @() - $remainingGid = @() - - foreach ($gid in $existingGid) - { - if (($gid -in $groupids)) - { - $removedGid += $gid - } - else - { - $remainingGid += $gid - } - } - - if ($removedGid.count -eq 0) - { - # already absent from requested groups - continue - } - - foreach($gid in $remainingGid) - { - $grps += @{usrgrpid = $gid} - } - - $prms = @{ - userid = $User.userid - usrgrps = $grps - } - # Sad, but not mass API. - Invoke-ZabbixApi $session "user.update" $prms | select -ExpandProperty userids - } - } -} - - - -################################################################################ -## ACTIONS -################################################################################ - -function Get-Action -{ - <# - .SYNOPSIS - Retrieve and filter users. - - .DESCRIPTION - Query all actions with many filters, or get all actions. - - .INPUTS - This function does not take pipe input. - - .OUTPUTS - The ZabbixAction objects corresponding to the filter. - - .EXAMPLE - PS> Get-ZbxAction - Actionid Name def_shortdata OperationsReadable - -------- ---- ------------- ------------------ - 2 Auto discovery. Linux servers. {@{ConditionEvaluat... - 3 Report problems to Zabbix a... {TRIGGER.STATUS}:... {@{ConditionEvaluat... - 4 Report not supported items {ITEM.STATE}: {HO... {@{ConditionEvaluat... - 5 Report not supported low le... {LLDRULE.STATE}: ... {@{ConditionEvaluat... - 6 Report unknown triggers {TRIGGER.STATE}: ... {@{ConditionEvaluat... - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$False)][Alias("ActionId")] - # Only retrieve the action with the given ID - [int[]] $Id, - - [Parameter(Mandatory=$False)] - # Only retrieve actions which use the following hosts in their conditions - [int[]] $HostId, - - [Parameter(Mandatory=$False)] - # Only retrieve actions which use the following groups in their conditions - [int[]] $HostGroupId, - - [Parameter(Mandatory=$False)] - # Only retrieve actions which use the following triggers in their conditions - [int[]] $TriggerId, - - [Parameter(Mandatory=$False)] - # Only retrieve actions which send messages to these users - [int[]] $UserId, - - [Parameter(Mandatory=$False)][Alias("UsergrpId")] - # Only retrieve actions which send messages to these user groups - [int[]] $UserGroupId, - - [Parameter(Mandatory=$False, Position=0)][Alias("ActionName")] - # Filter by name - [string] $Name - ) - $prms = @{searchWildcardsEnabled=1; selectConditions = "extend"; selectOperations = "extend"; search= @{}} - if ($Id.Length -gt 0) {$prms["actionids"] = $Id} - if ($HostId.Length -gt 0) {$prms["hostids"] = $HostId} - if ($HostGroupId.Length -gt 0) {$prms["groupids"] = $HostGroupId} - if ($TriggerId.Length -gt 0) {$prms["triggerids"] = $TriggerId} - if ($UserId.Length -gt 0) {$prms["userids"] = $UserId} - if ($UserGroupId.Length -gt 0) {$prms["usrgrpids"] = $UserGroupId} - if ($Name -ne $null) {$prms["search"]["name"] = $Name} - $res = Invoke-ZabbixApi $session "action.get" $prms - $res |% { $action = $_; $action | Add-Member -NotePropertyName "OperationsReadable" -notepropertyvalue @($action.operations | Get-ReadableOperation) } - $res |% {$_.PSTypeNames.Insert(0,"ZabbixAction")} - $res -} - - -$ActOpType = @{ - 0 = "send message" - 1 = "remote command" - 2 = "add host" - 3 = "remove host" - 4 = "add to host group" - 5 = "moreve from host group" - 6 = "link to template" - 7 = "unlink from template" - 8 = "enable host" - 9 = "disable host" -} - -$ActOpCmd = @{ - 0 = "custom script" - 1 = "IPMI" - 2 = "SSH" - 3 = "Telnet" - 4 = "global script" -} - -$ActConditionEvalMethod = @{ - 0 = "AND/OR" - 1 = "AND" - 2 = "OR" -} - -$ActOpExecuteOn = @{ - 0 = "Zabbix agent" - 1 = "Zabbix server" -} - - -function Get-ReadableOperation([Parameter(Mandatory=$True, ValueFromPipeline=$true )]$op) -{ - Process - { - $res = New-Object psobject -Property @{ - OperationId = $_.operationid - OperationType = $ActOpType[[int]$_.operationtype] - EscalationPeriodSecond = $_.esc_period - EscalationStartStep = $_.esc_step_from - EscalationEndStep = $_.esc_step_to - ConditionEvaluationMethod = $ActConditionEvalMethod[[int]$_.evaltype] - MessageSubject = if($_.opmessage) {$_.opmessage.subject} else {$null} - MessageContent = if($_.opmessage) {$_.opmessage.message} else {$null} - MessageSendToGroups = $_.opmessage_grp | select usrgrpid - MessageSendToUsers = $_.opmessage_usr | select userid - CommandType = if($_.opcommand -ne $null) { $ActOpCmd[[int]$_.opcommand.type] } else {$null} - Command = if($_.opcommand -ne $null) { $_.opcommand.command } else {$null} - CommandUserName = if($_.opcommand -ne $null) { $_.opcommand.username } else {$null} - CommandGlobalScriptId = if($_.opcommand -ne $null) { $_.opcommand.scriptid } else {$null} - CommandExecuteOn = if($_.opcommand -ne $null) { $ActOpExecuteOn[[int]$_.opcommand.execute_on] } else {$null} - } - $res.PSTypeNames.Insert(0,"ZabbixActionOperation") - $res - } -} - - - -################################################################################ -## PROXIES -################################################################################ - -function Get-Proxy -{ - <# - .SYNOPSIS - Retrieve and filter proxies. - - .DESCRIPTION - Query all proxies with basic filters, or get all proxies. - - .INPUTS - This function does not take pipe input. - - .OUTPUTS - The ZabbixProxy objects corresponding to the filter. - - .EXAMPLE - PS> Get-ZbxProxy - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$False)][Alias("ProxyId")][int[]] - # Only retrieve the item with the given ID. - $Id, - - [Parameter(Mandatory=$False, Position=0)][Alias("ProxyName")] - # Filter by name. Accepts wildcard. - [string]$Name - ) - $prms = @{searchWildcardsEnabled=1; filter= @{selectInterface=1}; search=@{}} - if ($Id.Length -gt 0) {$prms["proxyids"] = $Id} - if ($Name -ne $null) {$prms["search"]["name"] = $Name} - Invoke-ZabbixApi $session "proxy.get" $prms |% {$_.proxyid = [int]$_.proxyid; $_.PSTypeNames.Insert(0,"ZabbixProxy"); $_} -} - - - -################################################################################ -## MEDIA -################################################################################ - -Add-Type -TypeDefinition @" - [System.Flags] - public enum ZbxSeverity - { - None = 0, - NotClassified = 1, - Information = 2, - Warning = 4, - Average = 8, - High = 16, - Disaster = 32 - } -"@ - - -Add-Type -TypeDefinition @" - public enum ZbxMediaTypeType - { - Email = 0, - Script = 1, - SMS = 2, - Jabber = 3, - EzTexting = 100 - } -"@ - - -function Get-Media -{ - <# - .SYNOPSIS - Retrieve and filter media (the definition of how a media type should be used for a user). - - .DESCRIPTION - Query all media with basic filters, or get all media. - - .INPUTS - This function does not take pipe input. - - .OUTPUTS - The ZabbixMedia objects corresponding to the filter. - - .EXAMPLE - PS> Get-ZbxMedia -Status Enabled - mediaid userid mediatypeid active - ------- ------ ----------- ------ - 1 3 1 Enabled - #> - [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$False)][Alias("MediaId")] - # Only retrieve the media with the given ID. - [int[]] $Id, - - [Parameter(Mandatory=$False)] - # Only retrieve media which are used by the users in the given group(s). - [int[]] $UserGroupId, - - [Parameter(Mandatory=$False)] - # Only retrieve media which are used by the given user(s). - [int[]] $UserId, - - [Parameter(Mandatory=$False)] - # Only retrieve media which use the give media type(s). - [int[]] $MediaTypeId, - - [Parameter(Mandatory=$False)] - # Only retrieve media which are in the given status. - [ZbxStatus] $Status - ) - $prms = @{} - if ($Id.Length -gt 0) {$prms["mediaids"] = $Id} - if ($UserGroupId.Length -gt 0) {$prms["usrgrpids"] = $UserGroupId} - if ($UserId.Length -gt 0) {$prms["userids"] = $UserId} - if ($MediaTypeId.Length -gt 0) {$prms["mediatypeids"] = $MediaTypeId} - if ($Status -ne $null) {$prms["filter"] = @{"active" = [int]$Status}} - Invoke-ZabbixApi $session "usermedia.get" $prms |% {$_.severity = [ZbxSeverity]$_.severity; $_.mediaid = [int]$_.mediaid; $_.active=[ZbxStatus]$_.active; $_.PSTypeNames.Insert(0,"ZabbixMedia"); $_} -} - - -function Get-MediaType -{ - <# - .SYNOPSIS - Retrieve and filter media types - - .DESCRIPTION - Query all media types with basic filters, or get all media types. - - .INPUTS - This function does not take pipe input. - - .OUTPUTS - The ZabbixMediaType objects corresponding to the filter. - - .EXAMPLE - PS> Get-ZbxMediaType -Type Email - mediatypeid type description - ----------- ---- ----------- - 1 Email Email - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$False)][Alias("MediaTypeId")] - # Only retrieve the media type with the given ID. - [int[]] $Id, - - [Parameter(Mandatory=$False, Position=0)][Alias("Description")] - # Filter by name. Accepts wildcard. - [string] $Name, - - [Parameter(Mandatory=$False, Position=0)][Alias("MediaTypeType")] - # Filter by type (email, SMS...) - [ZbxMediaTypeType] $Type - ) - $prms = @{search= @{}; filter=@{}; searchWildcardsEnabled=1; selectUsers = 0} - if ($Id.Length -gt 0) {$prms["mediatypeids"] = $Id} - if ($Name -ne $null) {$prms["search"]["description"] = $Name} - if ($Type -ne $null) {$prms["filter"]["type"] = [int]$Type} - - Invoke-ZabbixApi $session "mediatype.get" $prms |% {$_.mediatypeid = [int]$_.mediatypeid; $_.type = [ZbxMediaTypeType]$_.type; $_.status = [ZbxStatus]$_.status; $_.PSTypeNames.Insert(0,"ZabbixMediaType"); $_} -} - - -function Add-UserMail -{ - <# - .SYNOPSIS - Add a new mail type media to one or more users. - - .DESCRIPTION - Add a new mail type media to one or more users. Purely an ADD cmdlet - if there is already a mail media for the given user, it won't be - modified and the user will have multiple mail media. - - .INPUTS - This function takes ZbxUser objects or integer ID as pipeline input (equivalent to using -UserId parameter) - - .OUTPUTS - The ID of the new media object(s). - - .EXAMPLE - PS> Get-ZbxUser -Name toto1 | Add-ZbxUserMail toto1@company.com - 12 - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$True, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=2)][ValidateNotNullOrEmpty()][Alias("User", "Id")] - # One or more users to modify. Either user objects (with a userid property) or directly IDs. - [int[]] $UserId, - - [Parameter(Mandatory=$True, Position=0)] - # Mail adress to send the alerts to - [string] $SendTo, - - [Parameter(Mandatory=$False, Position=1)] - # A severity mask. Default is Disaster,High - [ZbxSeverity] $Severity = [ZbxSeverity]::Disaster -bor [ZbxSeverity]::High - ) - - Begin - { - $users = @() - $type = @(Get-MediaType -session $Session -type Email)[0] - $media = @{mediatypeid = $type.mediatypeid; sendto = $SendTo; active = [int][ZbxStatus]::Enabled; severity = [int]$Severity; period = "1-7,00:00-24:00"} - } - process - { - $UserId |% {$users += @{userid = $_}} - } - end - { - if ($users.Count -eq 0) { return } - Invoke-ZabbixApi $session "user.addmedia" @{users = $users; medias = $media} | select -ExpandProperty mediaids - } -} - -function Remove-Media -{ - <# - .SYNOPSIS - Remove one or more user media from Zabbix. - - .DESCRIPTION - Removal is immediate. - - .INPUTS - This function accepts ZabbixMedia objects or media IDs from the pipe. Equivalent to using -MediaId parameter. - - .OUTPUTS - The ID of the removed objects. - - .EXAMPLE - Remove all users - PS> Get-ZbxMedia | Remove-ZbxMedia - 10084 - 10085 - #> - param - ( - [Parameter(Mandatory=$False)] - # A valid Zabbix API session retrieved with New-ZbxApiSession. If not given, the latest opened session will be used, which should be enough in most cases. - [Hashtable] $Session, - - [Parameter(Mandatory=$True, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)][ValidateNotNullOrEmpty()][Alias("Media", "Id")] - # One or more media to remove. Either user objects (with a mediaid property) or directly IDs. - [int[]] $MediaId - ) - - Begin - { - $prms = @() - } - process - { - $prms += $MediaId +#Dot source the files +Foreach ($import in @($Public + $Private)) { + Try { + . $import.fullname + } Catch { + Write-Error -Message "Failed to import function $($import.fullname): $_" } - end - { - if ($prms.Count -eq 0) { return } - Invoke-ZabbixApi $session "user.deletemedia" $prms | select -ExpandProperty mediaids - } } \ No newline at end of file diff --git a/docker-compose-Zabbix-3.yml b/docker-compose-Zabbix-3.yml new file mode 100644 index 0000000..b2902b9 --- /dev/null +++ b/docker-compose-Zabbix-3.yml @@ -0,0 +1,42 @@ +version: "3.9" +services: + + mysql-zabbix: + image: "mysql:5.7" + environment: + MYSQL_USER: "zabbix" + MYSQL_PASSWORD: "zabbix_pwd" + MYSQL_ROOT_PASSWORD: "zabbix_pwd" + + zabbix-server-mysql: + image: "zabbix/zabbix-server-mysql:ubuntu-3.4-latest" + ports: + - "10051:10051" + environment: + DB_SERVER_HOST: "mysql-zabbix" + MYSQL_DATABASE: "zabbix" + MYSQL_USER: "zabbix" + MYSQL_PASSWORD: "zabbix_pwd" + MYSQL_ROOT_PASSWORD: "zabbix_pwd" + + zabbix-web: + image: "zabbix/zabbix-web-nginx-mysql:ubuntu-3.4-latest" + ports: + - "8080:80" + environment: + ZBX_SERVER_HOST: "zabbix-server-mysql" + DB_SERVER_HOST: "mysql-zabbix" + MYSQL_DATABASE: "zabbix" + MYSQL_USER: "zabbix" + MYSQL_PASSWORD: "zabbix_pwd" + MYSQL_ROOT_PASSWORD: "zabbix_pwd" + + pszabbix: + # image: "mcr.microsoft.com/powershell:latest" + build: + context: .devcontainer + dockerfile: .\pscoredev.Dockerfile + environment: + DEV_ZABBIX_HOST: zabbix-web + DEV_ZABBIX_API_URL: "http://zabbix-web:80/api_jsonrpc.php" + command: /bin/sh -c "while sleep 1000; do :; done" diff --git a/docker-compose-Zabbix-4.yml b/docker-compose-Zabbix-4.yml new file mode 100644 index 0000000..d8fc652 --- /dev/null +++ b/docker-compose-Zabbix-4.yml @@ -0,0 +1,42 @@ +version: "3.9" +services: + + mysql-zabbix: + image: "mysql:5.7" + environment: + MYSQL_USER: "zabbix" + MYSQL_PASSWORD: "zabbix_pwd" + MYSQL_ROOT_PASSWORD: "zabbix_pwd" + + zabbix-server-mysql: + image: "zabbix/zabbix-server-mysql:ubuntu-4.4-latest" + ports: + - "10051:10051" + environment: + DB_SERVER_HOST: "mysql-zabbix" + MYSQL_DATABASE: "zabbix" + MYSQL_USER: "zabbix" + MYSQL_PASSWORD: "zabbix_pwd" + MYSQL_ROOT_PASSWORD: "zabbix_pwd" + + zabbix-web: + image: "zabbix/zabbix-web-nginx-mysql:ubuntu-4.4-latest" + ports: + - "8080:8080" + environment: + ZBX_SERVER_HOST: "zabbix-server-mysql" + DB_SERVER_HOST: "mysql-zabbix" + MYSQL_DATABASE: "zabbix" + MYSQL_USER: "zabbix" + MYSQL_PASSWORD: "zabbix_pwd" + MYSQL_ROOT_PASSWORD: "zabbix_pwd" + + pszabbix: + # image: "mcr.microsoft.com/powershell:latest" + build: + context: .devcontainer + dockerfile: .\pscoredev.Dockerfile + environment: + DEV_ZABBIX_HOST: zabbix-web + DEV_ZABBIX_API_URL: "http://zabbix-web:8080/api_jsonrpc.php" + command: /bin/sh -c "while sleep 1000; do :; done" diff --git a/docker-compose-Zabbix-5.yml b/docker-compose-Zabbix-5.yml new file mode 100644 index 0000000..acc8a95 --- /dev/null +++ b/docker-compose-Zabbix-5.yml @@ -0,0 +1,42 @@ +version: "3.9" +services: + + mysql-zabbix: + image: "mysql:8.0" + environment: + MYSQL_USER: "zabbix" + MYSQL_PASSWORD: "zabbix_pwd" + MYSQL_ROOT_PASSWORD: "zabbix_pwd" + + zabbix-server-mysql: + image: "zabbix/zabbix-server-mysql:ubuntu-latest" + ports: + - "10051:10051" + environment: + DB_SERVER_HOST: "mysql-zabbix" + MYSQL_DATABASE: "zabbix" + MYSQL_USER: "zabbix" + MYSQL_PASSWORD: "zabbix_pwd" + MYSQL_ROOT_PASSWORD: "zabbix_pwd" + + zabbix-web: + image: "zabbix/zabbix-web-nginx-mysql:ubuntu-latest" + ports: + - "8080:8080" + environment: + ZBX_SERVER_HOST: "zabbix-server-mysql" + DB_SERVER_HOST: "mysql-zabbix" + MYSQL_DATABASE: "zabbix" + MYSQL_USER: "zabbix" + MYSQL_PASSWORD: "zabbix_pwd" + MYSQL_ROOT_PASSWORD: "zabbix_pwd" + + pszabbix: + # image: "mcr.microsoft.com/powershell:latest" + build: + context: .devcontainer + dockerfile: .\pscoredev.Dockerfile + environment: + DEV_ZABBIX_HOST: zabbix-web + DEV_ZABBIX_API_URL: "http://zabbix-web:8080/api_jsonrpc.php" + command: /bin/sh -c "while sleep 1000; do :; done" diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..b2902b9 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,42 @@ +version: "3.9" +services: + + mysql-zabbix: + image: "mysql:5.7" + environment: + MYSQL_USER: "zabbix" + MYSQL_PASSWORD: "zabbix_pwd" + MYSQL_ROOT_PASSWORD: "zabbix_pwd" + + zabbix-server-mysql: + image: "zabbix/zabbix-server-mysql:ubuntu-3.4-latest" + ports: + - "10051:10051" + environment: + DB_SERVER_HOST: "mysql-zabbix" + MYSQL_DATABASE: "zabbix" + MYSQL_USER: "zabbix" + MYSQL_PASSWORD: "zabbix_pwd" + MYSQL_ROOT_PASSWORD: "zabbix_pwd" + + zabbix-web: + image: "zabbix/zabbix-web-nginx-mysql:ubuntu-3.4-latest" + ports: + - "8080:80" + environment: + ZBX_SERVER_HOST: "zabbix-server-mysql" + DB_SERVER_HOST: "mysql-zabbix" + MYSQL_DATABASE: "zabbix" + MYSQL_USER: "zabbix" + MYSQL_PASSWORD: "zabbix_pwd" + MYSQL_ROOT_PASSWORD: "zabbix_pwd" + + pszabbix: + # image: "mcr.microsoft.com/powershell:latest" + build: + context: .devcontainer + dockerfile: .\pscoredev.Dockerfile + environment: + DEV_ZABBIX_HOST: zabbix-web + DEV_ZABBIX_API_URL: "http://zabbix-web:80/api_jsonrpc.php" + command: /bin/sh -c "while sleep 1000; do :; done" diff --git a/src/private/Get-ApiVersion.ps1 b/src/private/Get-ApiVersion.ps1 new file mode 100644 index 0000000..b75f54c --- /dev/null +++ b/src/private/Get-ApiVersion.ps1 @@ -0,0 +1,58 @@ + +function Get-ApiVersion +{ + <# + .SYNOPSIS + Retrieves the Zabbix API version from either an API session or a specific server + + .PARAMETER Session + A session hashtable created by calling New-ApiSession. If not specified, the function will look for $script:latestSession + + .PARAMETER Uri + Path to the Zabbix API endpoint on a specific Zabbix server + + .EXAMPLE + Get-ApiVersion + Gets the API version of the server used for the current API session + + .EXAMPLE + Get-ApiVersion $(New-ApiSession "http://myserver/zabbix/api_jsonrpc.php" (Get-Credentials MyAdminLogin)) + Gets the API version of the server while setting up a new API session. + + .EXAMPLE + Get-ApiVersion http://myZabbix.myNet.org/zabbix/api_jsonrpc.php + Gets the API version of a specific Zabbix server. + + #> + param( + [cmdletbinding(DefaultParameterSetName='Session')] + + [Parameter(ParameterSetName = 'Session', Position=0)] + [System.Collections.Hashtable] $Session = $script:LatestSession, + + [Parameter(ParameterSetName = 'Direct', Mandatory=$true)] + [string] $Uri + ) + + $targetURI = "" + switch($PSCmdlet.ParameterSetName) + { + 'Session' {$targetURI = $Session.uri} + 'Direct' {$targetURI = $Uri} + } + + $requestBody = New-JsonrpcRequest "apiinfo.version" @{} + $httpResult = "" + try + { + $httpResult = Invoke-RestMethod -Uri $targetURI -Method Post -ContentType "application/json" -Body $requestBody + } + catch + { + Write-Error "Invoke-RestMethod failed. Error: $($error[0])" + return $null + } + + $apiVersion = $httpResult.result + $apiVersion +} \ No newline at end of file diff --git a/src/private/Get-ReadableOperation.ps1 b/src/private/Get-ReadableOperation.ps1 new file mode 100644 index 0000000..20118ab --- /dev/null +++ b/src/private/Get-ReadableOperation.ps1 @@ -0,0 +1,27 @@ +function Get-ReadableOperation +{ + param([Parameter(Mandatory=$True, ValueFromPipeline=$true )]$op) + Process + { + $res = New-Object psobject -Property @{ + OperationId = $_.operationid + OperationType = $ActOpType[[int]$_.operationtype] + EscalationPeriodSecond = $_.esc_period + EscalationStartStep = $_.esc_step_from + EscalationEndStep = $_.esc_step_to + ConditionEvaluationMethod = $ActConditionEvalMethod[[int]$_.evaltype] + MessageSubject = if($_.opmessage) {$_.opmessage.subject} else {$null} + MessageContent = if($_.opmessage) {$_.opmessage.message} else {$null} + MessageSendToGroups = $_.opmessage_grp | select usrgrpid + MessageSendToUsers = $_.opmessage_usr | select userid + CommandType = if($_.opcommand -ne $null) { $ActOpCmd[[int]$_.opcommand.type] } else {$null} + Command = if($_.opcommand -ne $null) { $_.opcommand.command } else {$null} + CommandUserName = if($_.opcommand -ne $null) { $_.opcommand.username } else {$null} + CommandGlobalScriptId = if($_.opcommand -ne $null) { $_.opcommand.scriptid } else {$null} + CommandExecuteOn = if($_.opcommand -ne $null) { $ActOpExecuteOn[[int]$_.opcommand.execute_on] } else {$null} + } + $res.PSTypeNames.Insert(0,"ZabbixActionOperation") + $res + } +} + diff --git a/src/private/InternalTimeHelpers.ps1 b/src/private/InternalTimeHelpers.ps1 new file mode 100644 index 0000000..a458df6 --- /dev/null +++ b/src/private/InternalTimeHelpers.ps1 @@ -0,0 +1,30 @@ +function ConvertTo-EpochTime +{ + param + ( + # Parameter help description + [Parameter(Mandatory=$true)] + [DateTime] + $Date + ) + + # adapted from https://www.epochconverter.com/ + $dateString = Get-Date $Date.touniversaltime() -UFormat %s + $epochResult = [int][double]::Parse($dateString) + $epochResult +} + +function ConvertFrom-EpochTime +{ + param + ( + # Parameter help description + [Parameter(Mandatory=$true)] + [int] + $EpochTime + ) + + # adapted from https://www.epochconverter.com/ + [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($EpochTime)) + +} \ No newline at end of file diff --git a/src/private/InternalZabbixTypes.ps1 b/src/private/InternalZabbixTypes.ps1 new file mode 100644 index 0000000..d07d7f1 --- /dev/null +++ b/src/private/InternalZabbixTypes.ps1 @@ -0,0 +1,98 @@ + +Add-Type -TypeDefinition @" +public enum ZbxStatus +{ + Enabled = 0, + Disabled = 1 +} +"@ + + +Add-Type -TypeDefinition @" + public enum ZbxGuiAccess + { + WithDefaultAuthenticationMethod = 0, + WithInternalAuthentication = 1, + Disabled = 2 + } +"@ + +Add-Type -TypeDefinition @" + public enum ZbxPermission + { + Clear = -1, + Deny = 0, + ReadOnly = 2, + ReadWrite = 3 + } +"@ + +Add-Type -TypeDefinition @" + public enum ZbxUserType + { + User = 1, + Admin, + SuperAdmin + } +"@ + + + +$ActOpType = @{ + 0 = "send message" + 1 = "remote command" + 2 = "add host" + 3 = "remove host" + 4 = "add to host group" + 5 = "moreve from host group" + 6 = "link to template" + 7 = "unlink from template" + 8 = "enable host" + 9 = "disable host" +} + +$ActOpCmd = @{ + 0 = "custom script" + 1 = "IPMI" + 2 = "SSH" + 3 = "Telnet" + 4 = "global script" +} + +$ActConditionEvalMethod = @{ + 0 = "AND/OR" + 1 = "AND" + 2 = "OR" +} + +$ActOpExecuteOn = @{ + 0 = "Zabbix agent" + 1 = "Zabbix server" +} + +Add-Type -TypeDefinition @" + [System.Flags] + public enum ZbxSeverity + { + None = 0, + NotClassified = 1, + Information = 2, + Warning = 4, + Average = 8, + High = 16, + Disaster = 32 + } +"@ + + +Add-Type -TypeDefinition @" + public enum ZbxMediaTypeType + { + Email = 0, + Script = 1, + SMS = 2, + Jabber = 3, + EzTexting = 100 + } +"@ + diff --git a/src/private/Invoke-ZabbixApi.ps1 b/src/private/Invoke-ZabbixApi.ps1 new file mode 100644 index 0000000..4139d10 --- /dev/null +++ b/src/private/Invoke-ZabbixApi.ps1 @@ -0,0 +1,19 @@ +function Invoke-ZabbixApi($session, $method, $parameters = @{}) +{ + if ($session -eq $null -and $script:latestSession -eq $null) + { + throw "No session is opened. Call New-ZabbixApiSession before or pass a previously retrieved session object as a parameter." + } + if ($session -eq $null) + { + $session = $script:latestSession + } + + $r = Invoke-RestMethod -Uri $session.Uri -Method Post -ContentType "application/json" -Body (New-JsonrpcRequest $method $parameters $session.Auth) + if ($r.error -ne $null) + { + Write-Error -Message "$($r.error.message) $($r.error.data)" -ErrorId $r.error.code + return $null + } + return $r.result +} \ No newline at end of file diff --git a/src/private/New-JsonrpcRequest.ps1 b/src/private/New-JsonrpcRequest.ps1 new file mode 100644 index 0000000..746b651 --- /dev/null +++ b/src/private/New-JsonrpcRequest.ps1 @@ -0,0 +1,58 @@ +function New-JsonrpcRequest +{ + <# + .SYNOPSIS + Generates the jsonrpc body of the Zabbix API call + + .PARAMETER method + The Zabbix API method. + + .PARAMETER params + Arguments to the jsonrpc method as a hash table + + .PARAMETER auth + Authentication token from calling user.login method + + .EXAMPLE + New-JsonrpcRequest -method "maintenance.get" -params @{ "output" = "extend"; "selectGroups" = "extend"; "selectTimeperiods" = "extend" } -auth "038e1d7b1735c6a5436ee9eae095879e" + Prepares the body for a call to Zabix method maintenance.get + + .LINK + Zabbix API reference + https://www.zabbix.com/documentation/3.4/manual/api/reference + #> + param ( + [Parameter(Mandatory=$true)][string] $method, + [Parameter(Mandatory=$true)][hashtable] $params, + [string] $auth + ) + + $bodyHash = @{ jsonrpc = "2.0"; id = 1 } + + $bodyHash["method"] = $method + + if ($params.output -eq $null -and $method -like "*.get") + { + $params["output"] = "extend" + } + + # + # For some API, the params member is an array - not a hash + # Use "array" key to indicate this case and pass along the array + # + if($params.ContainsKey("array")) + { + $bodyHash["params"] = $params["array"] + } + else + { + $bodyHash["params"] = $params + } + + if(-not [string]::IsNullOrEmpty($auth)) + { + $bodyHash["auth"] = $auth + } + + return ConvertTo-Json $bodyHash -Depth 20 +} \ No newline at end of file diff --git a/src/public/Add-HostGroupMembership.ps1 b/src/public/Add-HostGroupMembership.ps1 new file mode 100644 index 0000000..97d390e --- /dev/null +++ b/src/public/Add-HostGroupMembership.ps1 @@ -0,0 +1,54 @@ +function Add-HostGroupMembership +{ + <# + .SYNOPSIS + Make a host (or multiple hosts) member of one or more host groups. + + .DESCRIPTION + This is additional: existing membership to other groups are not changed. + + .INPUTS + This function accepts ZabbixHost objects from the pipe. Equivalent to using -Host parameter. + + .OUTPUTS + The ID of the changed objects. + + .EXAMPLE + PS> Get-Host | Add-HostGroupMembership (Get-Group group1),(Get-Group group2) + 10084 + 10085 + + Add two groups to all hosts + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=1)][ValidateScript({ $_.PSObject.TypeNames[0] -eq 'ZabbixHost'})][ValidateNotNullOrEmpty()] + # The host or hostid to add to the hostgroup. + [PSCustomObject[]]$Host, + + [Parameter(Mandatory=$true, Position=0)][ValidateNotNullOrEmpty()] + # The Host is added to this list of one or more hostgroups. + [PSCustomObject[]]$HostGroup + ) + begin + { + $grpids = @($HostGroup |% {@{groupid = $_.groupid}} ) + $prms = @{hosts = @(); groups = $grpids} + } + process + { + $prms["hosts"] += $Host.hostid + } + end + { + if ($prms.Count -eq 0) { return } + $prms = @{ array = $prms } + Invoke-ZabbixApi $session "host.massadd" $prms | Select-Object -ExpandProperty hostids + } +} + + diff --git a/src/public/Add-UserGroupMembership.ps1 b/src/public/Add-UserGroupMembership.ps1 new file mode 100644 index 0000000..e318edd --- /dev/null +++ b/src/public/Add-UserGroupMembership.ps1 @@ -0,0 +1,96 @@ +function Add-UserGroupMembership +{ + <# + .SYNOPSIS + Make a user (or multiple users) member of one or more user groups. + + .DESCRIPTION + This is additional: existing membership to other groups are not changed. + + .INPUTS + This function accepts ZabbixUser objects or user IDs from the pipe. Equivalent to using -UserId parameter. + + .OUTPUTS + The ID of the changed objects. + + .EXAMPLE + PS> Get-User | Add-UserGroupMembership (Get-UserGroup group1),(Get-UserGroup group2) + 10084 + 10085 + + Add two groups to all users. + + .NOTES + Very slow when modifying many users as there is no "mass update" API for this operation in Zabbix. + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$True, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)][Alias("Id", "User")] + [ValidateNotNullOrEmpty()] + # User to add to the group + [int[]] $UserId, + + [Parameter(Mandatory=$True, ParameterSetName="Objects", Position=0)][ValidateScript({ $_.usrgrpid -ne $null})] + # Group to add the user to + [PSCustomObject[]] $UserGroup, + + [Parameter(Mandatory=$True, ParameterSetName="Ids",Position=0)] + # Group to add the user to + [int[]] $UserGroupId + ) + + begin + { + $prms = @() + $groupids = @() + if ($PSCmdlet.ParameterSetName -eq "Objects") + { + $UserGroup |% { $groupids += $_.usrgrpid} + } + else + { + $groupids += $UserGroupId + } + } + process + { + foreach ($uid in $UserId) + { + $User = Get-User -session $s -id $uid + $grps = @() + $existingGid = @($User.usrgrps.usrgrpid) + $addedGid = @() + + foreach ($gid in $groupids) + { + if (-not ($gid -in $existingGid)) + { + $addedGid += $gid + } + } + + if ($addedGid.count -eq 0) + { + # already in requested groups + continue + } + + $addedGid += $existingGid + foreach($gid in $addedGid) + { + $grps += @{usrgrpid = $gid} + } + + $prms = @{ + userid = $User.userid + usrgrps = $grps + } + # Sad, but not mass API. + Invoke-ZabbixApi $session "user.update" $prms | Select-Object -ExpandProperty userids + } + } +} diff --git a/src/public/Add-UserGroupPermission.ps1 b/src/public/Add-UserGroupPermission.ps1 new file mode 100644 index 0000000..51811e7 --- /dev/null +++ b/src/public/Add-UserGroupPermission.ps1 @@ -0,0 +1,90 @@ +function Add-UserGroupPermission +{ + <# + .SYNOPSIS + Set permissions for user groups on host groups. + + .DESCRIPTION + Add, modify or remove permissions granted to one or more user groups on one or more host groups. + This is idempotent. + This is additional: existing permissions on host groups not mentionned in -HostGroup are not modified. + + .INPUTS + This function accepts ZabbixUserGroup objects from the pipe. Equivalent to using -UserGroup parameter. + + .OUTPUTS + The ID of the modified objects. + + .EXAMPLE + PS> $usergroup11,$usergroup2 | Add-UserGroupPermission $hostgroup1,$hostgroup2 ReadWrite + 10084 + 10085 + + .NOTES + There is no Remove-UserGroupPermission, as this method with -Permission Clear actually removes a permission. + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$true, Position=0)][ValidateScript({ $_.groupid -ne $null})][ValidateNotNullOrEmpty()] + # The host group(s) to add to the user group. + [PSCustomObject[]]$HostGroup, + + [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=2)][ValidateScript({ $_.usrgrpid -ne $null})][ValidateNotNullOrEmpty()] + # The user groups to add permissions to. Can come from the pipe. + [PSCustomObject[]]$UserGroup, + + [Parameter(Mandatory=$true, Position=1)] + # The permission to grant on the specified groups. "Clear" means any rule concerning these groups will be removed from the user groups. + [ZbxPermission] $Permission + ) + begin + { + $newRights = @() + if ($Permission -ne [ZbxPermission]::Clear) { + $newRights = [pscustomobject] @( + $HostGroup | ForEach-Object { + @{id = $_.groupid; permission = [int]$Permission} + } + ) + } + $HostGroupIds = @($HostGroup | Select-Object -ExpandProperty groupid) + $usrgrpids = @() + $prms = @() + } + process + { + $usrgrpids += $UserGroup.usrgrpid + } + end + { + # Note: there is no usergroup.massremove verb in the API. And the usergroup.massadd method cannot update existing permissions. + # So we have to use the normal "update" verb. To do so we need to collect existing permissions and alter them. + # This is done in "end" and not in "process" so as to make a single GET API request to fetch existing rights - much faster. + + if ($usrgrpids.Count -eq 0) { return } + + foreach ($usergroup in (Get-UserGroup -Id $usrgrpids)) + { + # First filter existing permissions - do not touch permissions which are not about the $HostGroups + $rights = @() + foreach($right in $usergroup.rights) + { + if (-not($right.id -in $HostGroupIds)) + { + $rights += $right + } + } + # Then add permissions for $HostGroups + $rights += $newRights + + # Finaly create the update object + $prms += [PSCustomObject] @{usrgrpid = $usergroup.usrgrpid; rights = $rights} + } + $prms = @{ array = $prms } + Invoke-ZabbixApi $session "usergroup.update" $prms | Select-Object -ExpandProperty usrgrpids + } +} diff --git a/src/public/Add-UserMail.ps1 b/src/public/Add-UserMail.ps1 new file mode 100644 index 0000000..526b5c4 --- /dev/null +++ b/src/public/Add-UserMail.ps1 @@ -0,0 +1,55 @@ +function Add-UserMail +{ + <# + .SYNOPSIS + Add a new mail type media to one or more users. + + .DESCRIPTION + Add a new mail type media to one or more users. Purely an ADD cmdlet - if there is already a mail media for the given user, it won't be + modified and the user will have multiple mail media. + + .INPUTS + This function takes ZbxUser objects or integer ID as pipeline input (equivalent to using -UserId parameter) + + .OUTPUTS + The ID of the new media object(s). + + .EXAMPLE + PS> Get-User -Name toto1 | Add-UserMail toto1@company.com + 12 + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$True, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=2)][ValidateNotNullOrEmpty()][Alias("User", "Id")] + # One or more users to modify. Either user objects (with a userid property) or directly IDs. + [int[]] $UserId, + + [Parameter(Mandatory=$True, Position=0)] + # Mail adress to send the alerts to + [string] $SendTo, + + [Parameter(Mandatory=$False, Position=1)] + # A severity mask. Default is Disaster,High + [ZbxSeverity] $Severity = [ZbxSeverity]::Disaster -bor [ZbxSeverity]::High + ) + + Begin + { + $users = @() + $type = @(Get-MediaType -session $Session -type Email)[0] + $media = @{mediatypeid = $type.mediatypeid; sendto = $SendTo; active = [int][ZbxStatus]::Enabled; severity = [int]$Severity; period = "1-7,00:00-24:00"} + } + process + { + $UserId |% {$users += @{userid = $_}} + } + end + { + if ($users.Count -eq 0) { return } + Invoke-ZabbixApi $session "user.addmedia" @{users = $users; medias = $media} | Select-Object -ExpandProperty mediaids + } +} diff --git a/src/public/Disable-Host.ps1 b/src/public/Disable-Host.ps1 new file mode 100644 index 0000000..f1cb909 --- /dev/null +++ b/src/public/Disable-Host.ps1 @@ -0,0 +1,45 @@ +function Disable-Host +{ + <# + .SYNOPSIS + Disable one or more hosts from Zabbix. + + .DESCRIPTION + Simple change of the status of the host. Idempotent. + + .INPUTS + This function accepts ZabbixHost objects or host IDs from the pipe. Equivalent to using -HostId parameter. + + .OUTPUTS + The ID of the changed objects. + + .EXAMPLE + Disable all hosts + PS> Get-Host | Disable-Host + 10084 + 10085 + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true, Position=0)][Alias("Id", "Host")] + # The ID of one or more hosts to disable. You can also pipe a ZabbixHost object or any object with a hostid or id property. + [int[]]$HostId + ) + begin + { + $ids = @() + } + Process + { + $HostId |% {$ids += @{hostid = $_}} + } + end + { + if ($ids.Count -eq 0) { return } + Invoke-ZabbixApi $session "host.massupdate" @{hosts=$ids; status=1} | Select-Object -ExpandProperty hostids + } +} diff --git a/src/public/Disable-UserGroup.ps1 b/src/public/Disable-UserGroup.ps1 new file mode 100644 index 0000000..c8b57c4 --- /dev/null +++ b/src/public/Disable-UserGroup.ps1 @@ -0,0 +1,46 @@ +function Disable-UserGroup +{ + <# + .SYNOPSIS + Disable one or more user groups. + + .DESCRIPTION + Simple change of the status of the group. Idempotent. + + .INPUTS + This function accepts ZabbixuserGroup objects or user group IDs from the pipe. Equivalent to using -UserGroupId parameter. + + .OUTPUTS + The ID of the changed objects. + + .EXAMPLE + Disable all user groups + PS> Get-UserGroup | Disable-UserGroup + 10084 + 10085 + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true, Position=0)][Alias("Id", "UserGroup", "GroupId", "UsrGrpId")] + # The ID of one or more user groups to disable. You can also pipe a ZabbixUserGroup object or any object with a usrgrpid or id property. + [int[]]$UserGroupId + ) + begin + { + $ids = @() + } + Process + { + $ids += $UserGroupId + } + end + { + if ($ids.Count -eq 0) { return } + Invoke-ZabbixApi $session "usergroup.massupdate" @{usrgrpids=$ids; users_status=1} | Select-Object -ExpandProperty usrgrpids + } +} + diff --git a/src/public/Enable-Host.ps1 b/src/public/Enable-Host.ps1 new file mode 100644 index 0000000..a46f9d8 --- /dev/null +++ b/src/public/Enable-Host.ps1 @@ -0,0 +1,46 @@ +function Enable-Host +{ + <# + .SYNOPSIS + Enable one or more hosts from Zabbix. + + .DESCRIPTION + Simple change of the status of the host. Idempotent. + + .INPUTS + This function accepts ZabbixHost objects or host IDs from the pipe. Equivalent to using -HostId parameter. + + .OUTPUTS + The ID of the changed objects. + + .EXAMPLE + Enable all hosts + PS> Get-Host | Enable-Host + 10084 + 10085 + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true, Position=0)][Alias("Id", "Host")] + # The ID of one or more hosts to enable. You can also pipe a ZabbixHost object or any object with a hostid or id property. + [int[]]$HostId + ) + begin + { + $ids = @() + } + Process + { + $HostId |% {$ids += @{hostid = $_}} + } + end + { + if ($ids.Count -eq 0) { return } + Invoke-ZabbixApi $session "host.massupdate" @{hosts=$ids; status=0} | Select-Object -ExpandProperty hostids + } +} + diff --git a/src/public/Enable-UserGroup.ps1 b/src/public/Enable-UserGroup.ps1 new file mode 100644 index 0000000..6e285c7 --- /dev/null +++ b/src/public/Enable-UserGroup.ps1 @@ -0,0 +1,46 @@ +function Enable-UserGroup +{ + <# + .SYNOPSIS + Enable one or more user groups. + + .DESCRIPTION + Simple change of the status of the group. Idempotent. + + .INPUTS + This function accepts ZabbixuserGroup objects or user group IDs from the pipe. Equivalent to using -UserGroupId parameter. + + .OUTPUTS + The ID of the changed objects. + + .EXAMPLE + Enable all user groups + PS> Get-UserGroup | Enable-UserGroup + 10084 + 10085 + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$true, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true, Position=0)][Alias("Id", "UserGroup", "GroupId", "UsrGrpId")] + # The ID of one or more user groups to enable. You can also pipe a ZabbixUserGroup object or any object with a usrgrpid or id property. + [int[]]$UserGroupId + ) + begin + { + $ids = @() + } + Process + { + $ids += $UserGroupId + } + end + { + if ($ids.Count -eq 0) { return } + Invoke-ZabbixApi $session "usergroup.massupdate" @{usrgrpids=$ids; users_status=0} | Select-Object -ExpandProperty usrgrpids + } +} + diff --git a/src/public/Get-Action.ps1 b/src/public/Get-Action.ps1 new file mode 100644 index 0000000..67812d3 --- /dev/null +++ b/src/public/Get-Action.ps1 @@ -0,0 +1,72 @@ +function Get-Action +{ + <# + .SYNOPSIS + Retrieve and filter users. + + .DESCRIPTION + Query all actions with many filters, or get all actions. + + .INPUTS + This function does not take pipe input. + + .OUTPUTS + The ZabbixAction objects corresponding to the filter. + + .EXAMPLE + PS> Get-Action + Actionid Name def_shortdata OperationsReadable + -------- ---- ------------- ------------------ + 2 Auto discovery. Linux servers. {@{ConditionEvaluat... + 3 Report problems to Zabbix a... {TRIGGER.STATUS}:... {@{ConditionEvaluat... + 4 Report not supported items {ITEM.STATE}: {HO... {@{ConditionEvaluat... + 5 Report not supported low le... {LLDRULE.STATE}: ... {@{ConditionEvaluat... + 6 Report unknown triggers {TRIGGER.STATE}: ... {@{ConditionEvaluat... + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$False)][Alias("ActionId")] + # Only retrieve the action with the given ID + [int[]] $Id, + + [Parameter(Mandatory=$False)] + # Only retrieve actions which use the following hosts in their conditions + [int[]] $HostId, + + [Parameter(Mandatory=$False)] + # Only retrieve actions which use the following groups in their conditions + [int[]] $HostGroupId, + + [Parameter(Mandatory=$False)] + # Only retrieve actions which use the following triggers in their conditions + [int[]] $TriggerId, + + [Parameter(Mandatory=$False)] + # Only retrieve actions which send messages to these users + [int[]] $UserId, + + [Parameter(Mandatory=$False)][Alias("UsergrpId")] + # Only retrieve actions which send messages to these user groups + [int[]] $UserGroupId, + + [Parameter(Mandatory=$False, Position=0)][Alias("ActionName")] + # Filter by name + [string] $Name + ) + $prms = @{searchWildcardsEnabled=1; selectConditions = "extend"; selectOperations = "extend"; search= @{}} + if ($Id.Length -gt 0) {$prms["actionids"] = $Id} + if ($HostId.Length -gt 0) {$prms["hostids"] = $HostId} + if ($HostGroupId.Length -gt 0) {$prms["groupids"] = $HostGroupId} + if ($TriggerId.Length -gt 0) {$prms["triggerids"] = $TriggerId} + if ($UserId.Length -gt 0) {$prms["userids"] = $UserId} + if ($UserGroupId.Length -gt 0) {$prms["usrgrpids"] = $UserGroupId} + if ($Name -ne $null) {$prms["search"]["name"] = $Name} + $res = Invoke-ZabbixApi $session "action.get" $prms + $res |% { $action = $_; $action | Add-Member -NotePropertyName "OperationsReadable" -notepropertyvalue @($action.operations | Get-ReadableOperation) } + $res |% {$_.PSTypeNames.Insert(0,"ZabbixAction")} + $res +} diff --git a/src/public/Get-Host.ps1 b/src/public/Get-Host.ps1 new file mode 100644 index 0000000..bb8d505 --- /dev/null +++ b/src/public/Get-Host.ps1 @@ -0,0 +1,66 @@ +function Get-Host +{ + <# + .SYNOPSIS + Retrieve and filter hosts. + + .DESCRIPTION + Query all hosts (not templates) with basic filters, or get all hosts. + + .INPUTS + This function does not take pipe input. + + .OUTPUTS + The ZabbixHost objects corresponding to the filter. + + .EXAMPLE + PS> Get-Host + hostid host name status + ------ ---- ---- ------ + 10084 Zabbix server Zabbix server Enabled + 10105 Agent Mongo 1 Agent Mongo 1 Enabled + + .EXAMPLE + PS> Get-Host -Id 10084 + hostid host name status + ------ ---- ---- ------ + 10084 Zabbix server Zabbix server Enabled + + .EXAMPLE + PS> Get-Host "Agent*" + hostid host name status + ------ ---- ---- ------ + 10105 Agent Mongo 1 Agent Mongo 1 Enabled + 10106 Agent Mongo 2 Agent Mongo 2 Enabled + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$False)][Alias("HostId")] + # Only retrieve the items with the given ID(s). + [int[]] $Id, + + [Parameter(Mandatory=$False)] + # Only retrieve items which belong to the given group(s). + [int[]] $HostGroupId, + + [Parameter(Mandatory=$False, Position=0)][Alias("HostName")] + # Filter by hostname. Accepts wildcard. + [string] $Name + ) + $prms = @{search= @{}; searchWildcardsEnabled = 1; selectInterfaces = @("interfaceid", "ip", "dns"); selectParentTemplates = 1} + if ($Id.Length -gt 0) {$prms["hostids"] = $Id} + if ($HostGroupId.Length -gt 0) {$prms["groupids"] = $GroupId} + if ($Name -ne $null) {$prms["search"]["name"] = $Name} + $result = Invoke-ZabbixApi $session "host.get" $prms + $result | ForEach-Object { + $_.status = [ZbxStatus]$_.status + $_.hostid = [int]$_.hostid + $_.PSTypeNames.Insert(0,"ZabbixHost") + $_ + } +} + diff --git a/src/public/Get-HostGroup.ps1 b/src/public/Get-HostGroup.ps1 new file mode 100644 index 0000000..449ec80 --- /dev/null +++ b/src/public/Get-HostGroup.ps1 @@ -0,0 +1,60 @@ +function Get-HostGroup +{ + <# + .SYNOPSIS + Retrieve and filter host groups. + + .DESCRIPTION + Query all host groups with basic filters, or get all host groups. + + .INPUTS + This function does not take pipe input. + + .OUTPUTS + The ZabbixHostGroup objects corresponding to the filter. + + .EXAMPLE + PS> Get-HostGroup "Linux*" + groupid internal flags name + ------- -------- ----- ---- + 1 0 0 Linux Group 1 + 2 0 0 Linux Group 2 + + .EXAMPLE + PS> Get-HostGroup + groupid internal flags name + ------- -------- ----- ---- + 1 0 0 Templates + 2 0 0 Linux servers + 4 0 0 Zabbix servers + + .EXAMPLE + PS> Get-HostGroup -Id 1 + groupid internal flags name + ------- -------- ----- ---- + 1 0 0 Templates + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$False)] + # Only retrieve the groups with the given ID(s) + [int[]] $Id, + + [Parameter(Mandatory=$False)] + # Only retrieve the groups which contain the given host(s) + [int[]] $HostId, + + [Parameter(Mandatory=$False, Position=0)][Alias("GroupName")] + # Filter by name. Accepts wildcard. + [string] $Name + ) + $prms = @{search= @{}; searchWildcardsEnabled = 1; selectHosts = 1} + if ($HostId.Length -gt 0) {$prms["hostids"] = $HostId} + if ($Id.Length -gt 0) {$prms["groupids"] = $Id} + if ($Name -ne $null) {$prms["search"]["name"] = $Name} + Invoke-ZabbixApi $session "hostgroup.get" $prms | ForEach-Object {$_.groupid = [int]$_.groupid; $_.PSTypeNames.Insert(0,"ZabbixGroup"); $_} +} diff --git a/src/public/Get-Maintenance.ps1 b/src/public/Get-Maintenance.ps1 new file mode 100644 index 0000000..be9a868 --- /dev/null +++ b/src/public/Get-Maintenance.ps1 @@ -0,0 +1,69 @@ + +function Get-Maintenance +{ + <# + .SYNOPSIS + Retrieve maintenance windows for a specific window, specific set of hosts or host group + + .DESCRIPTION + If called with no parameters, the function will return all maintenance windows configured on the Zabbix server + + + .INPUTS + This function does not take pipe input. + + .OUTPUTS + Zabbix maintenance objects + + .EXAMPLE + PS> Get-Maintenance + + maintenanceid name maintenance_type description + ------------- ---- ---------------- ----------- + 134 Lakenbake 0 Baken laken + 136 Plaza socks 1 Wool of course + + .EXAMPLE + PS> Get-Maintenance -Id 134 + + maintenanceid name maintenance_type description + ------------- ---- ---------------- ----------- + 134 Lakenbake 0 Baken laken + + + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$False)][Alias("MaintenanceId")] + # Only retrieve the items with the given ID(s). + [int[]] $Id, + + [Parameter(Mandatory=$False)] + # Only retrieve items which belong to the given group(s). + [int[]] $HostGroupId, + + [Parameter(Mandatory=$False, Position=0)] + # Filter by hostname. Accepts wildcard. + [int[]] $HostId + ) + $prms = @{ output="extend"; selectGroups="extend"; selectTimePeriods="extend"} + if ($Id.Length -gt 0) + { + $prms["maintenanceids"] = $Id + } + if ($HostGroupId.Length -gt 0) + { + $prms["groupids"] = $GroupId + } + if ($HostId.Length -gt 0) + { + $prms["hostids"] = $HostId + } + $result = Invoke-ZabbixApi $session "maintenance.get" $prms + $result +} + diff --git a/src/public/Get-Media.ps1 b/src/public/Get-Media.ps1 new file mode 100644 index 0000000..3e3e31d --- /dev/null +++ b/src/public/Get-Media.ps1 @@ -0,0 +1,56 @@ +function Get-Media +{ + <# + .SYNOPSIS + Retrieve and filter media (the definition of how a media type should be used for a user). + + .DESCRIPTION + Query all media with basic filters, or get all media. + + .INPUTS + This function does not take pipe input. + + .OUTPUTS + The ZabbixMedia objects corresponding to the filter. + + .EXAMPLE + PS> Get-Media -Status Enabled + mediaid userid mediatypeid active + ------- ------ ----------- ------ + 1 3 1 Enabled + #> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSUseSingularNouns", "")] + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$False)][Alias("MediaId")] + # Only retrieve the media with the given ID. + [int[]] $Id, + + [Parameter(Mandatory=$False)] + # Only retrieve media which are used by the users in the given group(s). + [int[]] $UserGroupId, + + [Parameter(Mandatory=$False)] + # Only retrieve media which are used by the given user(s). + [int[]] $UserId, + + [Parameter(Mandatory=$False)] + # Only retrieve media which use the give media type(s). + [int[]] $MediaTypeId, + + [Parameter(Mandatory=$False)] + # Only retrieve media which are in the given status. + [ZbxStatus] $Status + ) + $prms = @{} + if ($Id.Length -gt 0) {$prms["mediaids"] = $Id} + if ($UserGroupId.Length -gt 0) {$prms["usrgrpids"] = $UserGroupId} + if ($UserId.Length -gt 0) {$prms["userids"] = $UserId} + if ($MediaTypeId.Length -gt 0) {$prms["mediatypeids"] = $MediaTypeId} + if ($Status -ne $null) {$prms["filter"] = @{"active" = [int]$Status}} + Invoke-ZabbixApi $session "usermedia.get" $prms | ForEach-Object {$_.severity = [ZbxSeverity]$_.severity; $_.mediaid = [int]$_.mediaid; $_.active=[ZbxStatus]$_.active; $_.PSTypeNames.Insert(0,"ZabbixMedia"); $_} +} diff --git a/src/public/Get-MediaType.ps1 b/src/public/Get-MediaType.ps1 new file mode 100644 index 0000000..277e4ac --- /dev/null +++ b/src/public/Get-MediaType.ps1 @@ -0,0 +1,46 @@ +function Get-MediaType +{ + <# + .SYNOPSIS + Retrieve and filter media types + + .DESCRIPTION + Query all media types with basic filters, or get all media types. + + .INPUTS + This function does not take pipe input. + + .OUTPUTS + The ZabbixMediaType objects corresponding to the filter. + + .EXAMPLE + PS> Get-MediaType -Type Email + mediatypeid type description + ----------- ---- ----------- + 1 Email Email + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$False)][Alias("MediaTypeId")] + # Only retrieve the media type with the given ID. + [int[]] $Id, + + [Parameter(Mandatory=$False, Position=0)][Alias("Description")] + # Filter by name. Accepts wildcard. + [string] $Name, + + [Parameter(Mandatory=$False, Position=0)][Alias("MediaTypeType")] + # Filter by type (email, SMS...) + [ZbxMediaTypeType] $Type + ) + $prms = @{search= @{}; filter=@{}; searchWildcardsEnabled=1; selectUsers = 0} + if ($Id.Length -gt 0) {$prms["mediatypeids"] = $Id} + if ($Name -ne $null) {$prms["search"]["description"] = $Name} + if ($Type -ne $null) {$prms["filter"]["type"] = [int]$Type} + + Invoke-ZabbixApi $session "mediatype.get" $prms | ForEach-Object {$_.mediatypeid = [int]$_.mediatypeid; $_.type = [ZbxMediaTypeType]$_.type; $_.status = [ZbxStatus]$_.status; $_.PSTypeNames.Insert(0,"ZabbixMediaType"); $_} +} diff --git a/src/public/Get-Proxy.ps1 b/src/public/Get-Proxy.ps1 new file mode 100644 index 0000000..4cde6c0 --- /dev/null +++ b/src/public/Get-Proxy.ps1 @@ -0,0 +1,38 @@ +function Get-Proxy +{ + <# + .SYNOPSIS + Retrieve and filter proxies. + + .DESCRIPTION + Query all proxies with basic filters, or get all proxies. + + .INPUTS + This function does not take pipe input. + + .OUTPUTS + The ZabbixProxy objects corresponding to the filter. + + .EXAMPLE + PS> Get-Proxy + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$False)][Alias("ProxyId")][int[]] + # Only retrieve the item with the given ID. + $Id, + + [Parameter(Mandatory=$False, Position=0)][Alias("ProxyName")] + # Filter by name. Accepts wildcard. + [string]$Name + ) + $prms = @{searchWildcardsEnabled=1; filter= @{selectInterface=1}; search=@{}} + if ($Id.Length -gt 0) {$prms["proxyids"] = $Id} + if ($Name -ne $null) {$prms["search"]["name"] = $Name} + Invoke-ZabbixApi $session "proxy.get" $prms | ForEach-Object {$_.proxyid = [int]$_.proxyid; $_.PSTypeNames.Insert(0,"ZabbixProxy"); $_} +} + diff --git a/src/public/Get-Template.ps1 b/src/public/Get-Template.ps1 new file mode 100644 index 0000000..0effa6e --- /dev/null +++ b/src/public/Get-Template.ps1 @@ -0,0 +1,64 @@ +function Get-Template +{ + <# + .SYNOPSIS + Retrieve and filter templates. + + .DESCRIPTION + Query all templates (not hosts) with basic filters, or get all templates. + + .INPUTS + This function does not take pipe input. + + .OUTPUTS + The ZabbixTemplate objects corresponding to the filter. + + .EXAMPLE + PS> Get-Host + templateid name description + ---------- ---- ----------- + 10001 Template OS Linux + 10047 Template App Zabbix Server + 10048 Template App Zabbix Proxy + 10050 Template App Zabbix Agent + + .EXAMPLE + PS> Get-Host -Id 10001 + templateid name description + ---------- ---- ----------- + 10001 Template OS Linux + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$False)][Alias("TemplateId")] + # Only retrieve the template with the given ID. + [int[]] $Id, + + [Parameter(Mandatory=$False)] + # Only retrieve remplates which belong to the given group(s). + [int[]] $GroupId, + + [Parameter(Mandatory=$False)] + # Only retrieve templates which are linked to the given hosts + [int[]] $HostId, + + [Parameter(Mandatory=$False)] + # Only retrieve templates which are children of the given parent template(s) + [int[]] $ParentId, + + [Parameter(Mandatory=$False, Position=0)][Alias("TemplateName")] + # Filter by name. Accepts wildcard. + [string] $Name + ) + $prms = @{search= @{}; searchWildcardsEnabled=1} + if ($Id.Length -gt 0) {$prms["templateids"] = $Id} + if ($GroupId.Length -gt 0) {$prms["groupids"] = $GroupId} + if ($HostId.Length -gt 0) {$prms["hostids"] = $HostId} + if ($Name -ne $null) {$prms["search"]["name"] = $Name} + Invoke-ZabbixApi $session "template.get" $prms | ForEach-Object {$_.templateid = [int]$_.templateid; $_.PSTypeNames.Insert(0,"ZabbixTemplate"); $_} +} + diff --git a/src/public/Get-User.ps1 b/src/public/Get-User.ps1 new file mode 100644 index 0000000..e10309f --- /dev/null +++ b/src/public/Get-User.ps1 @@ -0,0 +1,59 @@ +function Get-User +{ + <# + .SYNOPSIS + Retrieve and filter users. + + .DESCRIPTION + Query all users with basic filters, or get all users. + + .INPUTS + This function does not take pipe input. + + .OUTPUTS + The ZabbixUser objects corresponding to the filter. + + .EXAMPLE + PS> Get-User "marsu*" + userid alias name surname usrgrpsnames + ------ ----- ---- ------- ------------ + 1 marsu1 Zabbix Administrator Zabbix administrators + 2 marsu2 Guests + + .EXAMPLE + PS> Get-User + userid alias name surname usrgrpsnames + ------ ----- ---- ------- ------------ + 1 Admin Zabbix Administrator Zabbix administrators + 2 guest Guests + + .EXAMPLE + PS> Get-User -Id 1 + userid alias name surname usrgrpsnames + ------ ----- ---- ------- ------------ + 1 Admin Zabbix Administrator Zabbix administrators + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$False, ValueFromPipelineByPropertyName=$true)][Alias("UserId")] + # Only retrieve the user with the given ID + [int[]] $Id, + + [Parameter(Mandatory=$False, ValueFromPipelineByPropertyName=$true )][Alias("UsergrpId")] + # Only retrieve users which belong to these user groups + [int[]] $UserGroupId, + + [Parameter(Mandatory=$False, Position=0)][Alias("UserName")] + # Filter by name. Accepts wildcard. + [string] $Name + ) + $prms = @{selectUsrgrps = "extend"; getAccess = 1; search= @{}; searchWildcardsEnabled = 1} + if ($Id.Length -gt 0) {$prms["userids"] = $Id} + if ($UserGroupId.Length -gt 0) {$prms["usrgrpids"] = $UserGroupId} + if ($Name -ne $null) {$prms["search"]["alias"] = $Name} + Invoke-ZabbixApi $session "user.get" $prms | ForEach-Object {$_.userid = [int]$_.userid; $_.PSTypeNames.Insert(0,"ZabbixUser"); $_} +} diff --git a/src/public/Get-UserGroup.ps1 b/src/public/Get-UserGroup.ps1 new file mode 100644 index 0000000..5eefac0 --- /dev/null +++ b/src/public/Get-UserGroup.ps1 @@ -0,0 +1,59 @@ +function Get-UserGroup +{ + <# + .SYNOPSIS + Retrieve and filter user groups. + + .DESCRIPTION + Query all user groups with basic filters, or get all user groups. + + .INPUTS + This function does not take pipe input. + + .OUTPUTS + The ZabbixUserGroup objects corresponding to the filter. + + .EXAMPLE + PS> Get-UserGroup "*admin*" + usrgrpid count name + -------- ----- ---- + 7 1 Zabbix administrators + + .EXAMPLE + PS> Get-UserGroup + usrgrpid count name + -------- ----- ---- + 7 1 Zabbix administrators + 8 4 Guests + 9 0 Disabled + + .EXAMPLE + PS> Get-UserGroup -Id 7 + usrgrpid count name + -------- ----- ---- + 7 1 Zabbix administrators + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$False)][Alias("UserGroupId", "UsrGrpId")] + # Only retrieve the usergroup with the given ID + [int[]] $Id, + + [Parameter(Mandatory=$False)] + # Only retrieve groups which contain the given users + [int[]] $UserId, + + [Parameter(Mandatory=$False, Position=0)][Alias("UserGroupName")] + # Filter by name. Accepts wildcard. + [string] $Name + ) + $prms = @{searchWildcardsEnabled=1; selectUsers= 1; selectRights = 1; search= @{}} + if ($Id.Length -gt 0) {$prms["usrgrpids"] = $Id} + if ($UserId.Length -gt 0) {$prms["userids"] = $UserId} + if ($Name -ne $null) {$prms["search"]["name"] = $Name} + Invoke-ZabbixApi $session "usergroup.get" $prms | ForEach-Object {$_.usrgrpid = [int]$_.usrgrpid; $_.users_status = [ZbxStatus]$_.users_status; $_.debug_mode = [ZbxStatus]$_.debug_mode; $_.PSTypeNames.Insert(0,"ZabbixUserGroup"); $_} +} diff --git a/src/public/New-ApiSession.ps1 b/src/public/New-ApiSession.ps1 new file mode 100644 index 0000000..48cbcd8 --- /dev/null +++ b/src/public/New-ApiSession.ps1 @@ -0,0 +1,57 @@ +function New-ApiSession +{ + <# + .SYNOPSIS + Create a new authenticated session which can be used to call the Zabbix REST API. + + .DESCRIPTION + It must be called all other functions. It returns the actual session object, but usually + this object is not needed as the module caches and reuses the latest successful session. + + The validity of the credentials is checked and an error is thrown if not. + + .INPUTS + This function does not take pipe input. + + .OUTPUTS + The session object. + + .EXAMPLE + PS> New-ApiSession "http://myserver/zabbix/api_jsonrpc.php" (Get-Credentials MyAdminLogin) + Name Value + ---- ----- + Auth 2cce0ad0fac0a5da348fdb70ae9b233b + Uri http://myserver/zabbix/api_jsonrpc.php + WARNING : Connected to Zabbix version 3.2.1 + #> + param( + # The Zabbix REST endpoint. It should be like "http://myserver/zabbix/api_jsonrpc.php". + [uri] $ApiUri, + + # The credentials used to authenticate. Use Get-Credential to create this object. + [PSCredential]$auth, + + # If this switch is used, the information message "connected to..." will not be displayed. + [switch]$Silent + ) + + $bodyJson = new-JsonrpcRequest "user.login" @{user = $auth.UserName; password = $auth.GetNetworkCredential().Password} + $r = Invoke-RestMethod -Uri $ApiUri -Method Post -ContentType "application/json" -Body $bodyJson + if ($r -eq $null -or $r.result -eq $null -or [string]::IsNullOrWhiteSpace($r.result)) + { + Write-Error -Message "Session could not be opened" + } + $script:latestSession = @{Uri = $ApiUri; Auth = $r.result} + $script:latestSession + + $ver = Get-ApiVersion -Session $script:latestSession + $vers = $ver.split(".") + if ( ($vers[0] -lt 2) -or ($vers[0] -eq 2 -and $vers[1] -lt 4)) + { + Write-Warning "PSZabbix has not been tested with this version of Zabbix ${ver}. Tested version are >= 2.4. It should still work but be warned." + } + if (-not $Silent) + { + Write-Information "Connected to Zabbix version ${ver}" + } +} \ No newline at end of file diff --git a/src/public/New-Host.ps1 b/src/public/New-Host.ps1 new file mode 100644 index 0000000..e6d1e74 --- /dev/null +++ b/src/public/New-Host.ps1 @@ -0,0 +1,118 @@ +function New-Host +{ + <# + .SYNOPSIS + Create a new host. + + .DESCRIPTION + Create a new host. + + .INPUTS + This function does not take pipe input. + + .OUTPUTS + The ZabbixHost object created. + + .EXAMPLE + PS> New-Host -Name "mynewhostname$(Get-Random)" -HostGroupId 2 -TemplateId 10108 -Dns localhost + hostid host name status + ------ ---- ---- ------ + 10084 mynewhostname321 mynewhostname Enabled + + .NOTES + Contrary to other New-* functions inside this module, this method does not take pipe input. + This is inconsistent and needs to be changed. + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [parameter(Mandatory=$true)][Alias("HostName")] + # The name of the new host (not the visible name) + [string] $Name, + + [parameter(Mandatory=$false)][Alias("DisplayName")] + # The name as displayed in the interface. Defaults to Name. + [string] $VisibleName, + + [parameter(Mandatory=$false)] + # A description of the new host. + [string] $Description = $null, + + [parameter(Mandatory=$true, ParameterSetName="Ids")] + # The groups the new host should belong to. + [int[]] $HostGroupId, + + [parameter(Mandatory=$true, ParameterSetName="Objects")] + # The groups the new host should belong to. + [PSCustomObject[]] $HostGroup, + + [parameter(Mandatory=$true, ParameterSetName="Ids")] + # The templates the new host should belong to. + [int[]] $TemplateId, + + [parameter(Mandatory=$true, ParameterSetName="Objects")] + # The templates the new host should belong to. + [PSCustomObject[]] $Template, + + [parameter(Mandatory=$false)] + # An optional map of inventory properties + $Inventory = @{}, + + [parameter(Mandatory=$true)] + # The DNS or IP address to use to contact the host + [string] $Dns, + + [parameter(Mandatory=$false)] + # The port to use to use to contact the host. Default is 10050. + [int] $Port = 10050, + + [parameter(Mandatory=$false)] + # Should the newly created host be enabled? Default is true. + [ZbxStatus] $Status = [ZbxStatus]::Enabled, + + [parameter(Mandatory=$false)] + # The ID of the proxy to use. Default is no proxy. + [int] $ProxyId + ) + + $isIp = 0 + try { [ipaddress]$Dns; $isIp = 1} catch {} + + if ($Hostgroupid -ne $null) + { + $HostGroup = @() + $HostGroupId |% { $HostGroup += @{"groupid" = $_} } + } + if ($TemplateId -ne $null) + { + $Template = @() + $TemplateId |% { $Template += @{"templateid" = $_} } + } + + $prms = @{ + host = $Name + name = if ([string]::IsNullOrWhiteSpace($VisibleName)) { $null } else { $VisibleName } + description = $Description + interfaces = @( @{ + type = 1 + main = 1 + useip = $isIp + dns = if ($isIp -eq 1) { "" } else { $Dns } + ip = if ($isIp -eq 0) { "" } else { $Dns } + port = $Port + }) + groups = $HostGroup + templates = $Template + inventory_mode = 0 + inventory = $Inventory + status = [int]$Status + proxy_hostid = if ($ProxyId -eq $null) { "" } else { $ProxyId } + } + + $r = Invoke-ZabbixApi $session "host.create" $prms + if ($r) { Get-Host -session $s -Id $r.hostids } +} + diff --git a/src/public/New-HostGroup.ps1 b/src/public/New-HostGroup.ps1 new file mode 100644 index 0000000..f0852af --- /dev/null +++ b/src/public/New-HostGroup.ps1 @@ -0,0 +1,55 @@ +function New-HostGroup +{ + <# + .SYNOPSIS + Create a new host group. + + .DESCRIPTION + Create a new host group. + + .INPUTS + This function accepts a ZabbixHostGroup as pipe input, or any object which properties map the function parameters. + + .OUTPUTS + The ZabbixHostGroup object created. + + .EXAMPLE + PS> New-HostGroup "newgroupname1","newgroupname2" + groupid internal flags name + ------- -------- ----- ---- + 13 0 0 newgroupname1 + 14 0 0 newgroupname2 + + .EXAMPLE + PS> "newgroupname1","newgroupname2" | New-HostGroup + groupid internal flags name + ------- -------- ----- ---- + 13 0 0 newgroupname1 + 14 0 0 newgroupname2 + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)][ValidateNotNullOrEmpty()][Alias("HostGroupName")] + # The name of the new group (one or more separated by commas) + [string[]] $Name + ) + begin + { + $prms = @() + } + process + { + $Name |% { $prms += @{name = $_} } + } + end + { + if ($prms.Count -eq 0) { return } + $prms = @{ array = $prms } + $r = Invoke-ZabbixApi $session "hostgroup.create" $prms + Get-HostGroup -Session $s -Id $r.groupids + } +} diff --git a/src/public/New-Maintenance.ps1 b/src/public/New-Maintenance.ps1 new file mode 100644 index 0000000..b8e85a5 --- /dev/null +++ b/src/public/New-Maintenance.ps1 @@ -0,0 +1,105 @@ + +function New-Maintenance +{ + <# + .SYNOPSIS + Create maintenance windows for a specific set of hosts or host groups + + .DESCRIPTION + Both the host id and host group parameter is optional, but between the two, at least one host or host group must be specified. + + .INPUTS + This function does not take pipe input, but it should. + + .OUTPUTS + Id of the new Zabbix maintenance object + + .EXAMPLE + PS> New-Maintenance -HostId 42,43 -Name "Lakenbake" + + maintenanceid name maintenance_type description + ------------- ---- ---------------- ----------- + 134 Lakenbake 0 Baken laken + + .EXAMPLE + PS> New-Maintenance -HostGroupId 14 -Name "Lakenbake Group" + + maintenanceid name maintenance_type description + ------------- ---- ---------------- ----------- + 134 Lakenbake 0 Baken laken + + + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$true)] + # Name of the maintenance window + [string] $Name, + + [Parameter(Mandatory=$False)] + # IDs of the host groups that will undergo maintenance. + [int[]] $HostGroupId, + + [Parameter(Mandatory=$False)] + # IDs of the hosts that will undergo maintenance. + [int[]] $HostId, + + [Parameter(Mandatory=$False)] + # Start of the maintenance window + [DateTime] $StartTime = $(Get-Date), + + [Parameter(Mandatory=$False)] + # Start of the maintenance window + [TimeSpan] $Duration = $(New-TimeSpan -Hours 1) + + ) + + if([string]::IsNullOrEmpty($Name)) + { + throw "-Name parameter must be populated" + } + $prms = @{"name" = $Name} + + # + # Affected hosts + # + if($HostGroupId -eq $null -and $HostId -eq $null) + { + throw "Either -HostId or -HostGroupId must be specified." + } + if ($HostGroupId.Length -gt 0) + { + $prms["groupids"] = $HostGroupId + } + if ($HostId.Length -gt 0) + { + $prms["hostids"] = $HostId + } + + # + # Maintenance window boundaries + # + $prms["active_since"] = ConvertTo-EpochTime $StartTime + $prms["active_till"] = $prms["active_since"] + $Duration.TotalSeconds + + # + # Only create one-time maintenance period - matching the maintenance window size. + # + $oneTimePeriod = + @( + @{ + "timeperiod_type"= 0; # one time only + "start_date" = $prms["active_since"]; # same as window + "period" = $Duration.TotalSeconds; # same as window + } + ) + $prms["timeperiods"] = $oneTimePeriod + + $result = Invoke-ZabbixApi $session "maintenance.create" $prms + $result +} + diff --git a/src/public/New-User.ps1 b/src/public/New-User.ps1 new file mode 100644 index 0000000..da83e4f --- /dev/null +++ b/src/public/New-User.ps1 @@ -0,0 +1,137 @@ +function New-User +{ + <# + .SYNOPSIS + Create a new user. + + .DESCRIPTION + Create a new user. + + .INPUTS + This function accepts a ZabbixUser as pipe input, or any object which properties map the function parameters. + + .OUTPUTS + The ZabbixUser object created. + + .EXAMPLE + PS> New-User -Alias "login1" -name "marsu" -UserGroupId (get-group "GROUPNAME*").id + userid alias name surname usrgrpsnames + ------ ----- ---- ------- ------------ + 19 login1 marsu GROUPNAME1,GROUPNAME2,GROUPNAME3 + + Create a user from scratch. + + .EXAMPLE + PS> $u = New-User -Alias "login1" -name "marsu" -UserGroupId (get-group "GROUPNAME*").id + PS> $u | New-User -alias "login2" + userid alias name surname usrgrpsnames + ------ ----- ---- ------- ------------ + 20 login2 marsu GROUPNAME1,GROUPNAME2,GROUPNAME3 + + Copy a user. + #> + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingUserNameAndPassWordParams", "")] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")] + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$true, ParameterSetName = "login_withgroupid")] + [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$true, ParameterSetName = "login_withgroupobject")] + [Alias("Login")] + # Login of the new user. Must be unique. + [string] $Alias, + + [Parameter(Mandatory=$False, ValueFromPipelineByPropertyName=$true, ParameterSetName = "login_withgroupid")] + [Parameter(Mandatory=$False, ValueFromPipelineByPropertyName=$true, ParameterSetName = "login_withgroupobject")] + [Alias("Pwd", "passwd")] + # Password of the new user. If not specified, a long random string is used (useful if authenticated + # against a LDAP, as in that case the internal Zabbix password is not used). + [string] $Password = $null, + + [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$true, ParameterSetName = "pscred_withgroupid")] + [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$true, ParameterSetName = "pscred_withgroupobject")] + # A Credential (from Get-Credential or other source) object containing both login and password for the new user. + [PSCredential][System.Management.Automation.Credential()] $Credential, + + [Parameter(Mandatory=$False, ValueFromPipelineByPropertyName=$true)] + # Display name of the new user. If not given, the Alias is used. + [string] $Name, + + [Parameter(Mandatory=$False, ValueFromPipelineByPropertyName=$true )] + # Type of user. Default is simple user. + [ZbxUserType] $UserType = [ZbxUserType]::User, + + [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$true, ParameterSetName = "login_withgroupid")] + [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$true, ParameterSetName = "pscred_withgroupid")] + [ValidateNotNullOrEmpty()][Alias("UsrGrpId")] + # The ID of the groups the new user belongs to. + [int[]] $UserGroupId, + + [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$true, ParameterSetName = "login_withgroupobject")] + [Parameter(Mandatory=$True, ValueFromPipelineByPropertyName=$true, ParameterSetName = "pscred_withgroupobject")] + [ValidateNotNullOrEmpty()][ValidateScript({ $_.usrgrpid -ne $null})] + [Alias("UsrGrps")] + # The groups the new user belongs to. + [object[]] $UserGroup, + + [Parameter(Mandatory=$False)] + # Mail adress to send alerts to + [string] $MailAddress, + + [Parameter(Mandatory=$False)] + # A severity mask for alerts. Only used if $MailAdress is specified. Default is Disaster,High + [ZbxSeverity] $AlertOn = [ZbxSeverity]::Disaster -bor [ZbxSeverity]::High + ) + + begin + { + $prms = @{} + $media = @() + if ($MailAddress -ne '') + { + $media += @{ + mediatypeid = @(Get-MediaType -Type email)[0].mediatypeid + sendto = $MailAddress + active = [int][ZbxStatus]::Enabled + severity = $AlertOn + period = "1-7,00:00-24:00" + } + } + } + process + { + $usergrps = @() + if ($PSCmdlet.ParameterSetName -in "login_withgroupid", "pscred_withgroupid") + { + $UserGroupId |% { $usergrps += @{usrgrpid = $_} } + } + else + { + $usergrps += $UserGroup + } + + if ($PSCmdlet.ParameterSetName -in "pscred_withgroupid", "pscred_withgroupobject") + { + $Alias = $Credential.GetNetworkCredential().UserName + $Pp = $Credential.GetNetworkCredential().Password + } + + $prms += @{ + alias = $Alias + name = if ($Name -ne $null) { $Name } else {$Alias} + type = [int]$UserType + passwd = if ($Password -ne $null) {$Password} else { "" + (Get-Random -Maximum ([long]::MaxValue)) } + usrgrps = $usergrps + user_medias = $media + } + } + end + { + if ($prms.Count -eq 0) { return } + $id = Invoke-ZabbixApi $session "user.create" $prms + Get-User -Session $Session -Id $id.userids + } +} diff --git a/src/public/New-UserGroup.ps1 b/src/public/New-UserGroup.ps1 new file mode 100644 index 0000000..3397673 --- /dev/null +++ b/src/public/New-UserGroup.ps1 @@ -0,0 +1,63 @@ +function New-UserGroup +{ + <# + .SYNOPSIS + Create a new user group. + + .DESCRIPTION + Create a new user group. + + .INPUTS + This function accepts a ZabbixUserGroup as pipe input, or any object which properties map the function parameters. + + .OUTPUTS + The ZabbixUserGroup object created. + + .EXAMPLE + PS> New-UserGroup "newgroupname1","newgroupname2" + usrgrpid count name + -------- ----- ---- + 7 1 newgroupname1 + 8 1 newgroupname2 + + .EXAMPLE + PS> "newgroupname1","newgroupname2" | New-UserGroup + usrgrpid count name + -------- ----- ---- + 7 1 newgroupname1 + 8 1 newgroupname2 + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)][ValidateNotNullOrEmpty()][Alias("UserGroupName")] + # The name of the new group (one or more separated by commas) + [string[]] $Name, + + [Parameter(Mandatory=$false)] + # Status of the new group. Default is enabled. + $Status = [ZbxStatus]::Enabled, + + [Parameter(Mandatory=$false)] + # If members have access to the GUI. Default is WithDefaultAuthenticationMethod. + $GuiAccess = [ZbxGuiAccess]::WithDefaultAuthenticationMethod + ) + begin + { + $prms = @() + } + process + { + $Name |% { $prms += @{name = $_; gui_access = [int]$GuiAccess; users_status = [int]$Status} } + } + end + { + if ($prms.Count -eq 0) { return } + $prms = @{ array = $prms } + $r = Invoke-ZabbixApi $session "usergroup.create" $prms + Get-UserGroup -Session $s -Id $r.usrgrpids + } +} diff --git a/src/public/Remove-Host.ps1 b/src/public/Remove-Host.ps1 new file mode 100644 index 0000000..7fa9ea0 --- /dev/null +++ b/src/public/Remove-Host.ps1 @@ -0,0 +1,48 @@ +function Remove-Host +{ + <# + .SYNOPSIS + Remove one or more hosts from Zabbix. + + .DESCRIPTION + Removal is immediate. + + .INPUTS + This function accepts ZabbixHost objects or host IDs from the pipe. Equivalent to using -HostId parameter. + + .OUTPUTS + The ID of the removed objects. + + .EXAMPLE + Remove all hosts + PS> Get-Host | Remove-Host + 10084 + 10085 + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)][ValidateNotNullOrEmpty()][Alias("Id")] + # The ID of one or more hosts to remove. You can also pipe a ZabbixHost object or any object with a hostid or id property. + [int[]]$HostId + ) + + begin + { + $prms = @() + } + process + { + $prms += $HostId + } + end + { + if ($prms.Count -eq 0) { return } + $prms = @{ array = $prms } + Invoke-ZabbixApi $session "host.delete" $prms | Select-Object -ExpandProperty hostids + } +} + diff --git a/src/public/Remove-HostGroup.ps1 b/src/public/Remove-HostGroup.ps1 new file mode 100644 index 0000000..5cc47e8 --- /dev/null +++ b/src/public/Remove-HostGroup.ps1 @@ -0,0 +1,47 @@ +function Remove-HostGroup +{ + <# + .SYNOPSIS + Remove one or more host groups from Zabbix. + + .DESCRIPTION + Removal is immediate. + + .INPUTS + This function accepts ZabbixHostGroup objects or host group IDs from the pipe. Equivalent to using -HostGroupId parameter. + + .OUTPUTS + The ID of the removed objects. + + .EXAMPLE + Remove all groups + PS> Get-HostGroup | Remove-HostGroup + 10084 + 10085 + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)][ValidateNotNullOrEmpty()][Alias("Id", "GroupId")] + # ID of one or more groups to remove. You can also pipe in objects with an "ID" of "groupid" property. + [int[]]$HostGroupId + ) + + begin + { + $prms = @() + } + process + { + $prms += $HostGroupId + } + end + { + if ($prms.Count -eq 0) { return } + $prms = @{ array = $prms } + Invoke-ZabbixApi $session "hostgroup.delete" $prms | Select-Object -ExpandProperty groupids + } +} diff --git a/src/public/Remove-HostGroupMembership.ps1 b/src/public/Remove-HostGroupMembership.ps1 new file mode 100644 index 0000000..1f6b8fe --- /dev/null +++ b/src/public/Remove-HostGroupMembership.ps1 @@ -0,0 +1,50 @@ +function Remove-HostGroupMembership +{ + <# + .SYNOPSIS + Remove a host (or multiple hosts) as a member of one or more host groups. + + .DESCRIPTION + This is additional: existing membership to other groups are not changed. + + .INPUTS + This function accepts ZabbixHost objects from the pipe. Equivalent to using -Host parameter. + + .OUTPUTS + The ID of the changed objects. + + .EXAMPLE + PS> Get-Host | Remove-HostGroupMembership (Get-Group group1),(Get-Group group2) + 10084 + 10085 + + Make sure no host is member of two specified groups. + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=1)][ValidateScript({ $_.PSObject.TypeNames[0] -eq 'ZabbixHost'})][ValidateNotNullOrEmpty()] + # The host or hostid to remove from the hostgroup(s). + [PSCustomObject[]]$Host, + + [Parameter(Mandatory=$true, Position=0)][ValidateNotNullOrEmpty()][ValidateScript({ $_.PSObject.TypeNames[0] -eq 'ZabbixGroup'})] + # The Host is removed from this list of one or more hostgroups. + [PSCustomObject[]]$HostGroup + ) + begin + { + $grpids = @($HostGroup |% {$_.groupid} ) + $prms = @{hostids = @(); groupids = $grpids} + } + process + { + $prms["hostids"] += $Host.hostid + } + end + { + Invoke-ZabbixApi $session "host.massremove" $prms | Select-Object -ExpandProperty hostids + } +} diff --git a/src/public/Remove-Maintenance.ps1 b/src/public/Remove-Maintenance.ps1 new file mode 100644 index 0000000..02ca485 --- /dev/null +++ b/src/public/Remove-Maintenance.ps1 @@ -0,0 +1,50 @@ + +function Remove-Maintenance +{ + <# + .SYNOPSIS + Retrieve maintenance windows for a specific window, specific set of hosts or host group + + .DESCRIPTION + If called with no parameters, the function will return all maintenance windows configured on the Zabbix server + + + .INPUTS + This function does not take pipe input. + + .OUTPUTS + Zabbix maintenance objects + + .EXAMPLE + PS> Remove-Maintenance -MaintenanceId 2 + + + .EXAMPLE + PS> Remove-Maintenance -MaintenanceId 1,2,3 + + + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$False)][Alias("MaintenanceId")] + # Only retrieve the items with the given ID(s). + [int[]] $Id + ) + $prms = @{} + if ($Id.Length -gt 0) + { + $prms["array"] = $Id # "array" key is an instruction to New-JsonrpcRequest - not a body element + } + else + { + throw "Invalid input array of maintenance Ids" + } + + $result = Invoke-ZabbixApi $session "maintenance.delete" $prms + $result +} + diff --git a/src/public/Remove-Media.ps1 b/src/public/Remove-Media.ps1 new file mode 100644 index 0000000..11ec217 --- /dev/null +++ b/src/public/Remove-Media.ps1 @@ -0,0 +1,47 @@ +function Remove-Media +{ + <# + .SYNOPSIS + Remove one or more user media from Zabbix. + + .DESCRIPTION + Removal is immediate. + + .INPUTS + This function accepts ZabbixMedia objects or media IDs from the pipe. Equivalent to using -MediaId parameter. + + .OUTPUTS + The ID of the removed objects. + + .EXAMPLE + Remove all users + PS> Get-Media | Remove-Media + 10084 + 10085 + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$True, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)][ValidateNotNullOrEmpty()][Alias("Media", "Id")] + # One or more media to remove. Either user objects (with a mediaid property) or directly IDs. + [int[]] $MediaId + ) + + Begin + { + $prms = @() + } + process + { + $prms += $MediaId + } + end + { + if ($prms.Count -eq 0) { return } + $prms = @{ array = $prms } + Invoke-ZabbixApi $session "user.deletemedia" $prms | Select-Object -ExpandProperty mediaids + } +} \ No newline at end of file diff --git a/src/public/Remove-Template.ps1 b/src/public/Remove-Template.ps1 new file mode 100644 index 0000000..006b10f --- /dev/null +++ b/src/public/Remove-Template.ps1 @@ -0,0 +1,46 @@ +function Remove-Template +{ + <# + .SYNOPSIS + Remove one or more templates from Zabbix. + + .DESCRIPTION + Removal is immediate. + + .INPUTS + This function accepts ZabbixTemplate objects or template IDs from the pipe. Equivalent to using -TemplateId parameter. + + .OUTPUTS + The ID of the removed objects. + + .EXAMPLE + Remove all templates + PS> Get-Template | Remove-Template + 10084 + 10085 + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)][ValidateNotNullOrEmpty()][Alias("Template")] + # The templates to remove. Either template objects (with a templateid property) or directly IDs. + [int[]]$TemplateId + ) + + begin + { + $prms = @() + } + process + { + $prms += $TemplateId + } + end + { + if ($prms.Count -eq 0) { return } + Invoke-ZabbixApi $session "template.delete" $prms | Select-Object -ExpandProperty templateids + } +} diff --git a/src/public/Remove-User.ps1 b/src/public/Remove-User.ps1 new file mode 100644 index 0000000..d52abf8 --- /dev/null +++ b/src/public/Remove-User.ps1 @@ -0,0 +1,48 @@ +function Remove-User +{ + <# + .SYNOPSIS + Remove one or more users from Zabbix. + + .DESCRIPTION + Removal is immediate. + + .INPUTS + This function accepts ZabbixUser objects or user IDs from the pipe. Equivalent to using -UserId parameter. + + .OUTPUTS + The ID of the removed objects. + + .EXAMPLE + Remove all users + PS> Get-User | Remove-User + 10084 + 10085 + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$True, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)][ValidateNotNullOrEmpty()][Alias("User", "Id")] + # One or more users to remove. Either user objects (with a userid property) or directly IDs. + [int[]] $UserId + ) + + Begin + { + $allUserIds = @() + } + process + { + $allUserIds += $UserId + } + end + { + if ($allUserIds.Count -eq 0) { return } + $prms = @{ array = $allUserIds } + Invoke-ZabbixApi $session "user.delete" $prms | Select-Object -ExpandProperty userids + } +} + diff --git a/src/public/Remove-UserGroup.ps1 b/src/public/Remove-UserGroup.ps1 new file mode 100644 index 0000000..5959191 --- /dev/null +++ b/src/public/Remove-UserGroup.ps1 @@ -0,0 +1,48 @@ +function Remove-UserGroup +{ + <# + .SYNOPSIS + Remove one or more user groups from Zabbix. + + .DESCRIPTION + Removal is immediate. + + .INPUTS + This function accepts ZabbixUserGroup objects or user group IDs from the pipe. Equivalent to using -UserGroupId parameter. + + .OUTPUTS + The ID of the removed objects. + + .EXAMPLE + Remove all groups + PS> Get-UserGroup | Remove-UserGroup + 10084 + 10085 + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [parameter(Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true, Position=0)][ValidateNotNullOrEmpty()][Alias("UsrGrpId", "UserGroup", "Id")] + # Id of one or more groups to remove. You can also pipe in objects with an "Id" of "usrgrpid" property. + [int[]]$UserGroupId + ) + + begin + { + $userGroupIds = @() + } + process + { + $userGroupIds += $UserGroupId + } + end + { + if ($userGroupIds.Count -eq 0) { return } + $prms = @{ array = $userGroupIds} + Invoke-ZabbixApi $session "usergroup.delete" $prms | Select-Object -ExpandProperty usrgrpids + } +} + diff --git a/src/public/Remove-UserGroupMembership.ps1 b/src/public/Remove-UserGroupMembership.ps1 new file mode 100644 index 0000000..8b2269d --- /dev/null +++ b/src/public/Remove-UserGroupMembership.ps1 @@ -0,0 +1,98 @@ +function Remove-UserGroupMembership +{ + <# + .SYNOPSIS + Remove a user (or multiple users) as a member of one or more user groups. + + .DESCRIPTION + This is additional: existing membership to other groups are not changed. + + .INPUTS + This function accepts ZabbixUser objects or user IDs from the pipe. Equivalent to using -UserId parameter. + + .OUTPUTS + The ID of the changed objects. + + .EXAMPLE + PS> Get-User | Remove-UserGroupMembership (Get-UserGroup group1),(Get-UserGroup group2) + 10084 + 10085 + + Make sure no user is member of two specified groups. + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$True, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)][Alias("Id", "User")] + [ValidateNotNullOrEmpty()] + # User to remove from the groups + [int[]] $UserId, + + [Parameter(Mandatory=$True, ParameterSetName="Objects", Position=0)][ValidateScript({ $_.usrgrpid -ne $null})] + # Groups to remove the users from + [PSCustomObject[]] $UserGroup, + + [Parameter(Mandatory=$True, ParameterSetName="Ids",Position=0)] + # Groups to remove the users from + [int[]] $UserGroupId + ) + + begin + { + $prms = @() + $groupids = @() + if ($PSCmdlet.ParameterSetName -eq "Objects") + { + $UserGroup |% { $groupids += $_.usrgrpid} + } + else + { + $groupids += $UserGroupId + } + } + process + { + foreach ($uid in $UserId) + { + $User = Get-User -session $s -id $uid + $grps = @() + $existingGid = @($User.usrgrps.usrgrpid) + $removedGid = @() + $remainingGid = @() + + foreach ($gid in $existingGid) + { + if (($gid -in $groupids)) + { + $removedGid += $gid + } + else + { + $remainingGid += $gid + } + } + + if ($removedGid.count -eq 0) + { + # already absent from requested groups + continue + } + + foreach($gid in $remainingGid) + { + $grps += @{usrgrpid = $gid} + } + + $prms = @{ + userid = $User.userid + usrgrps = $grps + } + # Sad, but not mass API. + Invoke-ZabbixApi $session "user.update" $prms | Select-Object -ExpandProperty userids + } + } +} + diff --git a/src/public/Update-Host.ps1 b/src/public/Update-Host.ps1 new file mode 100644 index 0000000..ded5489 --- /dev/null +++ b/src/public/Update-Host.ps1 @@ -0,0 +1,51 @@ +function Update-Host +{ + <# + .SYNOPSIS + Update the attributes of one or more existing Zabbix Hosts. + + .DESCRIPTION + Please note that this method actually updates all attributes of the host, even if they were not changed. + + This is first and foremost made to update direct attributes. To update linked linked objects like templates or interfaces, it is often more practical to use the dedicated cmdlets. + + .INPUTS + This function accepts ZabbixHost objects, on pipe or as argument. + + .OUTPUTS + The ID of the changed objects. + + .EXAMPLE + Sets a new description for all hosts. + PS> Get-Host |% { $_.name = "toto"; $_ } | Update-Host + 10084 + 10085 + #> + param + ( + [Parameter(Mandatory=$False)] + # A valid Zabbix API session retrieved with New-ApiSession. If not given, the latest opened session will be used, which should be enough in most cases. + [Hashtable] $Session, + + [Parameter(Mandatory=$true, ValueFromPipeline=$true, Position=0)] + [ValidateScript({ $_.PSObject.TypeNames[0] -eq 'ZabbixHost'})][ValidateNotNullOrEmpty()] + # One or more hosts to update. + [PSObject[]] $HostObject + ) + begin + { + $Hosts = @() + } + process + { + $Hosts += $HostObject + } + end + { + if ($Hosts.Count -eq 0) { return } + $prms = @{ array = $Hosts } + Invoke-ZabbixApi $session "host.update" $prms | Select-Object -ExpandProperty hostids + } +} + + diff --git a/test/integration/Module.Tests.ps1 b/test/integration/Module.Tests.ps1 new file mode 100644 index 0000000..207d8c6 --- /dev/null +++ b/test/integration/Module.Tests.ps1 @@ -0,0 +1,45 @@ +BeforeAll { + Try { + $module = 'PSZabbix' + $moduleRoot = "$PSScriptRoot/../../" + # Import-Module $PSScriptRoot/../../$module.psd1 + } Catch { + $e = $_ + Write-Warning "Error setup Tests $e $($_.exception)" + Throw $e + } +} +AfterAll { + Remove-Module $module -ErrorAction SilentlyContinue +} + +Describe -Tags ('Unit', 'Acceptance') "$module Module Tests" { + + Context 'Module Setup' { + It "has the root module $module.psm1" { + "$moduleRoot/$module.psm1" | Should -Exist + } + + It "has the a manifest file of $module.psd1" { + "$moduleRoot/$module.psd1" | Should -Exist + "$moduleRoot/$module.psd1" | Should -FileContentMatch "$module.psm1" + } + + It "$module is valid PowerShell code" { + $psFile = Get-Content -Path "$moduleRoot/$module.psm1" -ErrorAction Stop + $errors = $null + $null = [System.Management.Automation.PSParser]::Tokenize($psFile, [ref]$errors) + $errors.Count | Should -Be 0 + } + + It "has every public function exported" { + Import-Module $moduleRoot/$module.psd1 -ErrorAction Stop + foreach ($file in Get-ChildItem "$moduleRoot/src/public/*.ps1") { + # func name must include default module prefix + $funcName = (Split-Path $file -Leaf) -replace '(\S+)-(\S*).ps1','$1-Zbx$2' + (Get-Command -Module $module).Name | Should -Contain $funcName + } + Remove-Module $module -ErrorAction SilentlyContinue + } + } +} \ No newline at end of file diff --git a/test/integration/PSZabbix.Tests.ps1 b/test/integration/PSZabbix.Tests.ps1 new file mode 100644 index 0000000..e4ffa7f --- /dev/null +++ b/test/integration/PSZabbix.Tests.ps1 @@ -0,0 +1,680 @@ +[Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingConvertToSecureStringWithPlainText", "")] +param() +BeforeAll { + Try { + $moduleName = 'PSZabbix' + $moduleRoot = "$PSScriptRoot/../../" + Import-Module $moduleRoot/$moduleName.psd1 -Force + + $global:baseUrl = $env:DEV_ZABBIX_API_URL + if ('' -eq $global:baseUrl) { + $global:baseUrl = "http://tools/zabbix/api_jsonrpc.php" + } + $secpasswd = ConvertTo-SecureString "zabbix" -AsPlainText -Force + $global:admin = New-Object System.Management.Automation.PSCredential ("Admin", $secpasswd) + + $wrongsecpasswd = ConvertTo-SecureString "wrong" -AsPlainText -Force + $global:admin2 = New-Object System.Management.Automation.PSCredential ("Admin", $wrongsecpasswd) + + $s = New-ZbxApiSession $baseUrl $global:admin -silent + + $testTemplate = Get-ZbxTemplate | Select-Object -First 1 + $testTemplateId = $testTemplate.templateid + } Catch { + $e = $_ + Write-Warning "Error setup Tests $e $($_.exception)" + Throw $e + } + +} +AfterAll { + Remove-Module $moduleName +} + +Describe "New-ZbxApiSession" { + BeforeAll { + $session = New-ZbxApiSession $baseUrl $admin -silent + } + + It "connects to zabbix and returns a non-empty session object" { + $session | Should -Not -Be $null + $session["Uri"] | Should -Not -Be $null + $session["Auth"] | Should -Not -Be $null + } + + It "fails when URL is wrong" { + { New-ZbxApiSession "http://localhost:12345/zabbix" $admin } | Should -Throw + } + + It "fails when login/password is wrong" { + { New-ZbxApiSession $baseUrl $admin2 } | Should -Throw + } +} + +Describe "New-ZbxHost" { + AfterAll { + Get-ZbxHost 'pestertesthost*' | Remove-ZbxHost + } + It "can create an enabled host from explicit ID parameters" { + $h = New-ZbxHost -Name "pestertesthost$(Get-Random)" -HostGroupId 2 -TemplateId $testTemplateId -Dns localhost + $h | Should -Not -Be $null + $h.status | Should -Be 0 + } + It "can create an disabled host from explicit ID parameters" { + $h = New-ZbxHost -Name "pestertesthost$(Get-Random)" -HostGroupId 2 -TemplateId $testTemplateId -Dns localhost -status disabled + $h | Should -Not -Be $null + $h.status | Should -Be 1 + } + It "should throw if invalid Group or template Id" { + { New-ZbxHost -Name "pestertesthost$(Get-Random)" -HostGroupId 2 -TemplateId 9999 -Dns localhost -status disabled } | Should -Throw + { New-ZbxHost -Name "pestertesthost$(Get-Random)" -HostGroupId 9999 -TemplateId $testTemplateId -Dns localhost -status disabled } | Should -Throw + } +} + +Describe "Get-ZbxHost" { + BeforeAll { + $h1 = New-ZbxHost -Name "pestertesthost1" -HostGroupId 2 -TemplateId $testTemplateId -Dns localhost + $h2 = New-ZbxHost -Name "pestertesthost2" -HostGroupId 2 -TemplateId $testTemplateId -Dns localhost + } + It "can return all hosts" { + Get-ZbxHost | Should -Not -BeNullOrEmpty + } + It "can filter by name with wildcard (explicit parameter)" { + Get-ZbxHost "pestertesthost*" | Should -Not -BeNullOrEmpty + Get-ZbxHost "pestertesthostXXX*" | Should -BeNullOrEmpty + } + It "can filter by ID (explicit parameter)" { + $h = (Get-ZbxHost "pestertesthost*")[0] + (Get-ZbxHost -Id $h.hostid).host | Should -Be $h.host + } + It "can filter by group membership (explicit parameter)" { + $h = (Get-ZbxHost "pestertesthost*")[0] + (Get-ZbxHost -Id $h.hostid -HostGroupId 2).host | Should -Be $h.host + } +} + +Describe "Remove-ZbxHost" { + BeforeEach { + $h1 = New-ZbxHost -Name "pestertesthostrem" -HostGroupId 2 -TemplateId $testTemplateId -Dns localhost -errorAction silentlycontinue + $h2 = New-ZbxHost -Name "pestertesthostrem2" -HostGroupId 2 -TemplateId $testTemplateId -Dns localhost -errorAction silentlycontinue + # if the test before failed e.g. because the host already exists, New-Host returns $null + if ($null -eq $h1) { $h1 = Get-ZbxHost "pestertesthostrem" } + if ($null -eq $h2) { $h2 = Get-ZbxHost "pestertesthostrem2" } + } + AfterAll { + remove-ZbxHost $h1.hostid, $h2.hostid -ErrorAction silentlycontinue + } + It "can delete from one explicit ID parameter" { + remove-ZbxHost $h1.hostid | Should -Be $h1.hostid + } + It "can delete from multiple explicit ID parameters" { + remove-ZbxHost $h1.hostid, $h2.hostid | Should -Be @($h1.hostid, $h2.hostid) + } + It "can delete from multiple piped IDs" { + $h1.hostid, $h2.hostid | remove-ZbxHost | Should -Be @($h1.hostid, $h2.hostid) + } + It "can delete from one piped object parameter" { + $h1 | remove-ZbxHost | Should -Be $h1.hostid + } + It "can delete from multiple piped objects" { + $h1, $h2 | remove-ZbxHost | Should -Be @($h1.hostid, $h2.hostid) + } +} + +Describe "Disable-ZbxHost" { + BeforeAll { + New-ZbxHost -Name "pestertesthost1" -HostGroupId 2 -TemplateId $testTemplateId -Dns localhost -errorAction silentlycontinue + New-ZbxHost -Name "pestertesthost2" -HostGroupId 2 -TemplateId $testTemplateId -Dns localhost -errorAction silentlycontinue + $h1 = Get-ZbxHost pestertesthost1 + $h2 = Get-ZbxHost pestertesthost2 + } + AfterAll { + Remove-ZbxHost $h1.HostId,$h2.HostId + } + + It "can enable multiple piped objects" { + $h1, $h2 | Disable-ZbxHost | Should -Be @($h1.hostid, $h2.hostid) + (Get-ZbxHost pestertesthost1).status | Should -Be 1 + } + It "can enable multiple piped IDs" { + $h1.hostid, $h2.hostid | Disable-ZbxHost | Should -Be @($h1.hostid, $h2.hostid) + (Get-ZbxHost pestertesthost1).status | Should -Be 1 + } + It "can enable multiple explicit parameter IDs" { + Disable-ZbxHost $h1.hostid, $h2.hostid | Should -Be @($h1.hostid, $h2.hostid) + (Get-ZbxHost pestertesthost1).status | Should -Be 1 + } +} + +Describe "Enable-ZbxHost" { + BeforeAll { + New-ZbxHost -Name "pestertesthost1" -HostGroupId 2 -TemplateId $testTemplateId -Dns localhost -errorAction silentlycontinue + New-ZbxHost -Name "pestertesthost2" -HostGroupId 2 -TemplateId $testTemplateId -Dns localhost -errorAction silentlycontinue + $h1 = Get-ZbxHost pestertesthost1 + $h2 = Get-ZbxHost pestertesthost2 + } + BeforeEach { + Disable-ZbxHost $h1.hostid, $h2.hostid + } + AfterAll { + Remove-ZbxHost $h1.HostId,$h2.HostId + } + + It "can enable multiple piped objects" { + $h1, $h2 | Enable-ZbxHost | Should -Be @($h1.hostid, $h2.hostid) + (Get-ZbxHost pestertesthost1).status | Should -Be 0 + } + It "can enable multiple piped IDs" { + $h1.hostid, $h2.hostid | Enable-ZbxHost | Should -Be @($h1.hostid, $h2.hostid) + (Get-ZbxHost pestertesthost1).status | Should -Be 0 + } + It "can enable multiple explicit parameter IDs" { + Enable-ZbxHost $h1.hostid, $h2.hostid | Should -Be @($h1.hostid, $h2.hostid) + (Get-ZbxHost pestertesthost1).status | Should -Be 0 + } +} + +Describe "Add-ZbxHostGroupMembership" { + BeforeAll { + New-ZbxHost -Name "pestertesthost1" -HostGroupId 2 -TemplateId $testTemplateId -Dns localhost -errorAction silentlycontinue + New-ZbxHost -Name "pestertesthost2" -HostGroupId 2 -TemplateId $testTemplateId -Dns localhost -errorAction silentlycontinue + $h1 = Get-ZbxHost pestertesthost1 + $h2 = Get-ZbxHost pestertesthost2 + New-ZbxHostGroup "pestertest1" -errorAction silentlycontinue + New-ZbxHostGroup "pestertest2" -errorAction silentlycontinue + $g1 = Get-ZbxHostGroup pestertest1 + $g2 = Get-ZbxHostGroup pestertest2 + } + AfterAll { + Remove-ZbxHostGroup $g1.GroupId + Remove-ZbxHostGroup $g2.GroupId + Get-ZbxHost 'pestertesthost*' | Remove-ZbxHost + } + + It "adds a set of groups given as a parameter to multiple piped hosts" { + $h1, $h2 | Add-ZbxHostGroupMembership $g1, $g2 + (Get-ZbxHostGroup pestertest1).hosts.Count | Should -Be 2 + } +} + +Describe "Remove-ZbxHostGroupMembership" { + BeforeAll { + New-ZbxHost -Name "pestertesthost1" -HostGroupId 2 -TemplateId $testTemplateId -Dns localhost -errorAction silentlycontinue + New-ZbxHost -Name "pestertesthost2" -HostGroupId 2 -TemplateId $testTemplateId -Dns localhost -errorAction silentlycontinue + $h1 = Get-ZbxHost pestertesthost1 + $h2 = Get-ZbxHost pestertesthost2 + New-ZbxHostGroup "pestertest1" -errorAction silentlycontinue + New-ZbxHostGroup "pestertest2" -errorAction silentlycontinue + $g1 = Get-ZbxHostGroup pestertest1 + $g2 = Get-ZbxHostGroup pestertest2 + } + AfterAll { + Remove-ZbxHostGroup $g1.GroupId -ErrorAction silentlycontinue + Remove-ZbxHostGroup $g2.GroupId -ErrorAction silentlycontinue + Get-ZbxHost 'pestertesthost*' | Remove-ZbxHost -ErrorAction silentlycontinue + } + + It "removes a set of groups given as a parameter to multiple piped hosts" { + $h1, $h2 | Remove-ZbxHostGroupMembership $g1, $g2 + (Get-ZbxHostGroup pestertest1).hosts.Count | Should -Be 0 + } +} + +Describe "Get-ZbxTemplate" { + It "can return all templates" { + Get-ZbxTemplate | Should -Not -BeNullOrEmpty + } + It "can filter by name with wildcard (explicit parameter)" { + Get-ZbxTemplate "Template OS Lin*" | Should -Not -BeNullOrEmpty + Get-ZbxTemplate "XXXXXXXXXXXXXX" | Should -BeNullOrEmpty + } + It "can filter by ID (explicit parameter)" { + $h = (Get-ZbxTemplate "Template OS Lin*")[0] + (Get-ZbxTemplate -Id $h.templateid).host | Should -Be $h.host + } +} + +Describe "New-ZbxHostGroup" { + It "creates a new group with explicit name parameter" { + $g = New-ZbxHostGroup "pestertest$(Get-Random)", "pestertest$(Get-Random)" + $g.count | Should -Be 2 + $g[0].name | Should -Match "pestertest" + } + It "creates a new group with piped names" { + $g = "pestertest$(Get-Random)", "pestertest$(Get-Random)" | New-ZbxHostGroup + $g.count | Should -Be 2 + $g[0].name | Should -Match "pestertest" + } + It "creates a new group with piped objects" { + $g = (New-Object -TypeName PSCustomObject -Property @{name = "pestertest$(Get-Random)" }), (New-Object -TypeName PSCustomObject -Property @{name = "pestertest$(Get-Random)" }) | New-ZbxHostGroup + $g.count | Should -Be 2 + $g[0].name | Should -Match "pestertest" + } +} + +Describe "Get-ZbxHostGroup" { + It "can return all groups" { + $ret = Get-ZbxHostGroup + $ret | Should -Not -BeNullOrEmpty + $ret.Count | Should -BeGreaterThan 1 + } + It "can filter by name with wildcard (explicit parameter)" { + $ret = Get-ZbxHostGroup "pestertest*" + $ret | Should -Not -BeNullOrEmpty + $ret.name | Should -BeLike 'pestertest*' + $ret = Get-ZbxHostGroup "XXXXXXXXXXXXXX" + $ret | Should -BeNullOrEmpty + } + It "can filter by ID (explicit parameter)" { + $h = (Get-ZbxHostGroup "pestertest*")[0] + (Get-ZbxHostGroup -Id $h.groupid).name | Should -Be $h.name + } +} + +Describe "Remove-ZbxHostGroup" { + It "can delete from one explicit ID parameter" { + New-ZbxHostGroup -Name "pestertestrem" -errorAction silentlycontinue + $h = Get-ZbxHostGroup pestertestrem + remove-ZbxHostGroup $h.groupid | Should -Be $h.groupid + Get-ZbxHostGroup pestertestrem | Should -BeNullOrEmpty + } + It "can delete from multiple explicit ID parameters" { + $h1 = New-ZbxHostGroup -Name "pestertestrem" + $h2 = New-ZbxHostGroup -Name "pestertestrem2" -errorAction silentlycontinue + $h2 = Get-ZbxHostgroup pestertestrem2 + remove-ZbxHostgroup $h1.groupid, $h2.groupid | Should -Be @($h1.groupid, $h2.groupid) + Get-ZbxHostGroup pestertestrem | Should -BeNullOrEmpty + Get-ZbxHostGroup pestertestrem2 | Should -BeNullOrEmpty + } + It "can delete from multiple piped IDs" { + $h1 = New-ZbxHostGroup -Name "pestertestrem" + $h2 = New-ZbxHostGroup -Name "pestertestrem2" + $h1.groupid, $h2.groupid | remove-ZbxHostgroup | Should -Be @($h1.groupid, $h2.groupid) + } + It "can delete from one piped object parameter" { + $h = New-ZbxHostGroup -Name "pestertestrem" + $h | remove-ZbxHostgroup | Should -Be $h.groupid + } + It "can delete from multiple piped objects" { + $h1 = New-ZbxHostGroup -Name "pestertestrem" + $h2 = New-ZbxHostGroup -Name "pestertestrem2" + $h1, $h2 | remove-ZbxHostgroup | Should -Be @($h1.groupid, $h2.groupid) + } +} + +Describe "Get-ZbxUserGroup" { + It "can return all groups" { + Get-ZbxUserGroup | Should -Not -BeNullOrEmpty + } + It "can filter by name with wildcard (explicit parameter)" { + Get-ZbxUserGroup "Zabbix*" | Should -Not -BeNullOrEmpty + Get-ZbxUserGroup "XXXXXXXXXXXXXX" | Should -BeNullOrEmpty + } + It "can filter by ID (explicit parameter)" { + $h = (Get-ZbxUserGroup "Zabbix*")[0] + (Get-ZbxUserGroup -Id $h.usrgrpid).name | Should -Be $h.name + } +} + +Describe "New-ZbxUserGroup" { + It "creates a new group with explicit name parameter" { + $g = New-ZbxUserGroup "pestertest$(Get-Random)", "pestertest$(Get-Random)" + $g.count | Should -Be 2 + $g[0].name | Should -Match "pestertest" + } + It "creates a new group with piped names" { + $g = "pestertest$(Get-Random)", "pestertest$(Get-Random)" | New-ZbxUserGroup + $g.count | Should -Be 2 + $g[0].name | Should -Match "pestertest" + } + It "creates a new group with piped objects" { + $g = (New-Object -TypeName PSCustomObject -Property @{name = "pestertest$(Get-Random)" }), (New-Object -TypeName PSCustomObject -Property @{name = "pestertest$(Get-Random)" }) | New-ZbxUserGroup + $g.count | Should -Be 2 + $g[0].name | Should -Match "pestertest" + } +} + +Describe "Remove-ZbxUserGroup" { + It "can delete from one explicit ID parameter" { + New-ZbxUserGroup -Name "pestertestrem" -errorAction silentlycontinue + $h = Get-ZbxUserGroup pestertestrem + Remove-ZbxUserGroup $h.usrgrpid | Should -Be $h.usrgrpid + Get-ZbxUserGroup pestertestrem | Should -BeNullOrEmpty + } + It "can delete from multiple explicit ID parameters" { + $h1 = New-ZbxUserGroup -Name "pestertestrem" + $h2 = New-ZbxUserGroup -Name "pestertestrem2" -errorAction silentlycontinue + $h2 = Get-ZbxUserGroup pestertestrem2 + remove-ZbxUserGroup $h1.usrgrpid, $h2.usrgrpid | Should -Be @($h1.usrgrpid, $h2.usrgrpid) + Get-ZbxUserGroup pestertestrem | Should -BeNullOrEmpty + Get-ZbxUserGroup pestertestrem2 | Should -BeNullOrEmpty + } + It "can delete from multiple piped IDs" { + $h1 = New-ZbxUserGroup -Name "pestertestrem" + $h2 = New-ZbxUserGroup -Name "pestertestrem2" + $h1.usrgrpid, $h2.usrgrpid | remove-ZbxUserGroup | Should -Be @($h1.usrgrpid, $h2.usrgrpid) + } + It "can delete from one piped object parameter" { + $h = New-ZbxUserGroup -Name "pestertestrem" + $h | remove-ZbxUserGroup | Should -Be $h.usrgrpid + } + It "can delete from multiple piped objects" { + $h1 = New-ZbxUserGroup -Name "pestertestrem" + $h2 = New-ZbxUserGroup -Name "pestertestrem2" + $h1, $h2 | remove-ZbxUserGroup | Should -Be @($h1.usrgrpid, $h2.usrgrpid) + } +} + +Describe "Get-ZbxUser" { + It "can return all users" { + $ret = Get-ZbxUser + $ret | Should -Not -BeNullOrEmpty + } + It "can filter by name with wildcard (explicit parameter)" { + $ret = Get-ZbxUser "Admi*" + $ret | Should -Not -BeNullOrEmpty + $ret | Should -HaveCount 1 + $ret.Alias | Should -Be 'Admin' + $ret.Name | Should -Be 'Zabbix' + } + It "can filter by ID (explicit parameter)" { + $h = Get-ZbxUser "Admin" + $h | Should -HaveCount 1 + (Get-ZbxUser -Id $h.userid).alias | Should -Be $h.alias + } + It "returns nothing on unknown user" { + $ret = Get-ZbxUser "XXXXXXXXXXXXXX" + $ret | Should -BeNullOrEmpty + $ret = Get-ZbxUser -Id 9999999 + $ret | Should -BeNullOrEmpty + } +} + +Describe "New-ZbxUser" { + BeforeAll { + $userToCopy = "pestertest$(Get-random)" + } + AfterAll { + Get-ZbxUser 'pestertest*' | Remove-ZbxUser + } + It "creates a new user with explicit parameters" { + $g = @(New-ZbxUser -Alias $userToCopy -name "marsu" -UserGroupId 8) + $g.count | Should -Be 1 + $g[0].name | Should -Match "marsu" + } + It "create user with Media Email" { + $username = "pestertest$(Get-random)-withmail" + $g = @(New-ZbxUser -Alias $username -name "marsu" -UserGroupId 8 -MailAddress 'huhu@example.com') + $g.count | Should -Be 1 + $g[0].name | Should -Match "marsu" + Remove-ZbxUser $g.UserId + } + #TODO: fix example + It "creates a new user from another user (copy)" -Skip { + $u = Get-ZbxUser -Name $userToCopy + # $u = @(New-ZbxUser -Alias "pestertest$(Get-random)" -name "marsu" -UserGroupId 8) + $g = $u | New-ZbxUser -alias "pestertest$(Get-random)" + $g.userid | Should -Not -Be $null + $g.name | Should -Match "marsu" + $g.usrgrps.usrgrpid | Should -Be 8 + } +} + +Describe "Remove-ZbxUser" { + BeforeEach { + New-ZbxUser -Alias "pestertestrem" -UserGroupId 8 -errorAction silentlycontinue | Should -Not -BeNullOrEmpty + New-ZbxUser -Alias "pestertestrem2" -UserGroupId 8 -errorAction silentlycontinue | Should -Not -BeNullOrEmpty + $user1 = Get-ZbxUser -Name 'pestertestrem' + $user2 = Get-ZbxUser -Name 'pestertestrem2' + } + AfterEach { + Remove-ZbxUser $user1.userid -ErrorAction silentlycontinue + Remove-ZbxUser $user2.userid -ErrorAction silentlycontinue + } + It "can delete from one explicit ID parameter" { + Remove-ZbxUser $user1.userid | Should -Be $user1.userid + Get-ZbxUser pestertestrem | Should -BeNullOrEmpty + } + It "can delete from multiple explicit ID parameters" { + Remove-ZbxUser $user1.userid, $user2.userid | Should -Be @($User1.userid, $User2.userid) + Get-ZbxUser pestertestrem | Should -BeNullOrEmpty + Get-ZbxUser pestertestrem2 | Should -BeNullOrEmpty + } + It "can delete from multiple piped IDs" { + $user1.userid, $user2.userid | Remove-ZbxUser | Should -Be @($user1.userid, $user2.userid) + } + It "can delete from one piped object parameter" { + $user1 | Remove-ZbxUser | Should -Be $user1.userid + } + It "can delete from multiple piped objects" { + $user1, $user2 | Remove-ZbxUser | Should -Be @($user1.userid, $user2.userid) + } +} + +Describe "Add-ZbxUserGroupMembership" { + It "can add two user groups (explicit parameter) to piped users" { + Get-ZbxUser "pester*" | Remove-ZbxUser + Get-ZbxUserGroup "pester*" | remove-ZbxUserGroup + + $g1 = New-ZbxUserGroup -Name "pestertestmembers" + $g2 = New-ZbxUserGroup -Name "pestertestmembers2" + $g1 = Get-ZbxUserGroup pestertestmembers + $g2 = Get-ZbxUserGroup pestertestmembers2 + + $u1 = New-ZbxUser -Alias "pestertestrem" -UserGroupId 8 + $u2 = New-ZbxUser -Alias "pestertestrem2" -UserGroupId 8 + $u1 = Get-ZbxUser pestertestrem + $u2 = Get-ZbxUser pestertestrem2 + + $u1, $u2 | Add-ZbxUserGroupMembership $g1, $g2 | Should -Be @($u1.userid, $u2.userid) + $u1 = Get-ZbxUser pestertestrem + $u2 = Get-ZbxUser pestertestrem2 + $u1.usrgrps | select -ExpandProperty usrgrpid | Should -Be @(8, $g1.usrgrpid, $g2.usrgrpid) + } + It "same with ID instead of objects" { + Get-ZbxUser "pester*" | Remove-ZbxUser + Get-ZbxUserGroup "pester*" | remove-ZbxUserGroup + + $g1 = New-ZbxUserGroup -Name "pestertestmembers3" + $g2 = New-ZbxUserGroup -Name "pestertestmembers4" + $g1 = Get-ZbxUserGroup pestertestmembers3 + $g2 = Get-ZbxUserGroup pestertestmembers4 + + $u1 = New-ZbxUser -Alias "pestertestrem3" -UserGroupId 8 + $u2 = New-ZbxUser -Alias "pestertestrem4" -UserGroupId 8 + $u1 = Get-ZbxUser pestertestrem3 + $u2 = Get-ZbxUser pestertestrem4 + + $u1.userid, $u2.userid | Add-ZbxUserGroupMembership $g1.usrgrpid, $g2.usrgrpid | Should -Be @($u1.userid, $u2.userid) + $u1 = Get-ZbxUser pestertestrem3 + $u2 = Get-ZbxUser pestertestrem4 + $u1.usrgrps | select -ExpandProperty usrgrpid | Should -Be @(8, $g1.usrgrpid, $g2.usrgrpid) + } +} + +Describe "Remove-ZbxUserGroupMembership" { + It "can remove two user groups (explicit parameter) to piped users" { + Get-ZbxUser "pester*" | Remove-ZbxUser + Get-ZbxUserGroup "pester*" | remove-ZbxUserGroup + + $g1 = New-ZbxUserGroup -Name "pestertestmembers" + $g2 = New-ZbxUserGroup -Name "pestertestmembers2" + $g1 = Get-ZbxUserGroup pestertestmembers + $g2 = Get-ZbxUserGroup pestertestmembers2 + + $u1 = New-ZbxUser -Alias "pestertestrem" -UserGroupId 8 + $u2 = New-ZbxUser -Alias "pestertestrem2" -UserGroupId 8 + $u1 = Get-ZbxUser pestertestrem + $u2 = Get-ZbxUser pestertestrem2 + + $u1, $u2 | Add-ZbxUserGroupMembership $g1, $g2 | Should -Be @($u1.userid, $u2.userid) + $u1, $u2 | Remove-ZbxUserGroupMembership $g1, $g2 | Should -Be @($u1.userid, $u2.userid) + $u1 = Get-ZbxUser pestertestrem + $u2 = Get-ZbxUser pestertestrem2 + $u1.usrgrps | select -ExpandProperty usrgrpid | Should -Be @(8) + } + It "same with ID instead of objects" { + Get-ZbxUser "pester*" | Remove-ZbxUser + Get-ZbxUserGroup "pester*" | remove-ZbxUserGroup + + $g1 = New-ZbxUserGroup -Name "pestertestmembers3" + $g2 = New-ZbxUserGroup -Name "pestertestmembers4" + $g1 = Get-ZbxUserGroup pestertestmembers3 + $g2 = Get-ZbxUserGroup pestertestmembers4 + + $u1 = New-ZbxUser -Alias "pestertestrem3" -UserGroupId 8 + $u2 = New-ZbxUser -Alias "pestertestrem4" -UserGroupId 8 + $u1 = Get-ZbxUser pestertestrem3 + $u2 = Get-ZbxUser pestertestrem4 + + $u1.userid, $u2.userid | Add-ZbxUserGroupMembership $g1.usrgrpid, $g2.usrgrpid | Should -Be @($u1.userid, $u2.userid) + $u1 = Get-ZbxUser pestertestrem3 + $u2 = Get-ZbxUser pestertestrem4 + $u1.usrgrps | select -ExpandProperty usrgrpid | Should -Be @(8, $g1.usrgrpid, $g2.usrgrpid) + $u1.userid, $u2.userid | Remove-ZbxUserGroupMembership $g1.usrgrpid, $g2.usrgrpid | Should -Be @($u1.userid, $u2.userid) + $u1 = Get-ZbxUser pestertestrem3 + $u2 = Get-ZbxUser pestertestrem4 + $u1.usrgrps | select -ExpandProperty usrgrpid | Should -Be @(8) + } +} + +Describe "Add-ZbxUserGroupPermission" { + BeforeAll { + Get-ZbxHostGroup "pester*" | remove-ZbxHostGroup -ErrorAction silentlycontinue + Get-ZbxUserGroup "pester*" | remove-ZbxUserGroup -ErrorAction silentlycontinue + } + AfterAll { + Get-ZbxHostGroup "pester*" | remove-ZbxHostGroup + Get-ZbxUserGroup "pester*" | remove-ZbxUserGroup + } + It "can add a Read permission to two piped user groups on two host groups" { + + New-ZbxUserGroup -Name "pestertest1", "pestertest2" + $ug1 = Get-ZbxUserGroup pestertest1 + $ug2 = Get-ZbxUserGroup pestertest2 + + New-ZbxHostGroup "pestertest1", "pestertest2" + $hg1 = Get-ZbxHostGroup pestertest1 + $hg2 = Get-ZbxHostGroup pestertest2 + + $ug1, $ug2 | Add-ZbxUserGroupPermission $hg1, $hg2 ReadWrite | Should -Be @($ug1.usrgrpid, $ug2.usrgrpid) + $ug1 = Get-ZbxUserGroup pestertest1 + $ug2 = Get-ZbxUserGroup pestertest2 + $ug1.rights | select -ExpandProperty id | Should -Be @($hg1.groupid, $hg2.groupid) + $ug1.rights | select -ExpandProperty permission | Should -Be @(3, 3) + } + It "can alter and clear permissions on a host group without touching permissions on other groups" { + $ug1 = Get-ZbxUserGroup pestertest1 + $ug2 = Get-ZbxUserGroup pestertest2 + $hg1 = Get-ZbxHostGroup pestertest1 + $hg2 = Get-ZbxHostGroup pestertest2 + + # Sanity check + $ug1.rights | select -ExpandProperty id | Should -Be @($hg1.groupid, $hg2.groupid) + $ug1.rights | select -ExpandProperty permission | Should -Be @(3, 3) + + # Set HG1 RO. + $ug1, $ug2 | Add-ZbxUserGroupPermission $hg1 ReadOnly | Should -Be @($ug1.usrgrpid, $ug2.usrgrpid) + $ug1 = Get-ZbxUserGroup pestertest1 + $ug2 = Get-ZbxUserGroup pestertest2 + $ug1.rights | select -ExpandProperty id | Should -Be @($hg1.groupid, $hg2.groupid) + $ug1.rights | select -ExpandProperty permission | Should -Be @(2, 3) + + # Clear HG1 + $ug1, $ug2 | Add-ZbxUserGroupPermission $hg1 Clear | Should -Be @($ug1.usrgrpid, $ug2.usrgrpid) + $ug1 = Get-ZbxUserGroup pestertest1 + $ug2 = Get-ZbxUserGroup pestertest2 + $ug1.rights | select -ExpandProperty id | Should -Be @($hg2.groupid) + $ug1.rights | select -ExpandProperty permission | Should -Be @(3) + } +} + +Describe "Get-ZbxMediaType" { + It "can return all types" { + Get-ZbxMediaType | Should -Not -BeNullOrEmpty + } + It "can filter by technical media type" { + Get-ZbxMediaType -type Email | Should -Not -BeNullOrEmpty + Get-ZbxMediaType -type EzTexting | Should -BeNullOrEmpty + } +} + +Describe "Add-ZbxUserMail" { + It "can add a mail to a user without mail" { + $u = @(New-ZbxUser -Alias "pestertestmedia$(Get-random)" -name "marsu" -UserGroupId 8)[0] + $u | Add-ZbxUserMail toto1@company.com | Should -Not -BeNullOrEmpty + } + It "can add a mail with specific severity filter" { + $u = @(New-ZbxUser -Alias "pestertestmedia$(Get-random)" -name "marsu" -UserGroupId 8)[0] + $u | Add-ZbxUserMail toto1@company.com Information, Warning | Should -Not -BeNullOrEmpty + } +} + +Describe "Get-ZbxMedia" { + It "can return all media" { + Get-ZbxMedia | Should -Not -BeNullOrEmpty + } + + It "can filter by media type" { + Get-ZbxMedia -MediaTypeId (Get-ZbxMediaType -Type email).mediatypeid | Should -Not -BeNullOrEmpty + } + + It "can filter actions used by certain users" { + Get-ZbxMedia -UserId @(Get-ZbxUser -Name "pestertestmedia*")[0].userid | Should -Not -BeNullOrEmpty + Get-ZbxMedia -UserId @(Get-ZbxUser -Name "Admin")[0].userid | Should -BeNullOrEmpty + } +} + +Describe "Remove-ZbxMedia" { + It "can remove piped media" { + Get-ZbxMedia | Remove-ZbxMedia | Should -Not -BeNullOrEmpty + Get-ZbxMedia | Should -BeNullOrEmpty + Get-ZbxUser -Name "pestertestmedia*" | Remove-ZbxUser > $null + } +} + +Describe "Disable-ZbxUserGroup" { + BeforeAll { + New-ZbxUserGroup -Name "pestertestenable1" -errorAction silentlycontinue + $h1 = Get-ZbxUserGroup pestertestenable1 + } + AfterAll { + Get-ZbxUserGroup 'pestertestenable1' | Remove-ZbxUserGroup + } + + It "can disable multiple piped objects" { + $h1 | Disable-ZbxUserGroup | Should -Be @($h1.usrgrpid) + [int](Get-ZbxUserGroup pestertestenable1).users_status | Should -Be 1 + } +} + +Describe "Enable-ZbxUserGroup" { + BeforeAll { + New-ZbxUserGroup -Name "pestertestenable1" -errorAction silentlycontinue + $h1 = Get-ZbxUserGroup pestertestenable1 + } + AfterAll { + Get-ZbxUserGroup 'pestertestenable1' | Remove-ZbxUserGroup + } + + It "can enable multiple piped objects" { + $h1 | Enable-ZbxUserGroup | Should -Be @($h1.usrgrpid) + [int](Get-ZbxUserGroup pestertestenable1).users_status | Should -Be 0 + } +} + +Describe "Update-ZbxHost" { + BeforeAll { + $name = "pestertesthost$(Get-Random)" + Get-ZbxHost -name "perster*" | remove-ZbxHost + Get-ZbxHost -name "newname" | remove-ZbxHost + $h = New-ZbxHost -Name $name -HostGroupId 2 -TemplateId $testTemplateId -Dns localhost -errorAction silentlycontinue + } + + It "can update the name of a host" { + $h.name = "newname" + $h | Update-ZbxHost + Get-ZbxHost -id $h.hostid | select -ExpandProperty name | Should -Be "newname" + Remove-ZbxHost $h.hostId + } +} \ No newline at end of file diff --git a/test/private/Get-ApiVersion.Tests.ps1 b/test/private/Get-ApiVersion.Tests.ps1 new file mode 100644 index 0000000..52bd883 --- /dev/null +++ b/test/private/Get-ApiVersion.Tests.ps1 @@ -0,0 +1,63 @@ +BeforeAll { + . $PSScriptRoot/../../src/private/New-JsonrpcRequest.ps1 + . $PSScriptRoot/../../src/private/Get-ApiVersion.ps1 +} + +Describe "Get-ApiVersion" { + BeforeAll { + function HashVersionFromUri([string]$theUri) + { + $bytes = [System.Security.Cryptography.HashAlgorithm]::Create("MD5").ComputeHash([System.Text.Encoding]::UTF8.GetBytes($theUri)) + $version = 0 + $bytes | Foreach-Object { $version += $_ } + $version + } + + $uri_1 = "http://1.1.1.1/" + $ver_1 = HashVersionFromUri $uri_1 + $uri_2 = "http://2.2.2.2/" + $ver_2 = HashVersionFromUri $uri_2 + + Mock Invoke-RestMethod { + param($Uri, $Method, $ContentType, $Body) + $version = HashVersionFromUri $Uri + @{jsonrpc=2.0; result=$version; id=1} + } + + } + + BeforeEach { + $script:LatestSession = @{Uri = $uri_1; Auth = "dummy_token"} + } + + AfterEach { + Remove-Variable -Scope script -Name LatestSession + } + + Context "Session parameter set" { + + It "Defaults to Session parameter set by position" { + $version = Get-ApiVersion @{Uri = $uri_2; Auth = "dummy_token"} + $version | should -Be $ver_2 + } + + It "Session parameter is specified explicitly" { + $version = Get-ApiVersion -Session @{Uri = $uri_2; Auth = "dummy_token"} + $version | should -Be $ver_2 + } + + It "Session is picked up implicitly from the environment" { + $version = Get-ApiVersion + $version | should -Be $ver_1 + } + + } + + Context "Direct parameter set" { + + It "Ignores existing session variable when the direct parameter is used" { + $version = Get-ApiVersion -Uri $uri_2 + $version | should -Be $ver_2 + } + } +} \ No newline at end of file diff --git a/test/private/Get-ReadableOperation.Tests.ps1 b/test/private/Get-ReadableOperation.Tests.ps1 new file mode 100644 index 0000000..77ce4e5 --- /dev/null +++ b/test/private/Get-ReadableOperation.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/private/Get-ReadableOperation.ps1 +} + + describe "Get-ReadableOperation"{ It "has no unit tests"{}} diff --git a/test/private/InternalTimeHelpers.Tests.ps1 b/test/private/InternalTimeHelpers.Tests.ps1 new file mode 100644 index 0000000..aa253ae --- /dev/null +++ b/test/private/InternalTimeHelpers.Tests.ps1 @@ -0,0 +1,21 @@ +BeforeAll { + . $PSScriptRoot/../../src/private/InternalTimeHelpers.ps1 +} + + +Describe "Time helpers" { + Context "Simple conversions" { + It "Converts DateTime to epoch" { + $yesterday = Get-Date '2018-05-15 04:00:00 GMT' # "Monday, May 14, 2018 9:00:00 PM" + $epochTime = ConvertTo-EpochTime $yesterday + $epochTime | should -Be 1526356800 + } + + It "Converts from epoch time to DateTime" { + $yesterday = Get-Date '2018-05-15 04:00:00 GMT' + $epochTime = 1526356800 + $yesterdayAgain = ConvertFrom-EpochTime $epochTime + $yesterday | Should -Be $yesterdayAgain + } + } +} \ No newline at end of file diff --git a/test/private/Invoke-ZabbixApi.Tests.ps1 b/test/private/Invoke-ZabbixApi.Tests.ps1 new file mode 100644 index 0000000..bb9ab42 --- /dev/null +++ b/test/private/Invoke-ZabbixApi.Tests.ps1 @@ -0,0 +1,67 @@ +BeforeAll { + . $PSScriptRoot/../../src/private/New-JsonrpcRequest.ps1 + . $PSScriptRoot/../../src/private/Invoke-ZabbixApi.ps1 +} + +Describe "Invoke-ZabbixApi" { + BeforeEach { + $script:LatestSession = @{Uri = "LatestSession"; Auth = "dummy_token"} + } + + AfterEach { + Remove-Variable -Scope script -Name LatestSession + } + + Context "Web Exceptions" { + BeforeAll { + Mock Invoke-RestMethod { + throw "The remote name could not be resolved: 'myserver'" + } + } + It "Bubbles up exceptions from Rest calls" { + { Invoke-ZabbixApi "http://myserver" $PhonyCreds } | Should -Throw + } + } + + Context "Session variable situations" { + BeforeAll { + Mock Invoke-RestMethod { + param($Uri, $Method, $ContentType, $Body) + @{jsonrpc=2.0; result=$Uri; id=1} # hack - pass the uri back as auth so we can see which session varible was used. + } + Mock New-JsonrpcRequest {} + } + + It "Uses the session parameter if provided" { + $result = Invoke-ZabbixApi -Session @{Uri = "ParamSession"} -method "some.method" -parameters @{"dummy" = "parameters"} + $result | Should -Be "ParamSession" + } + + It "Uses the lastsession global if session parameter is null" { + $result = Invoke-ZabbixApi -Session $null -method "some.method" -parameters @{"dummy" = "parameters"} + $result | Should -Be "LatestSession" + } + + It "Throws if both session and lastsession are null" { + Remove-Variable -Scope script -Name LatestSession + { Invoke-ZabbixApi -Session $null -method "some.method" -parameters @{"dummy" = "parameters"}} | Should -Throw + $script:LatestSession = @{Uri = "LatestSession"; Auth = "dummy_token"} # put it back to appease test cleanup + } + } + + Context "Zabbix errors" { + BeforeAll { + Mock Invoke-RestMethod { + @{"error"=@{"message"="error message"; "data"="error data";"code"="error code"}} + } + Mock New-JsonrpcRequest {} + Mock Write-Error {} + } + + It "Writes an error and returns null if a Zabbix error is encountered" { + $result = Invoke-ZabbixApi -Session $null -method "some.method" -parameters @{"dummy" = "parameters"} + $result | Should -Be $null + Should -Invoke Write-Error -Times 1 -Exactly -Scope It + } + } +} \ No newline at end of file diff --git a/test/private/New-JsonrpcRequest.Tests.ps1 b/test/private/New-JsonrpcRequest.Tests.ps1 new file mode 100644 index 0000000..7c6dc1b --- /dev/null +++ b/test/private/New-JsonrpcRequest.Tests.ps1 @@ -0,0 +1,42 @@ +BeforeAll { + . $PSScriptRoot/../../src/private/New-JsonrpcRequest.ps1 +} + +Describe "New-JsonrpcRequest" { + It "Assembles a fully specified jsonrpc body" { + $resultJSON = New-JsonrpcRequest -method "maintenance.get" -params @{ "output" = "extend"; "selectGroups" = "extend"; "selectTimeperiods" = "extend" } -auth "038e1d7b1735c6a5436ee9eae095879e" + + $resultHash = ConvertFrom-Json $resultJSON + + $resultHash.method | Should -Be "maintenance.get" + $resultHash.params.output | Should -Be "extend" + $resultHash.params.selectGroups | Should -Be "extend" + $resultHash.params.selectTimeperiods | Should -Be "extend" + $resultHash.auth | Should -Be "038e1d7b1735c6a5436ee9eae095879e" + } + + It "Defaults the output param to 'extend' on '*.get' methods" { + $resultJSON = New-JsonrpcRequest -method "maintenance.get" -params @{ "selectGroups" = "extend"; "selectTimeperiods" = "extend" } -auth "038e1d7b1735c6a5436ee9eae095879e" + + $resultHash = ConvertFrom-Json $resultJSON + + $resultHash.params.output | Should -Be "extend" + } + + It "Handles auth as an optional parameter" { + $resultJSON = New-JsonrpcRequest -method "apiinfo.version" -params @{ "selectGroups" = "extend"; "selectTimeperiods" = "extend" } + + $resultObj = ConvertFrom-Json $resultJSON + + $resultObj.psobject.properties.Name -contains "auth" | should -be $false + } + + It "Contructs the params element as an array instead of hashtable, if instructed" { + $resultJSON = New-JsonrpcRequest -method "maintenance.delete" -params @{ "array" = @(1,2)} + + $resultObj = ConvertFrom-Json $resultJSON + + $resultObj.params[0] | Should -BeExactly 1 + $resultObj.params.Count | Should -BeExactly 2 + } +} \ No newline at end of file diff --git a/test/public/Add-HostGroupMembership.Tests.ps1 b/test/public/Add-HostGroupMembership.Tests.ps1 new file mode 100644 index 0000000..5783928 --- /dev/null +++ b/test/public/Add-HostGroupMembership.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Add-HostGroupMembership.ps1 +} + + describe "Add-HostGroupMembership"{ It "has no unit tests"{}} diff --git a/test/public/Add-UserGroupMembership.Tests.ps1 b/test/public/Add-UserGroupMembership.Tests.ps1 new file mode 100644 index 0000000..819ee24 --- /dev/null +++ b/test/public/Add-UserGroupMembership.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Add-UserGroupMembership.ps1 +} + + describe "Add-UserGroupMembership"{ It "has no unit tests"{}} diff --git a/test/public/Add-UserGroupPermission.Tests.ps1 b/test/public/Add-UserGroupPermission.Tests.ps1 new file mode 100644 index 0000000..5629375 --- /dev/null +++ b/test/public/Add-UserGroupPermission.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Add-UserGroupPermission.ps1 +} + + describe "Add-UserGroupPermission"{ It "has no unit tests"{}} diff --git a/test/public/Add-UserMail.Tests.ps1 b/test/public/Add-UserMail.Tests.ps1 new file mode 100644 index 0000000..21b54d3 --- /dev/null +++ b/test/public/Add-UserMail.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Add-UserMail.ps1 +} + + describe "Add-UserMail"{ It "has no unit tests"{}} diff --git a/test/public/Disable-Host.Tests.ps1 b/test/public/Disable-Host.Tests.ps1 new file mode 100644 index 0000000..c354f45 --- /dev/null +++ b/test/public/Disable-Host.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Disable-Host.ps1 +} + + describe "Disable-Host"{ It "has no unit tests"{}} diff --git a/test/public/Disable-UserGroup.Tests.ps1 b/test/public/Disable-UserGroup.Tests.ps1 new file mode 100644 index 0000000..ad08e56 --- /dev/null +++ b/test/public/Disable-UserGroup.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Disable-UserGroup.ps1 +} + + describe "Disable-UserGroup"{ It "has no unit tests"{}} diff --git a/test/public/Enable-Host.Tests.ps1 b/test/public/Enable-Host.Tests.ps1 new file mode 100644 index 0000000..ca99973 --- /dev/null +++ b/test/public/Enable-Host.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Enable-Host.ps1 +} + + describe "Enable-Host"{ It "has no unit tests"{}} diff --git a/test/public/Enable-UserGroup.Tests.ps1 b/test/public/Enable-UserGroup.Tests.ps1 new file mode 100644 index 0000000..a5ee85f --- /dev/null +++ b/test/public/Enable-UserGroup.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Enable-UserGroup.ps1 +} + + describe "Enable-UserGroup"{ It "has no unit tests"{}} diff --git a/test/public/Get-Action.Tests.ps1 b/test/public/Get-Action.Tests.ps1 new file mode 100644 index 0000000..d6d7f6c --- /dev/null +++ b/test/public/Get-Action.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Get-Action.ps1 +} + + describe "Get-Action"{ It "has no unit tests"{}} diff --git a/test/public/Get-Host.Tests.ps1 b/test/public/Get-Host.Tests.ps1 new file mode 100644 index 0000000..e358734 --- /dev/null +++ b/test/public/Get-Host.Tests.ps1 @@ -0,0 +1,71 @@ +BeforeAll { + Try { + . $PSScriptRoot/../../src/private/InternalZabbixTypes.ps1 + . $PSScriptRoot/../../src/public/Get-Host.ps1 + } Catch { + Write-Warning "Problem include? $_" + } +} + + +Describe "Get-Host" { + BeforeAll { + function Invoke-ZabbixApi {} # declare it so I can mock it + } + + Context "Parameter scenarios" { + BeforeAll { + Mock Invoke-ZabbixApi { + param ($session, $method, [hashtable] $prms) + # + # Just return the params for inspection - not a mock Zabbix result + # Set Status and HostID to avoid exception in the Get-Host function + # + $prms["Status"] = 1 + $prms["hostId"] = 123 + $prms["method"] = $method + $prms + } + } + + It "Is called with Id parameter" { + + $result = Get-Host -Id 1 + + $result.ContainsKey("hostids") | Should -be $true + $result["method"] | Should -be "host.get" + } + + It "Is called with HostId alias" { + + $result = Get-Host -HostId 2 + + $result.ContainsKey("hostids") | Should -be $true + $result["method"] | Should -be "host.get" + } + + It "Is called with HostGroupId parameter" { + + $result = Get-Host -HostGroupId 3 + + $result.ContainsKey("groupids") | Should -be $true + $result["method"] | Should -be "host.get" + } + + It "Is called with Name parameter" { + + $result = Get-Host -Name "dummyID" + + $result["search"].ContainsKey("name") | Should -be $true + $result["method"] | Should -be "host.get" + } + + It "Is called with HostName alias" { + + $result = Get-Host -HostName "dummyID" + + $result["search"].ContainsKey("name") | Should -be $true + $result["method"] | Should -be "host.get" + } + } +} \ No newline at end of file diff --git a/test/public/Get-HostGroup.Tests.ps1 b/test/public/Get-HostGroup.Tests.ps1 new file mode 100644 index 0000000..90694e4 --- /dev/null +++ b/test/public/Get-HostGroup.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Get-HostGroup.ps1 +} + + describe "Get-HostGroup"{ It "has no unit tests"{}} diff --git a/test/public/Get-Maintenance.Tests.ps1 b/test/public/Get-Maintenance.Tests.ps1 new file mode 100644 index 0000000..f4e67e5 --- /dev/null +++ b/test/public/Get-Maintenance.Tests.ps1 @@ -0,0 +1,60 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Get-Maintenance.ps1 + . $PSScriptRoot/../../src/private/InternalZabbixTypes.ps1 +} + + +Describe "Get-Maintenance" { + BeforeAll { + function Invoke-ZabbixApi {} # declare it so I can mock it + } + + Context "Parameter scenarios" { + BeforeAll { + Mock Invoke-ZabbixApi { + param ($session, $method, [hashtable] $prms) + # + # Just return the params for inspection - not a mock Zabbix result + # Set Status and HostID to avoid exception in the Get-Host function + # + $prms["Status"] = 1 + $prms["hostId"] = 123 + $prms["method"] = $method + $prms + } + } + + It "Is called with Id parameter" { + + $result = Get-Maintenance -Id 1 + + $result.ContainsKey("maintenanceids") | Should -be $true + $result["method"] | Should -be "maintenance.get" + } + + It "Is called with MaintenanceId alias" { + + $result = Get-Maintenance -MaintenanceId 2 + + $result.ContainsKey("maintenanceids") | Should -be $true + $result["method"] | Should -be "maintenance.get" + } + + It "Is called with HostGroupId parameter" { + + $result = Get-Maintenance -HostGroupId 3 + + $result.ContainsKey("groupids") | Should -be $true + $result["method"] | Should -be "maintenance.get" + } + + It "Is called with HostId parameter" { + + $result = Get-Maintenance -HostId 4 + + $result.ContainsKey("hostids") | Should -be $true + $result["method"] | Should -be "maintenance.get" + } + + } +} \ No newline at end of file diff --git a/test/public/Get-Media.Tests.ps1 b/test/public/Get-Media.Tests.ps1 new file mode 100644 index 0000000..4a3e0a7 --- /dev/null +++ b/test/public/Get-Media.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Get-Media.ps1 +} + + describe "Get-Media"{ It "has no unit tests"{}} diff --git a/test/public/Get-MediaType.Tests.ps1 b/test/public/Get-MediaType.Tests.ps1 new file mode 100644 index 0000000..6a1046b --- /dev/null +++ b/test/public/Get-MediaType.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Get-MediaType.ps1 +} + + describe "Get-MediaType"{ It "has no unit tests"{}} diff --git a/test/public/Get-Proxy.Tests.ps1 b/test/public/Get-Proxy.Tests.ps1 new file mode 100644 index 0000000..d920c23 --- /dev/null +++ b/test/public/Get-Proxy.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Get-Proxy.ps1 +} + + describe "Get-Proxy"{ It "has no unit tests"{}} diff --git a/test/public/Get-Template.Tests.ps1 b/test/public/Get-Template.Tests.ps1 new file mode 100644 index 0000000..263ebea --- /dev/null +++ b/test/public/Get-Template.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Get-Template.ps1 +} + + describe "Get-Template"{ It "has no unit tests"{}} diff --git a/test/public/Get-User.Tests.ps1 b/test/public/Get-User.Tests.ps1 new file mode 100644 index 0000000..902a9ec --- /dev/null +++ b/test/public/Get-User.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Get-User.ps1 +} + + describe "Get-User"{ It "has no unit tests"{}} diff --git a/test/public/Get-UserGroup.Tests.ps1 b/test/public/Get-UserGroup.Tests.ps1 new file mode 100644 index 0000000..64fe8ff --- /dev/null +++ b/test/public/Get-UserGroup.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Get-UserGroup.ps1 +} + + describe "Get-UserGroup"{ It "has no unit tests"{}} diff --git a/test/public/New-ApiSession.Tests.ps1 b/test/public/New-ApiSession.Tests.ps1 new file mode 100644 index 0000000..1b93336 --- /dev/null +++ b/test/public/New-ApiSession.Tests.ps1 @@ -0,0 +1,82 @@ +BeforeAll { + . $PSScriptRoot/../../src/private/New-JsonrpcRequest.ps1 + . $PSScriptRoot/../../src/private/Get-ApiVersion.ps1 + . $PSScriptRoot/../../src/public/New-ApiSession.ps1 +} + + +Describe "New-ApiSession" { + BeforeAll { + $PhonyUser = "nonUser" + $PhonyPassword = "nonPassword" | ConvertTo-SecureString -AsPlainText -Force + $PhonyCreds = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList $PhonyUser,$PhonyPassword + $PhonyUri = "http://myserver/zabbix/api_jsonrpc.php" + $PhonyAuth = "2cce0ad0fac0a5da348fdb70ae9b233b" + } + + Context "Web Exceptions" { + BeforeAll { + Mock Invoke-RestMethod { + throw "The remote name could not be resolved: 'myserver'" + } + } + + It "Bubbles up exceptions from Rest calls" { + { New-ApiSession "http://myserver" $PhonyCreds } | Should -Throw + } + } + + Context "Supported version of Zabbix" { + BeforeAll { + Mock Invoke-RestMethod { + @{jsonrpc=2.0; result=$PhonyAuth; id=1} + } + Mock Get-ApiVersion { + "3.2" + } + Mock Write-Information {} + Mock Write-Warning {} + } + + It "Checks Zabbix version and writes a success message" { + + $session = New-ApiSession $PhonyUri $PhonyCreds + + $session["Uri"] | Should -Be $PhonyUri + $session["Auth"] | Should -Be $PhonyAuth + Should -Invoke Write-Information -Times 1 -Exactly -Scope It + Should -Invoke Write-Warning -Times 0 -Exactly -Scope It + } + + It "Writes no information messages if the silent switch is specified" { + + $session = New-ApiSession $PhonyUri $PhonyCreds -silent + + Should -Invoke Write-Information -Times 0 -Exactly -Scope It # no increment in call count since last test + } + + } + + Context "Successful connection - unsupported version" { + BeforeAll { + Mock Invoke-RestMethod { + @{jsonrpc=2.0; result=$PhonyAuth; id=1} + } + Mock Get-ApiVersion { + "1.2" + } + Mock Write-Information {} + Mock Write-Warning {} + } + + It "Checks Zabbix version and writes a warning message if the version is unsupported" { + + $session = New-ApiSession $PhonyUri $PhonyCreds + + $session["Uri"] | Should -Be $PhonyUri + $session["Auth"] | Should -Be $PhonyAuth + Should -Invoke Write-Information -Times 1 -Exactly -Scope It + Should -Invoke Write-Warning -Times 1 -Exactly -Scope It + } + } +} diff --git a/test/public/New-Host.Tests.ps1 b/test/public/New-Host.Tests.ps1 new file mode 100644 index 0000000..47021d3 --- /dev/null +++ b/test/public/New-Host.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/New-Host.ps1 +} + + describe "New-Host"{ It "has no unit tests"{}} diff --git a/test/public/New-HostGroup.Tests.ps1 b/test/public/New-HostGroup.Tests.ps1 new file mode 100644 index 0000000..bcd70f6 --- /dev/null +++ b/test/public/New-HostGroup.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/New-HostGroup.ps1 +} + + describe "New-HostGroup"{ It "has no unit tests"{}} diff --git a/test/public/New-Maintenance.Tests.ps1 b/test/public/New-Maintenance.Tests.ps1 new file mode 100644 index 0000000..3778750 --- /dev/null +++ b/test/public/New-Maintenance.Tests.ps1 @@ -0,0 +1,123 @@ +BeforeAll { + . $PSScriptRoot/../../src/private/InternalTimeHelpers.ps1 + . $PSScriptRoot/../../src/public/New-Maintenance.ps1 +} + + +Describe "New-Maintenance" { + BeforeAll { + function Invoke-ZabbixApi {} # declare it so I can mock it + } + + Context "Parameter scenarios" { + BeforeAll { + Mock Invoke-ZabbixApi { + param ($session, $method, [hashtable] $prms) + # + # Just return the params for inspection - not a mock Zabbix result + # + $prms["method"] = $method + $prms + } + } + + It "Is called with HostGroupId parameter" { + + $result = New-Maintenance -HostGroupId 3 -Name "Patch Tuesday" + + $result.ContainsKey("groupids") | Should -be $true + $result["groupids"][0] | Should -BeExactly 3 + $result["method"] | Should -be "maintenance.create" + $result["method"] | Should -be "maintenance.create" + } + + It "Check that the Name parameter is populated" { + + { New-Maintenance -HostGroupId 3 -Name "" } | Should -Throw + } + + It "Populates the Name parameter" { + + $result = New-Maintenance -HostGroupId 3 -Name "Patch Tuesday" + + $result.ContainsKey("name") | Should -be $true + $result["method"] | Should -be "maintenance.create" + $result["name"] | Should -be "Patch Tuesday" + } + + It "Is called with HostId parameter" { + + $result = New-Maintenance -HostId 4 -Name "Patch Tuesday" + + $result.ContainsKey("hostids") | Should -be $true + $result["hostids"][0] | Should -BeExactly 4 + $result["method"] | Should -be "maintenance.create" + } + + It "Is called with multiple HostId parameters" { + + $result = New-Maintenance -HostId 4,5,6 -Name "Patch Tuesday" + + $result.ContainsKey("hostids") | Should -be $true + $result["hostids"].Count | Should -BeExactly 3 + $result["method"] | Should -be "maintenance.create" + } + + It "requires one or the other of the -HostId and -HostGroupId parameters" { + + { New-Maintenance -Name "Patch Tuesday" } | Should -Throw + + } + + It "is called with the -StartTime parameter" { + + $thisTime = Get-Date -Year 2000 -Month 1 -Day 1 + $thisEpoch = ConvertTo-EpochTime $thisTime + + $result = New-Maintenance -HostId 4 -Name "Patch Tuesday" -StartTime $thisTime + + $StartTime = $result["active_since"] + $StartTime | should -be $thisEpoch + } + + It "is called with the -Duration parameter" { + $thisTime = Get-Date -Year 2000 -Month 1 -Day 1 + $thisDurationInSeconds = 123 + $thisDuration = New-TimeSpan -Seconds $thisDurationInSeconds + + $result = New-Maintenance -HostId 4 -Name "Patch Tuesday" -StartTime $thisTime -Duration $thisDuration + + $StopTime = $result["active_till"] + $StartTime = $result["active_since"] + $TimeDelta = $StopTime - $StartTime + $TimeDelta | Should -be $thisDurationInSeconds + } + + It "Defaults the StartTime parameter to now" { + + $NowStamp = Get-Date + + $result = New-Maintenance -HostId 4 -Name "Patch Tuesday" + + $result.ContainsKey("timeperiods") | Should -be $true + $result.ContainsKey("active_till") | Should -be $true + $result.ContainsKey("active_since") | Should -be $true + + $StartTimeEpoch = $result["active_since"] + $NowStampEpoch = ConvertTo-EpochTime $NowStamp + $StartTimeEpoch | Should -BeExactly $NowStampEpoch + } + + It "Defaults the -Duration parameter to one hour" { + + $result = New-Maintenance -HostId 4 -Name "Patch Tuesday" + + $StopTime = $result["active_till"] + $StartTime = $result["active_since"] + $TimeDelta = $StopTime - $StartTime + $AnHoursWorthOfSeconds = $(New-TimeSpan -Hours 1).TotalSeconds + $TimeDelta | Should -be $AnHoursWorthOfSeconds + } + + } +} \ No newline at end of file diff --git a/test/public/New-User.Tests.ps1 b/test/public/New-User.Tests.ps1 new file mode 100644 index 0000000..8fbff67 --- /dev/null +++ b/test/public/New-User.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/New-User.ps1 +} + + describe "New-User"{ It "has no unit tests"{}} diff --git a/test/public/New-UserGroup.Tests.ps1 b/test/public/New-UserGroup.Tests.ps1 new file mode 100644 index 0000000..7f2148b --- /dev/null +++ b/test/public/New-UserGroup.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/New-UserGroup.ps1 +} + + describe "New-UserGroup"{ It "has no unit tests"{}} diff --git a/test/public/Remove-Host.Tests.ps1 b/test/public/Remove-Host.Tests.ps1 new file mode 100644 index 0000000..a9b5abe --- /dev/null +++ b/test/public/Remove-Host.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Remove-Host.ps1 +} + + describe "Remove-Host"{ It "has no unit tests"{}} diff --git a/test/public/Remove-HostGroup.Tests.ps1 b/test/public/Remove-HostGroup.Tests.ps1 new file mode 100644 index 0000000..ce74034 --- /dev/null +++ b/test/public/Remove-HostGroup.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Remove-HostGroup.ps1 +} + + describe "Remove-HostGroup"{ It "has no unit tests"{}} diff --git a/test/public/Remove-HostGroupMembership.Tests.ps1 b/test/public/Remove-HostGroupMembership.Tests.ps1 new file mode 100644 index 0000000..6f2b9c7 --- /dev/null +++ b/test/public/Remove-HostGroupMembership.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Remove-HostGroupMembership.ps1 +} + + describe "Remove-HostGroupMembership"{ It "has no unit tests"{}} diff --git a/test/public/Remove-Maintenance.Tests.ps1 b/test/public/Remove-Maintenance.Tests.ps1 new file mode 100644 index 0000000..810b326 --- /dev/null +++ b/test/public/Remove-Maintenance.Tests.ps1 @@ -0,0 +1,56 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Remove-Maintenance.ps1 +} + + +Describe "Remove-Maintenance" { + BeforeAll { + function Invoke-ZabbixApi {} # declare it so I can mock it + } + + Context "Parameter scenarios" { + BeforeAll { + Mock Invoke-ZabbixApi { + param ($session, $method, [hashtable] $prms) + # + # Just return the params for inspection - not a mock Zabbix result + # Set Status and HostID to avoid exception in the Get-Host function + # + $prms["Status"] = 1 + $prms["hostId"] = 123 + $prms["method"] = $method + $prms + } + } + + It "Is called with Id parameter" { + + $result = Remove-Maintenance -Id 1 + + $result["array"][0] | Should -BeExactly 1 + $result["method"] | Should -be "maintenance.delete" + } + + It "Is called with MaintenanceId alias" { + + $result = Remove-Maintenance -MaintenanceId 2 + + $result["array"][0] | Should -BeExactly 2 + $result["method"] | Should -be "maintenance.delete" + } + + It "Is called with multiple maintenance Ids" { + + $result = Remove-Maintenance -MaintenanceId 1,2,3 + + $($result["array"]).Count | Should -BeExactly 3 + $result["method"] | Should -be "maintenance.delete" + } + + It "Throws if called with empty array of Ids" { + + { Remove-Maintenance -MaintenanceId $() } | Should -Throw + + } + } +} \ No newline at end of file diff --git a/test/public/Remove-Media.Tests.ps1 b/test/public/Remove-Media.Tests.ps1 new file mode 100644 index 0000000..7b0e69f --- /dev/null +++ b/test/public/Remove-Media.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Remove-Media.ps1 +} + + describe "Remove-Media"{ It "has no unit tests"{}} diff --git a/test/public/Remove-Template.Tests.ps1 b/test/public/Remove-Template.Tests.ps1 new file mode 100644 index 0000000..d192c6e --- /dev/null +++ b/test/public/Remove-Template.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Remove-Template.ps1 +} + + describe "Remove-Template"{ It "has no unit tests"{}} diff --git a/test/public/Remove-User.Tests.ps1 b/test/public/Remove-User.Tests.ps1 new file mode 100644 index 0000000..59eb447 --- /dev/null +++ b/test/public/Remove-User.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Remove-User.ps1 +} + + describe "Remove-User"{ It "has no unit tests"{}} diff --git a/test/public/Remove-UserGroup.Tests.ps1 b/test/public/Remove-UserGroup.Tests.ps1 new file mode 100644 index 0000000..f7a62f2 --- /dev/null +++ b/test/public/Remove-UserGroup.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Remove-UserGroup.ps1 +} + + describe "Remove-UserGroup"{ It "has no unit tests"{}} diff --git a/test/public/Remove-UserGroupMembership.Tests.ps1 b/test/public/Remove-UserGroupMembership.Tests.ps1 new file mode 100644 index 0000000..43121f9 --- /dev/null +++ b/test/public/Remove-UserGroupMembership.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Remove-UserGroupMembership.ps1 +} + + describe "Remove-UserGroupMembership"{ It "has no unit tests"{}} diff --git a/test/public/Update-Host.Tests.ps1 b/test/public/Update-Host.Tests.ps1 new file mode 100644 index 0000000..e38f64e --- /dev/null +++ b/test/public/Update-Host.Tests.ps1 @@ -0,0 +1,5 @@ +BeforeAll { + . $PSScriptRoot/../../src/public/Update-Host.ps1 +} + + describe "Update-Host"{ It "has no unit tests"{}}