SPPCmdlets.psm1
Function Add-SPPBundle { <# .SYNOPSIS Add SPP bundle. .DESCRIPTION The Add-SPPBundle command adds a Service Pack for ProLiant bundle. .PARAMETER Directory Bundle directory. .PARAMETER File Bundle file. .PARAMETER Manifest Bundle manifest directory. .PARAMETER Packages Bundle packages directory. .EXAMPLE Add-SPPBundle E:\ Add SPP bundle contained in the specified directory. Use default locations for the bundle file, manifest and packages directories. .EXAMPLE Add-SPPBundle -File E:\packages\bp003135.xml -Manifest E:\manifest -Packages E:\packages Add SPP bundle using the specified file. Use the specified locations for the manifest and packages directories. .INPUTS None .OUTPUTS None #> [CmdletBinding()] Param ( [Parameter(Mandatory=$true, HelpMessage="Bundle directory", Position=0, ParameterSetName="Directory")] [ValidateNotNullOrEmpty()] [String] $Directory, [Parameter(Mandatory=$true, HelpMessage="Bundle file", ParameterSetName="File")] [ValidateNotNullOrEmpty()] [String] $File, [Parameter(Mandatory=$true, HelpMessage="Bundle manifest folder", ParameterSetName="File")] [ValidateNotNullOrEmpty()] [String] $Manifest, [Parameter(Mandatory=$true, HelpMessage="Bundle packages folder", ParameterSetName="File")] [ValidateNotNullOrEmpty()] [String] $Packages ) # Set bundles if (!$Script:Bundles) { $Script:Bundles = @{} } # Check bundle directory if ($Directory) { if (Test-Path -PathType Leaf -Path (Join-Path $Directory "packages\bp*.xml")) { # Set bundle file $BundleFile = (Resolve-Path -Path (Join-Path $Directory "packages\bp*.xml") | Select-Object -First 1).Path.ToLower() # Check bundle added if ($Script:Bundles.ContainsKey($BundleFile)) { Throw "Bundle '$($BundleFile)' already added" } # Set manifest directory $Manifest = Join-Path $Directory "manifest" # Check manifest directory if (Test-Path -PathType Container -Path $Manifest) { # Set manifest directory full path $ManifestDirectory = (Resolve-Path -Path $Manifest).Path } else { Throw "Manifest directory '$Manifest' not found" } # Set packages directory $Packages = Join-Path $Directory "packages" # Check packages directory if (Test-Path -PathType Container -Path $Packages) { # Set packages directory full path $PackagesDirectory = (Resolve-Path -Path $Packages).Path } else { Throw "Packages directory '$Packages' not found" } } elseif (Test-Path -PathType Leaf -Path (Join-Path $Directory "hp\swpackages\bp*.xml")) { # Set bundle file $BundleFile = (Resolve-Path -Path (Join-Path $Directory "hp\swpackages\bp*.xml") | Select-Object -First 1).Path.ToLower() # Check bundle added if ($Script:Bundles.ContainsKey($BundleFile)) { Throw "Bundle '$($BundleFile)' already added" } # Set manifest directory $Manifest = Join-Path $Directory "hp_manifest" # Check manifest directory if (Test-Path -PathType Container -Path $Manifest) { # Set manifest directory full path $ManifestDirectory = (Resolve-Path -Path $Manifest).Path } else { Throw "Manifest directory '$Manifest' not found" } # Set packages directory $Packages = Join-Path $Directory "hp\swpackages" # Check packages directory if (Test-Path -PathType Container -Path $Packages) { # Set packages directory full path $PackagesDirectory = (Resolve-Path -Path $Packages).Path } else { Throw "Packages directory '$Packages' not found" } } else { Throw "Bundle directory '$Directory' not valid" } } # Check bundle file if ($File) { # Check bundle file if (Test-Path -PathType Leaf -Path $File) { # Set full bundle file path $BundleFile = (Resolve-Path -Path $File).Path.ToLower() } else { Throw "Bundle file '$File' not found" } # Check bundle added if ($Script:Bundles.ContainsKey($BundleFile)) { Throw "Bundle '$($BundleFile)' already added" } # Check manifest directory if (Test-Path -PathType Container -Path $Manifest) { # Set full manifest directory path $ManifestDirectory = (Resolve-Path -Path $Manifest).Path } else { Throw "Manifest directory '$Manifest' not found" } # Check packages directory if (Test-Path -PathType Container -Path $Packages) { # Set full packages directory path $PackagesDirectory = (Resolve-Path -Path $Packages).Path } else { Throw "Packages directory '$Packages' not found" } } # Check system file $SystemFile = Join-Path $ManifestDirectory "system.xml" if (!(Test-Path -PathType Leaf -Path $SystemFile)) { Throw "Manifest file '$SystemFile' not found" } # Check operating system file $OperatingSystemFile = Join-Path $ManifestDirectory "os.xml" if (!(Test-Path -PathType Leaf -Path $OperatingSystemFile)) { Throw "Manifest file '$OperatingSystemFile' not found" } # Check category file $CategoryFile = Join-Path $ManifestDirectory "category.xml" if (!(Test-Path -PathType Leaf -Path $CategoryFile)) { Throw "Manifest file '$CategoryFile' not found" } # Check device file $DeviceFile = Join-Path $ManifestDirectory "device.xml" if (!(Test-Path -PathType Leaf -Path $DeviceFile)) { Throw "Manifest file '$DeviceFile' not found" } # Check type file $TypeFile = Join-Path $ManifestDirectory "type.xml" if (!(Test-Path -PathType Leaf -Path $TypeFile)) { Throw "Manifest file '$TypeFile' not found" } # Check component file $ComponentFile = Join-Path $ManifestDirectory "meta.xml" if (!(Test-Path -PathType Leaf -Path $ComponentFile)) { Throw "Manifest file '$ComponentFile' not found" } # Check revision history file $RevisionHistoryFile = Join-Path $ManifestDirectory "revision_history.xml" if (!(Test-Path -PathType Leaf -Path $RevisionHistoryFile)) { Throw "Manifest file '$RevisionHistoryFile' not found" } # Display progress Write-Progress -Activity "Adding bundle $($BundleFile) ..." -Status "Reading bundle" -PercentComplete 0 # Read bundle xml $BundleXML = Select-Xml -XPath "/cpq_bundle" -Path $BundleFile # Create bundle object $Bundle = New-Object PSObject -Property ([ordered]@{ File = $BundleFile Name = $BundleXML.Node.SelectSingleNode("name/name_xlate[@lang='en']").InnerText Description = $BundleXML.Node.SelectSingleNode("description/description_xlate[@lang='en']").InnerText Tag = $BundleXML.Node.tag ProductID = $BundleXML.Node.id.product VersionID = $BundleXML.Node.id.version Category = $BundleXML.Node.SelectSingleNode("category/category_xlate[@lang='en']").InnerText Version = $BundleXML.Node.version.value Revision = $BundleXML.Node.version.revision FullVersion = $BundleXML.Node.version.value + $BundleXML.Node.version.revision TypeOfChange = @{'0'='Optional';'1'='Recommended';'2'='Critical'}[$BundleXML.Node.version.type_of_change] ReleaseYear = $BundleXML.Node.release_date.year ReleaseMonth = $BundleXML.Node.release_date.month ReleaseDay = $BundleXML.Node.release_date.day ReleaseHour = $BundleXML.Node.release_date.hour ReleaseMinute = $BundleXML.Node.release_date.minute ReleaseSecond = $BundleXML.Node.release_date.second Divisions = @() OperatingSystems = @() PrerequisiteNotes = @() InstallationNotes = @() AvailabilityNotes = @() DocumentationNotes = @() RevisionHistory = @() Contents = @() Components = @() }) # Set bundle object type $Bundle.PSObject.TypeNames.Insert(0,'SPPBundle') # Add divisions foreach ($node in Select-Xml -XPath "divisions/division/division_xlate[@lang='en']" -Xml $BundleXML.Node) { $Bundle.Divisions += $node.Node.InnerText } # Add operating systems foreach ($node in Select-Xml -XPath "operating_systems/operating_system/operating_system_xlate" -Xml $BundleXML.Node) { $Bundle.OperatingSystems += $node.Node.InnerText } # Add prerequisite notes foreach ($node in Select-Xml -XPath "prerequisite_notes/prerequisite_notes_xlate[@lang='en']/prerequisite_notes_xlate_part" -Xml $BundleXML.Node) { $Bundle.PrerequisiteNotes += $node.Node.InnerText.Replace(" ", " ") } # Add installation notes foreach ($node in Select-Xml -XPath "installation_notes/installation_notes_xlate[@lang='en']/installation_notes_xlate_part" -Xml $BundleXML.Node) { $Bundle.InstallationNotes += $node.Node.InnerText.Replace(" ", " ") } # Add availability notes foreach ($node in Select-Xml -XPath "availability_notes/availability_notes_xlate[@lang='en']/availability_notes_xlate_part" -Xml $BundleXML.Node) { $Bundle.AvailabilityNotes += $node.Node.InnerText.Replace(" ", " ") } # Add documentation notes foreach ($node in Select-Xml -XPath "documentation_notes/documentation_notes_xlate[@lang='en']/documentation_notes_xlate_part" -Xml $BundleXML.Node) { $Bundle.DocumentationNotes += $node.Node.InnerText.Replace(" ", " ") } # Add revision history foreach ($node in Select-Xml -XPath "revision_history/revision/version[@value]/parent::revision" -Xml $BundleXML.Node) { # Create revision $Revision = New-Object PSObject -Property ([ordered]@{ Version = $node.Node.version.value Revision = $node.Node.version.revision FullVersion = $node.Node.version.value + $node.Node.version.revision TypeOfChange = @{'0'='Optional';'1'='Recommended';'2'='Critical'}[$node.Node.version.type_of_change] Enhancements = @() Fixes = @() }) # Add enhancements foreach ($enhancement in Select-Xml -XPath "revision_enhancements_xlate[@lang='en']/revision_enhancements_xlate_part" -Xml $node.Node) { if ($enhancement.Node.InnerText) { $Revision.Enhancements += $enhancement.Node.InnerText.Replace(" ", " ") } } # Add fixes foreach ($fix in Select-Xml -XPath "revision_fixes_xlate[@lang='en']/revision_fixes_xlate_part" -Xml $node.Node) { if ($fix.Node.InnerText) { $Revision.fixes += $fix.Node.InnerText.Replace(" ", " ") } } # Add revision $Bundle.RevisionHistory += $Revision } # Add contents foreach ($node in Select-Xml -XPath "contents/package" -Xml $BundleXML.Node) { $Bundle.Contents += $node.Node.InnerText } # Add bundle $Script:Bundles.Add($Bundle.File, $Bundle) # Display progress Write-Progress -Activity "Adding bundle $($BundleFile) ..." -Status "Reading systems" -PercentComplete 10 # Set systems if (!$Script:Systems) { $Script:Systems = @{} } # Read system xml $SystemXML = Select-Xml -XPath "//systems/system" -Path $SystemFile # Add systems foreach ($node in $SystemXML) { # Read system key $SystemKey = $node.Node.id # Check system key if ($Script:Systems.ContainsKey($SystemKey)) { # Select system $System = $Script:Systems[$SystemKey] } else { # Create system object $System = New-Object PSObject -Property ([ordered]@{ Key = $node.Node.id Name = $node.Node.SelectSingleNode("name/name_xlate[@lang='en']").InnerText SystemID = $node.Node.systemid FirmwareID = $node.Node.firmwareid Components = @{} }) # Set system object type $System.PSObject.TypeNames.Insert(0,'SPPSystem') $System.PSObject.TypeNames.Insert(1,'SPPFilter') # Add system $Script:Systems.Add($System.Key, $System) } # Add bundle $System.Components.Add($BundleFile, @{}) # Add components foreach ($component in Select-Xml -XPath "product_version" -Xml $node.Node) { # Read component key $ComponentKey = $component.Node.id.product + "-" + $component.Node.id.version # Add component if (!$System.Components[$BundleFile].ContainsKey($ComponentKey)) { $System.Components[$BundleFile].Add($ComponentKey, $null) } } } # Display progress Write-Progress -Activity "Adding bundle $($BundleFile) ..." -Status "Reading operating systems" -PercentComplete 20 # Set operating systems if (!$Script:OperatingSystems) { $Script:OperatingSystems = @{} } # Read operating system xml $OperatingSystemXML = Select-Xml -XPath "//operating_systems/operating_system" -Path $OperatingSystemFile # Add operating systems foreach ($node in $OperatingSystemXML) { # Read operating system key $OperatingSystemKey = $node.Node.id # Check operating system key if ($Script:OperatingSystems.ContainsKey($OperatingSystemKey)) { # Select operating system $OperatingSystem = $Script:OperatingSystems[$OperatingSystemKey] } else { # Create operating system object $OperatingSystem = New-Object PSObject -Property ([ordered]@{ Key = $node.Node.id Name = $node.Node.SelectSingleNode("name/name_xlate[@lang='en']").InnerText Platform = $node.Node.supported_operating_system.platform Major = $node.Node.supported_operating_system.major Minor = $node.Node.supported_operating_system.minor Components = @{} }) # Set operating system object type $OperatingSystem.PSObject.TypeNames.Insert(0,'SPPOperatingSystem') $OperatingSystem.PSObject.TypeNames.Insert(1,'SPPFilter') # Add operating system $Script:OperatingSystems.Add($OperatingSystem.Key, $OperatingSystem) } # Add bundle $OperatingSystem.Components.Add($BundleFile, @{}) # Add components foreach ($component in Select-Xml -XPath "product_version" -Xml $node.Node) { # Read component key $ComponentKey = $component.Node.id.product + "-" + $component.Node.id.version # Add component if (!$OperatingSystem.Components[$BundleFile].ContainsKey($ComponentKey)) { $OperatingSystem.Components[$BundleFile].Add($ComponentKey, $null) } } } # Display progress Write-Progress -Activity "Adding bundle $($BundleFile) ..." -Status "Reading categories" -PercentComplete 30 # Set categories if (!$Script:Categories) { $Script:Categories = @{} } # Read category xml $CategoryXML = Select-Xml -XPath "//categories/category" -Path $CategoryFile # Add categories foreach ($node in $CategoryXML) { # Read category key $CategoryKey = $node.Node.id # Check category key if ($Script:Categories.ContainsKey($CategoryKey)) { # Select category $Category = $Script:Categories[$CategoryKey] } else { # Create category object $Category = New-Object PSObject -Property ([ordered]@{ Key = $node.Node.id Name = $node.Node.SelectSingleNode("name/name_xlate[@lang='en']").InnerText Components = @{} }) # Set category object type $Category.PSObject.TypeNames.Insert(0,'SPPCategory') $Category.PSObject.TypeNames.Insert(1,'SPPFilter') # Add category $Script:Categories.Add($Category.Key, $Category) } # Add bundle $Category.Components.Add($BundleFile, @{}) # Add components foreach ($component in Select-Xml -XPath "product_version" -Xml $node.Node) { # Read component key $ComponentKey = $component.Node.id.product + "-" + $component.Node.id.version # Add component if (!$Category.Components[$BundleFile].ContainsKey($ComponentKey)) { $Category.Components[$BundleFile].Add($ComponentKey, $null) } } } # Display progress Write-Progress -Activity "Adding bundle $($BundleFile) ..." -Status "Reading devices" -PercentComplete 40 # Set devices if (!$Script:Devices) { $Script:Devices = @{} } # Read device xml $DeviceXML = Select-Xml -XPath "//devices/device" -Path $DeviceFile # Add devices foreach ($node in $DeviceXML) { # Read device key $DeviceKey = $node.Node.id # Check device key if ($Script:Devices.ContainsKey($DeviceKey)) { # Select device $Device = $Script:Devices[$DeviceKey] } else { # Create device object $Device = New-Object PSObject -Property ([ordered]@{ Key = $node.Node.id Name = $node.Node.SelectSingleNode("name/name_xlate[@lang='en']").InnerText DeviceType = $node.Node.device_type DeviceIDString = $node.Node.deviceidstring Components = @{} }) # Set device object type $Device.PSObject.TypeNames.Insert(0,'SPPDevice') $Device.PSObject.TypeNames.Insert(1,'SPPFilter') # Add device $Script:Devices.Add($Device.Key, $Device) } # Add bundle $Device.Components.Add($BundleFile, @{}) # Add components foreach ($component in Select-Xml -XPath "product_version" -Xml $node.Node) { # Read component key $ComponentKey = $component.Node.id.product + "-" + $component.Node.id.version # Add component if (!$Device.Components[$BundleFile].ContainsKey($ComponentKey)) { $Device.Components[$BundleFile].Add($ComponentKey, $null) } } } # Display progress Write-Progress -Activity "Adding bundle $($BundleFile) ..." -Status "Reading types" -PercentComplete 50 # Set types if (!$Script:Types) { $Script:Types = @{} } # Read type xml $TypeXML = Select-Xml -XPath "//types/type" -Path $TypeFile # Add types foreach ($node in $TypeXML) { # Read type key $TypeKey = $node.Node.id # Check type key if ($Script:Types.ContainsKey($TypeKey)) { # Select type $Type = $Script:Types[$TypeKey] } else { # Create type object $Type = New-Object PSObject -Property ([ordered]@{ Key = $node.Node.id Name = $node.Node.id Components = @{} }) # Set type object type $Type.PSObject.TypeNames.Insert(0,'SPPType') $Type.PSObject.TypeNames.Insert(1,'SPPFilter') # Add type $Script:Types.Add($Type.Key, $Type) } # Add bundle $Type.Components.Add($BundleFile, @{}) # Add components foreach ($component in Select-Xml -XPath "product_version" -Xml $node.Node) { # Read component key $ComponentKey = $component.Node.id.product + "-" + $component.Node.id.version # Add component if (!$Type.Components[$BundleFile].ContainsKey($ComponentKey)) { $Type.Components[$BundleFile].Add($ComponentKey, $null) } } } # Display progress Write-Progress -Activity "Adding bundle $($BundleFile) ..." -Status "Reading revision history" -PercentComplete 60 # Set revision history $RevisionHistory = @{} # Read revision history xml $RevisionHistoryXML = Select-Xml -XPath "//revision_history/product_version" -Path $RevisionHistoryFile # Add components foreach ($component in $RevisionHistoryXML) { # Read component key $ComponentKey = $component.Node.id.product + "-" + $component.Node.id.version # Set revisions $Revisions = @() # Add revisions foreach ($node in Select-Xml -XPath "revision_history/revision/version[@value]/.." -Xml $component.Node) { # Create revision $Revision = New-Object PSObject -Property ([ordered]@{ Version = $node.Node.version.value Revision = $node.Node.version.revision FullVersion = $node.Node.version.value + $node.Node.version.revision TypeOfChange = @{'0'='Optional';'1'='Recommended';'2'='Critical'}[$node.Node.version.type_of_change] Enhancements = @() Fixes = @() }) # Add enhancements foreach ($enhancement in Select-Xml -XPath "revision_enhancements_xlate[@lang='en']/revision_enhancements_xlate_part" -Xml $node.Node) { if ($enhancement.Node.InnerText) { $Revision.Enhancements += $enhancement.Node.InnerText.Replace(" ", " ") } } # Add fixes foreach ($fix in Select-Xml -XPath "revision_fixes_xlate[@lang='en']/revision_fixes_xlate_part" -Xml $node.Node) { if ($fix.Node.InnerText) { $Revision.fixes += $fix.Node.InnerText.Replace(" ", " ") } } # Add revision $Revisions += $Revision } # Add revision history if (!$RevisionHistory.ContainsKey($ComponentKey)) { $RevisionHistory.Add($ComponentKey, $Revisions) } } # Display progress Write-Progress -Activity "Adding bundle $($BundleFile) ..." -Status "Reading components" -PercentComplete 80 # Read component xml $ComponentXML = Select-Xml -XPath "//product/product_version" -Path $ComponentFile # Add components foreach ($node in $ComponentXML) { # Read component key $ComponentKey = $node.Node.id.product + "-" + $node.Node.id.version # Create component object $Component = New-Object PSObject -Property ([ordered]@{ Key = $ComponentKey Bundle = $Bundle.Version BundleFile = $BundleFile Name = $node.Node.SelectSingleNode("name/name_xlate[@lang='en']").InnerText.Trim() ProductID = $node.Node.id.product VersionID = $node.Node.id.version Description = $node.Node.SelectSingleNode("description/description_xlate[@lang='en']").InnerText AltName = $node.Node.SelectSingleNode("alt_name/alt_name_xlate[@lang='en']").InnerText FileName = $node.Node.filename Version = $node.Node.version.value Revision = $node.Node.version.revision FullVersion = $node.Node.version.value + $node.Node.version.revision UpgradeRequirement = $node.Node.upgrade_requirement.value Different = $node.Node.different BuildNumber = $node.Node.build.number Type = $node.Node.type.id Category = $node.Node.SelectSingleNode("category/category_xlate[@lang='en']").InnerText Manufacturer = $node.Node.SelectSingleNode("manufacturer_name/manufacturer_name_xlate[@lang='en']").InnerText TypeOfChange = @{'0'='Optional';'1'='Recommended';'2'='Critical'}[$node.Node.version.type_of_change] ReleaseYear = $node.Node.release_date.year ReleaseMonth = $node.Node.release_date.month ReleaseDay = $node.Node.release_date.day ReleaseHour = $node.Node.release_date.hour ReleaseMinute = $node.Node.release_date.minute ReleaseSecond = $node.Node.release_date.second RequiredDiskSpaceKB = $node.Node.prerequisites.required_diskspace.size_kb OperatingSystems = @() Divisions = @() Files = @() PrerequisiteNotes = @() InstallationNotes = @() AvailabilityNotes = @() DocumentationNotes = @() RevisionHistory = @() }) # Set component object type $Component.PSObject.TypeNames.Insert(0,'SPPComponent') # Add operating systems foreach ($operatingsystem in Select-Xml -XPath "operating_systems/operating_system/operating_system_xlate" -Xml $node.Node) { $Component.OperatingSystems += $operatingsystem.Node.InnerText } # Add divisions foreach ($division in Select-Xml -XPath "divisions/division/division_xlate[@lang='en']" -Xml $node.Node) { $Component.Divisions += $division.Node.InnerText } # Add files foreach ($item in Select-Xml -XPath "files/file" -Xml $node.Node) { $Component.Files += New-Object PSObject -Property ([ordered]@{ Name = $item.Node.name FileUrl = Join-Path $PackagesDirectory $item.Node.name Size = $item.Node.size DateModified = $item.Node.date_modified Md5Sum = $item.Node.md5sum Sha1Sum = $item.Node.sha1sum }) } # Add prerequisite notes foreach ($item in Select-Xml -XPath "prerequisite_notes/prerequisite_notes_xlate[@lang='en']/prerequisite_notes_xlate_part" -Xml $node.Node) { $Component.PrerequisiteNotes += $item.Node.InnerText.Replace(" ", " ") } # Add installation notes foreach ($item in Select-Xml -XPath "installation_notes/installation_notes_xlate[@lang='en']/installation_notes_xlate_part" -Xml $node.Node) { $Component.InstallationNotes += $item.Node.InnerText.Replace(" ", " ") } # Add availability notes foreach ($item in Select-Xml -XPath "availability_notes/availability_notes_xlate[@lang='en']/availability_notes_xlate_part" -Xml $node.Node) { $Component.AvailabilityNotes += $item.Node.InnerText.Replace(" ", " ") } # Add documentation notes foreach ($item in Select-Xml -XPath "documentation_notes/documentation_notes_xlate[@lang='en']/documentation_notes_xlate_part" -Xml $node.Node) { $Component.DocumentationNotes += $item.Node.InnerText.Replace(" ", " ") } # Add revision history if ($RevisionHistory.ContainsKey($ComponentKey)) { $Component.RevisionHistory = $RevisionHistory[$ComponentKey] } # Add component $Bundle.Components += $Component } } Function Get-SPPBundle { <# .SYNOPSIS Get SPP bundles. .DESCRIPTION The Get-SPPBundle command gets Service Pack for ProLiant bundles. .PARAMETER File Bundle files. Wildcards are accepted (e.g. *bp*). If omitted the command will get all available bundles. .EXAMPLE Get-SPPBundle E:\packages\bp003135.xml Get SPP bundle identified by the specified file. .EXAMPLE Get-SPPBundle Get all available SPP bundles. .INPUTS None .OUTPUTS SPPBundle[] #> [CmdletBinding()] Param ( [Parameter(Mandatory=$false, HelpMessage="Bundle files", Position=0)] [ValidateNotNullOrEmpty()] [String[]] $File ) # Set bundles by file $BundlesByFile = @{} # Check files if ($File) { # Add bundles by file foreach ($value in $File) { foreach ($bundle in $Script:Bundles.Values) { if (!$BundlesByFile.ContainsKey($bundle.File)) { if ($bundle.File -like $value) { $BundlesByFile.Add($bundle.File, $bundle) } } } } } else { # Add all bundles $BundlesByFile = $Script:Bundles } # Output bundles Write-Output $BundlesByFile.Values | Sort-Object -Property FullVersion -Descending } Function Remove-SPPBundle { <# .SYNOPSIS Remove SPP bundles. .DESCRIPTION The Remove-SPPBundle command removes Service Pack for ProLiant bundles. .PARAMETER File Bundle files. Wildcards are accepted (e.g. *bp*). .EXAMPLE Remove-SPPBundle E:\packages\bp003135.xml Remove SPP bundle identified by the specified file. .INPUTS None .OUTPUTS None #> [CmdletBinding(SupportsShouldProcess, ConfirmImpact='Low')] Param ( [Parameter(Mandatory=$true, HelpMessage="Bundle file", Position=0)] [ValidateNotNullOrEmpty()] [String[]] $File ) # Confirm removal if (!$PSCmdlet.ShouldProcess($File)) { return } # Set bundles by file $BundlesByFile = @{} # Add bundles by file foreach ($value in $File) { foreach ($bundle in $Script:Bundles.Values) { if (!$BundlesByFile.ContainsKey($bundle.File)) { if ($bundle.File -like $value) { $BundlesByFile.Add($bundle.File, $bundle) } } } } # Remove selected bundles foreach ($key in $BundlesByFile.Keys) { # Remove bundle $Script:Bundles.Remove($key) # Set systems to remove $SystemsToRemove = @() # Remove system components foreach ($system in $Script:Systems.Values) { # Check bundle if ($system.Components.ContainsKey($key)) { # Remove bundle $system.Components.Remove($key) # Check system if ($system.Components.Count -eq 0) { $SystemsToRemove += $system } } } # Remove systems foreach ($system in $SystemsToRemove) { $Script:Systems.Remove($system.Key) } # Set operating systems to remove $OperatingSystemsToRemove = @() # Remove operating system components foreach ($operatingsystem in $Script:OperatingSystems.Values) { # Check bundle if ($operatingsystem.Components.ContainsKey($key)) { # Remove bundle $operatingsystem.Components.Remove($key) # Check operating system if ($operatingsystem.Components.Count -eq 0) { $OperatingSystemsToRemove += $operatingsystem } } } # Remove operating systems foreach ($operatingsystem in $OperatingSystemsToRemove) { $Script:OperatingSystems.Remove($operatingsystem.Key) } # Set categories to remove $CategoriesToRemove = @() # Remove category components foreach ($category in $Script:Categories.Values) { # Check bundle if ($category.Components.ContainsKey($key)) { # Remove bundle $category.Components.Remove($key) # Check category if ($category.Components.Count -eq 0) { $CategoriesToRemove += $category } } } # Remove categories foreach ($category in $CategoriesToRemove) { $Script:Categories.Remove($category.Key) } # Set devices to remove $DevicesToRemove = @() # Remove device components foreach ($device in $Script:Devices.Values) { # Check bundle if ($device.Components.ContainsKey($key)) { # Remove bundle $device.Components.Remove($key) # Check device if ($device.Components.Count -eq 0) { $DevicesToRemove += $device } } } # Remove devices foreach ($device in $DevicesToRemove) { $Script:Devices.Remove($device.Key) } # Set types to remove $TypesToRemove = @() # Remove type components foreach ($type in $Script:Types.Values) { # Check bundle if ($type.Components.ContainsKey($key)) { # Remove bundle $type.Components.Remove($key) # Check type if ($type.Components.Count -eq 0) { $TypesToRemove += $type } } } # Remove types foreach ($type in $TypesToRemove) { $Script:Types.Remove($type.Key) } } } Function ConvertTo-SPPBundleHtml { <# .SYNOPSIS Convert SPP bundles to html. .DESCRIPTION The ConvertTo-SPPBundleHtml command converts Support Pack for ProLiant bundle objects to html format. .PARAMETER Bundle Bundle objects. .PARAMETER File Output html file. If omitted the output will be sent to console. .PARAMETER Details Include bundle details. This adds bundle notes, revision history, and contents to the output. .EXAMPLE Get-SPPBundle | ConvertTo-SPPBundleHtml 'bundle.html' Convert bundle objects to html format and save the output to the file 'bundle.html'. .EXAMPLE Get-SPPBundle | ConvertTo-SPPBundleHtml -Details | Set-Content 'bundle.html' Convert bundle objects, including details, to html format and send the output to console. .INPUTS SPPBundle[] .OUTPUTS String[] #> [CmdletBinding()] Param ( [Parameter(Mandatory=$true, HelpMessage="Bundle objects", ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [PSObject[]] $Bundle, [Parameter(Mandatory=$false, HelpMessage="Output html file", Position=0)] [ValidateNotNullOrEmpty()] [String] $File, [Parameter(Mandatory=$false, HelpMessage="Include bundle details")] [ValidateNotNullOrEmpty()] [Switch] $Details ) BEGIN { # Set bundles $Bundles = @() # Process bundles from variable foreach ($object in $Bundle) { if ($object.PSObject.TypeNames -contains "SPPBundle") { $Bundles += $object } } } PROCESS { # Process bundles from pipeline foreach ($object in $Bundle) { if ($object.PSObject.TypeNames -contains "SPPBundle") { $Bundles += $object } } } END { # Check html file if ($File) { # Check file exists $FileName = Resolve-Path $File -ErrorAction SilentlyContinue -ErrorVariable ResolvePath if ($FileName) { if($Host.UI.PromptForChoice("Overwrite File (ConvertTo-SPPBundleHtml)" , "File '$FileName' exists. Do you want to overwriet it?" , @("&Yes", "&No"), 1) -eq 1) { return } $HtmlFile = $FileName.Path } else { $HtmlFile = $ResolvePath[0].TargetObject } # Create stream writer $StreamWriter = New-Object System.IO.StreamWriter $HtmlFile } else { # Create memory stream $HtmlStream = New-Object System.IO.MemoryStream # Create stream writer $StreamWriter = New-Object System.IO.StreamWriter $HtmlStream } # Check bundles if ($Bundles) { # Write output $StreamWriter.WriteLine("<html>") $StreamWriter.WriteLine(" <head>") $StreamWriter.WriteLine(" <style>") $StreamWriter.WriteLine(" a {color: teal; text-decoration: none;}") $StreamWriter.WriteLine(" a:hover {text-decoration: underline;}") $StreamWriter.WriteLine(" .dimmed {color: gray;}") $StreamWriter.WriteLine(" .spaced:first-child {display: block; margin-top: 0; margin-bottom: 0.5em;}") $StreamWriter.WriteLine(" .spaced {display: block; margin-top: 1.5em; margin-bottom: 0.5em;}") $StreamWriter.WriteLine(" .caps {text-transform: capitalize;}") $StreamWriter.WriteLine(" .title {width: 98%; margin: 1em auto; border-bottom: 2px solid lightseagreen; padding-bottom: 0.5em; font-size: 95%; font-family: verdana;color: chocolate;}") $StreamWriter.WriteLine(" .titlevalue {width: 100%;}") $StreamWriter.WriteLine(" .properties {width: 98%; margin: 1em auto 2em; padding-bottom: 0.5em; font-size: 75%; font-family: verdana;}") $StreamWriter.WriteLine(" .propname {width: 15%; vertical-align: top; padding-bottom: 1.5em;}") $StreamWriter.WriteLine(" .propvalue {width: 85%; vertical-align: top; padding-bottom: 1.5em;}") $StreamWriter.WriteLine(" .note p, .note ul, .note ol {margin: 0 !important; padding: 0 !important;}") $StreamWriter.WriteLine(" .note li {list-style-position: inside !important;}") $StreamWriter.WriteLine(" .note li ul, .note li ol {margin-left: 1em !important;}") $StreamWriter.WriteLine(" .note li p:first-child {display: inline !important;}") $StreamWriter.WriteLine(" .note blockquote {margin: 0 !important; padding: 0 !important;}") $StreamWriter.WriteLine(" .note table {margin: 1em 0 !important; padding: 0 !important; font-style: normal !important; font-size: 100% !important; font-family: verdana !important; border-collapse: collapse !important;}") $StreamWriter.WriteLine(" .note strong, .note b {font-weight: normal !important;}") $StreamWriter.WriteLine(" .note u {text-decoration: none !important;}") $StreamWriter.WriteLine(" .note br {display: inline !important; line-height: 0 !important;}") $StreamWriter.WriteLine(" .note em, .note i {font-style: normal !important;}") $StreamWriter.WriteLine(" </style>") $StreamWriter.WriteLine(" </head>") $StreamWriter.WriteLine(" <body>") foreach ($bundle in $Bundles) { # Write name $StreamWriter.WriteLine(" <table class=`"title`">") $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"titlevalue`">") $StreamWriter.WriteLine(" $($bundle.Name)") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") $StreamWriter.WriteLine(" </table>") # Write version $StreamWriter.WriteLine(" <table class=`"properties`">") $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Version") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") $StreamWriter.WriteLine(" <span class=`"spaced`">$($bundle.Version)</span>") if ($bundle.Revision) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Revision: $($bundle.Revision)</span>") } $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") # Write file $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" File") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") $StreamWriter.WriteLine(" $($bundle.File)") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") # Write tag if ($bundle.Tag) { $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Tag") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") $StreamWriter.WriteLine(" <span class=`"caps`">$($bundle.Tag)</span>") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") } # Write category $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Category") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") $StreamWriter.WriteLine(" $($bundle.Category)") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") # Write description $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Description") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") $StreamWriter.WriteLine(" $($bundle.Description)") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") # Write release date if ($bundle.ReleaseYear -and $bundle.ReleaseMonth -and $bundle.ReleaseDay) { $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Release Date") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") $StreamWriter.WriteLine(" $($bundle.ReleaseYear)-$($bundle.ReleaseMonth)-$($bundle.ReleaseDay)") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") } # Write divisions if ($bundle.Divisions) { $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Divisions") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") $StreamWriter.WriteLine(" <p>") foreach ($division in $bundle.Divisions) { $StreamWriter.WriteLine(" $division<br/>") } $StreamWriter.WriteLine(" </p>") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") } # Write operating systems $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Operating Systems") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") $StreamWriter.WriteLine(" <p>") foreach ($operatingsystem in $bundle.OperatingSystems | Sort-Object) { $StreamWriter.WriteLine(" $operatingsystem<br/>") } $StreamWriter.WriteLine(" </p>") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") if ($Details) { # Write notes if ($bundle.PrerequisiteNotes -or $bundle.InstallationNotes -or $bundle.AvailabilityNotes -or $bundle.DocumentationNotes) { $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Notes") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") # Write prerequisite notes if ($bundle.PrerequisiteNotes) { $StreamWriter.WriteLine(" <span class=`"spaced`">Prerequisites:</span>") foreach ($note in $bundle.PrerequisiteNotes) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $note") $StreamWriter.WriteLine(" </div>") } } # Write installation notes if ($bundle.InstallationNotes) { $StreamWriter.WriteLine(" <span class=`"spaced`">Installation:</span>") foreach ($note in $bundle.InstallationNotes) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $note") $StreamWriter.WriteLine(" </div>") } } # Write availability notes if ($bundle.AvailabilityNotes) { $StreamWriter.WriteLine(" <span class=`"spaced`">Availability:</span>") foreach ($note in $bundle.AvailabilityNotes) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $note") $StreamWriter.WriteLine(" </div>") } } # Write documentation notes if ($bundle.DocumentationNotes) { $StreamWriter.WriteLine(" <span class=`"spaced`">Documentation:</span>") foreach ($note in $bundle.DocumentationNotes) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $note") $StreamWriter.WriteLine(" </div>") } } $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") } # Write revision history if ($bundle.RevisionHistory) { $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Revision History") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") # Write revisions foreach ($revision in $bundle.RevisionHistory | Sort-Object -Property FullVersion -Descending) { $StreamWriter.WriteLine(" <span class=`"spaced`">$($revision.Version)</span>") if ($revision.Revision) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Revision: $($revision.Revision)</span>") } # Write enhancements if ($revision.Enhancements) { $StreamWriter.WriteLine(" <span class=`"spacedin`">Enhancements:</span>") foreach ($enhancement in $revision.Enhancements) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $enhancement") $StreamWriter.WriteLine(" </div>") } } # Write fixes if ($revision.Fixes) { $StreamWriter.WriteLine(" <span class=`"spacedin`">Fixes:</span>") foreach ($fix in $revision.Fixes) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $fix") $StreamWriter.WriteLine(" </div>") } } } $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") } # Write contents $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Contents") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") $StreamWriter.WriteLine(" <p>") foreach ($package in $bundle.Contents | Sort-Object) { $StreamWriter.WriteLine(" $package<br/>") } $StreamWriter.WriteLine(" </p>") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") } $StreamWriter.WriteLine(" </table>") } # Write html closing $StreamWriter.WriteLine(" </body>") $StreamWriter.WriteLine("</html>") # Flush stream writer $StreamWriter.Flush() if (!$File) { # Create stream reader $StreamReader = New-Object System.IO.StreamReader $HtmlStream # Write output $HtmlStream.Position = 0 while ($null -ne ($line = $StreamReader.ReadLine())) { Write-Output $line } # Close stream reader $StreamReader.Close() } # Close stream writer $StreamWriter.Close() } } } Function ConvertTo-SPPBundleCsv { <# .SYNOPSIS Convert SPP bundles to csv. .DESCRIPTION The ConvertTo-SPPBundleCsv command converts Support Pack for ProLiant bundle objects to csv format. .PARAMETER Bundle Bundle objects. .PARAMETER File Output csv file. If omitted the output will be sent to console. .EXAMPLE Get-SPPBundle | ConvertTo-SPPBundleCsv -File 'bundle.csv' Convert bundle objects to csv format and save the output to the file 'bundle.csv'. .EXAMPLE Get-SPPBundle | ConvertTo-SPPBundleCsv | Set-Content 'bundle.csv' Convert bundle objects to csv format and send the output to console. .INPUTS SPPBundle[] .OUTPUTS String[] #> [CmdletBinding()] Param ( [Parameter(Mandatory=$true, HelpMessage="Bundle objects", ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [PSObject[]] $Bundle, [Parameter(Mandatory=$false, HelpMessage="Output csv file", Position=0)] [ValidateNotNullOrEmpty()] [String] $File ) BEGIN { # Set bundles $Bundles = @() # Process bundles from variable foreach ($object in $Bundle) { if ($object.PSObject.TypeNames -contains "SPPBundle") { $Bundles += $object } } } PROCESS { # Process bundles from pipeline foreach ($object in $Bundle) { if ($object.PSObject.TypeNames -contains "SPPBundle") { $Bundles += $object } } } END { # Check csv file if ($File) { # Check file exists $FileName = Resolve-Path $File -ErrorAction SilentlyContinue -ErrorVariable ResolvePath if ($FileName) { if($Host.UI.PromptForChoice("Overwrite File (ConvertTo-SPPBundleCsv)" , "File '$FileName' exists. Do you want to overwriet it?" , @("&Yes", "&No"), 1) -eq 1) { return } $CsvFile = $FileName.Path } else { $CsvFile = $ResolvePath[0].TargetObject } # Create stream writer $StreamWriter = New-Object System.IO.StreamWriter $CsvFile } else { # Create memory stream $CsvStream = New-Object System.IO.MemoryStream # Create stream writer $StreamWriter = New-Object System.IO.StreamWriter $CsvStream } # Check bundles if ($Bundles) { # Write header $StreamWriter.WriteLine('Name, Version, Revision, File, Tag, Category, Description, Release Date, Division, Operating System') # Add lines foreach ($bundle in $Bundles) { # Write name $line = '"' + $bundle.Name + '"' # Write version $line += ',"' + $bundle.Version + '"' # Write revision $line += ',"' + $bundle.Revision + '"' # Write file $line += ',"' + $bundle.File + '"' # Write tag $line += ',"' + $bundle.Tag + '"' # Write category $line += ',"' + $bundle.Category + '"' # Write description $line += ',"' + $bundle.Description + '"' # Write release date if ($bundle.ReleaseYear -and $bundle.ReleaseMonth -and $bundle.ReleaseDay) { $line += ',"' + $bundle.ReleaseYear + '-' + $bundle.ReleaseMonth + '-' + $bundle.ReleaseDay + '"' } else { $line += ',""' } # Set division lines $divisionlines = @() # Write divisions foreach ($division in $bundle.Divisions) { $divisionlines += $line + ',"' + $division + '"' } # Set operating system lines $operatingsystemlines = @() # Write operating systems foreach ($line in $divisionlines) { foreach ($operatingsystem in $bundle.OperatingSystems) { $operatingsystemlines += $line + ',"' + $operatingsystem + '"' } } # Write operating system lines foreach ($line in $operatingsystemlines) { $StreamWriter.WriteLine($line) } } # Flush stream writer $StreamWriter.Flush() if (!$File) { # Create stream reader $StreamReader = New-Object System.IO.StreamReader $CsvStream # Write output $CsvStream.Position = 0 while ($null -ne ($line = $StreamReader.ReadLine())) { Write-Output $line } # Close stream reader $StreamReader.Close() } # Close stream writer $StreamWriter.Close() } } } Function Get-SPPSystem { <# .SYNOPSIS Get SPP systems. .DESCRIPTION The Get-SPPSystem command gets Service Pack for ProLiant systems. .PARAMETER Name System names. Wildcards are accepted (e.g. *DL360*). If omitted the command will get all systems. .PARAMETER Bundle System bundles. If omitted the command will get systems from all bundles. .PARAMETER PassThru Pass through filter objects. This outputs filter objects received from the input pipeline. .EXAMPLE Get-SPPSystem *DL380* Get all systems that contain 'DL360' in their names. .EXAMPLE Get-SPPBundle E:\packages\bp003135.xml | Get-SPPSystem -Name *G5*,*G6* Get all systems, from the specified bundle, that contain 'G5' or 'G6' in their names. .INPUTS SPPBundle[] .OUTPUTS SPPFilter[], SPPSystem[] #> [CmdletBinding()] Param ( [Parameter(Mandatory=$false, HelpMessage="System names", Position=0)] [ValidateNotNullOrEmpty()] [String[]] $Name, [Parameter(Mandatory=$false, HelpMessage="System bundles", Position=1, ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [PSObject[]] $Bundle, [Parameter(Mandatory=$false, HelpMessage="Pass through filter objects")] [ValidateNotNullOrEmpty()] [Switch] $PassThru ) BEGIN { # Set bundles $Bundles = @() # Set filters $Filters = @() # Process bundles from variable foreach ($object in $Bundle) { if ($object.PSObject.TypeNames -contains "SPPBundle") { $Bundles += $object } } } PROCESS { # Process bundles from pipeline foreach ($object in $Bundle) { if ($object.PSObject.TypeNames -contains "SPPBundle") { $Bundles += $object } elseif ($PassThru -and ($object.PSObject.TypeNames -contains "SPPFilter")) { $Filters += $object } } } END { # Set systems by bundle $SystemsByBundle = @{} # Check bundles if ($Bundles.Count -ne 0) { # Add systems by bundle foreach ($bundle in $Bundles) { foreach ($system in $Script:Systems.Values) { if ($system.Components.ContainsKey($bundle.File)) { $SystemsByBundle.Add($system.Key, $system) } } } } else { # Add all systems $SystemsByBundle = $Script:Systems } # Set systems by name $SystemsByName = @{} # Check names if ($Name) { # Add systems by name foreach ($value in $Name) { foreach ($system in $SystemsByBundle.Values) { if (!$SystemsByName.ContainsKey($system.Key)) { if ($system.Name -like $value) { $SystemsByName.Add($system.Key, $system) } } } } } else { # Add all systems by bundle $SystemsByName = $SystemsByBundle } # Output filters Write-Output $Filters # Output systems Write-Output $SystemsByName.Values | Sort-Object -Property Name } } Function Get-SPPOperatingSystem { <# .SYNOPSIS Get SPP operating systems. .DESCRIPTION The Get-SPPOperatingSystem command gets Service Pack for ProLiant operating systems. .PARAMETER Name Operating system names. Wildcards are accepted (e.g. *VMware*). If omitted the command will get all operating systems. .PARAMETER Bundle Operating system bundles. If omitted the command will get operating systems from all bundles. .PARAMETER PassThru Pass through filter objects. This outputs filter objects received from the input pipeline. .EXAMPLE Get-SPPOperatingSystem *VMware* Get all operating systems that contain 'VMware' in their names. .EXAMPLE Get-SPPBundle E:\packages\bp003135.xml | Get-SPPOperatingSystem -Name *Windows*,*Linux* Get all operating systems, from the specified bundle, that contain 'Windows' or 'Linux' in their names. .INPUTS SPPBundle[] .OUTPUTS SPPFilter[], SPPOperatingSystem[] #> [CmdletBinding()] Param ( [Parameter(Mandatory=$false, HelpMessage="Operating system names", Position=0)] [ValidateNotNullOrEmpty()] [String[]] $Name, [Parameter(Mandatory=$false, HelpMessage="Operating system bundles", Position=1, ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [PSObject[]] $Bundle, [Parameter(Mandatory=$false, HelpMessage="Pass through filter objects")] [ValidateNotNullOrEmpty()] [Switch] $PassThru ) BEGIN { # Set bundles $Bundles = @() # Set filters $Filters = @() # Process bundles from variable foreach ($object in $Bundle) { if ($object.PSObject.TypeNames -contains "SPPBundle") { $Bundles += $object } } } PROCESS { # Process bundles from pipeline foreach ($object in $Bundle) { if ($object.PSObject.TypeNames -contains "SPPBundle") { $Bundles += $object } elseif ($PassThru -and ($object.PSObject.TypeNames -contains "SPPFilter")) { $Filters += $object } } } END { # Set operating systems by bundle $OperatingSystemsByBundle = @{} # Check bundles if ($Bundles.Count -ne 0) { # Add operating systems by bundle foreach ($bundle in $Bundles) { foreach ($operatingsystem in $Script:OperatingSystems.Values) { if ($operatingsystem.Components.ContainsKey($bundle.File)) { $OperatingSystemsByBundle.Add($operatingsystem.Key, $operatingsystem) } } } } else { # Add all oeprating systems $OperatingSystemsByBundle = $Script:OperatingSystems } # Set operating systems by name $OperatingSystemsByName = @{} # Check names if ($Name) { # Add opearating systems by name foreach ($value in $Name) { foreach ($operatingsystem in $OperatingSystemsByBundle.Values) { if (!$OperatingSystemsByName.ContainsKey($operatingsystem.Key)) { if ($operatingsystem.Name -like $value) { $OperatingSystemsByName.Add($operatingsystem.Key, $operatingsystem) } } } } } else { # Add all operating systems by bundle $OperatingSystemsByName = $OperatingSystemsByBundle } # Output filters Write-Output $Filters # Output operating systems Write-Output $OperatingSystemsByName.Values | Sort-Object -Property Name } } Function Get-SPPCategory { <# .SYNOPSIS Get SPP categories. .DESCRIPTION The Get-SPPCategory command gets Service Pack for ProLiant categories. .PARAMETER Name Category names. Wildcards are accepted (e.g. *Firmware*). If omitted the command will get all categories. .PARAMETER Bundle Category bundles. If omitted the command will get categories from all bundles. .PARAMETER PassThru Pass through filter objects. This outputs filter objects received from the input pipeline. .EXAMPLE Get-SPPCategory *Firmware* Get all categories that contain 'Firmware' in their names. .EXAMPLE Get-SPPBundle E:\packages\bp003135.xml | Get-SPPCategory -Name *Firmware*,*Driver* Get all categories, from the specified bundle, that contain 'Firmware' or 'Driver' in their names. .INPUTS SPPBundle[] .OUTPUTS SPPFilter, SPPCategory[] #> [CmdletBinding()] Param ( [Parameter(Mandatory=$false, HelpMessage="Category names", Position=0)] [ValidateNotNullOrEmpty()] [String[]] $Name, [Parameter(Mandatory=$false, HelpMessage="Category bundles", Position=1, ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [PSObject[]] $Bundle, [Parameter(Mandatory=$false, HelpMessage="Pass through filter objects")] [ValidateNotNullOrEmpty()] [Switch] $PassThru ) BEGIN { # Set bundles $Bundles = @() # Set filters $Filters = @() # Process bundles from variable foreach ($object in $Bundle) { if ($object.PSObject.TypeNames -contains "SPPBundle") { $Bundles += $object } } } PROCESS { # Process bundles from pipeline foreach ($object in $Bundle) { if ($object.PSObject.TypeNames -contains "SPPBundle") { $Bundles += $object } elseif ($PassThru -and ($object.PSObject.TypeNames -contains "SPPFilter")) { $Filters += $object } } } END { # Set categories by bundle $CategoriesByBundle = @{} # Check bundles if ($Bundles.Count -ne 0) { # Add categories by bundle foreach ($bundle in $Bundles) { foreach ($category in $Script:Categories.Values) { if ($category.Components.ContainsKey($bundle.File)) { $CategoriesByBundle.Add($category.Key, $category) } } } } else { # Add all categories $CategoriesByBundle = $Script:Categories } # Set categories by name $CategoriesByName = @{} # Check names if ($Name) { # Add categories by name foreach ($value in $Name) { foreach ($category in $CategoriesByBundle.Values) { if (!$CategoriesByName.ContainsKey($category.Key)) { if ($category.Name -like $value) { $CategoriesByName.Add($category.Key, $category) } } } } } else { # Add all categories by bundle $CategoriesByName = $CategoriesByBundle } # Output filters Write-Output $Filters # Output categories Write-Output $CategoriesByName.Values | Sort-Object -Property Name } } Function Get-SPPDevice { <# .SYNOPSIS Get SPP devices. .DESCRIPTION The Get-SPPDevice command gets Service Pack for ProLiant devices. .PARAMETER Name Device names. Wildcards are accepted (e.g. *VMware*). If omitted the command will get all devices. .PARAMETER Bundle Device bundles. If omitted the command will get devices from all bundles. .PARAMETER PassThru Pass through filter objects. This outputs filter objects received from the input pipeline. .EXAMPLE Get-SPPDevice *HBA* Get all devices that contain 'HBA' in their names. .EXAMPLE Get-SPPBundle E:\packages\bp003135.xml | Get-SPPDevice -Name *HBA*,*NIC* Get all devices, from the specified bundle, that contain 'HBA' or 'NIC' in their names. .INPUTS SPPBundle[] .OUTPUTS SPPFilter[], SPPDevice[] #> [CmdletBinding()] Param ( [Parameter(Mandatory=$false, HelpMessage="Device names", Position=0)] [ValidateNotNullOrEmpty()] [String[]] $Name, [Parameter(Mandatory=$false, HelpMessage="Device bundles", Position=1, ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [PSObject[]] $Bundle, [Parameter(Mandatory=$false, HelpMessage="Pass through filter objects")] [ValidateNotNullOrEmpty()] [Switch] $PassThru ) BEGIN { # Set bundles $Bundles = @() # Set filters $Filters = @() # Process bundles from variable foreach ($object in $Bundle) { if ($object.PSObject.TypeNames -contains "SPPBundle") { $Bundles += $object } } } PROCESS { # Process bundles from pipeline foreach ($object in $Bundle) { if ($object.PSObject.TypeNames -contains "SPPBundle") { $Bundles += $object } elseif ($PassThru -and ($object.PSObject.TypeNames -contains "SPPFilter")) { $Filters += $object } } } END { # Set devices by bundle $DevicesByBundle = @{} # Check bundles if ($Bundles.Count -ne 0) { # Add devices by bundle foreach ($bundle in $Bundles) { foreach ($device in $Script:Devices.Values) { if ($device.Components.ContainsKey($bundle.File)) { $DevicesByBundle.Add($device.Key, $device) } } } } else { # Add all devices $DevicesByBundle = $Script:Devices } # Set devices by name $DevicesByName = @{} # Check names if ($Name) { # Add devices by name foreach ($value in $Name) { foreach ($device in $DevicesByBundle.Values) { if (!$DevicesByName.ContainsKey($device.Key)) { if ($device.Name -like $value) { $DevicesByName.Add($device.Key, $device) } } } } } else { # Add all devices by bundle $DevicesByName = $DevicesByBundle } # Output filters Write-Output $Filters # Output devices Write-Output $DevicesByName.Values | Sort-Object -Property Name } } Function Get-SPPType { <# .SYNOPSIS Get SPP types. .DESCRIPTION The Get-SPPType command gets Service Pack for ProLiant types. .PARAMETER Name Type names. Wildcards are accepted (e.g. *VMware*). If omitted the command will get all types. .PARAMETER Bundle Type bundles. If omitted the command will get types from all bundles. .PARAMETER PassThru Pass through filter objects. This outputs filter objects received from the input pipeline. .EXAMPLE Get-SPPType *component* Get all types that contain 'component' in their names. .EXAMPLE Get-SPPBundle E:\packages\bp003135.xml | Get-SPPType -Name *component*,*software* Get all types, from the specified bundle, that contain 'component' or 'software' in their names. .INPUTS SPPBundle[] .OUTPUTS SPPFilter[], SPPType[] #> [CmdletBinding()] Param ( [Parameter(Mandatory=$false, HelpMessage="Type names", Position=0)] [ValidateNotNullOrEmpty()] [String[]] $Name, [Parameter(Mandatory=$false, HelpMessage="Type bundles", Position=1, ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [PSObject[]] $Bundle, [Parameter(Mandatory=$false, HelpMessage="Pass through filter objects")] [ValidateNotNullOrEmpty()] [Switch] $PassThru ) BEGIN { # Set bundles $Bundles = @() # Set filters $Filters = @() # Process bundles from variable foreach ($object in $Bundle) { if ($object.PSObject.TypeNames -contains "SPPBundle") { $Bundles += $object } } } PROCESS { # Process bundles from pipeline foreach ($object in $Bundle) { if ($object.PSObject.TypeNames -contains "SPPBundle") { $Bundles += $object } elseif ($PassThru -and ($object.PSObject.TypeNames -contains "SPPFilter")) { $Filters += $object } } } END { # Set types by bundle $TypesByBundle = @{} # Check bundles if ($Bundles.Count -ne 0) { # Add types by bundle foreach ($bundle in $Bundles) { foreach ($type in $Script:Types.Values) { if ($type.Components.ContainsKey($bundle.File)) { $TypesByBundle.Add($type.Key, $type) } } } } else { # Add all types $TypesByBundle = $Script:Types } # Set types by name $TypesByName = @{} # Check names if ($Name) { # Add types by name foreach ($value in $Name) { foreach ($type in $TypesByBundle.Values) { if (!$TypesByName.ContainsKey($type.Key)) { if ($type.Name -like $value) { $TypesByName.Add($type.Key, $type) } } } } } else { # Add all types by bundle $TypesByName = $TypesByBundle } # Output filters Write-Output $Filters # Output types Write-Output $TypesByName.Values | Sort-Object -Property Name } } Function Get-SPPComponent { <# .SYNOPSIS Get SPP components. .DESCRIPTION The Get-SPPComponent command gets Service Pack for ProLiant components. .PARAMETER Name Component names. Wildcards are accepted (e.g. *iLO*). If omitted the command will get all components. .PARAMETER Bundle Component bundles. If omitted the command will get components from all bundles. .PARAMETER Filter Component filter objects. Can be any of System, OperatingSystem, Category, Device, or Type objects used to narrow down, i.e. filter, components selection. .PARAMETER Versions Component versions (All, Changed, or Unchanged). 'Changed' will only get components that have different versions across the selected bundles. 'Unchanged' will only get components that have the same version across the selected bundles. All, the default, will get all components from the selected bundles. .EXAMPLE Get-SPPComponent *iLO* Get all components that contain 'iLO' in their names. .EXAMPLE Get-SPPBundle E:\packages\bp003135.xml | Get-SPPComponent -Name *iLO*,*SmartArray* Get all components, from the specified bundle, that contain 'iLO' or 'SmartArray' in their names. .EXAMPLE Get-SPPSystem *BL460c* | Get-SPPComponent Get all components for the specified systems. .EXAMPLE Get-SPPOperatingSystem *VMware* | Get-SPPComponent -Versions Changed Get only components that have different versions across bundles, for the specified operating systems. .INPUTS SPPBundle[], SPPSystem[], SPPOperatingSystem[], SPPCategory[], SPPDevice[], SPPType[] .OUTPUTS SPPCompoent[] #> [CmdletBinding()] Param ( [Parameter(Mandatory=$false, HelpMessage="Component names", Position=0)] [ValidateNotNullOrEmpty()] [String[]] $Name, [Parameter(Mandatory=$false, HelpMessage="Component bundles", ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [PSObject[]] $Bundle, [Parameter(Mandatory=$false, HelpMessage="Component filter objects", ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [PSObject[]] $Filter, [Parameter(Mandatory=$false, HelpMessage="Component versions")] [ValidateSet("All", "Changed", "Unchanged", "Unique")] [ValidateNotNullOrEmpty()] [String] $Versions="All" ) BEGIN { # Set bundles $Bundles = @() # Set systems $Systems = @() # Set operating systems $OperatingSystems = @() # Set categories $Categories = @() # Set devices $Devices = @() # Set types $Types = @() # Process bundles from variable foreach ($object in $Bundle) { if ($object.PSObject.TypeNames -contains "SPPBundle") { $Bundles += $object } } # Process filters from variable foreach ($object in $Filter) { if ($object.PSObject.TypeNames -contains "SPPSystem") { $Systems += $object } elseif ($object.PSObject.TypeNames -contains "SPPOperatingSystem") { $OperatingSystems += $object } elseif ($object.PSObject.TypeNames -contains "SPPCategory") { $Categories += $object } elseif ($object.PSObject.TypeNames -contains "SPPDevice") { $Devices += $object } elseif ($object.PSObject.TypeNames -contains "SPPType") { $Types += $object } } } PROCESS { # Process bundles from pipeline foreach ($object in $Bundle) { if ($object.PSObject.TypeNames -contains "SPPBundle") { $Bundles += $object } } # Process systems from pipeline foreach ($object in $Filter) { if ($object.PSObject.TypeNames -contains "SPPSystem") { $Systems += $object } elseif ($object.PSObject.TypeNames -contains "SPPOperatingSystem") { $OperatingSystems += $object } elseif ($object.PSObject.TypeNames -contains "SPPCategory") { $Categories += $object } elseif ($object.PSObject.TypeNames -contains "SPPDevice") { $Devices += $object } elseif ($object.PSObject.TypeNames -contains "SPPType") { $Types += $object } } } END { # Set components $Components = @() # Set component groups $Groups = @{} # Check bundles if ($Bundles.Count -eq 0) { $Bundles = $Script:Bundles.Values } # Check components foreach ($bundle in $Bundles) { foreach ($component in $bundle.Components) { # Check systems if ($Systems.Count -ne 0 ) { # Reset keep flag $keep = $false # Check component foreach ($filter in $Systems) { if ($filter.Components.ContainsKey($bundle.File)) { $keep = $filter.Components[$bundle.File].ContainsKey($component.Key) if ($keep) { break } } } # Check keep flag if (!$keep) { continue } } # Check operating systems if ($OperatingSystems.Count -ne 0 ) { # Reset keep flag $keep = $false # Check component foreach ($filter in $OperatingSystems) { if ($filter.Components.ContainsKey($bundle.File)) { $keep = $filter.Components[$bundle.File].ContainsKey($component.Key) if ($keep) { break } } } # Check keep flag if (!$keep) { continue } } # Check categories if ($Categories.Count -ne 0 ) { # Reset keep flag $keep = $false # Check component foreach ($filter in $Categories) { if ($filter.Components.ContainsKey($bundle.File)) { $keep = $filter.Components[$bundle.File].ContainsKey($component.Key) if ($keep) { break } } } # Check keep flag if (!$keep) { continue } } # Check devices if ($Devices.Count -ne 0 ) { # Reset keep flag $keep = $false # Check component foreach ($filter in $Devices) { if ($filter.Components.ContainsKey($bundle.File)) { $keep = $filter.Components[$bundle.File].ContainsKey($component.Key) if ($keep) { break } } } # Check keep flag if (!$keep) { continue } } # Check types if ($Types.Count -ne 0 ) { # Reset keep flag $keep = $false # Check component foreach ($filter in $Types) { if ($filter.Components.ContainsKey($bundle.File)) { $keep = $filter.Components[$bundle.File].ContainsKey($component.Key) if ($keep) { break } } } # Check keep flag if (!$keep) { continue } } # Check names if ($Name) { # Reset keep flag $keep = $false # Check component foreach ($value in $Name) { $keep = ($component.Name -like $value) if ($keep) { break } } # Check keep flag if (!$keep) { continue } } # Check component group if (!$Groups.ContainsKey($component.ProductID)) { # Add component group $Groups.Add($component.ProductID, @()) } # Add component $Groups[$component.ProductID] += $component } } # Check versions if ($Versions -eq "Unique") { # Check component groups foreach ($group in $Groups.Values) { # Check component count if ($group.count -eq 1) { # Add unique components $Components += $group } } } elseif ($Versions -eq "Changed") { # Check component groups foreach ($group in $Groups.Values) { # Check component count if ($group.count -eq 1) { continue } # Set version keys $keys = @{} # Reset common flag $common = $false # Check components foreach ($component in $group) { if ($keys.Count -eq 0) { $keys.Add($component.FullVersion, $null) } else { $common = $keys.ContainsKey($component.FullVersion) if ($common) { break } else { $keys.Add($component.FullVersion, $null) } } } # Check common flag if (!$common) { # Add changed components $Components += $group } else { continue } } } elseif ($Versions -eq "Unchanged") { # Check component groups foreach ($group in $Groups.Values) { # Check component count if ($group.count -eq 1) { continue } # Set version keys $keys = @{} # Reset common flag $common = $false # Check components foreach ($component in $group) { if ($keys.Count -eq 0) { $keys.Add($component.FullVersion, $null) } else { $common = $keys.ContainsKey($component.FullVersion) if (!$common) { break } } } # Check common flag if ($common) { # Add unchanged components $Components += $group } else { continue } } } else { # Check component groups foreach ($group in $Groups.Values) { # Add all components $Components += $group } } # Output selected components Write-Output $Components | Sort-Object -Property Name, FullVersion -Descending } } Function Copy-SPPComponent { <# .SYNOPSIS Copy SPP component files. .DESCRIPTION The Copy-SPPComponent command copies Service Pack for ProLiant component files to a directory. .PARAMETER Component Component objects. .PARAMETER Directory Destination directory. The directory must exist. If a file to be copied already exists in the destination directory it will be overwritten. .EXAMPLE Get-SPPComponent | Copy-SPPComponent C:\Components Copy component files to destination directory 'C:\Components'. .INPUTS SPPComponent[] .OUTPUTS None #> [CmdletBinding()] Param ( [Parameter(Mandatory=$true, HelpMessage="Component objects", ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [PSObject[]] $Component, [Parameter(Mandatory=$true, HelpMessage="Destination directory", Position=0)] [ValidateNotNullOrEmpty()] [String] $Directory ) BEGIN { # Set components $Components = @() # Process components from variable foreach ($object in $Component) { if ($object.PSObject.TypeNames -contains "SPPComponent") { $Components += $object } } } PROCESS { # Process components from pipeline foreach ($object in $Component) { if ($object.PSObject.TypeNames -contains "SPPComponent") { $Components += $object } } } END { # Check destination directory if (Test-Path -PathType Container -Path $Directory) { # Set destination directory full path $DestinationDirectory = (Resolve-Path -Path $Directory).Path } else { Throw "Destination directory '$Directory' not found" } # Set processed count $processed = 0 # Copy components foreach ($component in $Components) { # Display progress Write-Progress -Activity "Copying components to '$DestinationDirectory' ..." -Status "Copying '$($component.FileName)'" -PercentComplete ([int]($processed++ / $Components.Count * 100)) # Copy component files foreach ($file in $component.Files) { # Set file item $item = Get-Item $file.FileUrl # Copy files Copy-Item -Path "$(Join-Path $item.Directory $item.BaseName)*" -Destination $DestinationDirectory -Force } } } } Function ConvertTo-SPPComponentHtml { <# .SYNOPSIS Convert SPP components to html. .DESCRIPTION The ConvertTo-SPPComponentHtml command converts Support Pack for ProLiant component objects to html format. .PARAMETER Component Component objects. .PARAMETER File Output html file. If omitted the output will be sent to console. .PARAMETER Details Include component details. This adds component notes, revision history, and contents to the output. .PARAMETER Combine Combine component versions. This combines all versions of each component under one section. .EXAMPLE Get-SPPComponent | ConvertTo-SPPComponentHtml -File 'components.html' Convert component objects to html format and save the output to the file 'components.html'. .EXAMPLE Get-SPPComponent | ConvertTo-SPPComponentHtml -Details | Set-Content 'components.html' Convert component objects, including details, to html format and send the output to console. .INPUTS SPPComponent[] .OUTPUTS String[] #> [CmdletBinding()] Param ( [Parameter(Mandatory=$true, HelpMessage="Component objects", ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [PSObject[]] $Component, [Parameter(Mandatory=$false, HelpMessage="Output html file", Position=0)] [ValidateNotNullOrEmpty()] [String] $File, [Parameter(Mandatory=$false, HelpMessage="Include component details")] [ValidateNotNullOrEmpty()] [Switch] $Details, [Parameter(Mandatory=$false, HelpMessage="Combine component versions")] [ValidateNotNullOrEmpty()] [Switch] $Combine ) BEGIN { # Set components $Components = @() # Process components from variable foreach ($object in $Component) { if ($object.PSObject.TypeNames -contains "SPPComponent") { $Components += $object } } } PROCESS { # Process components from pipeline foreach ($object in $Component) { if ($object.PSObject.TypeNames -contains "SPPComponent") { $Components += $object } } } END { # Check html file if ($File) { # Check file exists $FileName = Resolve-Path $File -ErrorAction SilentlyContinue -ErrorVariable ResolvePath if ($FileName) { if($Host.UI.PromptForChoice("Overwrite File (ConvertTo-SPPComponentHtml)" , "File '$FileName' exists. Do you want to overwriet it?" , @("&Yes", "&No"), 1) -eq 1) { return } $HtmlFile = $FileName.Path } else { $HtmlFile = $ResolvePath[0].TargetObject } # Create stream writer $StreamWriter = New-Object System.IO.StreamWriter $HtmlFile } else { # Create memory stream $HtmlStream = New-Object System.IO.MemoryStream # Create stream writer $StreamWriter = New-Object System.IO.StreamWriter $HtmlStream } # Check components if ($Components -and $Combine) { # Set component groups $Groups = @{} # Set component revisions $RevisionHistory = @{} # Add components foreach ($component in $Components) { # Check component group if (!$Groups.ContainsKey($component.ProductID)) { # Add component group $Groups.Add($component.ProductID, @()) # Add revision history $RevisionHistory.Add($component.ProductID, @()) } # Add component $Groups[$component.ProductID] += $component # Add revisions $RevisionHistory[$component.ProductID] += $component.RevisionHistory } # Write output $StreamWriter.WriteLine("<html>") $StreamWriter.WriteLine(" <head>") $StreamWriter.WriteLine(" <style>") $StreamWriter.WriteLine(" a {color: teal; text-decoration: none;}") $StreamWriter.WriteLine(" a:hover {text-decoration: underline;}") $StreamWriter.WriteLine(" .dimmed {color: gray;}") $StreamWriter.WriteLine(" .spaced:first-child {display: block; margin-top: 0; margin-bottom: 0.5em;}") $StreamWriter.WriteLine(" .spaced {display: block; margin-top: 1.5em; margin-bottom: 0.5em;}") $StreamWriter.WriteLine(" .spacedin {display: block; margin-bottom: 0.5em;}") $StreamWriter.WriteLine(" .caps {text-transform: capitalize;}") $StreamWriter.WriteLine(" .title {width: 98%; margin: 1em auto; border-bottom: 2px solid lightseagreen; padding-bottom: 0.5em; font-size: 95%; font-family: verdana;color: chocolate;}") $StreamWriter.WriteLine(" .titlevalue {width: 100%;}") $StreamWriter.WriteLine(" .properties {width: 98%; margin: 1em auto 2em; padding-bottom: 0.5em; font-size: 75%; font-family: verdana;}") $StreamWriter.WriteLine(" .propname {width: 15%; vertical-align: top; padding-bottom: 2em;}") $StreamWriter.WriteLine(" .propvalue {width: 85%; vertical-align: top; padding-bottom: 2em;}") $StreamWriter.WriteLine(" .note p, .note ul, .note ol {margin: 0 !important; padding: 0 !important;}") $StreamWriter.WriteLine(" .note li {list-style-position: inside !important;}") $StreamWriter.WriteLine(" .note li ul, .note li ol {margin-left: 1em !important;}") $StreamWriter.WriteLine(" .note li p:first-child {display: inline !important;}") $StreamWriter.WriteLine(" .note blockquote {margin: 0 !important; padding: 0 !important;}") $StreamWriter.WriteLine(" .note table {margin: 1em 0 !important; padding: 0 !important; font-style: normal !important; font-size: 100% !important; font-family: verdana !important; border-collapse: collapse !important;}") $StreamWriter.WriteLine(" .note strong, .note b {font-weight: normal !important;}") $StreamWriter.WriteLine(" .note u {text-decoration: none !important;}") $StreamWriter.WriteLine(" .note br {display: inline !important; line-height: 0 !important;}") $StreamWriter.WriteLine(" .note em, .note i {font-style: normal !important;}") $StreamWriter.WriteLine(" </style>") $StreamWriter.WriteLine(" </head>") $StreamWriter.WriteLine(" <body>") foreach ($key in $Groups.Keys) { # Set group $group = $Groups[$key] # Set latest component $componentx = $group | Sort-Object -Property FullVersion, Bundle -Descending | Select-Object -First 1 # Set revisions $revisions = $RevisionHistory[$key] # Write name $StreamWriter.WriteLine(" <table class=`"title`">") $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"titlevalue`">") $StreamWriter.WriteLine(" $($componentx.Name)") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") $StreamWriter.WriteLine(" </table>") # Write versions $StreamWriter.WriteLine(" <table class=`"properties`">") $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Versions") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") foreach ($component in $group | Sort-Object -Property FullVersion, Bundle -Descending) { if ($component.TypeOfChange) { $StreamWriter.WriteLine(" <span class=`"spaced`">$($component.Version) ($($component.TypeOfChange))</span>") } else { $StreamWriter.WriteLine(" <span class=`"spaced`">$($component.Version)</span>") } if ($component.Revision) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Revision: $($component.Revision)</span><br/>") } if ($component.ReleaseYear -and $component.ReleaseMonth -and $component.ReleaseDay) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Release Date: $($component.ReleaseYear)-$($component.ReleaseMonth)-$($component.ReleaseDay)</span><br/>") } if ($component.BuildNumber) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Build Number: $($component.BuildNumber)</span>") } } $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") # Write bundle information foreach ($component in $group | Sort-Object -Property FullVersion, Bundle -Descending) { $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" <span class=`"spaced`">Bundle</span>") $StreamWriter.WriteLine(" <span class=`"dimmed`">Version: $($component.Version)</span><br/>") if ($component.Revision) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Revision: $($component.Revision)</span>") } $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") $StreamWriter.WriteLine(" <span class=`"spaced`">$($component.Bundle)</span>") $StreamWriter.WriteLine(" <span class=`"dimmed`">File: $($component.BundleFile)</span>") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") } # Write category $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Category") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") $StreamWriter.WriteLine(" <span class=`"spaced`">$($componentx.Category)</span>") if ($component.Type) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Type: $($componentx.Type)</span></br>") } if ($component.AltName) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Alternative Name: $($componentx.AltName)</span></br>") } if ($component.Manufacturer) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Manufacturer: $($componentx.Manufacturer)</span>") } $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") # Write description $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Description") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") $StreamWriter.WriteLine(" $($componentx.Description)") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") # Write operating systems $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Operating Systems") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") $StreamWriter.WriteLine(" <p>") foreach ($operatingsystem in $componentx.OperatingSystems | Sort-Object) { $StreamWriter.WriteLine(" $operatingsystem<br/>") } $StreamWriter.WriteLine(" </p>") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") # Write files foreach ($component in $group | Sort-Object -Property FullVersion, Bundle -Descending) { $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" <span class=`"spaced`">Files</span>") $StreamWriter.WriteLine(" <span class=`"dimmed`">Version: $($component.Version)</span><br/>") if ($component.Revision) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Revision: $($component.Revision)</span>") } $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") foreach ($item in $component.Files) { $StreamWriter.WriteLine(" <a class=`"spaced`" href=`"$($item.FileUrl)`">$($item.Name)</a>") $StreamWriter.WriteLine(" <span class=`"dimmed`">Size: $($item.Size)</span><br/>") $StreamWriter.WriteLine(" <span class=`"dimmed`">Date: $($item.DateModified)</span><br/>") $StreamWriter.WriteLine(" <span class=`"dimmed`">Md5sum: $($item.Md5Sum)</span>") } $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") } if ($Details) { # Write notes foreach ($component in $group | Sort-Object -Property FullVersion, Bundle -Descending) { if ($component.PrerequisiteNotes -or $component.InstallationNotes -or $component.AvailabilityNotes -or $component.DocumentationNotes) { $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" <span class=`"spaced`">Notes</span>") $StreamWriter.WriteLine(" <span class=`"dimmed`">Version: $($component.Version)</span><br/>") if ($component.Revision) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Revision: $($component.Revision)</span>") } $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") # Write prerequisite notes if ($component.PrerequisiteNotes) { $StreamWriter.WriteLine(" <span class=`"spaced`">Prerequisites:</span>") foreach ($note in $component.PrerequisiteNotes) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $note") $StreamWriter.WriteLine(" </div>") } } # Write installation notes if ($component.InstallationNotes) { $StreamWriter.WriteLine(" <span class=`"spaced`">Installation:</span>") foreach ($note in $component.InstallationNotes) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $note") $StreamWriter.WriteLine(" </div>") } } # Write availability notes if ($component.AvailabilityNotes) { $StreamWriter.WriteLine(" <span class=`"spaced`">Availability:</span>") foreach ($note in $component.AvailabilityNotes) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $note") $StreamWriter.WriteLine(" </div>") } } # Write documentation notes if ($component.DocumentationNotes) { $StreamWriter.WriteLine(" <span class=`"spaced`">Documentation:</span>") foreach ($note in $component.DocumentationNotes) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $note") $StreamWriter.WriteLine(" </div>") } } $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") } } # Write revision history if ($revisions) { $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Revision History") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") # Write revisions foreach ($revision in $revisions | Sort-Object -Property FullVersion -Descending -Unique) { if ($revision.TypeOfChange) { $StreamWriter.WriteLine(" <span class=`"spaced`">$($revision.Version) ($($revision.TypeOfChange))</span>") } else { $StreamWriter.WriteLine(" <span class=`"spaced`">$($revision.Version)</span>") } if ($revision.Revision) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Revision: $($revision.Revision)</span>") } # Write enhancements if ($revision.Enhancements) { $StreamWriter.WriteLine(" <span class=`"spacedin`">Enhancements:</span>") foreach ($enhancement in $revision.Enhancements) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $enhancement") $StreamWriter.WriteLine(" </div>") } } # Write fixes if ($revision.Fixes) { $StreamWriter.WriteLine(" <span class=`"spacedin`">Fixes:</span>") foreach ($fix in $revision.Fixes) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $fix") $StreamWriter.WriteLine(" </div>") } } } $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") } } $StreamWriter.WriteLine(" </table>") } # Write html closing $StreamWriter.WriteLine(" </body>") $StreamWriter.WriteLine("</html>") # Flush stream writer $StreamWriter.Flush() if (!$File) { # Create stream reader $StreamReader = New-Object System.IO.StreamReader $HtmlStream # Write output $HtmlStream.Position = 0 while ($null -ne ($line = $StreamReader.ReadLine())) { Write-Output $line } # Close stream reader $StreamReader.Close() } # Close stream writer $StreamWriter.Close() } # Check components if ($Components -and !$Combine) { # Write output $StreamWriter.WriteLine("<html>") $StreamWriter.WriteLine(" <head>") $StreamWriter.WriteLine(" <style>") $StreamWriter.WriteLine(" a {color: teal; text-decoration: none;}") $StreamWriter.WriteLine(" a:hover {text-decoration: underline;}") $StreamWriter.WriteLine(" .dimmed {color: gray;}") $StreamWriter.WriteLine(" .spaced:first-child {display: block; margin-top: 0; margin-bottom: 0.5em;}") $StreamWriter.WriteLine(" .spaced {display: block; margin-top: 1.5em; margin-bottom: 0.5em;}") $StreamWriter.WriteLine(" .spacedin {display: block; margin-bottom: 0.5em;}") $StreamWriter.WriteLine(" .caps {text-transform: capitalize;}") $StreamWriter.WriteLine(" .title {width: 98%; margin: 1em auto; border-bottom: 2px solid lightseagreen; padding-bottom: 0.5em; font-size: 95%; font-family: verdana;color: chocolate;}") $StreamWriter.WriteLine(" .titlevalue {width: 100%;}") $StreamWriter.WriteLine(" .properties {width: 98%; margin: 1em auto 2em; padding-bottom: 0.5em; font-size: 75%; font-family: verdana;}") $StreamWriter.WriteLine(" .propname {width: 15%; vertical-align: top; padding-bottom: 1.5em;}") $StreamWriter.WriteLine(" .propvalue {width: 85%; vertical-align: top; padding-bottom: 1.5em;}") $StreamWriter.WriteLine(" .note p, .note ul, .note ol {margin: 0 !important; padding: 0 !important;}") $StreamWriter.WriteLine(" .note li {list-style-position: inside !important;}") $StreamWriter.WriteLine(" .note li ul, .note li ol {margin-left: 1em !important;}") $StreamWriter.WriteLine(" .note li p:first-child {display: inline !important;}") $StreamWriter.WriteLine(" .note blockquote {margin: 0 !important; padding: 0 !important;}") $StreamWriter.WriteLine(" .note table {margin: 1em 0 !important; padding: 0 !important; font-style: normal !important; font-size: 100% !important; font-family: verdana !important; border-collapse: collapse !important;}") $StreamWriter.WriteLine(" .note strong, .note b {font-weight: normal !important;}") $StreamWriter.WriteLine(" .note u {text-decoration: none !important;}") $StreamWriter.WriteLine(" .note br {display: inline !important; line-height: 0 !important;}") $StreamWriter.WriteLine(" .note em, .note i {font-style: normal !important;}") $StreamWriter.WriteLine(" </style>") $StreamWriter.WriteLine(" </head>") $StreamWriter.WriteLine(" <body>") foreach ($component in $Components) { # Write name $StreamWriter.WriteLine(" <table class=`"title`">") $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"titlevalue`">") $StreamWriter.WriteLine(" $($component.Name)") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") $StreamWriter.WriteLine(" </table>") # Write version $StreamWriter.WriteLine(" <table class=`"properties`">") $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Version") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") if ($component.TypeOfChange) { $StreamWriter.WriteLine(" <span class=`"spaced`">$($component.Version) ($($component.TypeOfChange))</span>") } else { $StreamWriter.WriteLine(" <span class=`"spaced`">$($component.Version)</span>") } if ($component.Revision) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Revision: $($component.Revision)</span><br/>") } if ($component.ReleaseYear -and $component.ReleaseMonth -and $component.ReleaseDay) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Release Date: $($component.ReleaseYear)-$($component.ReleaseMonth)-$($component.ReleaseDay)</span><br/>") } if ($component.BuildNumber) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Build Number: $($component.BuildNumber)</span>") } $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") # Write bundle information $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Bundle") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") $StreamWriter.WriteLine(" <span class=`"spaced`">$($component.Bundle)</span>") $StreamWriter.WriteLine(" <span class=`"dimmed`">File: $($component.BundleFile)</span>") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") # Write category $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Category") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") $StreamWriter.WriteLine(" <span class=`"spaced`">$($component.Category)</span>") if ($component.Type) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Type: $($component.Type)</span></br>") } if ($component.AltName) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Alternative Name: $($component.AltName)</span></br>") } if ($component.Manufacturer) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Manufacturer: $($component.Manufacturer)</span>") } $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") # Write description $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Description") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") $StreamWriter.WriteLine(" $($component.Description)") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") # Write operating systems $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Operating Systems") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") $StreamWriter.WriteLine(" <p>") foreach ($operatingsystem in $component.OperatingSystems | Sort-Object) { $StreamWriter.WriteLine(" $operatingsystem<br/>") } $StreamWriter.WriteLine(" </p>") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") # Write files $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Files") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") foreach ($item in $component.Files) { $StreamWriter.WriteLine(" <a class=`"spaced`" href=`"$($item.FileUrl)`">$($item.Name)</a>") $StreamWriter.WriteLine(" <span class=`"dimmed`">Size: $($item.Size)</span><br/>") $StreamWriter.WriteLine(" <span class=`"dimmed`">Date: $($item.DateModified)</span><br/>") $StreamWriter.WriteLine(" <span class=`"dimmed`">Md5sum: $($item.Md5Sum)</span>") } $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") if ($Details) { # Write notes if ($component.PrerequisiteNotes -or $component.InstallationNotes -or $component.AvailabilityNotes -or $component.DocumentationNotes) { $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Notes") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") # Write prerequisite notes if ($component.PrerequisiteNotes) { $StreamWriter.WriteLine(" <span class=`"spaced`">Prerequisites:</span>") foreach ($note in $component.PrerequisiteNotes) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $note") $StreamWriter.WriteLine(" </div>") } } # Write installation notes if ($component.InstallationNotes) { $StreamWriter.WriteLine(" <span class=`"spaced`">Installation:</span>") foreach ($note in $component.InstallationNotes) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $note") $StreamWriter.WriteLine(" </div>") } } # Write availability notes if ($component.AvailabilityNotes) { $StreamWriter.WriteLine(" <span class=`"spaced`">Availability:</span>") foreach ($note in $component.AvailabilityNotes) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $note") $StreamWriter.WriteLine(" </div>") } } # Write documentation notes if ($component.DocumentationNotes) { $StreamWriter.WriteLine(" <span class=`"spaced`">Documentation:</span>") foreach ($note in $component.DocumentationNotes) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $note") $StreamWriter.WriteLine(" </div>") } } $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") } # Write revision history if ($component.RevisionHistory) { $StreamWriter.WriteLine(" <tr>") $StreamWriter.WriteLine(" <td class=`"propname`">") $StreamWriter.WriteLine(" Revision History") $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" <td class=`"propvalue`">") # Write revisions foreach ($revision in $component.RevisionHistory | Sort-Object -Property FullVersion -Descending) { if ($revision.TypeOfChange) { $StreamWriter.WriteLine(" <span class=`"spaced`">$($revision.Version) ($($revision.TypeOfChange))</span>") } else { $StreamWriter.WriteLine(" <span class=`"spaced`">$($revision.Version)</span>") } if ($revision.Revision) { $StreamWriter.WriteLine(" <span class=`"dimmed`">Revision: $($revision.Revision)</span>") } # Write enhancements if ($revision.Enhancements) { $StreamWriter.WriteLine(" <span class=`"spacedin`">Enhancements:</span>") foreach ($enhancement in $revision.Enhancements) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $enhancement") $StreamWriter.WriteLine(" </div>") } } # Write fixes if ($revision.Fixes) { $StreamWriter.WriteLine(" <span class=`"spacedin`">Fixes:</span>") foreach ($fix in $revision.Fixes) { $StreamWriter.WriteLine(" <div class=`"note dimmed spacedin`">") $StreamWriter.WriteLine(" $fix") $StreamWriter.WriteLine(" </div>") } } } $StreamWriter.WriteLine(" </td>") $StreamWriter.WriteLine(" </tr>") } } $StreamWriter.WriteLine(" </table>") } # Write html closing $StreamWriter.WriteLine(" </body>") $StreamWriter.WriteLine("</html>") # Flush stream writer $StreamWriter.Flush() if (!$File) { # Create stream reader $StreamReader = New-Object System.IO.StreamReader $HtmlStream # Write output $HtmlStream.Position = 0 while ($null -ne ($line = $StreamReader.ReadLine())) { Write-Output $line } # Close stream reader $StreamReader.Close() } # Close stream writer $StreamWriter.Close() } } } Function ConvertTo-SPPComponentCsv { <# .SYNOPSIS Convert SPP components to csv. .DESCRIPTION The ConvertTo-SPPComponentCsv command converts Support Pack for ProLiant component objects to csv format. .PARAMETER Component Component objects. .PARAMETER File Output csv file. If omitted the output will be sent to console. .EXAMPLE Get-SPPComponent | ConvertTo-SPPComponentCsv -File 'components.csv' Convert component objects to csv format and save the output to the file 'components.csv'. .EXAMPLE Get-SPPComponent | ConvertTo-SPPComponentCsv | Set-Content 'components.csv' Convert component objects to csv format and send the output to console. .INPUTS SPPComponent[] .OUTPUTS String[] #> [CmdletBinding()] Param ( [Parameter(Mandatory=$true, HelpMessage="Component objects", ValueFromPipeline=$true)] [ValidateNotNullOrEmpty()] [PSObject[]] $Component, [Parameter(Mandatory=$false, HelpMessage="Output csv file", Position=0)] [ValidateNotNullOrEmpty()] [String] $File ) BEGIN { # Set components $Components = @() # Process components from variable foreach ($object in $Component) { if ($object.PSObject.TypeNames -contains "SPPComponent") { $Components += $object } } } PROCESS { # Process components from pipeline foreach ($object in $Component) { if ($object.PSObject.TypeNames -contains "SPPComponent") { $Components += $object } } } END { # Check csv file if ($File) { # Check file exists $FileName = Resolve-Path $File -ErrorAction SilentlyContinue -ErrorVariable ResolvePath if ($FileName) { if($Host.UI.PromptForChoice("Overwrite File (ConvertTo-SPPComponentCsv)" , "File '$FileName' exists. Do you want to overwriet it?" , @("&Yes", "&No"), 1) -eq 1) { return } $CsvFile = $FileName.Path } else { $CsvFile = $ResolvePath[0].TargetObject } # Create stream writer $StreamWriter = New-Object System.IO.StreamWriter $CsvFile } else { # Create memory stream $CsvStream = New-Object System.IO.MemoryStream # Create stream writer $StreamWriter = New-Object System.IO.StreamWriter $CsvStream } # Check components if ($Components) { # Write header $StreamWriter.WriteLine('Name, Version, Revision, Build Number, Update, Bundle, Bundle File, Category, Description, Release Date, Type, Alternative Name, Manufacturer, File Name, File Size, File Date, File Md5sum, Operating System') # Add lines foreach ($component in $Components) { # Write name $line = '"' + $component.Name + '"' # Write version $line += ',"' + $component.Version + '"' # Write revision $line += ',"' + $component.Revision + '"' # Write build number $line += ',"' + $component.BuildNumber + '"' # Write update recommendation $line += ',"' + $component.TypeOfChange + '"' # Write bundle version $line += ',"' + $component.Bundle + '"' # Write bundle file $line += ',"' + $component.BundleFile + '"' # Write category $line += ',"' + $component.Category + '"' # Write description $line += ',"' + $component.Description + '"' # Write release date if ($component.ReleaseYear -and $component.ReleaseMonth -and $component.ReleaseDay) { $line += ',"' + $component.ReleaseYear + '-' + $component.ReleaseMonth + '-' + $component.ReleaseDay + '"' } else { $line += ',""' } # Write type $line += ',"' + $component.Type + '"' # Write alternative name $line += ',"' + $component.AltName + '"' # Write manufacturer $line += ',"' + $component.Manufacturer + '"' # Set file lines $filelines = @() # Write files foreach ($item in $component.Files) { $filelines += $line + ',"' + $item.Name + '","' + $item.Size + '","' + $item.DateModified + '","' + $item.Md5Sum + '"' } # Set operating system lines $operatingsystemlines = @() # Write operating systems foreach ($line in $filelines) { foreach ($operatingsystem in $component.OperatingSystems) { $operatingsystemlines += $line + ',"' + $operatingsystem + '"' } } # Write operating system lines foreach ($line in $operatingsystemlines) { $StreamWriter.WriteLine($line) } } # Flush stream writer $StreamWriter.Flush() if (!$File) { # Create stream reader $StreamReader = New-Object System.IO.StreamReader $CsvStream # Write output $CsvStream.Position = 0 while ($null -ne ($line = $StreamReader.ReadLine())) { Write-Output $line } # Close stream reader $StreamReader.Close() } # Close stream writer $StreamWriter.Close() } } } |