Private/Set-AtwsData.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 Set-AtwsData { <# .SYNOPSIS This function updates one or more Autotask entities with new or modified properties. .DESCRIPTION This function updates one or more Autotask entities with new or modified properties .INPUTS Autotask.Entity[]. One or more Autotask entities to update .OUTPUTS Autotask.Entity[]. The updated entities are re-downloaded from the API. .EXAMPLE Set-AtwsData -Entity $Entity Passes all Autotask entities in $Entity to the Autotask webservices API .NOTES NAME: Set-AtwsData .LINK Get-AtwsData New-AtwsData Remove-AtwsData #> [cmdletbinding( SupportsShouldProcess = $True, ConfirmImpact = 'Medium' )] [OutputType([PSObject[]])] param ( [Parameter( Mandatory = $True, ValueFromPipeline = $True )] [ValidateNotNullOrEmpty()] [PSObject[]] $Entity, [ValidateRange(0,100)] [Int] $ErrorLimit = 10 ) Begin { # Enable modern -Debug behavior If ($PSCmdlet.MyInvocation.BoundParameters['Debug'].IsPresent) { $DebugPreference = 'Continue' } Write-Debug ('{0}: Begin of function' -F $MyInvocation.MyCommand.Name) If (-not($Script:Atws.Url)) { Throw [ApplicationException] 'Not connected to Autotask WebAPI. Re-import module with valid credentials.' } $ErrorCount = 0 } Process { Write-Verbose ('{0}: Updating Autotask {1} with id {2}' -F $MyInvocation.MyCommand.Name, $Entity[0].GetType().Name, $($Entity.id -join ', ')) $Caption = 'Set-Atws{0}' -F $Entity[0].GetType().Name $VerboseDescrition = '{0}: About to modify {1} {2}(s). This action cannot be undone.' -F $Caption, $Entity.Count, $Entity[0].GetType().name $VerboseWarning = '{0}: About to modify {1} {2}(s). This action cannot be undone. Do you want to continue?' -F $Caption, $Entity.Count, $Entity[0].GetType().Name If ($PSCmdlet.ShouldProcess($VerboseDescrition, $VerboseWarning, $Caption)) { # update() function can take up to 200 objects at a time For ($i = 0; $i -lt $Entity.count; $i += 200) { $j = $i + 199 If ($j -ge $Entity.count) { $j = $Entity.count - 1 } Write-Debug -Message ('{0}: Creating chunk from index {1} to index {2}' -F $MyInvocation.MyCommand.Name, $i, $j) [Collections.ArrayList]$WorkingSet = $Entity[$i .. $j] # First try $Result = $atws.update($WorkingSet) # If we have errors, try to exclude objects errors If ($Result.Errors.Count -gt 0) { Do { $Errors = @() For ($t = 0; $t -lt $Result.Errors.Count; $t += 2) { # Count the errors, we have a limit $ErrorCount++ # First line is the error message $Message = $Result.Errors[$t].Message If ($Result.Errors.Count -gt $t) { # Next line may include the element index, first element = 1 If ($Result.Errors[$t + 1].Message -match '\[(\d+)\]') { [int]$Index = $Matches[1] } Else { $Index = 1 } } # Powershell arrays has first element = 0 $Index-- # Get the element $Element = $WorkingSet[$Index] # Remove Element from Workingset $Errors += $Element # Notify caller of skipped element Write-Warning ('Element with index {0} of type {1} with Id {2} was skipped because {3}' -F $Entity.IndexOf($Element), $Element.GetType().Name, $Element.id, $Message) } Foreach ($Element in $Errors) { $WorkingSet.Remove($Element) } # Try updating a second time $Result = $atws.update($WorkingSet) } Until ($Result.Errors.Count -eq 0 -or $WorkingSet.Count -eq 0 -or $ErrorCount -ge $ErrorLimit) } # We have tried multiple times! Still errors? If ($Result.Errors.Count -eq 0) { # The API documentation explicitly states that you can only use the objects returned # by the .create() function to get the new objects ID. # so to return objects with accurately represents what has been created we have to # get them again by id # But not all objects support queries, for instance service adjustments $EntityInfo = Get-AtwsFieldInfo -Entity $Result.EntityResultType -EntityInfo If ($Result.EntityResults.Count -gt 0 -and $EntityInfo.CanQuery) { $NewObjectFilter = 'id -eq {0}' -F ($Result.EntityResults.Id -join ' -or id -eq ') $EndResult += Get-AtwsData -Entity $Result.EntityResultType -Filter $NewObjectFilter } } Else { Write-Error ($Result.Errors.Message -join "`n") Break } } } } End { If ($EndResult.count -gt 0) { Write-Debug ('{0}: End of function, returning {1} updated {2}(s)' -F $MyInvocation.MyCommand.Name, $Result.count, $Result[0].GetType().Name) Return $EndResult } Else { Write-Debug ('{0}: End of function, no objects to return.' -F $MyInvocation.MyCommand.Name, $Result.count) } } } |