Private/Import-AtwsDiskCache.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 Import-AtwsDiskCache { <# .SYNOPSIS This function reads the cachefile into memory. .DESCRIPTION This function determines the correct paths to cache files and creates any missing path if necessary. If there isn't any cache for the current Autotask tenant available this function creates it, starting with a supplied cache file from the module. .INPUTS Nothing. .OUTPUTS Nothing, but the cache property of the SOAP Client object is filled. .EXAMPLE Import-AtwsDiskCache Loads the cache from disk .NOTES NAME: Import-AtwsDiskCache .LINK Export-AtwsDiskCache #> [CmdLetBinding()] Param() begin { Write-Verbose -Message ('{0}: trying to determine correct location for dynamic module cache.' -F $MyInvocation.MyCommand.Name) # Get the current module name $myModule = (Get-Command -Name $MyInvocation.MyCommand.Name).Module $cacheFile = 'AutotaskFieldInfoCache.xml' # Use join-path to be platform agnostic on slashes in paths $centralCache = Join-Path $(Join-Path $myModule.ModuleBase 'Private') $cacheFile Write-Verbose -Message ('{0}: Module cache location is {1}' -F $MyInvocation.MyCommand.Name, $centralCache) # On Windows we store the cache in the WindowsPowerhell folder in My documents # On macOS and Linux we use a dot-folder in the users $HOME folder as is customary if ([Runtime.InteropServices.RuntimeInformation]::IsOSPlatform([Runtime.InteropServices.OSPlatform]::Windows)) { $PersonalCacheDir = Join-Path $([environment]::GetFolderPath('MyDocuments')) 'WindowsPowershell\Cache' } else { $PersonalCacheDir = Join-Path $([environment]::GetFolderPath('MyDocuments')) '.config\powershell\atwsCache' } # Add tenant id to path $PersonalCacheDir = Join-Path $PersonalCacheDir $Script:Atws.CI # Add module version to cache path (join-path only takes a single childpath parameter) $PersonalCacheDir = Join-Path $PersonalCacheDir $My.ModuleVersion.ToString() # Save the cache path to the module information $Script:Atws.DynamicCache = $PersonalCacheDir $PersonalCache = Join-Path $PersonalCacheDir $CacheFile Write-Verbose -Message ('{0}: Personal cache location is {1}.' -F $MyInvocation.MyCommand.Name, $PersonalCache) } process { # Do not check for existence of personal cache if asked to load module without it # This function should not be called from a context where this is necessary, but # better be on the safe side if ($Script:Atws.Configuration.UseDiskCache) { if (-not (Test-Path $personalCache)) { Write-Verbose -Message ('{0}: There is no personal cache. Creating from central location.' -F $MyInvocation.MyCommand.Name) # Create Personalcache directory if it doesn't exist if (-not (Test-Path $personalCacheDir)) { New-Item -Path $personalCacheDir -ItemType Directory } # Copy the cache Copy-Item -Path $centralCache -Destination $personalCache -Force } # This should work now! if (Test-Path $personalCache) { Write-Verbose -Message ('{0}: Reading cache from disk.' -F $MyInvocation.MyCommand.Name) $Script:Atws.Cache = Import-Clixml -Path $personalCache } else { Throw [System.Exception] "Coult not create a cache file." } # Nested testing to make sure the structure is OK if ($Script:Atws.Cache -is [Hashtable]) { if ($Script:Atws.Cache.ContainsKey('00')) { if ($Script:Atws.Cache['00'] -is [PSCustomObject]) { if ([bool]($Script:Atws.Cache['00'].PSobject.Properties.name -match "FieldInfoCache")) { if (-not ($Script:Atws.Cache['00'].FieldInfoCache.Count -gt 0)) { Write-Warning ('{0}: Personal disk cache is broken! Deleting cache and trying again!' -F $MyInvocation.MyCommand.Name) # Delete ceache $null = Remove-Item -Path $personalCache -Force -ErrorAction SilentlyContinue # Restart import Import-AtwsDiskCache # Do not process rest of script return } } } } } } else { Write-Verbose -Message ('{0}: Running with -NoDiskCache. Initializing memory-only cache with data supplied with module ({1}).' -F $MyInvocation.MyCommand.Name, $centralCache) # Initialize memory only cache from module directory $Script:Atws.Cache = Import-Clixml -Path $centralCache } # We must be connected to know the customer identity number if ($Script:Atws.CI) { # If the current connection is for a new Autotask tenant, copy the blank # cache from the included pre-cache if (-not ($Script:Atws.Cache.ContainsKey($Script:Atws.CI))) { Write-Debug -Message ('{0}: Cache does not contain information about Autotask tenant {1}. Initializing.' -F $MyInvocation.MyCommand.Name, $Script:Atws.CI ) # Create a cache object to store API version along with the cache $Script:Atws.Cache[$Script:Atws.CI] = New-Object -TypeName PSObject -Property @{ ApiVersion = $Script:Atws.Cache['00'].ApiVersion ModuleVersion = [Version]$My.ModuleVersion } # Use Add-Member on the Hashtable, or the propertyvalue will be set to typename only # Copy the hashtable to a new object. We do NOT want a referenced copy! $newHashTable = Copy-PSObject -InputObject $Script:Atws.Cache['00'].FieldInfoCache Add-Member -InputObject $Script:Atws.Cache[$Script:Atws.CI] -MemberType NoteProperty -Name FieldInfoCache -Value $newHashTable } # Initialize the $Script:FieldInfoCache shorthand $Script:FieldInfoCache = $Script:Atws.Cache[$Script:Atws.CI].FieldInfoCache # If the API version has been changed at the Autotask end we unfortunately have to reload all # entities from scratch $currentApiVersion = $Script:Atws.GetWsdlVersion($Script:Atws.IntegrationsValue) if ($Script:Atws.Cache[$Script:Atws.CI].ApiVersion -ne $currentApiVersion -or [Version]$My.ModuleVersion -ne $Script:Atws.Cache[$Script:Atws.CI].ModuleVersion) { # Write-Warning to inform user that an update of static functions is due if ($Script:Atws.Cache[$Script:Atws.CI].ApiVersion -ne $currentApiVersion) { Write-Warning ('{0}: API version has been updated. You need to run "Update-AtwsFunctions -FunctionSet static" with writepermissions to the module directory or update the module.' -F $MyInvocation.MyCommand.Name) } # Call the import-everything function Update-AtwsDiskCache } } else { Write-Debug -Message ('{0}: No connection to Autotask or running with -NoDiskCache. Loading using module supplied data for Get-AtwsFieldInfo.' -F $MyInvocation.MyCommand.Name ) # Initialize the $Script:FieldInfoCache shorthand for base entity info $Script:FieldInfoCache = $Script:Atws.Cache['00'].FieldInfoCache } } end { Write-Verbose ('{0}: End of function' -F $MyInvocation.MyCommand.Name) } } |