IBMProductMedia.psm1
<#
PowerShell Classes to Model IBM Installation Media Key features: - Model product configuration that can be extracted as Clixml files for later use - Expand IBM media from local or network shares - Get estimated size of the product installation - Get list of repository locations once media has been extracted #> <# PowerShell Object Model for IBM Installation Manager media files. Typically media files are zip files provided by IBM. #> Class MediaFile { #Filename of the media file [String] $Name #(Optional) Location of the repository.config file within the zip file [String] $RepositoryConfigPath #(Optional) Size of media on disk once extracted [Long] $SizeOnDisk #Zip files inside this media file that may need to be extracted [MediaFile[]] $SubMediaFiles <# Extract this media file to the target path (Requires 7-Zip) #> [Bool] ExtractMedia([String] $TargetPath, [String] $SourcePath, [bool] $DeepScan = $false) { Return ($this._ExtractMedia($this, $TargetPath, $SourcePath, $DeepScan)) } hidden [Bool] _ExtractMedia([MediaFile] $mediaFile, [String] $TargetPath, [String] $SourcePath, [bool] $DeepScan) { $extracted = $false $fullMediaPath = Join-Path $SourcePath -ChildPath ($mediaFile.Name) if (!(Test-Path alias:zip)) { #Setup 7-Zip Alias $sevenZipExe = Get-SevenZipExecutable if (!([string]::IsNullOrEmpty($sevenZipExe)) -and (Test-Path($sevenZipExe))) { Set-Alias zip $sevenZipExe -Scope 'Script' } else { Write-Error "MediaFile depends on 7-Zip, please ensure 7-Zip is installed first" Return $false } } if (Test-Path($fullMediaPath)) { Write-Verbose "Extracting installation media from: $fullMediaPath" zip x "-o$TargetPath" "$fullMediaPath" | Out-Null # Some media have an additional zip file needed to extract, find it, expand it, and delete it to save disk space if ($DeepScan) { $childZipFiles = Get-ChildItem *.zip -Path $TargetPath foreach ($childZipFile in $childZipFiles) { zip x "-o$TargetPath" $childZipFile.FullName | Out-Null Remove-Item $childZipFile.FullName -force } } Write-Verbose "Completed extracting media files to directory: $TargetPath" $extracted = $true } else { Write-Error "Unable to access media files. Media Path is: $SourcePath" $extracted = $false } if ($extracted) { if ($mediaFile.SubMediaFiles -and ($mediaFile.SubMediaFiles.Count -gt 0)) { Foreach ($subMediaFile in $mediaFile.SubMediaFiles) { $extracted = $subMediaFile._ExtractMedia($subMediaFile, $TargetPath, $SourcePath) } } } Return $extracted } <# Returns a list of paths to the repository locations of this media file and its children #> [String[]] GetRepositoryLocations([String] $BasePath, [Bool] $Validate) { Return ($this._GetRepositoryLocations($this, $BasePath, $Validate)) } hidden [String[]] _GetRepositoryLocations([MediaFile] $mediaFile, [String] $BasePath, [Bool] $Validate) { [String[]] $repositories = @(); if ($mediaFile.RepositoryConfigPath) { $repositoryFullPath = Join-Path -Path $BasePath -ChildPath $mediaFile.RepositoryConfigPath if ($Validate) { try { if (Test-Path($repositoryFullPath)) { $repositories += $repositoryFullPath } else { Write-Error "Repository location not found: $repositoryFullPath" } } catch [System.Exception] { Write-Error "Repository location not found or could not be reached: $repositoryFullPath" } } else { $repositories += $repositoryFullPath } } if ($mediaFile.SubMediaFiles -and ($mediaFile.SubMediaFiles.Count -gt 0)) { Foreach ($subMediaFile in $mediaFile.SubMediaFiles) { $repositories += $subMediaFile._GetRepositoryLocations($subMediaFile, $BasePath, $Validate) } } Return $repositories } } <# PowerShell Object Model for IBM Products that will be installed via IBM Installation Manager #> Class IBMProductMedia { # Name of the IBM product, should match offering name in repository.xml [String] $Name # (optional) Shortname of the IBM product, will be added to the path when media is extracted. [String] $ShortName # Version of the IBM product, should match offering version in repository.xml [System.Version] $Version # List of media files that make up this product [MediaFile[]] $MediaFiles # List of fixes required for the installation [MediaFile[]] $RequiredFixesMediaFiles # List of other products that this product depends on as part of the installation [IBMProductMedia[]] $RequiredProducts <# Extracts all the required media for this product to be installed. #> [Bool] ExtractMedia([String] $TargetPath, [String] $SourcePath, [System.Management.Automation.PSCredential] $SourcePathCredential, [Bool] $CleanUp, [bool] $DeepScan = $false) { if (([string]::IsNullOrEmpty($SourcePath)) -or ([string]::IsNullOrEmpty($TargetPath))) { Write-Error "TargetPath and SourcePath are required parameters" Return $false } #Make sure media is available, map to random drive if network drive $networkShare = $false try { if (($SourcePath.StartsWith("\\")) -and (!(Test-Path($SourcePath)))) { $networkShare = $true } } catch [System.UnauthorizedAccessException] { $networkShare = $true } if ($networkShare) { Write-Verbose "Network Share detected, need to map" Set-NetUse -SharePath (Split-Path($SourcePath)) -SharePathCredential $SourcePathCredential -Ensure "Present" | Out-Null } if (!(Test-Path $SourcePath -PathType Container)) { Write-Error "Invalid SourcePath (Not A Folder). SourcePath should be a folder where the IBM media is residing" } if (($CleanUp) -and (Test-Path($TargetPath))) { Write-Verbose "Cleaning up existing target path for installation media: $TargetPath" Remove-Item $TargetPath -Recurse -Force } if (!(Test-Path($TargetPath))) { New-Item -ItemType directory -Path $TargetPath | Out-Null } try { $this._ExtractMedia($this, $TargetPath, $SourcePath, $DeepScan) } catch { $ErrorMessage = $_.Exception.Message Write-Error "An error occurred while extracting the media: $SourcePath \n Error Message: $ErrorMessage" } finally { if ($networkShare) { try { Set-NetUse -SharePath (Split-Path($SourcePath)) -SharePathCredential $SourcePathCredential -Ensure "Absent" | Out-Null } catch { Write-Warning "Unable to disconnect share: $SourcePath" } } } Return ($this._GetRepositoryLocations($this, $TargetPath, $CleanUp)) } hidden [Bool] _ExtractMedia([IBMProductMedia] $ibmProductMedia, [String] $TargetPath, [String] $SourcePath, [bool] $DeepScan) { [Bool] $extracted = $false [Bool] $hasMedia = $false [Bool] $mediaExtracted = $false [Bool] $hasFixes = $false [Bool] $fixesExtracted = $false [String[]] $productTargetPath = $TargetPath if ($ibmProductMedia.ShortName) { $productTargetPath = Join-Path -Path $TargetPath -ChildPath $ibmProductMedia.ShortName } if ($ibmProductMedia.MediaFiles -and ($ibmProductMedia.MediaFiles.Count -gt 0)) { $hasMedia = $true $mediaExtracted = $true Foreach ($mediaFile in $ibmProductMedia.MediaFiles) { if ($mediaExtracted) { $mediaExtracted = $mediaFile.ExtractMedia($productTargetPath, $SourcePath, $DeepScan) } } $extracted = $mediaExtracted } if (!$extracted -or ($hasMedia -and $mediaExtracted)) { if ($ibmProductMedia.RequiredFixesMediaFiles -and ($ibmProductMedia.RequiredFixesMediaFiles.Count -gt 0)) { $hasFixes = $true $fixesExtracted = $true Foreach ($mediaFile in $ibmProductMedia.RequiredFixesMediaFiles) { if ($fixesExtracted) { $fixesExtracted = $mediaFile.ExtractMedia($productTargetPath, $SourcePath, $DeepScan) } } $extracted = $fixesExtracted } } if (!$extracted -or (($hasFixes -or $hasMedia) -and $extracted)) { if ($ibmProductMedia.RequiredProducts -and ($ibmProductMedia.RequiredProducts.Count -gt 0)) { Foreach ($ibmProduct in $ibmProductMedia.RequiredProducts) { $extracted = $this._ExtractMedia($ibmProduct, $TargetPath, $SourcePath, $DeepScan) } } } Return $extracted } <# Returns a list of paths to the repository locations of this product and its dependent products #> [String[]] GetRepositoryLocations([String] $BasePath, [Bool] $Validate) { Return ($this._GetRepositoryLocations($this, $BasePath, $Validate)) } hidden [String[]] _GetRepositoryLocations([IBMProductMedia] $ibmProductMedia, [String] $BasePath, [Bool] $Validate) { [String[]] $repositories = @(); [String[]] $productBasePath = $BasePath if ($ibmProductMedia.ShortName) { $productBasePath = Join-Path -Path $BasePath -ChildPath $ibmProductMedia.ShortName } if ($ibmProductMedia.MediaFiles -and ($ibmProductMedia.MediaFiles.Count -gt 0)) { Foreach ($mediaFile in $ibmProductMedia.MediaFiles) { $repositories += $mediaFile.GetRepositoryLocations($productBasePath, $Validate) } } if ($ibmProductMedia.RequiredFixesMediaFiles -and ($ibmProductMedia.RequiredFixesMediaFiles.Count -gt 0)) { Foreach ($mediaFile in $ibmProductMedia.RequiredFixesMediaFiles) { $repositories += $mediaFile.GetRepositoryLocations($productBasePath, $Validate) } } if ($ibmProductMedia.RequiredProducts -and ($ibmProductMedia.RequiredProducts.Count -gt 0)) { Foreach ($ibmProduct in $ibmProductMedia.RequiredProducts) { $repositories += $this._GetRepositoryLocations($ibmProduct, $BasePath, $Validate) } } Return $repositories } <# Returns the estimated disk space that this product will consume once extracted #> [Long] GetTotalSizeOnDisk() { Return ($this._GetTotalSizeOnDisk($this)) } hidden [Long] _GetTotalSizeOnDisk([IBMProductMedia] $ibmProductMedia) { [Long] $sizeOnDisk = 0; if ($ibmProductMedia.MediaFiles -and ($ibmProductMedia.MediaFiles.Count -gt 0)) { Foreach ($mediaFile in $ibmProductMedia.MediaFiles) { $sizeOnDisk += $mediaFile.SizeOnDisk } } if ($ibmProductMedia.RequiredFixesMediaFiles -and ($ibmProductMedia.RequiredFixesMediaFiles.Count -gt 0)) { Foreach ($mediaFile in $ibmProductMedia.RequiredFixesMediaFiles) { $sizeOnDisk += $mediaFile.SizeOnDisk } } if ($ibmProductMedia.RequiredProducts -and ($ibmProductMedia.RequiredProducts.Count -gt 0)) { Foreach ($ibmProduct in $ibmProductMedia.RequiredProducts) { $sizeOnDisk += $this._GetTotalSizeOnDisk($ibmProduct) } } Return $sizeOnDisk } } |