MSI.psm1
#Requires -Version 2.0 # The MIT License (MIT) # # Copyright (c) Microsoft Corporation # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in all # copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. $script:loc = data { convertfrom-stringdata @' AdvtCaption = Confirm install AdvtDescription = Installing advertised features for product, {0}. AdvtWarning = Are you sure you want to install advertised features for product, {0}? '@ } import-localizeddata -bind loc -filename Resources.psd1 -ea SilentlyContinue function Get-MSIComponentState { # .ExternalHelp Microsoft.Tools.WindowsInstaller.PowerShell.dll-Help.xml [CmdletBinding(DefaultParameterSetName = "Product")] param ( [Parameter(ParameterSetName = "Product", Position = 0, Mandatory = $true, ValueFromPipeline = $true)] [Microsoft.Deployment.WindowsInstaller.ProductInstallation[]] $Product, [Parameter(ParameterSetName = "ProductCode", Position = 0, Mandatory = $true, ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)] [Microsoft.Tools.WindowsInstaller.PowerShell.ValidateGuid()] [string[]] $ProductCode, [Parameter(ParameterSetName = "ProductCode", ValueFromPipelineByPropertyName = $true)] [Alias("Context", "InstallContext")] [Microsoft.Deployment.WindowsInstaller.UserContexts] $UserContext = "All", [Parameter(ParameterSetName = "ProductCode", ValueFromPipelineByPropertyName = $true)] [Microsoft.Tools.WindowsInstaller.PowerShell.Sid()] [string] $UserSid ) process { if ($PSCmdlet.ParameterSetName -eq "ProductCode") { $Product = @(,(get-msiproductinfo @PSBoundParameters)) } $Product | foreach-object { [string] $productCode = $_.ProductCode # Get the state of every authored component in the product and applied patches. $_ | get-msitable -table Component | foreach-object { # Attach authored information from the product package to the output object. $_ | get-msicomponentinfo -productcode $productCode ` | foreach-object { $_.PSTypeNames.Insert(0, $_.PSTypeNames[0] + "#State"); $_ } ` | add-member -type NoteProperty -name Component -value $_.Component -passthru } } } } function Get-MSISharedComponentInfo { # .ExternalHelp Microsoft.Tools.WindowsInstaller.PowerShell.dll-Help.xml [CmdletBinding()] param ( [Parameter(Position = 0)] [ValidateNotNullOrEmpty()] [Microsoft.Tools.WindowsInstaller.PowerShell.ValidateGuid()] [string[]] $ComponentCode, [Parameter(Position = 1)] [ValidateRange(2, 2147483647)] [int] $Count = 2 ) end { $getcomponents = { get-msicomponentinfo } if ($ComponentCode) { $getcomponents = { get-msicomponentinfo -componentcode $ComponentCode } } & $getcomponents | group-object -property ComponentCode | where-object { $_.Count -ge $Count } ` | select-object -expand Group } } function Install-MSIAdvertisedFeature { # .ExternalHelp Microsoft.Tools.WindowsInstaller.PowerShell.dll-Help.xml [CmdletBinding(DefaultParameterSetName = "ProductCode", ConfirmImpact = "Medium", SupportsShouldProcess = $true)] param ( [Parameter(ParameterSetName = "ProductCode", ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [Microsoft.Tools.WindowsInstaller.PowerShell.ValidateGuid()] [string[]] $ProductCode, [Parameter(ParameterSetName = "Product", Mandatory = $true, ValueFromPipeline = $true)] [Microsoft.Deployment.WindowsInstaller.ProductInstallation[]] $Product, [Parameter(Position = 0, ValueFromPipelineByPropertyName = $true)] [ValidateNotNullOrEmpty()] [string[]] $FeatureName, [Parameter()] [switch] $Force, [Parameter(ValueFromPipelineByPropertyName = $true, ValueFromRemainingArguments = $true)] [string[]] $Properties ) begin { $YesToAll = $false $NoToAll = $false } process { # Get only specified or all products given a ProductCode. if ($PSBoundParameters.ContainsKey("ProductCode")) { $Product = get-msiproductinfo -productcode $ProductCode } elseif ($PSCmdlet.ParameterSetName -eq "ProductCode") { $Product = get-msiproductinfo } # Get only specified or all features for each selected product. if ($PSBoundParameters.ContainsKey("FeatureName")) { $features = $Product | foreach-object { get-msifeatureinfo -productcode $_.ProductCode -featurename $FeatureName } } else { $features = $Product | get-msifeatureinfo } # Construct and splat the necessary parameters to re-install each product. $features | where-object { $_.State -eq "Advertised" } | group-object ProductCode | foreach-object { $params = @{ "ProductCode" = $_.Name; "Properties" = "$Properties ADDLOCAL=$(($_.Group | select-object -expand Name) -join ',')" } # Get the advertised product name from the existing collection so we don't cause a reentrance issue. $name = $_.Name $name = $Product | where-object { $_.ProductCode -eq $name } | select-object -expand AdvertisedProductName $description = $script:loc.AdvtDescription -f $name $warning = $script:loc.AdvtWarning -f $name if ($PSCmdlet.ShouldProcess($description, $warning, $script:loc.AdvtCaption)) { if ($Force -or $PSCmdlet.ShouldContinue($null, $null, [ref] $YesToAll, [ref] $NoToAll)) { install-msiproduct @params } } } } } # Update the usage information for this module if installed. [Microsoft.Tools.WindowsInstaller.PowerShell.Module]::Use() |