Ian Manning
Ian Manning

Reputation: 81

Passing switches ( eg -IncludeManagementTools) to Install-WindowsFeature as variables

I'm using this as a way of finally getting around to using Stackoverflow properly!

I'm trying to run the following line as part of a larger script:

Install-WindowsFeature Web-Server -IncludeManagementTools

WHich obviously works on it's own, but not when I try and pass "-IncludeManagementTools" as part of a variable.

I'm reading in the list of features to install as part of a text file, and some of these have option parameters like -IncludeManagementTools . Passing the first part "Web-Server" works fine, passing the second part doesn't, unless typed in directly to the console, ie

    $var="Web-Server"        
    Install-WindowsFeature $var -IncludeManagementTools

Full current code is below; I've tried splitting on the variable as well as what is below, and using Switch statements rather than if loops, but the optional parameter always gets misinterpreted as the name of the feature to install eg:

    $currentline = "Web-Server -IncludeManagementTools"
    Install-WindowsFeature $currentline.Split(" ")[0]

Works, but

    $currentline = "Web-Server -IncludeManagementTools"
    Install-WindowsFeature $currentline.Split(" ")[0] $currentline.split(" ")[1]

Fails. ANy help greatly appreciated!

Full code:

Param(
    [Parameter(Mandatory=$true,Position=1)]
    [string]$ConfigFilePath
)

$featurelist = Import-Csv $ConfigFilePath

# Install requested features
$featurelist | % {
    # The install commands have some optional switches which could be in the input file
    # to avoid an error reading in the Install-* commands, split on " " and feed into the command as seperate strings
    If ( $_.feature -contains " " ) {
        If ( $_.feature -eq "-IncludeManagementTools") {Install-WindowsFeature -Name "($_.feature.Split(" ")[0]) -IncludeManagementTools"}
        Else {}
        If ( $_.feature -eq "-IncludeAllSubFeature") { Install-WindowsFeature -Name "($_.feature.Split(" ")[0]) -IncludeAllSubfeature" }
        Else {}
        }
    Else {
        Install-WindowsFeature -Name $_.feature
    }
}

$installed = @()

# Check installs work
$featurelist | % {
    # The install commands have some optional switches which could be in the input file
    # to avoid an error reading in the Get-* commands, remove anything that comes after a space (ie effectively removing optional switches)
    $installed += Get-WindowsFeature -Name $_.feature.Split(" ")[0]
    }

$missing = $installed | ? { $_.Installed -eq $false }

If (!($missing)) {
    Write-Host "All requested features installed ok." -ForegroundColor Green -BackgroundColor Black
}
Else {
    Write-Host "Some features requested weren't installed.  They will be outputted below." -ForegroundColor Black -BackgroundColor Red
    $missing
}

Upvotes: 1

Views: 767

Answers (2)

ErikW
ErikW

Reputation: 426

After running

Install-WindowsFeature Web-Server -IncludeManagementTools

Run the following

Get-WindowsFeature

It should show all windows features installed. Whatever is included in the 'Include Management Tools' switch is broken down and has it's own feature Name. So everything can be installed with 'Install-WindowsFeature -Name xxx'

Upvotes: 1

Bacon Bits
Bacon Bits

Reputation: 32230

This isn't a direct answer, more of a recommendation to change how you've structured your setup to something that's more explicit and more maintainable.

It looks to me like you'd benefit from using splatting. It lets you use a hashtable to hold the parameters for a command, which can make dynamic parameters a bit easier.

$WindowsFeatureParameters = @{
    Name = 'Web-Server'
    IncludeManagementTools = $true
}
Install-WindowsFeature @WindowsFeatureParameters

I would also change your CSV file to have a different column for each parameter. Imagine something like:

FeatureName,IncludeManagementTools,IncludeAllSubFeature
Web-Server,Yes,No

Now you can specify:

$FeatureList = Import-Csv $ConfigFilePath 
foreach ($Feature in $FeatureList) {
    $WindowsFeatureParameters = @{
        Name = 'Web-Server'
        IncludeManagementTools = ($Feature.IncludeManagementTools -eq 'Yes')
        IncludeAllSubFeature= ($Feature.IncludeAllSubFeature -eq 'Yes')
    }
    Install-WindowsFeature @WindowsFeatureParameters
}

$Installed = foreach ($Feature in $FeatureList) {
    Get-WindowsFeature -Name $Feature.FeatureName
}

$Missing = $Installed | Where-Object Installed -eq $false

Alternately, you can specify a variable with a switch to control it's value:

# Install with management tools
$ManagementTools = $true
Install-WindowsFeature 'Web-Server' -IncludeManagementTools:$ManagementTools

# Install without management tools
$ManagementTools = $false
Install-WindowsFeature 'Web-Server' -IncludeManagementTools:$ManagementTools

Obviously, $ManagementTools could be set by any boolean test.

Upvotes: 0

Related Questions