View/Install-WindowsFeature.Task.ps1

Function Global:Show-InstallStatusUi{
    Class StatusItem{
        $Status
        $IsCompleted
    }
    $Global:StatusList = @()

    $Global:WindowsFeatureUIStatus = New-Object StatusItem
    $Global:WindowsFeatureUIStatus.Status = $Arguments.DisplayName
    $Global:StatusList += $WindowsFeatureUIStatus
    $MainWindow.Dispatcher.Invoke({
        $MainWindow.FindName("StatusList").DataContext = $StatusList
        $MainWindow.FindName("StatusTitle").Text = "インストールしています"
        $MainWindow.FindName("IndicatorRoot").Visibility = [System.Windows.Visibility]::Visible
    })
    If ($Arguments.Type -eq "WindowsFeature"){
        Invoke-InstallWindowsFeature $Arguments.WindowsFeatureName
    }
    Else{
        Invoke-SilentInstall -Component $Arguments
    }
    
    $MainWindow.Dispatcher.Invoke({
        $MainWindow.FindName("IndicatorRoot").Visibility = [System.Windows.Visibility]::Collapsed
    })
}

Function Global:Invoke-SilentInstall($Component){
    $TemporayPath = (New-TemporaryFile).FullName
    Try{
        $LocalInstallerPath = (Join-Path (Get-ProgramDataDirectory) $Component.FileName)
        #$LocalInstallerPath = "$env:USERPROFILE\Downloads\$($Component.FileName)"
        If (-not (Test-Path $LocalInstallerPath -PathType Leaf)){
            Write-Verbose "[$($Component.DisplayName)] ダウンロードします"
            [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
            Invoke-WebRequest -Uri $Component.DownloadUrl -OutFile $TemporayPath
            $LocalInstallerPath = (Join-Path (Split-Path $TemporayPath -Parent) $Component.FileName)
            Move-Item -Path $TemporayPath -Destination $LocalInstallerPath -Force
            $TemporayPath = $LocalInstallerPath
        }
        Else{
            Write-Verbose "[$($Component.DisplayName)] ダウンロード済みのファイルを使用します"
        }
        If ((Get-AuthenticodeSignature $LocalInstallerPath).Status -ne "Valid"){
            Write-Error "デジタル署名が無効のため実行をキャンセルしました。`n途中でダウンロードがキャンセルされた、ファイルが破損した可能性があります。"
        }
        If ($Component.SilentInstall -like "msi" -and $Component.AcceptEula -ne $Null){
            $Process = (Start-Process -FilePath msiexec -ArgumentList "-Package $LocalInstallerPath -Passive -NoRestart $($Component.AcceptEula)" -PassThru -Wait)
        }
        ElseIf ($Component.SilentInstall -like "msi"){
            $Process = (Start-Process -FilePath msiexec -ArgumentList "-Package $LocalInstallerPath -Passive -NoRestart" -PassThru -Wait)
        }
        Else{
            $Process = (Start-Process -FilePath $LocalInstallerPath -ArgumentList "-Install -Passive" -PassThru -Wait)
        }
        write-warning $LocalInstallerPath
        If ($Process.ExitCode -ne 0){
            Write-Warning "[$($Component.DisplayName)] 実行しましたがインストールできませんでした: $($Process.ExitCode)"
        }
    }
    Catch{
        Write-Warning "[$($Component.DisplayName)] インストールできませんでした: $($_.Exception.Message)"
    }
    Finally{
        Remove-Item $TemporayPath -Force -ErrorAction Ignore | Out-Null
    }
}

Function Global:Invoke-InstallWindowsFeature($WindowsFeatureName){
    Try{
        Install-WindowsFeature $WindowsFeatureName -IncludeManagementTools
    }
    Catch{
        Write-Warning "[$($Component.DisplayName)] インストールできませんでした: $($_.Exception.Message)"
    }
}