Public/Get-AtwsFieldInfo.ps1
<#
.COPYRIGHT Copyright (c) ECIT Solutions AS. All rights reserved. Licensed under the MIT license. See https://github.com/ecitsolutions/Autotask/blob/master/LICENSE.md for license information. #> Function Get-AtwsFieldInfo { <# .SYNOPSIS This function gets valid fields for an Autotask Entity .DESCRIPTION This function gets valid fields for an Autotask Entity .INPUTS None. .OUTPUTS [Autotask.Field[]] .EXAMPLE Get-AtwsFieldInfo -Entity Account Gets all valid built-in fields and user defined fields for the Account entity. #> [cmdletbinding( SupportsShouldProcess = $true, ConfirmImpact = 'Low', DefaultParameterSetName = 'by_Entity' )] Param ( [Parameter( ParameterSetName = 'get_All' )] [switch] $All, [Parameter( ParameterSetName = 'get_Static' )] [switch] $Static, [Parameter( ParameterSetName = 'get_Dynamic' )] [switch] $Dynamic, [Parameter( Mandatory = $true, ParameterSetName = 'by_Reference' )] [switch] $ReferencingEntity, [Parameter( ParameterSetName = 'by_Entity' )] [Alias('UDF')] [switch] $UserDefinedFields, [Parameter( ParameterSetName = 'by_Entity' )] [switch] $EntityInfo, [Parameter( Mandatory = $true, Position = 0, ParameterSetName = 'by_Entity' )] [Parameter( Mandatory = $true, Position = 0, ParameterSetName = 'by_Reference' )] [string] $Entity, [Parameter( ParameterSetName = 'by_Entity' )] [Parameter( ParameterSetName = 'get_Dynamic' )] [Parameter( ParameterSetName = 'get_All' )] [switch] $UpdateCache ) begin { # Enable modern -Debug behavior if ($PSCmdlet.MyInvocation.BoundParameters['Debug'].IsPresent) { $DebugPreference = 'Continue' } Write-Debug ('{0}: Begin of function' -F $MyInvocation.MyCommand.Name) # Check if we are connected before trying anything if (-not($Script:Atws)) { throw [ApplicationException] 'Not connected to Autotask WebAPI. Re-import module with valid credentials.' return } # Has cache been loaded? if (-not($Script:Atws.Cache.Count -gt 0)) { # Load it. Import-AtwsDiskCache } $cacheExpiry = (Get-Date).AddMinutes(-15) } process { Function Update-AtwsEntity { [CmdLetBinding()] Param ( [Parameter( Mandatory = $true )] [string] $Entity ) begin { Write-Verbose ('{0}: Begin of function' -F $MyInvocation.MyCommand.Name) $cacheDirty = $false } process { $caption = $MyInvocation.MyCommand.Name $verboseDescription = '{0}: About to get built-in fields for {1}s' -F $caption, $Entity $verboseWarning = '{0}: About to get built-in fields for {1}s. Do you want to continue?' -F $caption, $Entity if ($PSCmdlet.ShouldProcess($verboseDescription, $verboseWarning, $caption)) { Write-Verbose -Message ("{0}: Calling .GetFieldInfo('{1}')" -F $MyInvocation.MyCommand.Name, $Entity) try { $result = $Script:Atws.GetFieldInfo($Script:Atws.IntegrationsValue, $Entity) } catch { Throw $_ Return } if ($result.Errors.Count -gt 0) { foreach ($AtwsError in $result.Errors) { Write-Error $AtwsError.Message } Return } } # No errors # Test if value has changed if (-not (Compare-PSObject -ReferenceObject $script:FieldInfoCache[$Entity].FieldInfo -DifferenceObject $result)) { # No errors Write-Verbose ('{0}: Save or update FieldInfo cache for entity {1}' -F $MyInvocation.MyCommand.Name, $Entity) $script:FieldInfoCache[$Entity].FieldInfo = $result # If not called during module load, give this warning if ($PSCmdLet.MyInvocation.ScriptName -notlike '*.psm1' -and $Script:Atws.Configuration.UseDiskCache) { Write-Warning ('{0}: The {1} entity has been modified in Autotask! Re-import module with -Argumentlist $creds, $ApiKey, "{1}" to refresh.' -F $MyInvocation.MyCommand.Name, $Entity) } $cacheDirty = $true } if ($script:FieldInfoCache[$Entity].EntityInfo.HasUserDefinedFields) { $caption = $MyInvocation.MyCommand.Name $verboseDescription = '{0}: About to get userdefined fields for {1}s' -F $caption, $Entity $verboseWarning = '{0}: About to get userdefined fields for {1}s. Do you want to continue?' -F $caption, $Entity if ($PSCmdlet.ShouldProcess($verboseDescription, $verboseWarning, $caption)) { $UDF = $Script:Atws.GetUDFInfo($Script:Atws.IntegrationsValue, $Entity) if ($result.Errors.Count -gt 0) { foreach ($AtwsError in $result.Errors) { Write-Error $AtwsError.Message } Return } } # UDF info will be empty the first time around if (-not ($script:FieldInfoCache[$Entity].UDFInfo)) { $script:FieldInfoCache[$Entity].UDFInfo = $UDF $cacheDirty = $true } elseif (-not(Compare-PSObject -ReferenceObject $script:FieldInfoCache[$Entity].UDFInfo -DifferenceObject $UDF)) { # No errors Write-Verbose ('{0}: Save or update UDF cache for entity {1}' -F $MyInvocation.MyCommand.Name, $Entity) $script:FieldInfoCache[$Entity].UDFInfo = $UDF $cacheDirty = $true } } $script:FieldInfoCache[$Entity].RetrievalTime = Get-Date } end { return $cacheDirty } } # By ENTITY if ($PSCmdlet.ParameterSetName -eq 'by_Entity') { Write-Verbose -Message ('{0}: Looking up detailed Fieldinfo for entity {1}' -F $MyInvocation.MyCommand.Name, $Entity) if (($script:FieldInfoCache[$Entity].HasPicklist -or $script:FieldInfoCache[$Entity].EntityInfo.HasUserDefinedFields) -and ($script:FieldInfoCache[$Entity].RetrievalTime -lt $cacheExpiry -or $UpdateCache.IsPresent)) { $cacheDirty = Update-AtwsEntity -Entity $Entity Write-Debug -Message ('{0}: Entity {1} has picklists and/or userdefined fields; cache was outdated or -UpdateCache was present.' -F $MyInvocation.MyCommand.Name, $Entity) } # Prepare an empty result set. If none of the conditions below are true, then the user tried to get # UDFs from an entity that does not support them. The result will be empty. $result = @() # If the user asked for UDFs and the entity supports UDFs, return the info. if ($UserDefinedFields.IsPresent -and $script:FieldInfoCache[$Entity].EntityInfo.HasUserDefinedFields) { Write-Debug ('{0}: Returning UDF info for entity {1} from cache' -F $MyInvocation.MyCommand.Name, $Entity) $result = $script:FieldInfoCache[$Entity].UDFInfo } elseif ($EntityInfo.IsPresent) { Write-Debug ('{0}: Returning EntityInfo info for entity {1} from cache' -F $MyInvocation.MyCommand.Name, $Entity) $result = $script:FieldInfoCache[$Entity].EntityInfo } elseif (-not ($UserDefinedFields.IsPresent)) { Write-Debug ('{0}: Returning fieldinfo for entity {1} from cache' -F $MyInvocation.MyCommand.Name, $Entity) $result = $script:FieldInfoCache[$Entity].FieldInfo } } # ReferencingEntity elseIf ($PSCmdlet.ParameterSetName -eq 'by_Reference') { $result = @() foreach ($object in $Script:FieldInfoCache.GetEnumerator()) { $isReferencing = $object.Value.FieldInfo.Where( { $_.ReferenceEntityType -eq $Entity }) # Include the fieldname. Or we will never be able to make this work foreach ($ref in $isReferencing) { $result += '{0}:{1}' -F $object.Name, $ref.Name } } } # For all other options else { if ($UpdateCache.IsPresent) { # Prepare parameters for @splatting $progressParameters = @{ Activity = 'All entities has been requested. Updating picklists.' Id = 9 } $entities = $script:FieldInfoCache.GetEnumerator().Where{ $_.Value.HasPicklist -or $_.Value.EntityInfo.HasUserDefinedfields } foreach ($object in $entities) { Write-Debug -Message ('{0}: Importing detailed information about Entity {1}' -F $MyInvocation.MyCommand.Name, $object.Key) # Calculating progress percentage and displaying it $index = $entities.IndexOf($object) + 1 $percentComplete = $index / $entities.Count * 100 $status = 'Entity {0}/{1} ({2:n0}%)' -F $index, $entities.Count, $percentComplete $currentOperation = "GetFieldInfo('{0}')" -F $object.Key Write-Progress -Status $status -PercentComplete $percentComplete -CurrentOperation $currentOperation @ProgressParameters # Is the Cache too old? I.E. older than 15 minutes? If ($object.Value.RetrievalTime -lt $cacheExpiry) { # Force a refresh by calling this function $cacheDirty = Update-AtwsEntity -Entity $Entity } } } # Cache has been loaded, has the right API version and everything is up to date # Return the correct set $result = switch ($PSCmdLet.ParameterSetName) { 'get_All' { $script:FieldInfoCache } 'get_Static' { $script:FieldInfoCache.GetEnumerator() | Where-Object { -not $_.Value.HasPickList } } 'get_Dynamic' { $script:FieldInfoCache.GetEnumerator() | Where-Object { $_.Value.HasPickList } } } } } end { if ($cacheDirty -and $Script:Atws.Configuration.UseDiskCache) { Export-AtwsDiskCache } Write-Debug ('{0}: End of function' -F $MyInvocation.MyCommand.Name) return $result } } |