PSIdoitNG.psm1
#Region '.\Private\Convert-PropertyToArray.ps1' -1 function Convert-PropertyToArray { <# .SYNOPSIS Convert-PropertyToArray .DESCRIPTION This function converts a PowerShell object with properties into an array of objects. .PARAMETER InputObject The input object to be converted. Details see example. .OUTPUTS Returns an array of objects, each containing the property name and value. .EXAMPLE Convert-PropertyToArray -InputObject $inputObject [PSCustomObject] @{ C__OBJTYPE__SERVICE = 'System Service'; C__OBJTYPE__APPLICATION = 'Application'; ... } into an array of the following definition [PSCustomObject] @{ Name = 'C__OBJTYPE__SERVICE'; Value = 'System Service'; } .... and so on #> [CmdletBinding()] param ( [PSCustomObject]$InputObject ) $result = foreach ($property in $InputObject.PSObject.Properties) { [PSCustomObject]@{ Name = $property.Name Value = $property.Value } } return $result } #EndRegion '.\Private\Convert-PropertyToArray.ps1' 41 #Region '.\Private\ModuleStartup.ps1' -1 function ModuleStartup { <# .SYNOPSIS Initializes the module by setting up the script parameters. .DESCRIPTION This function is called when the module is loaded. It sets up the script parameters and initializes the module. .EXAMPLE ModuleStartup This will initialize the module and set up the script parameters. .NOTES The function will be inserted into the .psm1 as any other function. At the end of the file, the function will be called to initialize the module. So the code will be executed when the module is loaded. #> [CmdletBinding()] param() $Script:IdoItParams = @{} $Script:IdoItParams['Connection'] = @{ Uri = $null Username = $null Password = $null ApiKey = $null SessionId = $null } } ModuleStartup #EndRegion '.\Private\ModuleStartup.ps1' 31 #Region '.\Private\NewDynamicParameter.ps1' -1 function NewDynamicParameter { <# .SYNOPSIS Create a new dynamic parameter. .DESCRIPTION This function creates a new dynamic parameter with the specified name, parameter set name, and attributes. .PARAMETER Name The name of the dynamic parameter. .PARAMETER ParametersetName The name of the parameter set to which the dynamic parameter belongs. .PARAMETER Mandatory Indicates whether the dynamic parameter is mandatory. .PARAMETER ParameterType The type of the dynamic parameter. .PARAMETER ValidateSet An array of valid values for the dynamic parameter. If not provided, the parameter will not have a validation set. .OUTPUTS Returns a RuntimeDefinedParameter object representing the dynamic parameter. .EXAMPLE $dynParam = NewDynamicParameter -Name 'MyDynamicParam' -ParametersetName 'MyParameterSet' -Mandatory $true -ParameterType 'System.String' -ValidateSet 'Value1', 'Value2' This example creates a new dynamic parameter named 'MyDynamicParam' with the specified attributes. .NOTES #> [CmdletBinding()] [OutputType([System.Management.Automation.RuntimeDefinedParameter])] param ( [Parameter(Mandatory = $true)] [string] $Name, [string] $ParametersetName = '', [boolean] $Mandatory = $false, [string] $ParameterType = 'System.String', [string[]] $ValidateSet = $null ) $attributeCollection = New-Object System.Collections.ObjectModel.Collection[System.Attribute] $attribute = New-Object System.Management.Automation.ParameterAttribute $attribute.Mandatory = $Mandatory $attribute.ParameterSetName = $ParametersetName $attributeCollection.Add($attribute) if ($null -ne $ValidateSet) { $attribute = New-Object System.Management.Automation.ValidateSetAttribute($ValidateSet) $attributeCollection.Add($attribute) } $dynParam = New-Object System.Management.Automation.RuntimeDefinedParameter($Name, $ParameterType, $attributeCollection) Write-Output $dynParam } #EndRegion '.\Private\NewDynamicParameter.ps1' 64 #Region '.\Public\Connect-IdoIt.ps1' -1 function Connect-IdoIt { <# .SYNOPSIS Connect-to Idoit API. .DESCRIPTION Connect-to Idoit API. This function is used to connect to the Idoit API and authenticate the user. .PARAMETER Uri The Uri to the idoit JSON-RPC API. should be like http[s]://your.i-doit.host/src/jsonrpc.php .PARAMETER Credential User with appropiate permissions to access the cmdb. .PARAMETER Username The username to connect to the Idoit API. .PARAMETER Password The password to connect to the Idoit API. The password is passed as a SecureString. .PARAMETER ApiKey This is the apikey you define in idoit unter Settings-> Interface-> JSON-RPC API to access the api .EXAMPLE PS> Connect-IdoIt -Uri 'https://test.uri' -Credential $credential -ApiKey 'TestApiKey' This will connect to the Idoit API using the provided Uri and Credential. The result of the login will be returned. .EXAMPLE PS> Connect-IdoIt -Uri 'https://test.uri' -Username 'TestUser' -Password (ConvertTo-SecureString 'TestPassword' -AsPlainText -Force) -ApiKey 'TestApiKey' This will connect to the Idoit API using the provided Uri, Username, Password and ApiKey. The result of the login will be returned. .NOTES #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidGlobalVars", "")] [Cmdletbinding()] Param( [Parameter(Mandatory = $True, ParameterSetName = "PSCredential")] [Parameter(Mandatory = $True, ParameterSetName = "UserPasswordApiKey")] [String] $Uri, [Parameter(Mandatory = $true, ParameterSetName = "PSCredential")] [System.Management.Automation.PSCredential] $Credential, [Parameter(Mandatory = $True, ParameterSetName = "UserPasswordApiKey")] [String] $Username, [Parameter(Mandatory = $True, ParameterSetName = "UserPasswordApiKey")] [SecureString] $Password, [Parameter(Mandatory = $True, ParameterSetName = "PSCredential")] [Parameter(Mandatory = $True, ParameterSetName = "UserPasswordApiKey")] [String] $ApiKey ) If ($PSBoundParameters['Debug']) { $DebugPreference = 'Continue' } switch ($PSCmdlet.ParameterSetName) { "UserPasswordApiKey" { $Script:IdoItParams["Connection"] = @{ Uri = $Uri Username = $Username Password = $Password ApiKey = $ApiKey } } "PSCredential" { $Script:IdoItParams["Connection"] = @{ Uri = $Uri Username = $Credential.UserName Password = $Credential.GetNetworkCredential().Password ApiKey = $ApiKey } } Default { Throw " Invalid parameter set $($PSCmdlet.ParameterSetName) specified." } } $Headers = @{ "Content-Type" = "application/json" "X-RPC-Auth-Username" = $Script:IdoItParams["Connection"].Username "X-RPC-Auth-Password" = $Script:IdoItParams["Connection"].Password } $splatInvoke = @{ Uri = $Script:IdoItParams["Connection"].Uri Headers = $Headers Method = "idoit.login" Params = @{} } $resultObj = Invoke-IdoIt @splatInvoke $result = [pscustomobject]@{ Account = $resultObj.name ClientName = $resultObj.'client-name' ClientId = $resultObj.'client-id' } $Script:IdoItParams["Connection"].SessionId = $resultObj.'session-id' # According to the i-doit API docs, this should return a version string. # As of version 33 is used in our environment, tt seems to be an integer. So we need to convert it to a string. $versionString = (Get-IdoItVersion).Version Try { # ugly way to check whether the [string] is an integer if ("$versionString" -match '^\d+$') { $versionString = [Version]::new($versionString, 0) } $null = [Version]$versionString } Catch { Throw "IdoIt version is not a valid version string: $versionString" } $result } #EndRegion '.\Public\Connect-IdoIt.ps1' 108 #Region '.\Public\Disconnect-IdoIt.ps1' -1 function Disconnect-IdoIt { <# .SYNOPSIS Disconnect-IdoIt logs out of the IdoIt API-Session. .DESCRIPTION Disconnect-IdoIt logs out of the IdoIt API-Session. .EXAMPLE PS> Disconnect-IdoIt This will disconnect from idoit .NOTES #> Try { Invoke-IdoIt -Method "idoit.logout" -Params @{} $Script:IdoItParams["Connection"].SessionId = $null } Catch { Throw } } #EndRegion '.\Public\Disconnect-IdoIt.ps1' 23 #Region '.\Public\Get-IdoItCategory.ps1' -1 function Get-IdoItCategory { <# .SYNOPSIS Get category properties and values for a given object id and category. .DESCRIPTION Get-IdoItCategory retrieves all category properties and values for a given object id and category. .PARAMETER Id The object id of the object for which you want to retrieve category properties and values. Alias: ObjId .PARAMETER Category The category constant name for which you want to retrieve properties and values. Alias: Const This parameter is dynamic and will be populated based on the object type of the specified Id. If the Id is not specified, all available categories will be returned. If an Id is used, where no object type is defined, the parameter will not be populated. .PARAMETER Status The status of the category. Default is 2 (active). .EXAMPLE PS> Get-IdoItCategory -Id 12345 -Category 'C__CATG__CPU' Retrieves a list of items of the category 'C__CATG__CPU' and its values for the object with id 12345. #> [CmdletBinding()] param ( [Parameter(Mandatory = $true, Position = 0, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Alias('ObjId')] [int] $Id, # dynamic parameter # [Parameter(Mandatory = $true, Position = 1, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] # [Alias('Const')] # [string] $Category, [Parameter(Position = 2, ParameterSetName = "Id")] [int] $Status = 2 ) DynamicParam { #region Category: if user has entered an Id, try to get defined categories for this object if ($Id -gt 0) { $obj = Get-IdoItObject -Id $Id -ErrorAction SilentlyContinue if ($null -ne $obj) { $objCategoryList = Get-IdoitObjectTypeCategory -Type $obj.objecttype -ErrorAction SilentlyContinue } if ($null -ne $objCategoryList) { $validCatConstList = $objCategoryList | Select-Object -ExpandProperty const } } else { if ($null -eq $validCatConstList) { # default: deliver all constants $validCatConstList = (Get-IdoItConstant | Where-Object Type -in ('GlobalCategory','SpecificCategory')).Name } } $dynParamCategory = NewDynamicParameter -Name 'Category' -ParameterType 'System.String' -ValidateSet $validCatConstList -Mandatory $true $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $RuntimeParameterDictionary.Add('Category', $dynParamCategory) #endregion return $RuntimeParameterDictionary } begin { } process { $params = @{ objID = $Id category = $PSBoundParameters['Category'] status = $Status } $result = Invoke-Idoit -Method 'cmdb.category.read' -Params $params if ($null -ne $result) { foreach ($item in $result) { $item.PSObject.TypeNames.Insert(0, 'Idoit.Category') $item } } } end { } } #EndRegion '.\Public\Get-IdoItCategory.ps1' 86 #Region '.\Public\Get-IdoitCategoryInfo.ps1' -1 Function Get-IdoitCategoryInfo { <# .SYNOPSIS Get-IdoitCategoryInfo .DESCRIPTION Get-IdoItCategoryInfo lets you discover all available category properties for a given category id. The list corresponds to the properties you will receive for each returned object after calling the cmdb.category.read method. .PARAMETER Category Look for category info by category name. This is the most common way to get category info. .PARAMETER CatgId Look for category info by category id of a global category. .PARAMETER CatsId Look for category info by category id of a s(?) category. .EXAMPLE PS>Get-IdoitCategoryInfo -Category 'C__CATG__CPU' Gives you detailed Info about every possible categaory value of this object. E.g. for 'C__CATG__CPU' you get title, manifacturer, type, frequency, cores, etc. ... cores: @{title=CPU cores; check=; info=; data=; ui=} @{ title = 'CPU cores'; check = @{ mandatory = 'False' }; info = @{ primary_field = 'False'; type = 'int'; backward = 'False'; title = 'LC__CMDB__CATG__CPU_CORES'; description = 'CPU cores' }; data = @{ type = 'int'; readonly = 'False'; index = 'False'; field = 'isys_catg_cpu_list__cores' }; ui = @{ type = 'text'; params = @{ p_strPlaceholder = 0; default = 0; p_strClass = 'input-mini' }; default = 1; id = 'C__CATG__CPU_CORES' } }; .NOTES #> Param ( [Parameter(Mandatory = $True, ParameterSetName="Category")] [String]$Category, [Parameter(Mandatory = $True, ParameterSetName="CatgId")] [int]$CatgId, [Parameter(Mandatory = $True, ParameterSetName="CatsId")] [int]$CatsId ) $params = @{} Switch ($PSCmdlet.ParameterSetName) { "Category" { $params.Add("category", $Category); break } "CatgId" { $params.Add("catgID",$CatgId); break } "CatsId" { $params.Add("catsID",$CatsId); break } } $result = Invoke-IdoIt -Method "cmdb.category_info.read" -Params $params $result.PSObject.Typenames.Add('Idoit.CategoryInfo') # TODO: when reading by Id, the category is not returned => results in a warning if ([string]::IsNullOrEmpty($Category)) { Write-Error "No category found for $Category" return $null } $result | Add-Member -MemberType NoteProperty -Name Category -Value $Category -Force return $result } #EndRegion '.\Public\Get-IdoitCategoryInfo.ps1' 62 #Region '.\Public\Get-IdoItConstant.ps1' -1 Function Get-IdoItConstant { <# .SYNOPSIS Get-IdoItConstant .DESCRIPTION It retrieve all constants from the API (objTypes, categories, global and specific categories). .OUTPUTS Returns a list Type of constant, name and value. .EXAMPLE Get-IdoItConstant Returns all the constants. .NOTES #> [CmdletBinding()] $params = @{} $result = Invoke-IdoIt -Method "idoit.constants" -Params $params # one of the things, which are wierd in this API # result is an object having a property by type of constant # e.g. $result.objectTypes, $result.Categories.G, $result.Categories.S, recordStates, ... # Each of this properties is set up as a object having a property by contstant name # and a value of the text (or title?) of that constant Convert-PropertyToArray -InputObject $result.objectTypes | Select-Object @{ name='Type'; Expression={'ObjectType'} }, Name, Value Convert-PropertyToArray -InputObject $result.recordStates | Select-Object @{ name='Type'; Expression={'RecordState'} }, Name, Value Convert-PropertyToArray -InputObject $result.Categories.G | Select-Object @{ name='Type'; Expression={'GlobalCategory'} }, Name, Value Convert-PropertyToArray -InputObject $result.Categories.S | Select-Object @{ name='Type'; Expression={'SpecificCategory'} }, Name, Value Convert-PropertyToArray -InputObject $result.Categories.g_custom | Select-Object @{ name='Type'; Expression={'CustomCategory'} }, Name, Value Convert-PropertyToArray -InputObject $result.relationTypes | Select-Object @{ name='Type'; Expression={'RelationType'} }, Name, Value Convert-PropertyToArray -InputObject $result.staticObjects | Select-Object @{ name='Type'; Expression={'StaticObject'} }, Name, Value } #EndRegion '.\Public\Get-IdoItConstant.ps1' 36 #Region '.\Public\Get-IdoitDialog.ps1' -1 function Get-IdoitDialog { <# .SYNOPSIS Get the dialog for a specific category and property from i-doit. .DESCRIPTION This function retrieves the dialog for a specific category and property. It returns a list of options available for the specified category and property. .PARAMETER params A hashtable containing the parameters for the dialog. The hashtable should contain at least the keys 'category' and 'property'. Example: @{ category='C__CATG__CPU'; property='manufacturer' } .EXAMPLE Get-IdoitDialog -params @{ category='C__CATG__CPU'; property='manufacturer' } Retrieves the dialog options for the CPU category and manufacturer property. .NOTES #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [hashtable] $params # parameters for the dialog, e.g. @{ category='C__CATG__CPU'; property='manufacturer' } ) begin { } process { $apiResult = Invoke-IdoIt -Endpoint 'cmdb.dialog' -Params $params foreach ($location in $apiResult) { $location | Add-Member -MemberType NoteProperty -Name 'ParentId' -Value $Id -Force -PassThru } } end { } } #EndRegion '.\Public\Get-IdoitDialog.ps1' 43 #Region '.\Public\Get-IdoitLocationTree.ps1' -1 function Get-IdoitLocationTree { <# .SYNOPSIS Get the next location tree from i-doit .DESCRIPTION This function retrieves the location tree from i-doit. The root location is returned if no Id is specified. .PARAMETER Id The Id of the location to retrieve the tree from. If 0 is specified, the root location is returned. .EXAMPLE Get-IdoitLocationTree -Id 0 Retrieves the root location. .EXAMPLE Get-IdoitLocationTree -Id 1 Retrieves the location tree starting from the location with Id 1 (root). >#> [CmdletBinding()] param ( [int] $Id # 0 returns the root location ) begin { } process { $apiResult = Invoke-IdoIt -Endpoint 'cmdb.location_tree' -Params @{ id = $Id } foreach ($location in $apiResult) { $location.PSObject.TypeNames.Insert(0, 'PSIdoitNG.Location') $location | Add-Member -MemberType NoteProperty -Name 'ParentId' -Value $Id -Force -PassThru } } end { } } #EndRegion '.\Public\Get-IdoitLocationTree.ps1' 45 #Region '.\Public\Get-IdoitObject.ps1' -1 function Get-IdoitObject { <# .SYNOPSIS Get-IdoitObject returns an object from the i-doit API or $null. .DESCRIPTION Get-IdoitObject returns an object or $null. .EXAMPLE Get-IdoitObject -Id 540 .PARAMETER Id The id of the object you want to retrieve from the i-doit API. #> [cmdletBinding(ConfirmImpact = 'Low')] [OutputType([Object])] param ( [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [int] $Id ) process { $apiResult = Invoke-Idoit -Method 'cmdb.object.read' -Params @{ id = $Id } if ($null -ne $apiResult) { $apiResult.PSObject.TypeNames.Insert(0, 'Idoit.Object') } else { Write-Error -Message "Object not found Id=$Id" } $apiResult } } #EndRegion '.\Public\Get-IdoitObject.ps1' 35 #Region '.\Public\Get-IdoItObjectType.ps1' -1 function Get-IdoItObjectType { <# .SYNOPSIS Get-IdoItObjectType retrieves object types from i-doit. .DESCRIPTION Get-IdoItObjectType retrieves object types from i-doit. You can specify the object type by its ID or title. .PARAMETER Id The ID of the object type to retrieve. This parameter is mandatory. .PARAMETER Const The title of the object type to retrieve. This parameter is mandatory. .PARAMETER Enabled If specified, only enabled object types will be retrieved. .PARAMETER Skip The number of object types to skip before returning results. This is useful for pagination. The default value is 0. .PARAMETER Limit The maximum number of object types to return. This is useful for pagination. The default value is 100. .EXAMPLE Get-IdoItObjectType -Id 1 Retrieves the object type with ID 1.^ .EXAMPLE Get-IdoItObjectType -Const "C_OBJTYPE_SERVICE","C_OBJTYPE_SERVER" Retrieves the object types with titles "C_OBJTYPE_SERVICE" and "C_OBJTYPE_SERVER". .EXAMPLE Get-IdoItObjectType -Enabled Retrieves all enabled object types. .EXAMPLE Get-IdoItObjectType -Limit 20 Get-IdoItObjectType -Skip 20 -Limit 20 Retrieves the the first 20 object types and then the next 20 object types. .DESCRIPTION Get-IdoItObjectType retrieves object types from i-doit. You can specify the object type by its ID or title. #> [CmdletBinding()] Param ( [Int[]] $Id, [Alias('Title')] [string[]] $Const, [Switch] $Enabled, [int] $Skip, [Int] $Limit ) #checkCmdbConnection Process { $params= @{} $filter = @{} foreach ($PSBoundParameter in $PSBoundParameters.Keys) { switch ($PSBoundParameter) { "Id" { $filter.Add("ids", @($Id)) break } "Const" { $filter.Add("titles", @($Const)) # sadly: the API param is title, searched are const strings break } "Enabled" { $filter.Add("enabled", 1) break } "Limit" { if ($Skip -gt 0) { $params.Add("limit", "$Skip,$Limit") } else { $params.Add("limit", $Limit) } break } } } $params.Add("filter", $filter) $result = Invoke-IdoIt -Method "cmdb.object_types.read" -Params $params $result | ForEach-Object { $_.PSObject.TypeNames.Add('Idoit.ObjectType') } Return $result } } #EndRegion '.\Public\Get-IdoItObjectType.ps1' 96 #Region '.\Public\Get-IdoItObjectTypeCategory.ps1' -1 Function Get-IdoItObjectTypeCategory { <# .SYNOPSIS Get-IdoItObjectTypeCategory .DESCRIPTION Gets all the categories that the specified object type is constructed of. .PARAMETER ObjId Object ID for which the categories should be returned. If this parameter is specified, the type of the object will be determined first. .PARAMETER Type Object type for which the categories should be returned. This can be a string or an integer. .OUTPUTS Returns a collection of IdoIt.ObjectTypeCategory objects. Each object represents a category. .EXAMPLE PS> Get-IdoItObjectTypeCategory -Type 'C__OBJTYPE__SERVER' This will get all categories that are assigned to the ObjectType 'Server' [PSCustomObject] @{ id = 31; title = 'Overview page'; const = 'C__CATG__OVERVIEW'; multi_value = 0; source_table = 'isys_catg_overview' } [PSCustomObject] @{ id = 42; title = 'Drive'; const = 'C__CATG__DRIVE'; multi_value = 1; source_table = 'isys_catg_drive' } ... .EXAMPLE PS> Get-IdoItObjectTypeCategory -Type 1 This will get all categories that are assigned to the ObjectType with ID 1. .EXAMPLE PS> Get-IdoItObjectTypeCategory -ObjId 540 This will get all categories for that object id (Server with ID 540). .NOTES #> [CmdletBinding(DefaultParameterSetName = 'ObjectType')] [OutputType([System.Object[]])] Param ( [Parameter (Mandatory = $false, ValueFromPipelineByPropertyName = $True, ParameterSetName = 'ObjectId')] [ValidateNotNullOrEmpty()] [int] $ObjId, [Parameter (Mandatory = $True, ValueFromPipeline = $True, ParameterSetName = 'ObjectType')] [ValidateNotNullOrEmpty()] [Alias('TypeId','Id')] $Type ) Process { $params = @{} switch ($PSCmdlet.ParameterSetName) { 'ObjectId' { # if we have an object id, we need to get the type first $obj = Get-IdoItObject -Id $ObjId if ($null -eq $obj) { Write-Error "Object with ID $ObjId not found." return } $Type = $obj.objecttype } 'ObjectType' { # do nothing, type is already set } } $params.Add("type", $Type) $result = Invoke-IdoIt -Method "cmdb.object_type_categories.read" -Params $params #idoit delivers two arrays, depending of global or specific categories. From a PowerShell #point of view this is ugly - so we flatten the result into one PSObject. ForEach ($thisProperty In $result.PSObject.Properties) { ForEach ($subProperty In $result.($thisProperty.Name)) { if ([string]::IsNullOrEmpty($subProperty.type)) { # older API version seems not to deliver the type? $subProperty | Add-Member -MemberType NoteProperty -Name "type" -Value $thisProperty.Name } $subProperty.PsObject.TypeNames.Insert(0,'IdoIt.ObjectTypeCategory') $subProperty } } } } #EndRegion '.\Public\Get-IdoItObjectTypeCategory.ps1' 84 #Region '.\Public\Get-IdoItObjectTypeGroup.ps1' -1 Function Get-IdoItObjectTypeGroup { <# .SYNOPSIS Get-IdoItObjectTypeGroup .DESCRIPTION Gets all the object type groups that are available in the i-doit CMDB. .EXAMPLE Get-IdoItObjectTypeGroup Return all object type groups. .NOTES #> [CmdletBinding()] Param () $result = Invoke-IdoIt -Method "cmdb.object_type_groups.read" $result | ForEach-Object { $_.PSObject.TypeNames.Insert(0, 'IdoIt.ObjectTypeGroup') } Write-Output $result } #EndRegion '.\Public\Get-IdoItObjectTypeGroup.ps1' 24 #Region '.\Public\Get-IdoItVersion.ps1' -1 Function Get-IdoItVersion { <# .SYNOPSIS Get the version of the Idoit instance .DESCRIPTION This function retrieves the version of the Idoit instance. Since some version of the API, it does return a integer value and not a version string. .EXAMPLE Get-IdoItVersion This will retrieve the version of the Idoit instance. .NOTES #> $result = Invoke-IdoIt -Method "idoit.version" -Params @{} return $result | Select-Object version, type, step } #EndRegion '.\Public\Get-IdoItVersion.ps1' 15 #Region '.\Public\Invoke-IdoIt.ps1' -1 Function Invoke-IdoIt { <# .SYNOPSIS Invoke-IdoIt API request to the i-doit RPC Endpoint .DESCRIPTION This function is calling the IdoIt API. The result is returned as a PSObject. .PARAMETER Endpoint This parameter the method yout want to call at the RPC Endpoint (see https://kb.i-doit.com/de/i-doit-add-ons/api/index.html). From my personal point of view, at the time of writing the documentation is not very good. .PARAMETER Params Hashtable creating request body with the methods parameters (https://kb.i-doit.com/de/i-doit-add-ons/api/index.html). The following additional parameters are inserted into the request body: ApiKey, Request id, Version .PARAMETER Headers Optional parameter if default headers should be overwritten (e.g. when logging into a new session). .PARAMETER Uri The Uri if the API Endpoint. .PARAMETER Version The version of the API. Default is 2.0 .PARAMETER ApiKey The API key to be used. Default is the one used in Connect. .EXAMPLE $result = -Method "idoit.logout" -Params @{} .NOTES To trace the API calls, set the global variable $Global:IdoitApiTrace to @(). For every API call, a new entry is added to the array. The entry contains the following properties: Endpoint: The endpoint called Request: The request body Response: The response body (if response was successful) Time: The time of the call Exception: The exception thrown (if any) #> [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidGlobalVars", "")] [CmdletBinding()] Param ( [Parameter( Mandatory = $True )] [ValidateNotNullOrEmpty()] [Alias('Method')] [String] $Endpoint, [ValidateNotNull()] [Hashtable] $Params = @{}, [Hashtable] $Headers = @{"Content-Type" = "application/json"; "X-RPC-Auth-Session" = $Script:IdoItParams["Connection"].SessionId}, [String] $Uri = $Script:IdoItParams["Connection"].Uri, [string] $Version = "2.0", [string] $ApiKey = $Script:IdoItParams["Connection"].ApiKey ) $Params['apikey'] = $ApiKey $body = @{ "method" = $Endpoint "version" = $Version "id" = [Guid]::NewGuid() "params" = $Params } $bodyJson = ConvertTo-Json -InputObject $body -Depth 4 Try { $apiResult = Invoke-RestMethod -Uri $Uri -Method Post -Body $bodyJson -Headers $Headers # remove quotes from integer values $apiResult = ($apiResult | ConvertTo-Json -Depth 10) -replace '(?m)"([0-9]+)"','$1' | ConvertFrom-Json if ($null -ne $Global:IdoitApiTrace) { $Global:IdoitApiTrace += [PSCustomObject]@{ Endpoint = $Endpoint Request = [PSCustomObject]$body Response = $apiResult Time = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") } } } Catch { if ($null -ne $Global:IdoitApiTrace) { $Global:IdoitApiTrace += [PSCustomObject]@{ Endpoint = $Endpoint Request = [PSCustomObject]$body Exception = $_ Time = (Get-Date).ToString("yyyy-MM-dd HH:mm:ss") } } if ($_.CategoryInfo.Reason -eq 'UriFormatException') { # check if the login was missing if ([string]::IsNullOrEmpty($Script:IdoItParams["Connection"].SessionId)) { Write-Error -Message "No valid session found. Please check your API connection." -ErrorAction Stop } } Throw $_ } If ($apiResult.PSObject.Properties.Name -Contains 'Error') { $errMsg = "Error $($apiResult.Error.Code) - $($apiResult.error.data.Description) - $($apiResult.error.message)" Throw $errMsg } else { If ( $body.Id -ne $apiResult.id) { Throw "Request id mismatch. Expected value was $RequestID but it is $($apiResult.id)" } if ($apiResult.result.PSObject.Properties.Name -Contains 'Success') { # cast success to boolean $apiResult.result.success = $apiResult.result.success -eq 'True' } $apiResult.result } } #EndRegion '.\Public\Invoke-IdoIt.ps1' 116 #Region '.\Public\New-IdoitObject.ps1' -1 function New-IdoitObject { <# .SYNOPSIS Create a new i-doit object. .DESCRIPTION This function creates a new object in i-doit with the specified name, type, category, purpose, status, and description. It checks if an object with the same name already exists, and if so, it throws an error unless the `-AllowDuplicates` switch is set. .PARAMETER Name The name of the object to create. This is a mandatory parameter. Alias: Title .PARAMETER ObjectType The type of the object to create. .PARAMETER Category An array of categories to assign to the object. This is optional. .PARAMETER Purpose The purpose of the object. Valid entries can be found in the i-doit documentation. .PARAMETER Status The status of the object. Valid entries can be found in the i-doit documentation. .PARAMETER Description A description for the object. This is optional. .PARAMETER AllowDuplicates A switch to allow creating an object with the same name as an existing object. If this switch is not set, the function will throw an error if an object with the same name already exists. .EXAMPLE New-IdoitObject -Name "New Server" -ObjectType "C__OBJTYPE__SERVER" -Category "C__CATG__GLOBAL" -Purpose "In production" -Status 'C__CMDB_STATUS__IN_OPERATION' -Description "This is a new server object." This command creates a new server object in i-doit with the specified name, type, category, purpose, status, and description. .NOTES The function is intended to create *new* object of a specific type. If you want to create an object with the same name as an existing object, use the `-AllowDuplicates` switch. If you want to update an existing object, use the `Set-IdoitObject` function instead. #> [CmdletBinding(SupportsShouldProcess = $True)] param ( [Parameter( Mandatory = $True, ValueFromPipelineByPropertyName = $True, Position = 0)] [ValidateNotNullOrEmpty()] [Alias( 'Title' )] [string] $Name, [Parameter( Mandatory = $True, ValueFromPipelineByPropertyName = $True)] [ValidateNotNullOrEmpty()] [string] $ObjectType, [Parameter( ValueFromPipelineByPropertyName = $True)] [ValidateNotNullOrEmpty()] [string[]] $Category, [Parameter( ValueFromPipelineByPropertyName = $True)] [ValidateNotNullOrEmpty()] [string] $Purpose, [Parameter( ValueFromPipelineByPropertyName = $True)] [ValidateNotNullOrEmpty()] [Alias( 'cmbd_status')] [string] $Status, [Parameter( ValueFromPipelineByPropertyName = $True)] [ValidateNotNullOrEmpty()] [string] $Description, [Parameter( ValueFromPipelineByPropertyName = $True)] [Switch] $AllowDuplicates ) begin { } process { # by default, an object of this type and name should not exist if (-not $AllowDuplicates) { $obj = Search-IdoItObject -Conditions @{"property" = "C__CATG__GLOBAL-title"; "comparison" = "="; "value" = $Name} -ErrorAction SilentlyContinue if ($null -ne $obj) { Write-Error "An object with the name '$Name' already exists. Use -AllowDuplicates to create a new object with the same name." return } } $params = @{ title = $Name type = $ObjectType } if ($Category.Count -gt 0) { $params.categories = @($Category) # use @(..) to ensure the value is an array } if ('' -ne $Purpose) { $params.purpose = $Purpose } if ('' -ne $Status) { $params.status = $Status } if ('' -ne $Description) { $params.description = $Description } if ($PSCmdlet.ShouldProcess("Creating object '$Name' of type '$ObjectType'")) { $apiResult = Invoke-IdoIt -Method 'cmdb.object.create' -Params $params if ($apiResult -and 'True' -eq $apiResult.success) { $ret = [PSCustomObject]@{ ObjId = $apiResult.id } Write-Output $ret } else { Write-Error "Failed to create object. Error: $($apiResult.message)" } } } end { } } #EndRegion '.\Public\New-IdoitObject.ps1' 119 #Region '.\Public\Search-IdoitObject.ps1' -1 function Search-IdoItObject { <# .SYNOPSIS Searches for objects in the i-doit CMDB based on specified conditions. .DESCRIPTION This cmdlet allows you to search for objects in the i-doit CMDB by providing an array of conditions. The conditions are passed as an array of hashtable entries. Against the usual naming of the functions, it implements "cmdb.condition.read". .PARAMETER Conditions An array of hashtable entries defining the search conditions. Each hashtable should include keys like "property", "operator", and "value". .PARAMETER Query A string representing the a simple search query. It will find all objects that match the query. This might be used to get a quick overview of objects in the i-doit CMDB. .EXAMPLE PS> Search-IdoItObject -Conditions @( @{ "property" = "C__CATG__GLOBAL-title"; "comparison" = "like"; "value" = "*r540*" }, @{ "property" = "C__CATG__GLOBAL-type"; "comparison" = "="; "value" = "5" } ) This will search for objects where the title contains "Server" and the type is "Server". id title sysid type created updated type_title type_icon type_group_title status -- ----- ----- ---- ------- ------- ---------- --------- ---------------- ------ 540 server540 SYSID_1730365404 5 2024-10-31 09:54:24 2025-05-15 16:05:08 Server /cmdb/object-type/image/5 2 .NOTES API version 33 behaviour (or some other?) Be aware that some files are case sensitive! I know, that this is not the best practice, but I don't know who designed this. not case sensitive (title): Search-IdoItObject -Conditions @{"property" = "C__CATG__GLOBAL-title"; "comparison" = "="; "value" = "yOuR-Server"} returns records but case sensitive (type) : Search-IdoItObject -Conditions @{"property" = "C__CATG__GLOBAL-type"; "comparison" = "="; "value" = "C__OBJTYPE__SERVER"} does not return records Receiving error message like "Failed to execute the search: Error code -32099 ..." This might happen, if you want to select a field, which is not part of the database table your (implicit) searching. E.g. Search-IdoItObject -Conditions @{"property" = "C__CATG__GLOBAL-type"; "comparison" = "="; "value" = "5"} | ft returns the field type_title id title sysid type created updated type_title type_icon type_group_title status -- ----- ----- ---- ------- ------- ---------- --------- ---------------- ------ 540 server540 SYSID_1730365404 5 2024-10-31 09:54:24 2025-04-27 06:52:30 Server /cmdb/object-type/image/5 2 Sorry, it seems not possible to search for a field of this name Search-IdoItObject -Conditions @{"property" = "C__CATG__GLOBAL-type_title"; "comparison" = "="; "value" = "Server"} | ft returns an error message like this: Exception: C:\Users\wagnerw\Lokal\Github\psidoit\psidoit\Public\Search-IdoItObject.ps1:49:17 Line | 49 | Throw "Failed to execute the search: $_" | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | Failed to execute the search: Error code -32099 - i-doit system error: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use | near ')' at line 7 - #> [CmdletBinding()] param ( [Parameter(Mandatory=$true, ParameterSetName='Conditions')] [hashtable[]]$Conditions, [Parameter(Mandatory=$true, ParameterSetName='Query')] [string]$Query ) process { try { switch ($PSCmdlet.ParameterSetName) { 'Conditions' { $result = Invoke-IdoIt -Endpoint 'cmdb.condition.read' -Params @{ conditions = $Conditions } $result = $result | ForEach-Object { $_.PSObject.TypeNames.Insert(0, 'IdoIt.ConditionalSearchResult') $_ } Write-Output $result } 'Query' { $result = Invoke-IdoIt -Endpoint 'idoit.search' -Params @{ query = $Query } $result = $result | ForEach-Object { $_.PSObject.TypeNames.Insert(0, 'IdoIt.QuerySearchResult') $_ } Write-Output $result } } } catch { Throw "Failed to execute the search: $_" } } } #EndRegion '.\Public\Search-IdoitObject.ps1' 95 #Region '.\Public\Set-IdoItCategory.ps1' -1 Function Set-IdoItCategory { <# .SYNOPSIS Set category properties and values for a given object id and category. .DESCRIPTION Set-IdoItCategory sets all category properties and values for a given object id and category. .PARAMETER Id The object id of the object for which you want to set category properties and values. Alias: ObjId .PARAMETER Category The category constant name for which you want to set properties and values. Alias: Const This is a dynamic parameter and will be set based on the objects type. .PARAMETER Data A hashtable containing the data to be set in the category. .EXAMPLE PS> Set-IdoItCategory -Id 12345 -Category 'C__CATG__CPU' -Data @{title = 'New Title'; status = 1} #> [CmdletBinding( SupportsShouldProcess = $True, DefaultParameterSetName = 'Update' )] Param ( [Parameter( Mandatory = $True, ValueFromPipelineByPropertyName = $True, Position = 0)] [ValidateNotNullOrEmpty()] [Alias( 'ObjId' )] [Int] $Id, # dynamic parameter # [String] $Category, [Parameter( Mandatory = $True )] [Hashtable] $Data ) DynamicParam { #region Category: if user has entered an Id, try to get defined categories for this object if ($Id -gt 0) { $obj = Get-IdoItObject -Id $Id -ErrorAction SilentlyContinue if ($null -eq $obj) { return } $objCategoryList = Get-IdoitObjectTypeCategory -Type $obj.objecttype -ErrorAction SilentlyContinue if ($null -eq $objCategoryList) { return } $validCatConstList = $objCategoryList | Select-Object -ExpandProperty const if ($null -eq $validCatConstList) { return } } else { $validCatConstList = (Get-IdoItConstant | Where-Object Type -in ('GlobalCategory','SpecificCategory')).Name } $dynParamCategory = NewDynamicParameter -Name 'Category' -ParameterType 'System.String' -ValidateSet $validCatConstList -Mandatory $true $RuntimeParameterDictionary = New-Object System.Management.Automation.RuntimeDefinedParameterDictionary $RuntimeParameterDictionary.Add('Category', $dynParamCategory) #endregion return $RuntimeParameterDictionary } begin { # Initialize the parameters $params = @{} } process { $params = @{ object = $Id # you wouldn't believe it, here object id must be passed as "object" (not objId!) category = $PSBoundParameters['Category'] data = $Data } # if the category has multi_value=1, then we need to get an entry id, otherwise we can set the values directly $cat = $objCategoryList | Where-Object { $_.const -eq $params.category } if ($cat.multi_value -eq 1 -and $Entry -eq 0) { $errResonse = [PSCustomObject]@{ Success = $false Error = "Category '$($params.category)' is a multi-value category. Currently(?) entry id is mandatory here." } Write-Output $errResonse Write-Error $errResonse return } elseif ($cat.multi_value -eq 0 -and $Data.Entry -gt 0) { $errResonse = [PSCustomObject]@{ Success = $false Error = "Category '$($params.category)' is a single-value category. Please do not specify an entry id." } Write-Output $errResonse Write-Error $errResonse return } If ($PSCmdlet.ShouldProcess("Updating category on object $Id")) { $result = Invoke-IdoIt -Method "cmdb.category.save" -Params $params return $result } } } #EndRegion '.\Public\Set-IdoItCategory.ps1' 92 #Region '.\Public\Start-IdoitApiTrace.ps1' -1 function Start-IdoitApiTrace { <# .SYNOPSIS Start the Idoit API trace. .DESCRIPTION This function starts the Idoit API trace by initializing a global variable to store the trace data. .PARAMETER None No parameters are required for this function. .EXAMPLE Start-IdoitApiTrace # Starts the Idoit API trace and initializes the global variable. .NOTES Any data already in the $Global:IdoItAPITrace variable will be lost. This function is intended for use in testing scenarios to capture API calls. #> [CmdletBinding(SupportsShouldProcess = $True)] [System.Diagnostics.CodeAnalysis.SuppressMessage('PSAVoidGlobalVars', '', Justification = 'Global variable is used outside this scope.')] param () # Suppress PSUseDeclaredVarsMoreThanAssignments for $Global:IdoItAPITrace # because it is intentionally assigned but not used in this scope. if ($PSCmdlet.ShouldProcess('IdoitApiTrace', 'Start')) { Write-Verbose -Message 'Starting Idoit API trace...' $Global:IdoItAPITrace = @() } } #EndRegion '.\Public\Start-IdoitApiTrace.ps1' 26 #Region '.\Public\Stop-IdoitApiTrace.ps1' -1 function Stop-IdoitApiTrace { <# .SYNOPSIS Stop the Idoit API trace. .DESCRIPTION This function stops the Idoit API trace by removing the global variable that stores the trace data. .PARAMETER None No parameters are required for this function. .EXAMPLE Stop-IdoitApiTrace # Stops the Idoit API trace and removes the global variable. .NOTES This function is intended for use in testing scenarios to stop capturing API calls. #> [CmdletBinding(SupportsShouldProcess = $True)] [System.Diagnostics.CodeAnalysis.SuppressMessage('PSAvoidGlobalVars', '', Justification = 'Global variable is used outside this scope.')] param () if ($PSCmdlet.ShouldProcess('IdoitApiTrace', 'Stop')) { Write-Verbose -Message 'Stopping Idoit API trace...' Remove-Variable -Name 'IdoitApiTrace' -Scope Global -ErrorAction SilentlyContinue } } #EndRegion '.\Public\Stop-IdoitApiTrace.ps1' 23 |