tests/Test-HostServerFeatures.ps1
function Test-HostServerFeatures { [CmdletBinding()] param ( [parameter()][string] $TestName = "Test-HostServerFeatures", [parameter()][string] $TestGroup = "configuration", [parameter()][string] $Description = "Validate Windows Server roles and features for CM site systems", [parameter()][hashtable] $ScriptParams ) try { [System.Collections.Generic.List[PSObject]]$tempdata = @() # for detailed test output to return if needed $stat = "PASS" $msg = "No issues found" Import-Module ServerManager if ($ScriptParams.ComputerName -ne $env:COMPUTERNAME) { if ($ScriptParams.Credential) { $features = Get-WindowsFeature -ComputerName $ScriptParams.ComputerName -Credential $ScriptParams.Credential -ErrorAction Stop } else { $features = Get-WindowsFeature -ComputerName $ScriptParams.ComputerName -ErrorAction Stop } } else { $features = Get-WindowsFeature -ErrorAction Stop } $LogFile = Join-Path $env:TEMP "serverfeatures.log" if ($ScriptParams.Remediate -eq $True -and ([string]::IsNullOrEmpty($ScriptParams.Source))) { throw "Source parameter is required for -Remediate but was not specified" } $flist = @($CmHealthConfig.windowsfeatures.Feature) if ($flist.Count -lt 1) { throw "failed to read features list from cmhealth settings file" } $exceptions = 0 [System.Collections.Generic.List[PSObject]]$missing = @() foreach ($feature in $features) { if ($feature.Name -in $flist) { if ($feature.Installed -ne $True) { Write-Verbose "$($feature.Name) is not installed!" if ($ScriptParams.Remediate -eq $True) { try { Write-Host "installing: $($Feature.Name)" -ForegroundColor Cyan if ($ScriptParams.ComputerName -ne $env:COMPUTERNAME) { if ($ScriptParams.Credential) { Install-WindowsFeature -Name "$($Feature.Name)" -ComputerName $ScriptParams.ComputerName -Credential $ScriptParams.Credential -Source $ScriptParams.Source -LogPath $LogFile -WarningAction SilentlyContinue -ErrorAction Stop } else { Install-WindowsFeature -Name "$($Feature.Name)" -ComputerName $ScriptParams.ComputerName -Source $ScriptParams.Source -LogPath $LogFile -WarningAction SilentlyContinue -ErrorAction Stop } } else { Install-WindowsFeature -Name "$($Feature.Name)" -Source $ScriptParams.Source -LogPath $LogFile -WarningAction SilentlyContinue -ErrorAction Stop } $tempdata.Add([pscustomobject]@{ Feature = $feature.Name Status = "Remediated" Message = "Success" }) } catch { $tempdata.Add([pscustomobject]@{ Feature = $feature.Name Status = "ERROR" Message = $_.Exception.Message -join ';' }) } } else { $exceptions++ $tempdata.Add([pscustomobject]@{ Feature = $feature.Name Statue = "FAIL" Message = "Not installed" }) $missing.Add($feature.Name) } } else { $tempdata.Add([pscustomobject]@{ Feature = $feature.Name Status = "PASS" Message = "Already installed" }) } } } if ($exceptions -gt 0) { $stat = "FAIL" $msg = "$exceptions features are missing: $($missing -join ',')" } } catch { $stat = 'ERROR' $msg = $_.Exception.Message -join ';' } finally { Write-Output $([pscustomobject]@{ TestName = $TestName TestGroup = $TestGroup TestData = $tempdata Description = $Description Status = $stat Message = $msg Credential = $(if($ScriptParams.Credential){$($ScriptParams.Credential).UserName} else { $env:USERNAME }) }) } } |