Private/Device/Export-PanDeviceDb.ps1
function Export-PanDeviceDb { <# .SYNOPSIS PowerPAN private helper function to serialize and store PanDevice objects from PanDeviceDb to JSON. .DESCRIPTION PowerPAN private helper function to serialize and store PanDevice objects from PanDeviceDb to JSON. .NOTES .INPUTS .OUTPUTS .EXAMPLE #> [CmdletBinding()] param( ) Begin { # Propagate -Debug and -Verbose to this module function, https://tinyurl.com/y5dcbb34 if($PSBoundParameters.Debug) { $DebugPreference = 'Continue' } if($PSBoundParameters.Verbose) { $VerbosePreference = 'Continue' } # Announce Write-Debug ($MyInvocation.MyCommand.Name + ':') # Detect PowerShell Core automatic variables for MacOS and Linux if($IsMacOS -or $IsLinux) { $StoredDirectoryPath = $Env:HOME + '/.powerpan' $StoredJsonPath = $Env:HOME + '/.powerpan/device.json' } # Otherwise Windows PowerShell and PowerShell Core on Windows will both have same environment variable name else { $StoredDirectoryPath = $Env:USERPROFILE + '/.powerpan' $StoredJsonPath = $Env:USERPROFILE + '/.powerpan/device.json' } if(-not (Test-Path -Path $StoredDirectoryPath -PathType Container)) { Write-Debug ($MyInvocation.MyCommand.Name + ': ' + "$StoredDirectoryPath directory does not exist. Creating.") New-Item -Path $StoredDirectoryPath -ItemType Directory -Force | Out-Null } if(-not (Test-Path -Path $StoredJsonPath -PathType Leaf)) { Write-Debug ($MyInvocation.MyCommand.Name + ': ' + "$StoredJsonPath file does not exist. Creating.") Set-Content -Path $StoredJsonPath -Value $null -Force | Out-Null } # Aggregate devices through each iteration of Process block (and foreach within Process block itself) # .NET Generic List provides under-the-hood efficiency during add/remove compared to PowerShell native arrays or ArrayList. # List type is [PSObject] -- objects are changed from [PanDevice] to custom objects on the way out to export. $StoredDeviceAgg = [System.Collections.Generic.List[PSObject]]@() } # Begin Block Process { foreach ($DeviceCur in $Global:PanDeviceDb) { Write-Debug ($MyInvocation.MyCommand.Name + ': ' + "Device Name: $($DeviceCur.Name)") # Build a custom hash table suitable for serializing to JSON in PowerShell End block # *Cannot* serialize the raw [PanDevice] object direclty. Needs some massaging to get # the Credential.Password [SecureString] and Key [SecureString] to their encrypted serializable/storable form. $CustomObj = @{ 'Name' = $DeviceCur.Name; 'Username' = $DeviceCur.Credential.UserName; 'ValidateCertificate' = $DeviceCur.ValidateCertificate; 'Protocol' = $DeviceCur.Protocol; 'Port' = $DeviceCur.Port } # End hash table # Add the Credential.Password if([String]::IsNullOrEmpty($DeviceCur.Credential.Password)) { $CustomObj.Add('Password', $null) } else { # Encrypted serialized/storable form $CustomObj.Add('Password', $($DeviceCur.Credential.Password | ConvertFrom-SecureString)) } # Add the Key if([String]::IsNullOrEmpty($DeviceCur.Key)) { $CustomObj.Add('Key', $null) } else { # Encrypted serialized/storable form $CustomObj.Add('Key', $($DeviceCur.Key | ConvertFrom-SecureString)) } # Add the Label if([String]::IsNullOrEmpty($DeviceCur.Label)) { $CustomObj.Add('Label', $null) } else { # Exclude "session-" labels $CustomObj.Add('Label', $($DeviceCur.Label | Where-Object {$_ -notmatch '^session-'} ) ) } # Add the current $CustomObj to the array of $StoredDeviceAgg to be written to storage $StoredDeviceAgg.Add($CustomObj) } } # Process Block End { if(-not [String]::IsNullorEmpty($StoredDeviceAgg) ) { Write-Debug ($MyInvocation.MyCommand.Name + ': ' + "Storing $($StoredDeviceAgg.Count) device$(if($StoredDeviceAgg.Count -ne 1){'s'}) to $StoredJsonPath") # Serialize and write to storage ConvertTo-Json -InputObject $StoredDeviceAgg | Set-Content -Path $StoredJsonPath -Force | Out-Null } } # End Block } # Function |