Last active
June 15, 2016 22:40
-
-
Save guitarrapc/7dc6c33854028345ee6d to your computer and use it in GitHub Desktop.
PowerShell WebPlatformInstaller Module (rough)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #region Initializer | |
| function New-WebPlatformInstaller | |
| { | |
| [OutputType([Void])] | |
| [CmdletBinding()] | |
| param() | |
| try | |
| { | |
| Add-Type -Path "C:\Program Files\Microsoft\Web Platform Installer\Microsoft.Web.PlatformInstaller.dll" | |
| } | |
| catch | |
| { | |
| } | |
| $script:WebPI = @{} | |
| } | |
| function New-WebPlatformInstallerProductManager | |
| { | |
| [OutputType([Void])] | |
| [CmdletBinding()] | |
| param() | |
| if ($null -eq $WebPI){ New-WebPlatformInstaller } | |
| $productManager = New-Object Microsoft.Web.PlatformInstaller.ProductManager | |
| $productManager.Load() | |
| $WebPI.productManager = $productManager | |
| Write-Verbose "Remove Blank Keywords Products / IIS Components (Windows Feature)" | |
| $WebPI.productManagerProducts = $WebPI.productManager.Products | where Keywords | where Title -notlike 'IIS:*' | |
| $WebPI.productManagerProductsIISComponent = $WebPI.productManager.Products | where Keywords | where Title -like 'IIS:*' | |
| } | |
| function New-WebPlatformInstallerInstallManager | |
| { | |
| [OutputType([Void])] | |
| [CmdletBinding()] | |
| param() | |
| if ($null -eq $WebPI){ New-WebPlatformInstaller } | |
| $WebPI.installManager = New-Object Microsoft.Web.PlatformInstaller.InstallManager | |
| } | |
| #endregion | |
| #region Product | |
| function Get-WebPlatformInstallerProduct | |
| { | |
| [OutputType([Microsoft.Web.PlatformInstaller.Product[]])] | |
| [CmdletBinding(DefaultParameterSetName = "Any")] | |
| param | |
| ( | |
| [parameter(Mandatory = 0, Position = 0, ValueFromPipelineByPropertyName = 1, ValueFromPipeline = 1)] | |
| [string[]]$ProductId, | |
| [switch]$Force | |
| ) | |
| begin | |
| { | |
| if (($null -eq $WebPI.productManagerProducts) -or $Force){ New-WebPlatformInstallerProductManager } | |
| # Initialize | |
| if ($PSBoundParameters.ContainsKey('ProductId')) | |
| { | |
| Write-Verbose ("ParameterSet 'ProductId' detected. Make sure IIS Components (Windows Feature) will never get result.") | |
| $result = $null | |
| $private:productManagerDic = New-Object 'System.Collections.Generic.Dictionary[[string], [Microsoft.Web.PlatformInstaller.Product]]' ([StringComparer]::OrdinalIgnoreCase) | |
| $WebPI.productManagerProducts | %{$productManagerDic.Add($_.ProductId, $_)} | |
| } | |
| } | |
| process | |
| { | |
| if (-not $PSBoundParameters.ContainsKey('ProductId')) | |
| { | |
| Write-Verbose ("Searching All Products.") | |
| return $WebPI.productManagerProducts | sort ProductId | |
| } | |
| foreach ($id in $ProductId) | |
| { | |
| # Search product by ProductId | |
| Write-Verbose ("Searching ProductId : '{0}'" -f $id) | |
| $isSuccess = $productManagerDic.TryGetValue($id, [ref]$result) | |
| if ($isSuccess){ $result; continue; } | |
| if ($id -in $WebPI.productManagerProductsIISComponent.ProductId){ [Console]::WriteLine("ProductId '{0}' will skip as it detected IIS Component." -f $id); continue; } | |
| throw New-Object System.InvalidOperationException ("WebPlatform Installation could not found package '{0}' as valid ProductId. Please select from '{1}'" -f $id, (($WebPI.productManagerProducts.ProductId | sort) -join "', '")) | |
| } | |
| } | |
| } | |
| function Test-WebPlatformInstallerProductIsInstalled | |
| { | |
| [OutputType([bool])] | |
| [CmdletBinding(DefaultParameterSetName = "Any")] | |
| param | |
| ( | |
| [parameter(Mandatory = 1, Position = 0, ValueFromPipelineByPropertyName = 1, ValueFromPipeline = 1)] | |
| [string[]]$ProductId | |
| ) | |
| Get-WebPlatformInstallerProduct -ProductId $ProductId | % {$_.IsInstalled($null)} | |
| } | |
| #endregion | |
| #region Install | |
| function Install-WebPlatformInstallerProgram | |
| { | |
| [OutputType([Microsoft.Web.PlatformInstaller.Product[]])] | |
| [CmdletBinding()] | |
| param | |
| ( | |
| [parameter(Mandatory = 0, Position = 0, ValueFromPipelineByPropertyName = 1, ValueFromPipeline = 1)] | |
| [string[]]$ProductId, | |
| [parameter(Mandatory = 0, Position = 0, ValueFromPipelineByPropertyName = 1)] | |
| [ValidateSet('en', 'fr', 'es', 'de', 'it', 'ja', 'ko', 'ru', 'zh-cn', 'zh-tw', 'cs', 'pl', 'tr', 'pt-br', 'he', 'zh-hk', 'pt-pt')] | |
| [string]$LanguageCode = 'en' | |
| ) | |
| begin | |
| { | |
| # Initialize | |
| if ($null -eq $WebPI.productManager){ New-WebPlatformInstallerProductManager } | |
| New-WebPlatformInstallerInstallManager | |
| $productIdList = New-Object 'System.Collections.Generic.List[string]' | |
| # Get Language | |
| [Microsoft.Web.PlatformInstaller.Language]$language = $WebPI.productManager.GetLanguage($LanguageCode) | |
| $installer = New-Object 'System.Collections.Generic.List[Microsoft.Web.PlatformInstaller.Installer]' | |
| function ShowInstallerContextStatus | |
| { | |
| if ($null -ne $WebPI.installManager.InstallerContexts){ $WebPI.installManager.InstallerContexts | Out-String -Stream | Write-Verbose } | |
| } | |
| function WatchInstallationStatus | |
| { | |
| [OutputType([bool])] | |
| [CmdletBinding()] | |
| param | |
| ( | |
| [parameter(Mandatory = 0, Position = 0, ValueFromPipelineByPropertyName = 1)] | |
| [Microsoft.Web.PlatformInstaller.InstallationState]$PreStatus, | |
| [parameter(Mandatory = 0, Position = 0, ValueFromPipelineByPropertyName = 1)] | |
| [Microsoft.Web.PlatformInstaller.InstallationState]$PostStatus | |
| ) | |
| # Skip | |
| if ($postStatus -eq $preStatus) | |
| { | |
| Write-Verbose "Installation not begin" | |
| return $false | |
| } | |
| # Monitor | |
| ShowInstallerContextStatus | |
| while($postStatus -ne [Microsoft.Web.PlatformInstaller.InstallationState]::InstallCompleted) | |
| { | |
| Start-Sleep -Milliseconds 100 | |
| $postStatus = $WebPI.installManager.InstallerContexts.InstallationState | |
| } | |
| ShowInstallerContextStatus | |
| $logfiles = $WebPI.installManager.InstallerContexts.Installer.LogFiles | |
| Write-Verbose ("'{0}' Installation completed. Check Log file at '{1}'." -f ($ProductId -join "', '"), ($logfiles -join "', '")) | |
| #Write-Verbose ("Latest Log file is '{0}'." -f (cat -Path ($logfiles) -Encoding UTF8 -Raw)) | |
| return $true | |
| } | |
| } | |
| process | |
| { | |
| Write-Verbose "Checking Product is already installed." | |
| $ProductId ` | |
| | % { | |
| if(Test-WebPlatformInstallerProductIsInstalled -ProductId $_){ [Console]::WriteLine("Package '{0}' already installed. Skip installation." -f $_); return; } | |
| $productIdList.Add($_) | |
| } | |
| } | |
| end | |
| { | |
| if (($productIdList | measure).count -eq 0){ return; } | |
| try | |
| { | |
| Write-Verbose "Get Product" | |
| [Microsoft.Web.PlatformInstaller.Product[]]$product = Get-WebPlatformInstallerProduct -ProductId $productIdList | |
| if ($null -eq $product){ throw New-Object System.NullReferenceException } | |
| Write-Verbose "Get Installer" | |
| $product ` | |
| | % { | |
| $x = $_.GetInstaller($language) | |
| if ($null -eq $x.InstallerFile){ [Console]::WriteLine("Package '{0}' detected as no Installer to install. Skip Installation." -f $_.ProductId); return; } | |
| $installer.Add($x) | |
| $WebPI.InstallManager.Load($installer) | |
| Write-Verbose "Donwload Installer" | |
| ShowInstallerContextStatus | |
| $failureReason = $null | |
| $success = $WebPI.InstallManager.InstallerContexts | %{ $WebPI.installManager.DownloadInstallerFile($_, [ref]$failureReason) } | |
| if ((-not $success) -and $failureReason){ throw New-Object System.InvalidOperationException ("Donwloading '{0}' Failed Exception!! Reason : {1}" -f ($ProductId -join "' ,'"), $failureReason ) } | |
| Write-Verbose "Show Donwloaded Installer Status" | |
| ShowInstallerContextStatus | |
| # Get Status | |
| [Microsoft.Web.PlatformInstaller.InstallationState]$preStatus = $WebPI.installManager.InstallerContexts.InstallationState | |
| Write-Verbose "Start Installation with StartInstallation()" | |
| $WebPI.installManager.StartInstallation() | |
| if (WatchInstallationStatus -PreStatus $preStatus -PostStatus $WebPI.installManager.InstallerContexts.InstallationState){ return; } | |
| Write-Verbose "Start Installation with StartApplicationInstallation()" | |
| $WebPI.installManager.StartApplicationInstallation() | |
| if (WatchInstallationStatus -PreStatus $preStatus -PostStatus $WebPI.installManager.InstallerContexts.InstallationState){ return; } | |
| Write-Verbose "Start Installation with StartSynchronousInstallation()" | |
| $installResult = $WebPI.installManager.StartSynchronousInstallation() | |
| if (WatchInstallationStatus -PreStatus $preStatus -PostStatus $WebPI.installManager.InstallerContexts.InstallationState){ return; } | |
| } | |
| } | |
| catch | |
| { | |
| throw $_ | |
| } | |
| finally | |
| { | |
| if ($null -ne $WebPI.installManager){ $WebPI.installManager.Dispose() } | |
| } | |
| } | |
| } | |
| #endregion |
Author
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Usage
Test-WebPlatformInstallerProductIsInstalled
Get-WebPlatformInstallerProduct
Install-WebPlatformInstallerProgram