Public/Get-AtwsFieldInfo.ps1
<#
.COPYRIGHT Copyright (c) Office Center Hønefoss AS. All rights reserved. Licensed under the MIT license. See https://github.com/officecenter/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.' } # Has cache been loaded? If (-not($script:Cache)) { # 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 $VerboseDescrition = '{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($VerboseDescrition, $VerboseWarning, $Caption)) { Write-Verbose -Message ("{0}: Calling .GetFieldInfo('{1}')" -F $MyInvocation.MyCommand.Name, $Entity) Try { $Result = $Script:atws.GetFieldInfo($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 $CacheDirty = $True } If ($script:FieldInfoCache[$Entity].EntityInfo.HasUserDefinedFields) { $Caption = $MyInvocation.MyCommand.Name $VerboseDescrition = '{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($VerboseDescrition, $VerboseWarning, $Caption)) { $UDF = $Script:atws.GetUDFInfo($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:UseDiskCache) { # If not called during module load, give this warning If ($PSCmdLet.MyInvocation.ScriptName -notlike '*.psm1') { Write-Warning ('One or more entities has been modified in Autotask! Re-import module with -Force to refresh.') } Export-AtwsDiskCache } Write-Debug ('{0}: End of function' -F $MyInvocation.MyCommand.Name) Return $Result } } |