functions/Export-PackageUpdateInfo.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
function Export-PackageUpdateInfo {
    <#
    .SYNOPSIS
        Export PackageUpdateInfo to a data file
 
    .DESCRIPTION
        Export PackageUpdateInfo to a data file
 
    .PARAMETER InputObject
        The PackageUpdateInfo from Get-PackageUpdateInfo function.
 
    .PARAMETER Path
        The filepath where to export the infos.
        Please specify a file as path.
 
        Default path value is:
        Linux: "$HOME/.local/share/powershell/PackageUpdateInfo/PackageUpdateInfo_$($PSEdition)_$($PSVersionTable.PSVersion.Major).xml")
        Windows: "$HOME\AppData\Local\Microsoft\Windows\PowerShell\PackageUpdateInfo_$($PSEdition)_$($PSVersionTable.PSVersion.Major).xml")
 
    .PARAMETER OutputFormat
        The output format for the data
        Available formats are "XML","JSON","CSV"
 
    .PARAMETER Encoding
        File Encoding for the file
 
    .PARAMETER Force
        If the directory for the file is not present, but a directory other then the default is specified,
        the function will try to create the diretory.
 
    .PARAMETER Append
        The output file will not be replaced. All information will be appended.
 
    .PARAMETER IncludeTimeStamp
        A timestamp will be added to the information records.
 
    .PARAMETER PassThru
        The exported objects will be parsed to the pipeline for further processing.
 
    .PARAMETER WhatIf
        If this switch is enabled, no actions are performed but informational messages will be displayed that explain what would happen if the command were to run.
 
    .PARAMETER Confirm
        If this switch is enabled, you will be prompted for confirmation before executing any operations that change state.
 
    .EXAMPLE
        PS C:\> Get-PackageUpdateInfo | Export-PackageUpdateInfo
 
        Example for usage of Export-PackageUpdateInfo
    #>

    [CmdletBinding( SupportsShouldProcess = $true,
        ConfirmImpact = 'Medium')]
    [Alias('epui')]
    [OutputType([PackageUpdate.Info])]
    Param (
        [Parameter(Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [PackageUpdate.Info[]]
        $InputObject,

        [Parameter(Position = 0)]
        [Alias("FullName", "FilePath")]
        [String]
        $Path,

        [ValidateSet("XML", "JSON", "CSV")]
        [Alias("Format")]
        [String]
        $OutputFormat = "XML",

        [ValidateSet("default", "utf7", "utf8", "utf32", "unicode", "ascii", "string", "oem", "bigendianunicode")]
        [String]
        $Encoding = "default",

        [switch]
        $Force,

        [switch]
        $Append,

        [switch]
        $IncludeTimeStamp,

        [switch]
        $PassThru
    )

    begin {
        # Set path variable to default value, when not specified
        if (-not $path) {
            if ($IsLinux) {
                $path = (Join-Path $HOME ".local/share/powershell/PackageUpdateInfo/PackageUpdateInfo_$($PSEdition)_$($PSVersionTable.PSVersion.Major).xml")
            } else {
                $path = (Join-Path $HOME "AppData\Local\Microsoft\Windows\PowerShell\PackageUpdateInfo_$($PSEdition)_$($PSVersionTable.PSVersion.Major).xml")
            }
        }

        # If file is specified as path
        if (Test-Path -Path $Path -PathType Leaf -IsValid) {
            # If file is present, resolve the path
            if (Test-Path -Path $Path -PathType Leaf) {
                $outputPath = Resolve-Path -Path $Path
            } else {
                # If Force switch is specified and the path does not exists
                if ($Force -and (-not (Resolve-Path -Path (Split-Path $Path -ErrorAction SilentlyContinue))) ) {
                    $null = New-Item -ItemType Directory -Path (Split-Path $Path) -ErrorAction Stop
                }
                # Try to create the file and resolve the path
                $outputPath = New-Item -ItemType File -Path $Path -ErrorAction Stop
                $outputPath = Resolve-Path -Path $outputPath
            }
        } elseif (Test-Path -Path $Path -PathType Container) {
            # If directory is specified as path
            Write-Error -Message "Specified Path is a directory. Please specify an file." -ErrorAction Stop
        } else {
            Write-Error -Message "Specified Path is an invalid directory. Please specify an valid file as output path." -ErrorAction Stop
        }

        $output = @()
    }

    process {
        if ($IncludeTimeStamp) {
            $InputObject | Add-Member -MemberType NoteProperty -Name TimeStamp -Value (Get-Date -Format s) -Force
        }

        if ($OutputFormat -in "JSON", "CSV") {
            $output += foreach ($object in $InputObject) {
                $hash = [ordered]@{
                    Name             = $object.Name
                    Repository       = $object.Repository
                    VersionInstalled = $object.VersionInstalled.ToString()
                    VersionOnline    = $object.VersionOnline.ToString()
                    NeedUpdate       = $object.NeedUpdate
                    Path             = $object.Path
                    ProjectUri       = $object.ProjectUri
                    IconUri          = $object.IconUri
                    ReleaseNotes     = $object.ReleaseNotes
                    Author           = $object.Author
                    PublishedDate    = ($object.PublishedDate | Get-Date -Format "yyyy-MM-dd HH:mm:ss")
                    Description      = $object.Description
                }
                if ($IncludeTimeStamp) {
                    $hash.add("TimeStamp", $object.TimeStamp)
                }
                New-Object -TypeName psobject -Property $hash
            }
        } else {
            $output += $InputObject
        }
    }

    end {
        if ($output) {
            if ($pscmdlet.ShouldProcess($outputPath, "Export PackageUpdateInfo")) {
                $outFileParams = @{
                    Encoding = $Encoding
                }
                if ($Append -and $OutputFormat -notlike "XML") { $outFileParams.Add("Append", $true) }

                if ($OutputFormat -in "JSON") {
                    $outFileParams.Add("FilePath", $outputPath.Path)
                    $output | ConvertTo-Json | Out-File @outFileParams
                } elseif ($OutputFormat -in "CSV") {
                    $outFileParams.Add("Path", $outputPath.Path)
                    $outFileParams.Add("Delimiter", ';')
                    $outFileParams.Add("NoTypeInformation", $true)
                    $output | Export-Csv @outFileParams
                } else {
                    $Exportdata = if ($Append -and ((Get-ChildItem -Path $outputPath.Path).Length -gt 0) ) { Import-Clixml -Path $outputPath.Path -ErrorAction SilentlyContinue } else { @() }
                    $Exportdata += $output
                    $Exportdata | Export-Clixml -Path $outputPath.Path -Encoding $Encoding
                }
            }

            if ($PassThru) {
                $output | ForEach-Object { [PackageUpdate.Info]$_ }
            }
        } else {
            Write-Verbose -Message "No data were processed, nothing to output."
            "" | Out-File $outputPath.Path -Encoding $Encoding
        }

    }
}