2.2 release - sync with Dev Branch

This commit is contained in:
Dan Cuomo 2019-07-13 14:03:26 -07:00
Родитель 8c02f9ee79
Коммит 429844e924
20 изменённых файлов: 671 добавлений и 1068 удалений

8
.gitignore поставляемый
Просмотреть файл

@ -3,6 +3,8 @@
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
DSCResource.Tests/
# User-specific files
*.suo
*.user
@ -222,7 +224,7 @@ ClientBin/
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
@ -318,7 +320,7 @@ __pycache__/
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
@ -327,5 +329,5 @@ ASALocalRun/
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
# MFractors (Xamarin productivity tool) working folder
.mfractor/

Просмотреть файл

@ -7,7 +7,7 @@ $Nodes = Get-DCBClusterNodes -Clusters 'S2DCluster01', 'S2DCluster02'
$Nodes | ForEach-Object {
$AllNodes += @{
NodeName = $_
RDMAEnabledAdapters = @(
@{ Name = 'RoCE-01' ; VLANID = '101' ; JumboPacket = 9000 }
@{ Name = 'RoCE-02' ; VLANID = '101' ; JumboPacket = 9000 }

Просмотреть файл

@ -131,7 +131,7 @@ The following options are currently supported:
- ****VLANID**** - (Required) The VLAN assigned to the adapter. Use `Get-NetAdapterAdvancedProperty -RegistryKeyword VLANID` to determine the assigned VLAN
- ****JumboPacket**** - (Optional) The jumbo frame size expected on the adapter. Use the following command to determine the assigned jumbo frame size `Get-NetAdapterAdvancedProperty -RegistryKeyword *JumboPacket`
-
-
- ****EncapOverhead**** - (Optional) The encap overhead specified on the physical adapter. Use the following command to determine the EncapOverhead size `Get-NetAdapterAdvancedProperty -RegistryKeyword *EncapOverhead`
This configuration will check for a configuration on the node like this:

Просмотреть файл

@ -1,6 +1,11 @@
##### :star: More by the Microsoft Core Networking team can be found using the [MSFTNet](https://github.com/topics/msftnet) topic
[![Build status](https://ci.appveyor.com/api/projects/status/ew1fsvkvnk3vi33i?svg=true)](https://ci.appveyor.com/project/MSFTCoreNet/Validate-DCB)
[![downloads](https://img.shields.io/powershellgallery/dt/Validate-DCB.svg?label=downloads)](https://www.powershellgallery.com/packages/Validate-DCB)
##### What's New in v2.1
## :star: More by the Microsoft Core Networking team
Find more from the Core Networking team using the [MSFTNet](https://github.com/topics/msftnet) topic
##### What's New in v2.2
For more information, please see [What's New](WhatsNew.md)
@ -32,7 +37,7 @@ Additional benefits include:
:heavy_check_mark: [New with version 2] Deploy the configuration to nodes
> :information_source: ****Note:****
> This tool does not modify your system unless you specify the -Deploy command.
> This tool does not modify your system unless you specify the -Deploy command.
> As such, you can re-validate the configuration as many times as desired.
# Overview
@ -45,7 +50,7 @@ RDMA over Converged Ethernet (RoCE) requires Data Center Bridging (DCB) technolo
This tool aims to validate the DCB configuration on the Windows nodes by taking an expected configuration as input and unit tests each Windows system.
> :heavy_exclamation_mark: ****Important****: The validation of the network fabric is out-of-scope for this tool
> :heavy_exclamation_mark: ****Important****: The validation of the network fabric is out-of-scope for this tool
# Scenarios
@ -125,7 +130,7 @@ In this example, the current context is used for testing an adapter that is expe
> :white_check_mark: ****Note:**** During runtime, a variable named $ConfigData contains the information from the config file. With a debugger attached, you can walk the variable like this:
>> ```PowerShell
>> [DBG]: PS C:\> $ConfigData.AllNodes.VMSwitch.RDMAEnabledAdapters
>> ```
>> ```
### Passing Tests
If your system passes a test you will see green text similar to this:
@ -151,7 +156,7 @@ You can verify this using the PowerShell noun identified in the test (in the exa
 
### Failing Tests
### Failing Tests
If your system is incorrectly configured, the test will provide an error message on-screen.
@ -161,7 +166,7 @@ Failing tests give information to identify the misconfiguration. In the failing
![](helpers/pics/FailingTest.png)
As you can see above, the ****Enabled**** property corresponding to the:
As you can see above, the ****Enabled**** property corresponding to the:
&emsp;&emsp;<img src="helpers/pics/ComponentID.png" width="475">

Просмотреть файл

@ -0,0 +1 @@


Просмотреть файл

@ -0,0 +1,98 @@
git config --global credential.helper store
Add-Content "$env:USERPROFILE\.git-credentials" "https://$($env:GitHubKey):x-oauth-basic@github.com`n"
git config --global user.email "dcuomo@outlook.com"
git config --global user.name "Dan Cuomo"
git config --global core.autocrlf false
git config --global core.safecrlf false
# Line break for readability in AppVeyor console
Write-Host -Object ''
# Make sure we're using the Master branch and that it's not a pull request
# Environmental Variables Guide: https://www.appveyor.com/docs/environment-variables/
if ($env:APPVEYOR_REPO_BRANCH -ne 'master')
{
Write-Warning -Message "Skipping version increment and publish for branch $env:APPVEYOR_REPO_BRANCH"
}
elseif ($env:APPVEYOR_PULL_REQUEST_NUMBER -gt 0)
{
Write-Warning -Message "Skipping version increment and publish for pull request #$env:APPVEYOR_PULL_REQUEST_NUMBER"
}
else
{
# We're going to add 1 to the revision value since a new commit has been merged to Master
# This means that the major / minor / build values will be consistent across GitHub and the Gallery
Try
{
# This is where the module manifest lives
$manifestPath = ".\$($env:RepoName).psd1"
# Start by importing the manifest to determine the version, then add 1 to the revision
$manifest = Test-ModuleManifest -Path $manifestPath -ErrorAction SilentlyContinue
[System.Version]$version = $manifest.Version
Write-Output "Old Version: $version"
[String]$newVersion = New-Object -TypeName System.Version -ArgumentList ($version.Major, $version.Minor, $version.Build, $env:APPVEYOR_BUILD_NUMBER)
Write-Output "New Version: $newVersion"
# Update the manifest with the new version value and fix the weird string replace bug
#$functionList = ((Get-ChildItem -Path .\$($env:RepoName)).BaseName)
$splat = @{
'Path' = $manifestPath
'ModuleVersion' = $newVersion
#'FunctionsToExport' = $functionList
'Copyright' = "(c) $( (Get-Date).Year ) Inc. All rights reserved."
}
Update-ModuleManifest @splat -ErrorAction SilentlyContinue
(Get-Content -Path $manifestPath) -replace "PSGet_$($env:RepoName)", "$($env:RepoName)" | Set-Content -Path $manifestPath
(Get-Content -Path $manifestPath) -replace 'NewManifest', "$($env:RepoName)" | Set-Content -Path $manifestPath
#(Get-Content -Path $manifestPath) -replace 'FunctionsToExport = ', 'FunctionsToExport = @(' | Set-Content -Path $manifestPath -Force
#(Get-Content -Path $manifestPath) -replace "$($functionList[-1])'", "$($functionList[-1])')" | Set-Content -Path $manifestPath -Force
}
catch
{
throw $_
}
# Publish the new version to the PowerShell Gallery
Try
{
# Build a splat containing the required details and make sure to Stop for errors which will trigger the catch
$PM = @{
Path = '.'
NuGetApiKey = $env:NuGetApiKey
ErrorAction = 'Stop'
Force = $true
}
Publish-Module @PM
Write-Host "$($env:RepoName) PowerShell Module version $newVersion published to the PowerShell Gallery." -ForegroundColor Cyan
}
Catch
{
Write-Warning "Publishing update $newVersion to the PowerShell Gallery failed."
throw $_
}
# Publish the new version back to Master on GitHub
Try
{
# Set up a path to the git.exe cmd, import posh-git to give us control over git, and then push changes to GitHub
# Note that "update version" is included in the appveyor.yml file's "skip a build" regex to avoid a loop
$env:Path += ";$env:ProgramFiles\Git\cmd"
Import-Module posh-git -ErrorAction Stop
git checkout master -q
git add --all
git status
git commit -s -m "Update version to $newVersion"
git push origin master -q
Write-Host "$($env:RepoName) PowerShell Module version $newVersion published to GitHub." -ForegroundColor Cyan
}
Catch
{
Write-Warning "Publishing update $newVersion to GitHub failed."
throw $_
}
}

Просмотреть файл

@ -0,0 +1,14 @@
# Invoke Pester to run tests, then save the results in NUnitXML to populate the AppVeyor tests section
# Pester : https://github.com/pester/Pester/wiki
# Pester Code Coverage : https://info.sapien.com/index.php/scripting/scripting-modules/testing-pester-code-coverage
New-Item -Path .\tests -Name results -ItemType Directory -Force
$testResultPath = '.\tests\build\results\TestResults.xml'
# This is a manifest so no code coverage is possible. Original line kept below:
#...\results\TestsResults.xml -PassThru -CodeCoverage .\MSFTNetworking.Tools.psd1
$res = Invoke-Pester -Path ".\tests\build\unit" -OutputFormat NUnitXml -OutputFile $testResultPath -PassThru
(New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultPath))
if ($res.FailedCount -gt 0) { throw "$($res.FailedCount) tests failed." }

Просмотреть файл

@ -0,0 +1,59 @@
git.exe clone -q https://github.com/PowerShell/DscResource.Tests
Import-Module -Name "$env:APPVEYOR_BUILD_FOLDER\DscResource.Tests\AppVeyor.psm1"
Invoke-AppveyorInstallTask
[string[]]$PowerShellModules = @("Pester", 'posh-git', 'psake', 'poshspec', 'PSScriptAnalyzer')
$ModuleManifest = Test-ModuleManifest .\$($env:RepoName).psd1 -ErrorAction SilentlyContinue
$repoRequiredModules = $ModuleManifest.RequiredModules.Name
if ($repoRequiredModules) { $PowerShellModules += $repoRequiredModules }
# This section is taken care of by Invoke-AppVeyorInstallTask
<#[string[]]$PackageProviders = @('NuGet', 'PowerShellGet')
# Install package providers for PowerShell Modules
ForEach ($Provider in $PackageProviders) {
If (!(Get-PackageProvider $Provider -ErrorAction SilentlyContinue)) {
Install-PackageProvider $Provider -Force -ForceBootstrap -Scope CurrentUser
}
}#>
# Install the PowerShell Modules
ForEach ($Module in $PowerShellModules) {
if ($Module -eq 'FailoverClusters') {
Install-WindowsFeature -Name 'RSAT-Clustering-Mgmt', 'RSAT-Clustering-PowerShell'
}
If (!(Get-Module -ListAvailable $Module -ErrorAction SilentlyContinue)) {
Install-Module $Module -Scope CurrentUser -Force -Repository PSGallery
}
Import-Module $Module
}
# Feature Installation
$serverFeatureList = 'Hyper-V'
$BuildSystem = Get-CimInstance -ClassName 'Win32_OperatingSystem'
Switch -Wildcard ($BuildSystem.Caption) {
'*Windows 10*' {
Write-Output 'Build System is Windows 10'
Write-Output "Not Implemented"
Write-Output 'Build System is Windows 10'
Write-Output "Not Implemented"
Write-Output 'Build System is Windows 10'
# Get FailoverCluster Capability Name
$capabilityName = (Get-WindowsCapability -Online | Where-Object Name -like *RSAT*FailoverCluster.Management*).Name
Add-WindowsCapability -Name $capabilityName -Online
}
Default {
Write-Output "Build System is $($BuildSystem.Caption)"
Install-WindowsFeature -Name $serverFeatureList -IncludeManagementTools
}
}

Просмотреть файл

@ -0,0 +1,27 @@
Describe "$($env:repoName)-Manifest" {
$DataFile = Import-PowerShellDataFile .\$($env:repoName).psd1 -ErrorAction SilentlyContinue
$TestModule = Test-ModuleManifest .\$($env:repoName).psd1 -ErrorAction SilentlyContinue
Context Manifest-Validation {
It "[Import-PowerShellDataFile] - $($env:repoName).psd1 is a valid PowerShell Data File" {
$DataFile | Should Not BeNullOrEmpty
}
It "[Test-ModuleManifest] - $($env:repoName).psd1 should pass the basic test" {
$TestModule | Should Not BeNullOrEmpty
}
Import-Module .\$($env:repoName).psd1 -Force -WarningAction SilentlyContinue -ErrorAction SilentlyContinue
$command = Get-Command $($env:repoName) -ErrorAction SilentlyContinue
It "Should have the $($env:repoName) function available" {
$command | Should not BeNullOrEmpty
}
}
<#
Context Validate-GlobalExamples {
Validate-DCB -ExampleConfig NDKm1 -TestScope Global
}
#>
}

Просмотреть файл

@ -143,9 +143,9 @@ Describe "[Modal Unit]" -Tag Modal {
$netAdapterAdvancedProperty = @()
$netAdapterAdvancedProperty += Get-NetAdapterAdvancedProperty -CimSession $nodeName -Name $AllRDMAEnabledAdapters.Name -ErrorAction SilentlyContinue
$actNetAdapterState.netAdapterAdvancedProperty = $netAdapterAdvancedProperty
Remove-Variable -Name netAdapterAdvancedProperty
#Note: $thisDriver will be empty if using a driver that is not recognized
@ -158,17 +158,17 @@ Describe "[Modal Unit]" -Tag Modal {
It "[SUT: $nodeName]-[RDMAEnabledAdapter: $($thisRDMAEnabledAdapter.Name)]-[Noun: NetAdapterAdvancedProperty] should be NetworkDirect (RDMA) capable" {
$actNetAdapterState.netAdapterAdvancedProperty | Where-Object{$_.Name -eq $thisRDMAEnabledAdapter.Name -and $_.RegistryKeyword -eq '*NetworkDirect'} | Should Not BeNullOrEmpty
}
### Verify Interface is RDMA Enabled
It "[SUT: $nodeName]-[RDMAEnabledAdapter: $($thisRDMAEnabledAdapter.Name)]-[Noun: NetAdapterAdvancedProperty] should have NetworkDirect (RDMA) Enabled" {
($actNetAdapterState.netAdapterAdvancedProperty | Where-Object{$_.Name -eq $thisRDMAEnabledAdapter.Name -and $_.RegistryKeyword -eq '*NetworkDirect'}).DisplayValue | Should Be 'Enabled'
}
### Verify Interface has a VLAN assigned - These NICs are native adapters (no VMSwitch attached)
It "[SUT: $nodeName]-[RDMAEnabledAdapter: $($thisRDMAEnabledAdapter.Name)]-[Noun: NetAdapterAdvancedProperty] should have VLAN $($thisRDMAEnabledAdapter.VLANID) assigned" {
($actNetAdapterState.netAdapterAdvancedProperty | Where-Object{$_.Name -eq $thisRDMAEnabledAdapter.Name -and $_.RegistryKeyword -eq 'VLANID'}).RegistryValue | Should Be $thisRDMAEnabledAdapter.VLANID
}
### Verify if JumboPackets are specified in the config file that they are set properly on the interfaces
If ($thisRDMAEnabledAdapter.JumboPacket) {
It "[SUT: $nodeName]-[RDMAEnabledAdapter: $($thisRDMAEnabledAdapter.Name)]-[Noun: NetAdapterAdvancedProperty] should have Jumbo Packet set to [$($thisRDMAEnabledAdapter.JumboPacket)]" {
@ -190,7 +190,7 @@ Describe "[Modal Unit]" -Tag Modal {
}
}
'Cavium' {
'Cavium' {
#Test for NetworkDirectTechnology - As they support multiple options, we test that the system specifies iWARP or RoCEv2
It "[SUT: $nodeName]-[Adapter: $($thisRDMAEnabledAdapter.Name)]-(Noun: NetAdapterAdvancedProperty) Network Direct Technology must be '1'(iWARP) or '4' (RoCEv2) on Marvell/Cavium adapters" {
$NetworkDirectTechnologyValue = (($actNetAdapterState.netAdapterAdvancedProperty | Where-Object Name -eq $thisRDMAEnabledAdapter.Name) | Where-Object RegistryKeyword -eq '*NetworkDirectTechnology').RegistryValue
@ -210,7 +210,7 @@ Describe "[Modal Unit]" -Tag Modal {
It "[SUT: $nodeName]-[Adapter: $($thisRDMAEnabledAdapter.Name)]-(Noun: NetAdapterAdvancedProperty) Miniport IPv4 RSC should be disabled" {
(($actNetAdapterState.netAdapterAdvancedProperty | Where-Object Name -eq $thisRDMAEnabledAdapter.Name) | Where-Object RegistryKeyword -eq '*RscIPv4').RegistryValue | Should Be 0
}
It "[SUT: $nodeName]-[Adapter: $($thisRDMAEnabledAdapter.Name)]-(Noun: NetAdapterAdvancedProperty) Miniport IPv6 RSC should be disabled" {
(($actNetAdapterState.netAdapterAdvancedProperty | Where-Object Name -eq $thisRDMAEnabledAdapter.Name) | Where-Object RegistryKeyword -eq '*RscIPv6').RegistryValue | Should Be 0
}
@ -224,7 +224,7 @@ Describe "[Modal Unit]" -Tag Modal {
$thisInterfaceDescription = ($actNetAdapterState.netAdapter | Where-Object Name -eq $thisRDMAEnabledAdapter.Name).InterfaceDescription
$lastBoot = Get-WinEvent -ComputerName $nodeName -LogName System -MaxEvents 1 -FilterXPath "*[System[Provider[@Name='eventlog'] and (Level=4 or Level=0) and (EventID=6005)]]"
Try {
# To get all events for testing (not just last boot) remove the TimeCreated in the FilterHashtable
$FWEvent = Get-WinEvent -ComputerName $nodeName -FilterHashTable @{LogName="System"; TimeCreated=$lastboot.TimeCreated; ID = 263; ProviderName = 'mlx5'} -ErrorAction SilentlyContinue
@ -234,7 +234,7 @@ Describe "[Modal Unit]" -Tag Modal {
$FWIndexStart = (0..($XMLFWEvent.Event.EventData.Data.Count - 1) | Where-Object { $XMLFWEvent.Event.EventData.Data[$_] -eq $thisInterfaceDescription }) + 1
$FWIndexEnd = $XMLFWEvent.Event.EventData.Data.Count - 2
$FWIndexMid = ($FWIndexStart..($FWIndexEnd)).Count / 2
$actFWVersion = $null
$recFWVersion = $null
@ -253,7 +253,7 @@ Describe "[Modal Unit]" -Tag Modal {
Remove-Variable -Name actFWVersion, recFWVersion
$interfaceIndex = (0..($XMLFWEvent.Event.EventData.Data.Count - 1) | Where-Object { $XMLFWEvent.Event.EventData.Data[$_] -eq $thisInterfaceDescription })
if ($XMLFWEvent.Event.EventData.Data[$interfaceIndex]) {
It "[SUT: $nodeName]-[Adapter: $($thisRDMAEnabledAdapter.Name)]-[Log: System; EventID: 263] Should have the recommended firmware version for this driver" {
$actualFWVersion | Should be $recommendedFWVersion
@ -293,17 +293,17 @@ Describe "[Modal Unit]" -Tag Modal {
It "[SUT: $nodeName]-[VMSwitch: $($thisCfgVMSwitch.Name)]-[RDMAEnabledAdapter: $($thisRDMAEnabledAdapter.Name)]-[Noun: NetAdapterAdvancedProperty] should be NetworkDirect (RDMA) capable" {
$actNetAdapterState.netAdapterAdvancedProperty | Where-Object{$_.Name -eq $thisRDMAEnabledAdapter.Name -and $_.RegistryKeyword -eq '*NetworkDirect'} | Should Not BeNullOrEmpty
}
### Verify Interface is RDMA Enabled
It "[SUT: $nodeName]-[VMSwitch: $($thisCfgVMSwitch.Name)]-[RDMAEnabledAdapter: $($thisRDMAEnabledAdapter.Name)]-[Noun: NetAdapterAdvancedProperty] should have NetworkDirect (RDMA) Enabled" {
($actNetAdapterState.netAdapterAdvancedProperty | Where-Object{$_.Name -eq $thisRDMAEnabledAdapter.Name -and $_.RegistryKeyword -eq '*NetworkDirect'}).DisplayValue | Should Be 'Enabled'
}
### Verify Interface has a VLAN of 0 - These NICs are attached to a VMSwitch attached, so vNICs will have the VLANID
It "[SUT: $nodeName]-[VMSwitch: $($thisCfgVMSwitch.Name)]-[RDMAEnabledAdapter: $($thisRDMAEnabledAdapter.Name)]-[Noun: NetAdapterAdvancedProperty] should have VLAN '0' assigned" {
($actNetAdapterState.netAdapterAdvancedProperty | Where-Object{$_.Name -eq $thisRDMAEnabledAdapter.Name -and $_.RegistryKeyword -eq 'VLANID'}).RegistryValue | Should Be 0
}
### Verify if JumboPackets are specified in the config file that they are set properly on the interfaces
If ($thisRDMAEnabledAdapter.JumboPacket) {
It "[SUT: $nodeName]-[VMSwitch: $($thisCfgVMSwitch.Name)]-[RDMAEnabledAdapter: $($thisRDMAEnabledAdapter.Name)]-[Noun: NetAdapterAdvancedProperty] should have Jumbo Packet set to [$($thisRDMAEnabledAdapter.JumboPacket)]" {
@ -324,28 +324,28 @@ Describe "[Modal Unit]" -Tag Modal {
(($actNetAdapterState.netAdapterAdvancedProperty | Where-Object Name -eq $thisRDMAEnabledAdapter.Name) | Where-Object RegistryKeyword -eq '*NetworkDirectTechnology').RegistryValue | Should Be 1
}
}
'Cavium' {
'Cavium' {
#Test for NetworkDirectTechnology - As they support multiple options, we test that the system specifies iWARP or RoCEv2
It "[SUT: $nodeName]-[Adapter: $($thisRDMAEnabledAdapter.Name)]-(Noun: NetAdapterAdvancedProperty) Network Direct Technology must be '1'(iWARP) or '4' (RoCEv2) on Marvell/Cavium adapters" {
$NetworkDirectTechnologyValue = (($actNetAdapterState.netAdapterAdvancedProperty | Where-Object Name -eq $thisRDMAEnabledAdapter.Name) | Where-Object RegistryKeyword -eq '*NetworkDirectTechnology').RegistryValue
$NetworkDirectTechnologyValue -eq 1 -or $NetworkDirectTechnologyValue -eq 4 | Should be $true
}
}
'Intel' {
#Test for NetworkDirectTechnology - Adapter must specify iWARP
It "[SUT: $nodeName]-[Adapter: $($thisRDMAEnabledAdapter.Name)]-(Noun: NetAdapterAdvancedProperty) Network Direct Technology must be '1' (iWARP) on Intel adapters" {
(($actNetAdapterState.netAdapterAdvancedProperty | Where-Object Name -eq $thisRDMAEnabledAdapter.Name) | Where-Object RegistryKeyword -eq '*NetworkDirectTechnology').RegistryValue | Should Be 1
}
}
'Mellanox' {
if ($driverName[$driverName.Count - 1] -like 'mlx4*') {
It "[SUT: $nodeName]-[Adapter: $($thisRDMAEnabledAdapter.Name)]-(Noun: NetAdapterAdvancedProperty) Miniport IPv4 RSC should be disabled" {
(($actNetAdapterState.netAdapterAdvancedProperty | Where-Object Name -eq $thisRDMAEnabledAdapter.Name) | Where-Object RegistryKeyword -eq '*RscIPv4').RegistryValue | Should Be 0
}
It "[SUT: $nodeName]-[Adapter: $($thisRDMAEnabledAdapter.Name)]-(Noun: NetAdapterAdvancedProperty) Miniport IPv6 RSC should be disabled" {
(($actNetAdapterState.netAdapterAdvancedProperty | Where-Object Name -eq $thisRDMAEnabledAdapter.Name) | Where-Object RegistryKeyword -eq '*RscIPv6').RegistryValue | Should Be 0
}
@ -359,36 +359,36 @@ Describe "[Modal Unit]" -Tag Modal {
$thisInterfaceDescription = ($actNetAdapterState.netAdapter | Where-Object Name -eq $thisRDMAEnabledAdapter.Name).InterfaceDescription
$lastBoot = Get-WinEvent -ComputerName $nodeName -LogName System -MaxEvents 1 -FilterXPath "*[System[Provider[@Name='eventlog'] and (Level=4 or Level=0) and (EventID=6005)]]"
Try {
# To get all events for testing (not just last boot) remove the TimeCreated in the FilterHashtable
$FWEvent = Get-WinEvent -ComputerName $nodeName -FilterHashTable @{LogName="System"; TimeCreated=$lastboot.TimeCreated; ID = 263; ProviderName = 'mlx5'} -ErrorAction SilentlyContinue
$thisFWEvent = $FWEvent | Where-Object Message -like "$thisInterfaceDescription Firmware version*"
$XMLFWEvent = [xml]$thisFWEvent[0].ToXml()
$FWIndexStart = (0..($XMLFWEvent.Event.EventData.Data.Count - 1) | Where-Object { $XMLFWEvent.Event.EventData.Data[$_] -eq $thisInterfaceDescription }) + 1
$FWIndexEnd = $XMLFWEvent.Event.EventData.Data.Count - 2
$FWIndexMid = ($FWIndexStart..($FWIndexEnd)).Count / 2
$actFWVersion = $null
$recFWVersion = $null
$XMLFWEvent.Event.EventData.Data[$FWIndexStart..($FWIndexStart + $FWIndexMid - 1)] | ForEach-Object {
$actFWVersion += $_ + "."
}
$XMLFWEvent.Event.EventData.Data[($FWIndexStart + $FWIndexMid)..$FWIndexEnd] | ForEach-Object {
$recFWVersion += $_ + "."
}
# Regex replace for last character (extra period)
$actualFWVersion = [string]::Concat($actFWVersion) -replace ".$"
$recommendedFWVersion = [string]::Concat($recFWVersion) -replace ".$"
Remove-Variable -Name actFWVersion, recFWVersion
$interfaceIndex = (0..($XMLFWEvent.Event.EventData.Data.Count - 1) | Where-Object { $XMLFWEvent.Event.EventData.Data[$_] -eq $thisInterfaceDescription })
if ($XMLFWEvent.Event.EventData.Data[$interfaceIndex]) {
It "[SUT: $nodeName]-[Adapter: $($thisRDMAEnabledAdapter.Name)]-[Log: System; EventID: 263] Should have the recommended firmware version for this driver" {
$actualFWVersion | Should be $recommendedFWVersion
@ -402,18 +402,18 @@ Describe "[Modal Unit]" -Tag Modal {
}
}
}
'Broadcom' {
#Test for NetworkDirectTechnology - Adapter must specify RoCEv2
It "[SUT: $nodeName]-[Adapter: $($thisRDMAEnabledAdapter.Name)]-(Noun: NetAdapterAdvancedProperty) Network Direct Technology must be '4' (RoCEv2) on Broadcom adapters" {
(($actNetAdapterState.netAdapterAdvancedProperty | Where-Object Name -eq $thisRDMAEnabledAdapter.Name) | Where-Object RegistryKeyword -eq '*NetworkDirectTechnology').RegistryValue | Should Be 4
}
}
'*' {
# Tests for all IHVs
}
'Default' {
It 'Hardware Vendor for Adapter not Identified' { $false | Should be $true }
}
@ -421,12 +421,12 @@ Describe "[Modal Unit]" -Tag Modal {
}
}
}
# No Disabled Adapters need to be specified, so only run this if there are disabled adapters
if ($cfgRDMADisabledAdapters.Name -or $cfgVMSwitch.RDMADisabledAdapters.Name) {
$DisabledNetAdapterAdvancedProperty = @()
$DisabledNetAdapterAdvancedProperty += Get-NetAdapterAdvancedProperty -CimSession $nodeName -Name $cfgRDMADisabledAdapters.Name, $cfgVMSwitch.RDMADisabledAdapters.Name -ErrorAction SilentlyContinue
$actNetAdapterState.DisabledNetAdapterAdvancedProperty = $DisabledNetAdapterAdvancedProperty
Remove-Variable DisabledNetAdapterAdvancedProperty
@ -439,7 +439,7 @@ Describe "[Modal Unit]" -Tag Modal {
($actNetAdapterState.DisabledNetAdapterAdvancedProperty | Where-Object{$_.Name -eq $thisRDMADisabledAdapter.Name -and $_.RegistryKeyword -eq '*NetworkDirect'}).DisplayValue | Should Not Be 'Enabled'
}
}
foreach ($thisRDMADisabledAdapter in $cfgVMSwitch.RDMADisabledAdapters.Name) {
### Verify RDMA is disabled or not capable on this adapter
It "[SUT: $nodeName]-[VMSwitch.RDMADisabledAdapter: $($thisRDMAEnabledAdapter)]-[Noun: NetAdapterAdvancedProperty] should have NetworkDirect (RDMA) Disabled" {
@ -455,27 +455,27 @@ Describe "[Modal Unit]" -Tag Modal {
}
}
}
Context "[Modal Unit]-[NetQos]-[SUT: $nodeName]-NetQos Settings" {
$NetQosPolicy = Get-NetQosPolicy -CimSession $nodeName -ErrorAction SilentlyContinue
$NetAdapterQos = Get-NetAdapterQos -CimSession $nodeName -ErrorAction SilentlyContinue
$NetQosFlowControl = Get-NetQosFlowControl -CimSession $nodeName -ErrorAction SilentlyContinue
$NetQosTrafficClass = Get-NetQosTrafficClass -CimSession $nodeName -ErrorAction SilentlyContinue
$NetQosDcbxSettingInterfaces = @()
$AllRDMAEnabledAdapters.Name | ForEach-Object {
$NetQosDcbxSettingInterfaces += Get-NetQosDcbxSetting -InterfaceAlias $_ -CimSession $nodeName -ErrorAction SilentlyContinue
}
$actNetQoSState = @{}
$actNetQoSState.NetQoSPolicy = $NetQosPolicy
$actNetQoSState.NetAdapterQos = $NetAdapterQos
$actNetQoSState.NetQoSFlowControl = $NetQosFlowControl
$actNetQoSState.NetQosTrafficClass = $NetQosTrafficClass
$actNetQoSState.NetQosDcbxSettingInterfaces = $NetQosDcbxSettingInterfaces
Remove-Variable -Name NetQosPolicy, NetAdapterQos, NetQosFlowControl, NetQosTrafficClass, NetQosDcbxSettingInterfaces
foreach ($thisPolicy in $configData.NonNodeData.NetQoS) {
### Verify this NetQos Policy exists
It "[SUT: $nodeName]-[NetQos: $($thisPolicy.Name)]-[Noun: NetQosPolicy] should have a NetQos policy named ($($thisPolicy.Name)) assigned" {
@ -513,12 +513,12 @@ Describe "[Modal Unit]" -Tag Modal {
It "[SUT: $nodeName]-[NetQos: $($thisPolicy.Name)]-[Noun: NetQosTrafficClass] Should have a traffic class named '[$($thisPolicy.Name)]'" {
$actNetQoSState.NetQosTrafficClass.Name -contains "[$($thisPolicy.Name)]" | Should Be $true
}
### Verify this traffic class is the expected BandwidthPercentage
It "[SUT: $nodeName]-[NetQos: $($thisPolicy.Name)]-[Noun: NetQosTrafficClass] The traffic class named '[$($thisPolicy.Name)]' should have a bandwidth percentage of ($($thisPolicy.BandwidthPercentage))" {
($actNetQoSState.NetQosTrafficClass | Where-Object Name -Like '*default*').BandwidthPercentage | Should Be $thisPolicy.BandwidthPercentage
}
### Verify this traffic class is the expected Algorithm
It "[SUT: $nodeName]-[NetQos: $($thisPolicy.Name)]-[Noun: NetQosTrafficClass] The traffic class named '[$($thisPolicy.Name)]' should have an algorithm of ($($thisPolicy.Algorithm))" {
($actNetQoSState.NetQosTrafficClass | Where-Object Name -Like '*default*').Algorithm | Should Be $thisPolicy.Algorithm
@ -529,17 +529,17 @@ Describe "[Modal Unit]" -Tag Modal {
It "[SUT: $nodeName]-[NetQos: $($thisPolicy.Name)]-[Noun: NetQosTrafficClass] Should have a traffic class named ($($thisPolicy.Name))" {
$actNetQoSState.NetQosTrafficClass.Name -contains "$($thisPolicy.Name)" | Should Be $true
}
### Verify This traffic class is the expected priority
### Verify This traffic class is the expected priority
It "[SUT: $nodeName]-[NetQos: $($thisPolicy.Name)]-[Noun: NetQosTrafficClass] The traffic class named ($($thisPolicy.Name)) should be priority ($($thisPolicy.PriorityValue8021Action))" {
($actNetQoSState.NetQosTrafficClass | Where-Object Name -eq "$($thisPolicy.Name)").Priority | Should Be $thisPolicy.PriorityValue8021Action
}
### Verify this traffic class is the expected BandwidthPercentage
It "[SUT: $nodeName]-[NetQos: $($thisPolicy.Name)]-[Noun: NetQosTrafficClass] The traffic class named ($($thisPolicy.Name)) should have a bandwidth percentage of ($($thisPolicy.BandwidthPercentage))" {
($actNetQoSState.NetQosTrafficClass | Where-Object Name -eq $thisPolicy.Name).BandwidthPercentage | Should Be $thisPolicy.BandwidthPercentage
}
### Verify this traffic class is the expected Algorithm
It "[SUT: $nodeName]-[NetQos: $($thisPolicy.Name)]-[Noun: NetQosTrafficClass] The traffic class named ($($thisPolicy.Name)) should have a algorithm of ($($thisPolicy.Algorithm))" {
($actNetQoSState.NetQosTrafficClass | Where-Object Name -eq $thisPolicy.Name).Algorithm | Should Be $thisPolicy.Algorithm
@ -552,7 +552,7 @@ Describe "[Modal Unit]" -Tag Modal {
It "[SUT: $nodeName]-[RDMAEnabledAdapters: $($thisRDMAEnabledAdapter.Name)]-[Noun: NetAdapterQos] should be enabled" {
($actNetQoSState.NetAdapterQos | Where-Object Name -eq $thisRDMAEnabledAdapter.Name).Enabled | Should Be $true
}
### Verify this adapter's DCBX setting is not Willing
It "[SUT: $nodeName]-[RDMAEnabledAdapters: $($thisRDMAEnabledAdapter.Name)]-[Noun: NetQosDcbxSetting] interfaces DCBX 'Willing' option should be false" {
($actNetQoSState.NetQosDcbxSettingInterfaces | Where-Object InterfaceAlias -like $thisRDMAEnabledAdapter.Name).Willing | Should Be 'false'
@ -567,7 +567,7 @@ Describe "[Modal Unit]" -Tag Modal {
$actvmSwitch = @{}
$actvmSwitch.vmSwitch = $vmSwitch
$actvmSwitch.vmSwitchTeam = $vmSwitchTeam
If ($thisCfgVMSwitch.IovEnabled) {
$NetAdapterSRIOV = @()
@ -615,7 +615,7 @@ Describe "[Modal Unit]" -Tag Modal {
It "[SUT: $nodeName]-[VMSwitch: $($thisCfgVMSwitch.Name)]-[Noun: VMSwitch] vSwitch contains ($($thisCfgVMSwitch.RDMAEnabledAdapters.Count)) adapters" {
($actvmSwitch.vmSwitch | Where-Object Name -eq $thisCfgVMSwitch.Name).NetAdapterInterfaceDescriptions.Count | Should Be $thisCfgVMSwitch.RDMAEnabledAdapters.Count
}
### Verify LBFO Multiplexor is not used
It "[SUT: $nodeName]-[VMSwitch: $($thisCfgVMSwitch.Name)]-[Noun: VMSwitch] vSwitch should not use LBFO Teaming" {
($actvmSwitch.vmSwitch | Where-Object Name -eq $thisCfgVMSwitch.Name).NetAdapterInterfaceDescription | Should Not Be 'Microsoft Network Adapter Multiplexor Driver'
@ -625,11 +625,11 @@ Describe "[Modal Unit]" -Tag Modal {
It "[SUT: $nodeName]-[VMSwitch: $($thisCfgVMSwitch.Name)]-[Noun: VMSwitch] vSwitch should be a teamed interface" {
($actvmSwitch.vmSwitch | Where-Object Name -eq $thisCfgVMSwitch.Name).NetAdapterInterfaceDescription | Should Be 'Teamed-Interface'
}
foreach ($thisRDMAEnabledAdapter in $thisCfgVMSwitch.RDMAEnabledAdapters) {
### Verify the expected phyiscal adapters are part of the team
It "[SUT: $nodeName]-[VMSwitch: $($thisCfgVMSwitch.Name)]-[RDMAEnabledAdapter: $($thisRDMAEnabledAdapter.Name)]-[Noun: VMSwitchTeam] Interface should be a member of the SET team" {
($actvmSwitch.vmSwitchTeam | Where-Object Name -eq $thisCfgVMSwitch.Name).NetAdapterInterfaceDescription -contains
($actvmSwitch.vmSwitchTeam | Where-Object Name -eq $thisCfgVMSwitch.Name).NetAdapterInterfaceDescription -contains
($actNetAdapterState.NetAdapter | Where-Object Name -eq $thisRDMAEnabledAdapter.Name).InterfaceDescription | Should be $true
}
}
@ -666,7 +666,7 @@ Describe "[Modal Unit]" -Tag Modal {
($actvmSwitch.vmSwitch | Where-Object Name -eq $thisCfgVMSwitch.Name).PacketDirectEnabled | Should Be $false
}
}
### Verify no catastrophic failures in the VMSwitch testing...
default { It "Could not determine the EmbeddedTeamingEnabled configuration" { $false | Should be $true }}
}
@ -697,7 +697,7 @@ Describe "[Modal Unit]" -Tag Modal {
It "[SUT: $nodeName]-[VMSwitch: $($thisCfgVMSwitch.Name)]-[Noun: VMSwitch] The VMSwitch should support SR-IOV" {
($actvmSwitch.vmSwitch | Where-Object Name -eq $thisCfgVMSwitch.Name).IovSupport | Should Be $true
}
### Verify the VMSwitch has SR-IOV Enabled
It "[SUT: $nodeName]-[VMSwitch: $($thisCfgVMSwitch.Name)]-[Noun: VMSwitch] The VMSwitch should have SR-IOV enabled" {
($actvmSwitch.vmSwitch | Where-Object Name -eq $thisCfgVMSwitch.Name).IovEnabled | Should Be $true
@ -722,7 +722,7 @@ Describe "[Modal Unit]" -Tag Modal {
$VMNetworkAdapter = Get-VMNetworkAdapter -Name $thisRDMAEnabledAdapter.VMNetworkAdapter -ManagementOS -CimSession $nodeName -ErrorAction SilentlyContinue
$VMNetworkAdapterTeamMapping = Get-VMNetworkAdapterTeamMapping -Name $thisRDMAEnabledAdapter.VMNetworkAdapter -ManagementOS -CimSession $nodeName -ErrorAction SilentlyContinue
$NetAdapter = @()
$NetAdapterRDMA = @()
$netAdapterAdvancedProperty = @()
@ -740,7 +740,7 @@ Describe "[Modal Unit]" -Tag Modal {
$actvmSwitch.VMNetworkAdapterTeamMapping = $VMNetworkAdapterTeamMapping
Remove-Variable -Name NetAdapter, NetAdapterRDMA, NetAdapterAdvancedProperty, VMNetworkAdapter, VMNetworkAdapterTeamMapping -ErrorAction SilentlyContinue
Context "[Modal Unit]-[VMSwitch: $($thisCfgVMSwitch.Name)]-[VMNetworkAdapter: $($thisRDMAEnabledAdapter.VMNetworkAdapter)]-[SUT: $nodeName]-Virtual NICs NetAdapter and NetAdapterAdvancedProperty Settings" {
### Verify the virtual NIC's NetAdapter Name is the same as the VMNetworkAdapter name
It "[SUT: $nodeName]-[VMSwitch: $($thisCfgVMSwitch.Name)]-[RDMAEnabledAdapter: $($thisRDMAEnabledAdapter.Name)]-[VMNetworkAdapter: $($thisRDMAEnabledAdapter.VMNetworkAdapter)]-[Noun: NetAdapter, VMNetworkAdapter] NetAdapter Name for the virtual NIC is named the same as the VMNetworkAdapter name" {
@ -884,7 +884,7 @@ Describe "[Modal Unit]" -Tag Modal {
$configData.NonNodeData.NetQos | Foreach-Object {
$thisPolicy = $_
if ($thisPolicy.ContainsKey('NetDirectPortMatchCondition')) {
Switch ($AdapterLinkSpeed) {
# SMB Bandwidth Limit is being calculated MB and being compared to adapter speed which is in Gbps converted to MiBps
@ -895,14 +895,14 @@ Describe "[Modal Unit]" -Tag Modal {
$SMBBandwidthLimit.BytesPerSecond / 1MB | Should BeLessThan $expectedLimitMB + 1
}
}
{$_ -gt 10000000000} {
$expectedLimitMB = (((($thisPolicy.BandwidthPercentage / 100) * .6) * $AdapterLinkSpeed) / 8) / 1000000
It "Should have an Live Migration limit of 750 MBps" {
$SMBBandwidthLimit.BytesPerSecond / 1MB | Should BeLessThan $expectedLimitMB + 1
}
}
default { It 'Link speed was not identified and so optimal live migration limit could not be determined' { $false | Should be $true } }
}
}
@ -912,4 +912,4 @@ Describe "[Modal Unit]" -Tag Modal {
}
}
#TODO: Update test helpers to check for VLAN Isolation and not VMnetworkAdapterVLAn
#TODO: Update test helpers to check for VLAN Isolation and not VMnetworkAdapterVlan

Просмотреть файл

@ -1,24 +1,24 @@
#
# Module manifest for module 'DataCenterBridging'
# Module manifest for module 'Validate-DCB'
#
# Generated by: Dan Cuomo
#
# Generated on: 2/9/2019
# Generated on: 6/8/2019
#
@{
# Script module or binary module file associated with this manifest.
RootModule = 'DataCenterBridging.psm1'
RootModule = 'Validate-DCB.psm1'
# Version number of this module.
ModuleVersion = '0.4'
ModuleVersion = '20190622.2.2.0'
# Supported PSEditions
# CompatiblePSEditions = @()
# ID used to uniquely identify this module
GUID = '363fa04e-5870-4db9-ba04-a2101f596754'
GUID = 'aad51a88-4b67-4c35-b840-0be9b0c914d2'
# Author of this module
Author = 'Dan Cuomo'
@ -27,10 +27,10 @@ Author = 'Dan Cuomo'
CompanyName = 'Microsoft'
# Copyright statement for this module
Copyright = '(c) 2019 Microsoft. All rights reserved.'
Copyright = '(c) 2019 Inc. All rights reserved.'
# Description of the functionality provided by this module
Description = 'This module provides DSCResources to configure Data Center Bridging on your system(s)'
Description = 'Validate-DCB is a module that validates the RDMA and Data Center Bridging (DCB) configuration best practices on Windows. DCB is a suite of standards used to provide hardware based bandwidth reservations and flow control. This is not required for iWARP RDMA traffic, however it is mandatory for RoCE RDMA traffic.'
# Minimum version of the Windows PowerShell engine required by this module
# PowerShellVersion = ''
@ -51,7 +51,14 @@ Description = 'This module provides DSCResources to configure Data Center Bridgi
# ProcessorArchitecture = ''
# Modules that must be imported into the global environment prior to importing this module
# RequiredModules = @()
RequiredModules = @(
@{ ModuleName = 'NetworkingDSC' ; ModuleVersion = '6.3.0.0' }
@{ ModuleName = 'xHyper-V' ; ModuleVersion = '3.16.0.0' }
@{ ModuleName = 'VMNetworkAdapter' ; ModuleVersion = '0.0.0.4' }
@{ ModuleName = 'DataCenterBridging'; ModuleVersion = '0.0.0.4' }
@{ ModuleName = 'FailoverClusters' ; ModuleVersion = '2.0.0.0' }
@{ ModuleName = 'PSDesiredStateConfiguration'; ModuleVersion = '1.1' }
)
# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()
@ -69,7 +76,7 @@ Description = 'This module provides DSCResources to configure Data Center Bridgi
# NestedModules = @()
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = @()
FunctionsToExport = 'Assert-DCBValidation'
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
CmdletsToExport = @()
@ -78,10 +85,10 @@ CmdletsToExport = @()
VariablesToExport = '*'
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
AliasesToExport = @()
AliasesToExport = @('Validate-DCB')
# DSC resources to export from this module
DscResourcesToExport = 'DCBNetQosFlowControl', 'DCBNetAdapterQos', 'DCBNetQosDcbxSetting', 'DCBNetQosPolicy', 'DCBNetQosTrafficClass'
# DscResourcesToExport = @()
# List of all modules packaged with this module
# ModuleList = @()
@ -95,13 +102,13 @@ PrivateData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
Tags = 'MSFTNetworking','Validate-DCB'
Tags = 'MSFTNet'
# A URL to the license for this module.
# LicenseUri = ''
# A URL to the main website for this project.
ProjectUri = 'https://aka.ms/Validate-DCB'
ProjectUri = 'https://github.com/microsoft/Validate-DCB'
# A URL to an icon representing this module.
# IconUri = ''

224
Validate-DCB.psm1 Normal file
Просмотреть файл

@ -0,0 +1,224 @@
function Assert-DCBValidation {
<#
.SYNOPSIS
Validate-DCB is a module that validates the RDMA and Data Center Bridging (DCB) configuration best practices on Windows.
DCB is a suite of standards used to provide hardware based bandwidth reservations and flow control. This is not required for iWARP RDMA traffic, however it is mandatory for RoCE RDMA traffic.
.DESCRIPTION
Note: Validate-DCB is now an alias for Assert-DCBValidation to avoid a warning when importing the module using an unapproved verb
Validate-DCB allows you to:
- Validate the expected configuration on one to N number of systems or clusters
- Validate the configuration meets best practices
Additional benefits include:
- The configuration doubles as DCB documentation for the expected configuration of your systems.
- Answer the question "What Changed?" when faced with an operational issue
This tool does not modify your system. As such, you can re-validate the configuration as many times as desired.
.PARAMETER LaunchUI
Use to launch a user interface to help create a configuration file. Use the following values to specify one of the example files.
Optionally allows you to deploy the configuration using Azure Automation at the end.
.PARAMETER ExampleConfig
Use to specify one of the example configuration files. Use the following values to specify one of the example files
| Value | Location |
| ------- |------------------------------------------|
| NDKm1 | .\Examples\NDKm1-examples.DCB.config.ps1 |
| NDKm2 | .\Examples\NDKm2-examples.DCB.config.ps1 |
Possible options include NDKm1 or NDKm2. This option cannot be used with the $ConfigFilePath parameter
.PARAMETER ConfigFilePath
Specifies the literal or relative paths to a custom configuration file.
This option cannot be used with the $ExampleConfig parameter
.PARAMETER ContinueOnFailure
By default, Validate-DCB will exit at the end of a describe block if at least one test has failed.
The intent is to give you an opportunity to correct the issue prior to moving on. This could have an impact
on the ability of future tests to run successfully.
Use this to attempt all tests even if a test failure is detected.
.PARAMETER Deploy
Deploy the configuration specified in the config file to the nodes.
By default, Validate-DCB validates the configuration. With this option, it will modify your system.
Please note: Due to the nature of declarative PowerShell (DSC) this could be destructive. For example,
if your config file specify's that a vSwitch's IovEnabled property is $true and it is not actually
configured properly on the system DSC will attempt to destroy the vSwitch and recreate it with
the correct settings. Since this option can only be configured at vSwitch creation time, there is only one option.
.PARAMETER TestScope
Determines the describe block to be run. You can use this to only run certain describe blocks.
By default, Global and Modal (currently all) describe blocks are run.
.EXAMPLE
Validate-DCB
.EXAMPLE
Validate-DCB -ExampleConfig NDKm2
.EXAMPLE
Validate-DCB -ConfigFilePath c:\temp\ClusterA.ps1
.EXAMPLE
Validate-DCB -ExampleConfig NDKm1 -TestScope Modal
.NOTES
Author: Windows Core Networking team @ Microsoft
Please file issues on GitHub @ GitHub.com/Microsoft/Validate-DCB
.LINK
More projects : https://github.com/microsoft/sdn
Windows Networking Blog : https://blogs.technet.microsoft.com/networking/
RDMA Configuration Guidance : https://aka.ms/ConvergedNIC
#>
[CmdletBinding(DefaultParameterSetName = 'Create Config')]
param (
[Parameter(ParameterSetName = 'DefaultConfig')]
[ValidateSet('NDKm1', 'NDKm2')]
[string] $ExampleConfig,
[Parameter(ParameterSetName = 'CustomConfig')]
[string] $ConfigFilePath,
[Parameter(ParameterSetName = 'Create Config')]
[switch] $LaunchUI = $true,
[Parameter(Mandatory = $false)]
[switch] $ContinueOnFailure = $false,
[Parameter(Mandatory = $false)]
[ValidateSet('All', 'Global', 'Modal')]
[string] $TestScope = 'All' ,
[Parameter(ParameterSetName = 'DefaultConfig')]
[Parameter(ParameterSetName = 'CustomConfig')]
[switch] $Deploy = $false ,
[Parameter(Mandatory=$false)]
[string] $reportPath
)
Clear-Host
If ($PSCmdlet.ParameterSetName -ne 'Create Config') { $LaunchUI = $false }
# TODO: Once converted to module, just add pester to required modules
If (-not (Get-Module -Name Pester -ListAvailable)) {
Write-Output 'Pester is an inbox PowerShell Module included in Windows 10, Windows Server 2016, and later'
Throw 'Catastrophic Failure :: PowerShell Module Pester was not found'
}
$here = Split-Path -Parent (Get-Module -Name Validate-DCB).Path
$startTime = Get-Date -format:'yyyyMMdd-HHmmss'
New-Item -Name 'Results' -Path $here -ItemType Directory -Force
If ($global:deploy -eq $true -or $LaunchUI -eq $true) {
Write-Output 'Deploy or LaunchUI options were selected...Verifying prerequisites'
$testFile = Join-Path -Path $here -ChildPath "tests\unit\global.unit.tests.ps1"
$launch_deploy = Invoke-Pester -Script $testFile -Tag 'Launch_Deploy' -PassThru
$launch_deploy | Select-Object -Property TagFilter, Time, TotalCount, PassedCount, FailedCount, SkippedCount, PendingCount | Format-Table -AutoSize
If ($launch_deploy.FailedCount -ne 0) {
Write-Error -Message "One or more of the required modules was not available on the system."
Break
}
Else {
Import-Module "$here\helpers\NetworkConfig\NetworkConfig.psd1" -Force
Import-Module "$here\helpers\UI\vDCBUI.psm1" -Force
}
}
#region Getting helpers & data...
If ($LaunchUI) {
$CheckModule = Get-Module -Name NetworkConfig, vDCBUI
If ($CheckModule.Count -ne 2) { 'NetworkConfig or vDCBUI Module was not available for import'; break }
Write-Output 'Launching Configuration and Deployment UI'
vDCBUI
$ConfigFile = $global:ConfigPath
If ($configFile -eq $null) {
Write-Error "Configuration file was not successfully saved"
break
}
Else { Write-Output "The configuration is located at $ConfigFile" }
}
ElseIf ($PSBoundParameters.ContainsKey('ExampleConfig')) {
$ConfigFile = $(Join-Path $Here -ChildPath "Examples\$ExampleConfig-examples.DCB.config.ps1")
$fullPath = (Get-ChildItem -Path $configFile).FullName
Write-Output "Example Configuration Mode ($ExampleConfig) was specified"
Write-Output "The default configuration located at $fullPath will be used"
}
ElseIf ($PSBoundParameters.ContainsKey('ConfigFilePath')) {
$fullPath = (Get-ChildItem -Path $ConfigFilePath).FullName
Write-Output "The Config File at $fullPath will be used"
$ConfigFile = $ConfigFilePath
}
If (Test-Path $ConfigFile) { & $ConfigFile }
Else { Throw "Catastrophic Failure :: Configuration File was not found at $ConfigFile" }
Remove-Variable -Name configData -ErrorAction SilentlyContinue
Import-Module "$here\helpers\helpers.psd1" -Force
$configData += Import-PowerShellDataFile -Path .\helpers\drivers\drivers.psd1
#endregion
Switch ($TestScope) {
'Global' {
if ($PSBoundParameters.ContainsKey('reportPath')) { $outputFile = $reportPath }
Else { $outputFile = "$here\Results\$startTime-Global-unit.xml" }
$testFile = Join-Path -Path $here -ChildPath "tests\unit\global.unit.tests.ps1"
$GlobalResults = Invoke-Pester -Script $testFile -Tag 'Global' -OutputFile $outputFile -OutputFormat NUnitXml -PassThru
$GlobalResults | Select-Object -Property TagFilter, Time, TotalCount, PassedCount, FailedCount, SkippedCount, PendingCount | Format-Table -AutoSize
}
'Modal' {
If ($global:deploy) { Publish-Automation }
if ($PSBoundParameters.ContainsKey('reportPath')) { $outputFile = $reportPath }
Else { $outputFile = "$here\Results\$startTime-Modal-unit.xml" }
$testFile = Join-Path -Path $here -ChildPath "tests\unit\modal.unit.tests.ps1"
$ModalResults = Invoke-Pester -Script $testFile -Tag 'Modal' -OutputFile $outputFile -OutputFormat NUnitXml -PassThru
$ModalResults | Select-Object -Property TagFilter, Time, TotalCount, PassedCount, FailedCount, SkippedCount, PendingCount | Format-Table -AutoSize
}
Default {
if ($PSBoundParameters.ContainsKey('reportPath')) { $outputFile = $reportPath }
Else { $outputFile = "$here\Results\$startTime-Global-unit.xml" }
$testFile = Join-Path -Path $here -ChildPath "tests\unit\global.unit.tests.ps1"
$GlobalResults = Invoke-Pester -Script $testFile -Tag 'Global' -OutputFile $outputFile -OutputFormat NUnitXml -PassThru
$GlobalResults | Select-Object -Property TagFilter, Time, TotalCount, PassedCount, FailedCount, SkippedCount, PendingCount | Format-Table -AutoSize
If ($global:deploy) { Publish-Automation }
If ($GlobalResults.FailedCount -ne 0) {
Write-Host 'Failures in Global exist. Please resolve failures prior to moving on'
Break
}
if ($PSBoundParameters.ContainsKey('reportPath')) { $outputFile = $reportPath }
Else { $outputFile = "$here\Results\$startTime-Modal-unit.xml" }
$testFile = Join-Path -Path $here -ChildPath "tests\unit\modal.unit.tests.ps1"
$ModalResults = Invoke-Pester -Script $testFile -Tag 'Modal' -OutputFile $outputFile -OutputFormat NUnitXml -PassThru
$ModalResults | Select-Object -Property TagFilter, Time, TotalCount, PassedCount, FailedCount, SkippedCount, PendingCount | Format-Table -AutoSize
}
}
}
New-Alias -Name 'Validate-DCB' -Value 'Assert-DCBValidation'

Просмотреть файл

@ -1,7 +1,12 @@
# What's New in v2.1
# What's New in v2.2
## New Features
- This feature branch is intended to
- Move Validate-DCB into a PowerShell Gallery capable module
- Integrate with the cluster health service
- Adding Build and Downloads badges
- GUI for creating the configuration!
- LaunchUI is in the default parameter set
- Alternatively use -LaunchUI
@ -25,9 +30,11 @@
- Added test to validate recommended FW is used with Mellanox drivers on Win-OF2 adapters (CX4 and higher)
- Incremented Recommended driver for Mellanox and Chelsio adapters
- Modified example configurations to set cluster heartbeat policy to priority 7-
- Modified example configurations to set cluster heartbeat policy to priority 7
## Structural Changes
- Separated module prerequisites into its own Global unit test inside global.unit.tests.ps1
- This will be run at the beginning of the initiate when the Launch or Deploy parameters are specified
- Separated driver requirements into their own file
- Separate Global and Modal test files for easier review of test code

59
appveyor.yml Normal file
Просмотреть файл

@ -0,0 +1,59 @@
# YAML Reference Guide : https://www.appveyor.com/docs/appveyor-yml/
# Environmental Variables Guide : https://www.appveyor.com/docs/environment-variables/
# YAML Validator : https://ci.appveyor.com/tools/validate-yaml
# AppVeyor Build Pipeline : https://www.appveyor.com/docs/build-configuration/
# GitHub push with tokens : https://www.appveyor.com/docs/how-to/git-push/
# Repo cloned into this folder on the build worker
clone_folder: c:\projects\Validate-DCB
# Date-based versioning. Validate-DCB is in version 2.1 (or higher based on build)
# Version will be of format: yyyyMMdd . 2 . 1 . Build Number e.g. 20190609.2.1.buildNumber
init:
- ps: $Env:repoName = $($env:APPVEYOR_REPO_NAME.Split('/')[1])
- ps: Update-AppveyorBuild -Version "$(Get-Date -format yyyyMMdd).2.$env:appveyor_build_number"
# Install script prior to running tests
install:
- ps: . .\tests\build\setup\install.ps1
# Initiate tests
test_script:
- ps: . .\tests\build\setup\initiate-tests.ps1
# finalize build
deploy_script:
- ps: . .\tests\build\setup\deploy.ps1
version: '{build}'
image:
- Visual Studio 2017
# Environment variables for PowerShell Gallery (NuGetAPIKey) and GitHub (GitHubKey) API key for publishing updates
# - The "secure:" value is the Appveyor encryption of the key
# - GitHub update occurs to ensure that the module version is incremented based on the build number
#CoreNetBuilder
environment:
NuGetApiKey:
secure: Kz5VZnHxQlD/mHk0dlvpxTN1isiwW9A5fWhRdL7a1vcGwbVHFyj/x9wrIkqpAkcf
GitHubKey:
secure: qpQkQoAMAquwRIDJtJT9rD8JZTVlNxAfOFqUgrsbCJy6C8AY0jFHMGap18SxmH+F
# Disable automatic builds; Without this, the following error shows up:
# "Specify a project or solution file. The directory does not contain a project or solution file."
build: "off"
max_jobs: 1
# Ignore testing a commit if specific strings used in commit message: updated readme, update readme, update docs, update version, update appveyor
skip_commits:
message: /updated readme.*|update readme.*s|update docs.*|update version.*|update appveyor.*/
files:
- README.md
# There's no need to alter the build number for a Pull Request (PR) since they don't modify anything
pull_requests:
do_not_increment_build_number: true

Просмотреть файл

@ -1,386 +0,0 @@
enum Ensure {
Absent
Present
}
[DscResource()]
Class DCBNetQosFlowControl {
[DscProperty(Mandatory)]
[Ensure] $Ensure
[DscProperty(Key)]
[ValidateRange(0,7)]
[int] $Priority
[DscProperty(NotConfigurable)]
[Boolean] $Enabled
[DCBNetQosFlowControl] Get() {
$FlowControlPriority = Get-NetQosFlowControl -Priority $this.Priority
$this.Enabled = $FlowControlPriority.Enabled
$this.Priority = $FlowControlPriority.Priority
return $this
}
[bool] Test() {
$FlowControlPriority = Get-NetQosFlowControl -Priority $this.Priority
$testState = $false
if ($this.Ensure -eq [Ensure]::Present) {
Switch ($FlowControlPriority.Enabled) {
$true {$testState = $true}
$false {$testState = $false}
}
}
elseif ($this.Ensure -eq [Ensure]::Absent) {
Switch ($FlowControlPriority.Enabled) {
$true {$testState = $false}
$false {$testState = $true}
}
}
Return $testState
}
[Void] Set() {
if ($this.Ensure -eq [Ensure]::Present) {
Write-Verbose "Enabling priority $($this.Priority)"
Set-NetQosFlowControl -Priority $this.Priority -Enabled $true
Write-Verbose "Priority $($this.Priority) is now Enabled"
}
elseif ($this.Ensure -eq [Ensure]::Absent) {
Write-Verbose "Enabling priority $($this.Priority)"
Set-NetQosFlowControl -Priority $this.Priority -Enabled $false
Write-Verbose "Priority $($this.Priority) is now disabled"
}
}
}
[DscResource()]
Class DCBNetAdapterQos {
[DscProperty(Mandatory)]
[Ensure] $Ensure
[DscProperty(Key)]
[string] $InterfaceName
[DscProperty(NotConfigurable)]
[Boolean] $Enabled
[DCBNetAdapterQos] Get() {
$NetAdapterQosState = Get-NetAdapterQos -Name $this.InterfaceName
$this.InterfaceName = $NetAdapterQosState.Name
$this.Enabled = $NetAdapterQosState.Enabled
return $this
}
[bool]Test() {
$NetAdapterQosState = Get-NetAdapterQos -Name $this.InterfaceName
$testState = $false
if ($this.Ensure -eq [Ensure]::Present) {
Switch ($NetAdapterQosState.Enabled) {
$true {$testState = $true}
$false {$testState = $false}
}
}
elseif ($this.Ensure -eq [Ensure]::Absent) {
Switch ($NetAdapterQosState.Enabled) {
$true {$testState = $false}
$false {$testState = $true}
}
}
Return $testState
}
[Void] Set() {
if ($this.Ensure -eq [Ensure]::Present) {
Write-Verbose "Enabling QoS on $($this.InterfaceName)"
Set-NetAdapterQos -Name $this.InterfaceName -Enabled $true
Write-Verbose "QoS is now enabled on $($this.InterfaceName)"
}
elseif ($this.Ensure -eq [Ensure]::Absent) {
Write-Verbose "Disabling QoS on $($this.InterfaceName)"
Set-NetAdapterQos -Name $this.InterfaceName -Enabled $false
Write-Verbose "QoS is now disabled on $($this.InterfaceName)"
}
}
}
[DscResource()]
Class DCBNetQosDcbxSetting {
[DscProperty(Key)]
[Ensure] $Ensure
[DCBNetQosDcbxSetting] Get() {
$NetQosDcbx = Get-NetQosDcbxSetting
if ($this.Ensure) {
$this.Willing = $NetQosDcbx.Willing
}
return $this
}
[bool]Test() {
$NetQosDcbx = Get-NetQosDcbxSetting
$testState = $false
if ($this.Ensure -eq [Ensure]::Present) {
Switch ($NetQosDcbx.Willing) {
$true {$testState = $true}
$false {$testState = $false}
}
}
elseif ($this.Ensure -eq [Ensure]::Absent) {
Switch ($NetQosDcbx.Willing) {
$true {$testState = $false}
$false {$testState = $true}
}
}
Return $testState
}
[Void] Set() {
if ($this.Ensure -eq [Ensure]::Present) {
Write-Verbose "Enabling DCBX Willing bit"
Write-Verbose "Note: DCBX is not supported on Windows Server 2016 or Windows Server 2019"
Set-NetQosDcbxSetting -Willing $true
Write-Verbose "DCBX Willing bit is now enabled"
Write-Verbose "Note: DCBX is not supported on Windows Server 2016 or Windows Server 2019"
}
elseif ($this.Ensure -eq [Ensure]::Absent) {
Write-Verbose "Disabling DCBX Willing bit"
Set-NetQosDcbxSetting -Willing $false
Write-Verbose "DCBX Willing bit is now disabled"
}
}
}
[DscResource()]
Class DCBNetQosPolicy {
[DscProperty(Mandatory)]
[Ensure] $Ensure
[DscProperty(Key)]
[string] $Name
[DscProperty(Mandatory)]
[string] $PriorityValue8021Action
[DscProperty()]
[ValidateSet('Default', 'SMB', 'Cluster', 'LiveMigration')]
[string] $Template
[DscProperty()]
[string] $NetDirectPortMatchCondition = 0
[DCBNetQosPolicy] Get() {
$NetQosPolicy = Get-NetQosPolicy -Name $this.Name -ErrorAction SilentlyContinue
$this.Name = $NetQosPolicy.Name
$this.PriorityValue8021Action = $NetQosPolicy.PriorityValue8021Action
if ($NetQosPolicy.Template -ne 'None') { $this.Template = $NetQosPolicy.Template }
if ($NetQosPolicy.NetDirectPortMatchCondition -ne '0') {
$this.NetDirectPortMatchCondition = $NetQosPolicy.NetDirectPortMatchCondition
}
return $this
}
[bool] Test() {
$NetQosPolicy = Get-NetQosPolicy -Name $this.Name -ErrorAction SilentlyContinue
$testState = $false
If ($NetQosPolicy) {
Switch ($this.Ensure) {
'Present' {
$teststate = $true
If ($NetQosPolicy.PriorityValue8021Action -ne $this.PriorityValue8021Action) { $teststate = $false }
If ($this.Template) {
If ($NetQosPolicy.Template -ne $this.Template) { $teststate = $false }
}
If ($this.NetDirectPortMatchCondition) {
If ($NetQosPolicy.NetDirectPortMatchCondition -ne $this.NetDirectPortMatchCondition) { $teststate = $false }
}
}
'Absent' { $teststate = $false }
}
} else {
Switch ($this.Ensure) {
'Present' { $teststate = $false }
'Absent' { $teststate = $true }
}
}
Return $testState
}
[Void] Set() {
$NetQosPolicy = Get-NetQosPolicy -Name $this.Name -ErrorAction SilentlyContinue
If ($NetQosPolicy) {
Switch ($this.Ensure) {
'Present' {
If ($this.PriorityValue8021Action) {
If ($NetQosPolicy.PriorityValue8021Action -ne $this.PriorityValue8021Action) {
Write-Verbose "Correcting the priority value of NetQosPolicy $($this.Name) to $($this.PriorityValue8021Action)"
Set-NetQosPolicy -Name $this.Name -PriorityValue8021Action $this.PriorityValue8021Action
Write-Verbose "Corrected the priority value of NetQosPolicy $($this.Name) to $($this.PriorityValue8021Action)"
}
}
if ($this.NetDirectPortMatchCondition) {
If ($NetQosPolicy.NetDirectPortMatchCondition -ne $this.NetDirectPortMatchCondition) {
Write-Verbose "Correcting the NetDirectPortMatchCondition value of NetQosPolicy $($this.Name) to $($this.NetDirectPortMatchCondition)"
Set-NetQosPolicy -Name $this.Name -NetDirectPortMatchCondition $this.NetDirectPortMatchCondition
Write-Verbose "Corrected the NetDirectPortMatchCondition value of NetQosPolicy $($this.Name) to $($this.NetDirectPortMatchCondition)"
}
}
If ($this.Template) {
If ($NetQosPolicy.Template -ne $this.Template) {
Write-Verbose "Correcting the Template value of NetQosPolicy $($this.Name) to $($this.Template)"
$templateParam = @{ $this.Template = $true }
Set-NetQosPolicy -Name $this.Name @templateParam
Write-Verbose "Corrected the Template value of NetQosPolicy $($this.Name) to $($this.Template)"
}
}
}
'Absent' {
Write-Verbose "Removing NetQosPolicy $($this.Name)"
Remove-NetQosPolicy -Name $this.Name
Write-Verbose "NetQosPolicy $($this.Name) has been removed"
}
}
} else {
if ($this.Ensure -eq [Ensure]::Present) {
if ($this.NetDirectPortMatchCondition -ne 0) {
Write-Verbose "Creating NetQosPolicy $($this.Name)"
New-NetQosPolicy -Name $this.Name -PriorityValue8021Action $this.PriorityValue8021Action -NetDirectPortMatchCondition $this.NetDirectPortMatchCondition
Write-Verbose "NetQosPolicy $($this.Name) has been created"
}
elseif ($this.Template -ne 'None') {
Write-Verbose "Creating NetQosPolicy $($this.Name)"
$templateParam = @{ $this.Template = $true }
New-NetQosPolicy -Name $this.Name -PriorityValue8021Action $this.PriorityValue8021Action @templateParam
Write-Verbose "NetQosPolicy $($this.Name) has been created"
}
else { Write-Verbose 'Catastrophic Failure' }
}
}
}
}
[DscResource()]
Class DCBNetQosTrafficClass {
[DscProperty(Mandatory)]
[Ensure] $Ensure
[DscProperty(Key)]
[string] $Name
[DscProperty(Mandatory)]
[string] $Priority
[DscProperty(Mandatory)]
[ValidateRange(1,99)]
[string] $BandwidthPercentage
[DscProperty(Mandatory)]
[ValidateSet('ETS','Strict')]
[string] $Algorithm = 'ETS'
[DCBNetQosTrafficClass] Get() {
$NetQosTrafficClass = Get-NetQosTrafficClass -Name $this.Name -ErrorAction SilentlyContinue
$this.Name = $NetQosTrafficClass.Name
$this.Priority = $NetQosTrafficClass.Priority
$this.BandwidthPercentage = $NetQosTrafficClass.BandwidthPercentage
$this.Algorithm = $NetQosTrafficClass.Algorithm
return $this
}
[bool] Test() {
$NetQosTrafficClass = Get-NetQosTrafficClass -Name $this.Name -ErrorAction SilentlyContinue
$testState = $false
If ($NetQosTrafficClass) {
Switch ($this.Ensure.ToString()) {
'Present' {
$teststate = $true
If ($NetQosTrafficClass.Priority -ne $this.Priority) { $teststate = $false }
If ($NetQosTrafficClass.BandwidthPercentage -ne $this.BandwidthPercentage) { $teststate = $false }
If ($NetQosTrafficClass.Algorithm -ne $this.Algorithm) { $teststate = $false }
}
'Absent' { $teststate = $false }
}
} else {
Switch ($this.Ensure) {
'Present' { $teststate = $false }
'Absent' { $teststate = $true }
}
}
Return $testState
}
[Void] Set() {
$NetQosTrafficClass = Get-NetQosTrafficClass -Name $this.Name -ErrorAction SilentlyContinue
If ($NetQosTrafficClass) {
Switch ($this.Ensure) {
'Present' {
If ($NetQosTrafficClass.Priority -ne $this.Priority) {
Write-Verbose "Correcting the priority value of NetQosTrafficClass $($this.Name) to $($this.Priority)"
Set-NetQosTrafficClass -Name $this.Name -Priority $this.Priority
Write-Verbose "Corrected the priority value of NetQosTrafficClass $($this.Name) to $($this.Priority)"
}
If ($NetQosTrafficClass.BandwidthPercentage -ne $this.BandwidthPercentage) {
Write-Verbose "Correcting the BandwidthPercentage value of NetQosTrafficClass $($this.Name) to $($this.BandwidthPercentage)"
Set-NetQosTrafficClass -Name $this.Name -BandwidthPercentage $this.BandwidthPercentage
Write-Verbose "Corrected the BandwidthPercentage value of NetQosTrafficClass $($this.Name) to $($this.BandwidthPercentage)"
}
If ($NetQosTrafficClass.Algorithm -ne $this.Algorithm) {
Write-Verbose "Correcting the Algorithm value of NetQosTrafficClass $($this.Name) to $($this.Algorithm)"
Set-NetQosTrafficClass -Name $this.Name -Algorithm $this.Algorithm
Write-Verbose "Corrected the Template value of NetQosTrafficClass $($this.Name) to $($this.Algorithm)"
}
}
'Absent' {
Write-Verbose "Removing NetQosTrafficClass $($this.Name)"
Remove-NetQosTrafficClass -Name $this.Name
Write-Verbose "NetQosTrafficClass $($this.Name) has been removed"
}
}
} else {
if ($this.Ensure -eq [Ensure]::Present) {
Write-Verbose "Creating NetQosTrafficClass $($this.Name)"
New-NetQosTrafficClass -Name $this.Name -Priority $this.Priority -BandwidthPercentage $this.BandwidthPercentage -Algorithm $this.Algorithm
Write-Verbose "NetQosTrafficClass $($this.Name) has been created"
}
}
}
}

Просмотреть файл

@ -1,131 +0,0 @@
#
# Module manifest for module 'VMNetworkAdapter'
#
# Generated by: Dan Cuomo
#
# Generated on: 2/9/2019
#
@{
# Script module or binary module file associated with this manifest.
RootModule = 'VMNetworkAdapter.psm1'
# Version number of this module.
ModuleVersion = '0.4'
# Supported PSEditions
# CompatiblePSEditions = @()
# ID used to uniquely identify this module
GUID = '363fa04e-5870-4db9-ba04-a2101f596754'
# Author of this module
Author = 'Dan Cuomo'
# Company or vendor of this module
CompanyName = 'Microsoft'
# Copyright statement for this module
Copyright = '(c) 2019 Microsoft. All rights reserved.'
# Description of the functionality provided by this module
Description = 'This module provides DSCResources to configure VMNetworkAdapters on your system(s)'
# Minimum version of the Windows PowerShell engine required by this module
# PowerShellVersion = ''
# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''
# Minimum version of the Windows PowerShell host required by this module
# PowerShellHostVersion = ''
# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
# DotNetFrameworkVersion = ''
# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
# CLRVersion = ''
# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''
# Modules that must be imported into the global environment prior to importing this module
# RequiredModules = @()
# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = @()
# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = @()
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
CmdletsToExport = @()
# Variables to export from this module
VariablesToExport = '*'
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
AliasesToExport = @()
# DSC resources to export from this module
DscResourcesToExport = 'VMNetworkAdapterTeamMapping', 'VMNetworkAdapterSettings', 'VMNetworkAdapterIsolation'
# List of all modules packaged with this module
# ModuleList = @()
# List of all files packaged with this module
# FileList = @()
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
Tags = 'MSFTNetworking','Validate-DCB'
# A URL to the license for this module.
# LicenseUri = ''
# A URL to the main website for this project.
ProjectUri = 'https://aka.ms/Validate-DCB'
# A URL to an icon representing this module.
# IconUri = ''
# ReleaseNotes of this module
# ReleaseNotes = ''
# Prerelease string of this module
# Prerelease = ''
# Flag to indicate whether the module requires explicit user acceptance for install/update
# RequireLicenseAcceptance = $false
# External dependent modules of this module
# ExternalModuleDependencies = @()
} # End of PSData hashtable
} # End of PrivateData hashtable
# HelpInfo URI of this module
# HelpInfoURI = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''
}

Просмотреть файл

@ -1,181 +0,0 @@
enum Ensure {
Absent
Present
}
[DscResource()]
Class VMNetworkAdapterTeamMapping {
[DscProperty(Mandatory)]
[Ensure] $Ensure
[DscProperty(Key)]
[String] $PhysicalNetAdapterName
[DscProperty(Key)]
[String] $VMNetworkAdapterName
[VMNetworkAdapterTeamMapping] Get() {
$VMNetworkAdapterTeamMapping = Get-VMNetworkAdapterTeamMapping -ManagementOS -VMNetworkAdapterName $this.VMNetworkAdapterName
$this.PhysicalNetAdapterName = $VMNetworkAdapterTeamMapping.NetAdapterName
$this.VMNetworkAdapterName = $VMNetworkAdapterTeamMapping.ParentAdapter.Name
return $this
}
[bool] Test() {
$VMNetworkAdapterTeamMapping = Get-VMNetworkAdapterTeamMapping -ManagementOS -VMNetworkAdapterName $this.VMNetworkAdapterName
$testState = $false
if ($this.Ensure -eq [Ensure]::Present) {
If ($VMNetworkAdapterTeamMapping.NetAdapterName -eq $this.PhysicalNetAdapterName -and
$VMNetworkAdapterTeamMapping.ParentAdapter.Name -eq $this.VMNetworkAdapterName) {
$testState = $true
}
Else { $testState = $false }
}
elseif ($this.Ensure -eq [Ensure]::Absent) {
If ($VMNetworkAdapterTeamMapping) { $testState = $false }
Else { $testState = $true }
}
Return $testState
}
[Void] Set() {
if ($this.Ensure -eq [Ensure]::Present) {
Write-Verbose "Mapping $($this.VMNetworkAdapterName) to $($this.PhysicalNetAdapterName)"
Set-VMNetworkAdapterTeamMapping -ManagementOS -VMNetworkAdapterName $this.VMNetworkAdapterName -PhysicalNetAdapterName $this.PhysicalNetAdapterName
Write-Verbose "$($this.VMNetworkAdapterName) is now mapped to $($this.PhysicalNetAdapterName)"
}
elseif ($this.Ensure -eq [Ensure]::Absent) {
Write-Verbose "Removing team mapping for $($this.VMNetworkAdapterName)"
Remove-VMNetworkAdapterTeamMapping -ManagementOS -Name $this.VMNetworkAdapterName
Write-Verbose "Team mapping for $($this.VMNetworkAdapterName) is now removed"
}
}
}
[DscResource()]
Class VMNetworkAdapterSettings {
[DscProperty(Key)]
[String] $VMNetworkAdapterName
[DscProperty(Mandatory)]
[String] $VMName = 'ManagementOS'
[DscProperty()]
[ValidateSet('On','Off')]
[String] $IeeePriorityTag = 'Off'
[VMNetworkAdapterSettings] Get() {
$params = @{}
if ($this.VMName -eq 'ManagementOS') {
$params.Add('ManagementOS', $true)
}
else { $params.Add('VMName', $this.VMName)}
$VMNetworkAdapter = Get-VMNetworkAdapter -VMNetworkAdapterName $this.VMNetworkAdapterName @params -ErrorAction SilentlyContinue
$this.VMNetworkAdapterName = $VMNetworkAdapter.Name
$this.IeeePriorityTag = $VMNetworkAdapter.IeeePriorityTag
return $this
}
[bool] Test() {
$params = @{}
if ($this.VMName -eq 'ManagementOS') {$params.Add('ManagementOS', $true)}
else {$params.Add('VMName', $this.VMName)}
$VMNetworkAdapter = Get-VMNetworkAdapter -VMNetworkAdapterName $this.VMNetworkAdapterName @params -ErrorAction SilentlyContinue
$testState = $false
If ($this.IeeePriorityTag -eq $VMNetworkAdapter.IeeePriorityTag) { $testState = $true }
Else { $testState = $false }
Return $testState
}
[Void] Set() {
$params = @{}
if ($this.VMName -eq 'ManagementOS') {$params.Add('ManagementOS', $true)}
else {$params.Add('VMName', $this.VMName)}
$VMNetworkAdapter = Get-VMNetworkAdapter -VMNetworkAdapterName $this.VMNetworkAdapterName @params -ErrorAction SilentlyContinue
if ($this.IeeePriorityTag -ne $VMNetworkAdapter.IeeePriorityTag) {
Write-Verbose "Configuring IEEEPriorityTag on vNIC $($VMNetworkAdapter.Name) to $($this.IeeePriorityTag)"
Set-VMNetworkAdapter -VMNetworkAdapterName $this.VMNetworkAdapterName @params -IeeePriorityTag $this.IeeePriorityTag
Write-Verbose "IEEEPriorityTag on vNIC $($VMNetworkAdapter.Name) is now $($this.IeeePriorityTag)"
}
}
}
[DscResource()]
Class VMNetworkAdapterIsolation {
[DscProperty(Mandatory)]
[Ensure] $Ensure
[DscProperty(Key)]
[String] $VMNetworkAdapterName
[DscProperty(Mandatory)]
[ValidateRange(0,4096)]
[uint16] $DefaultIsolationID
[DscProperty()]
[Boolean] $AllowUntaggedTraffic
[DscProperty()]
[ValidateSet('Vlan','None')]
[String] $IsolationMode
[VMNetworkAdapterIsolation] Get() {
$VMNetworkAdapterIsolation = Get-VMNetworkAdapterIsolation -ManagementOS -VMNetworkAdapterName $this.VMNetworkAdapterName
$this.IsolationMode = $VMNetworkAdapterIsolation.IsolationMode
$this.DefaultIsolationID = $VMNetworkAdapterIsolation.DefaultIsolationID
$this.AllowUntaggedTraffic = $VMNetworkAdapterIsolation.AllowUntaggedTraffic
return $this
}
[bool] Test() {
$VMNetworkAdapterIsolation = Get-VMNetworkAdapterIsolation -ManagementOS -VMNetworkAdapterName $this.VMNetworkAdapterName
$testState = $false
if ($this.Ensure -eq [Ensure]::Present) {
if ( $VMNetworkAdapterIsolation.IsolationMode -eq $this.IsolationMode `
-and $VMNetworkAdapterIsolation.AllowUntaggedTraffic -eq $this.AllowUntaggedTraffic `
-and $VMNetworkAdapterIsolation.DefaultIsolationID -eq $this.DefaultIsolationID )
{ $testState = $true }
else { $testState = $false }
}
elseif ($this.Ensure -eq [Ensure]::Absent) {
If ($VMNetworkAdapterIsolation) { $testState = $false }
Else { $testState = $true }
}
Return $testState
}
[Void] Set() {
if ($this.Ensure -eq [Ensure]::Present) {
Write-Verbose "Removing VMNetworkAdapterVlan if configured on $($this.VMNetworkAdapterName)"
Set-VMNetworkAdapterVlan -ManagementOS -VMNetworkAdapterName $this.VMNetworkAdapterName -Untagged
Write-Verbose "Configuring Isolation for $($this.VMNetworkAdapterName)"
Set-VMNetworkAdapterIsolation -ManagementOS -IsolationMode $this.IsolationMode -DefaultIsolationID $this.DefaultIsolationID`
-AllowUntaggedTraffic $this.AllowUntaggedTraffic -VMNetworkAdapterName $this.VMNetworkAdapterName
Write-Verbose "VLAN Isolation for $($this.VMNetworkAdapterName) is now configured"
}
elseif ($this.Ensure -eq [Ensure]::Absent) {
Write-Verbose "Resetting Isolation for $($this.VMNetworkAdapterName)"
Set-VMNetworkAdapterIsolation -ManagementOS -VMNetworkAdapterName $this.VMNetworkAdapterName -IsolationMode 'None'
Write-Verbose "Isolation for $($this.VMNetworkAdapterName) is now reset"
}
}
}

Просмотреть файл

@ -8,122 +8,122 @@
@{
# Script module or binary module file associated with this manifest.
RootModule = 'NetworkConfig.psm1'
# Script module or binary module file associated with this manifest.
RootModule = 'NetworkConfig.psm1'
# Version number of this module.
ModuleVersion = '0.1'
# Version number of this module.
ModuleVersion = '0.1'
# Supported PSEditions
# CompatiblePSEditions = @()
# Supported PSEditions
# CompatiblePSEditions = @()
# ID used to uniquely identify this module
GUID = '94eafd99-5d6a-42d1-904d-a03b015f547b'
# ID used to uniquely identify this module
GUID = '94eafd99-5d6a-42d1-904d-a03b015f547b'
# Author of this module
Author = 'Dan Cuomo'
# Author of this module
Author = 'Dan Cuomo'
# Company or vendor of this module
CompanyName = 'Microsoft'
# Company or vendor of this module
CompanyName = 'Microsoft'
# Copyright statement for this module
Copyright = '(c) 2019 Microsoft Corp. All rights reserved.'
# Copyright statement for this module
Copyright = '(c) 2019 Microsoft Corp. All rights reserved.'
# Description of the functionality provided by this module
Description = 'Deployment option for Validate-DCB'
# Description of the functionality provided by this module
Description = 'Deployment option for Validate-DCB'
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '5.0'
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '5.0'
# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''
# Name of the Windows PowerShell host required by this module
# PowerShellHostName = ''
# Minimum version of the Windows PowerShell host required by this module
# PowerShellHostVersion = ''
# Minimum version of the Windows PowerShell host required by this module
# PowerShellHostVersion = ''
# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
# DotNetFrameworkVersion = ''
# Minimum version of Microsoft .NET Framework required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
# DotNetFrameworkVersion = ''
# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
# CLRVersion = ''
# Minimum version of the common language runtime (CLR) required by this module. This prerequisite is valid for the PowerShell Desktop edition only.
# CLRVersion = ''
# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''
# Processor architecture (None, X86, Amd64) required by this module
# ProcessorArchitecture = ''
# Modules that must be imported into the global environment prior to importing this module
RequiredModules = @(
@{ ModuleName = 'NetworkingDSC' ; ModuleVersion = '6.3.0.0' }
@{ ModuleName = 'xHyper-V' ; ModuleVersion = '3.16.0.0' }
@{ ModuleName = 'VMNetworkAdapter' ; ModuleVersion = '0.0.0.4' }
@{ ModuleName = 'DataCenterBridging'; ModuleVersion = '0.0.0.4' }
@{ ModuleName = 'FailoverClusters' ; ModuleVersion = '2.0.0.0' }
@{ ModuleName = 'PSDesiredStateConfiguration'; ModuleVersion = '1.1' }
)
# Modules that must be imported into the global environment prior to importing this module
RequiredModules = @(
@{ ModuleName = 'NetworkingDSC' ; ModuleVersion = '6.3.0.0' }
@{ ModuleName = 'xHyper-V' ; ModuleVersion = '3.16.0.0' }
@{ ModuleName = 'VMNetworkAdapter' ; ModuleVersion = '0.0.0.4' }
@{ ModuleName = 'DataCenterBridging'; ModuleVersion = '0.0.0.4' }
@{ ModuleName = 'FailoverClusters' ; ModuleVersion = '2.0.0.0' }
@{ ModuleName = 'PSDesiredStateConfiguration'; ModuleVersion = '1.1' }
)
# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()
# Assemblies that must be loaded prior to importing this module
# RequiredAssemblies = @()
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = @()
# Script files (.ps1) that are run in the caller's environment prior to importing this module.
# ScriptsToProcess = @()
# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()
# Type files (.ps1xml) to be loaded when importing this module
# TypesToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()
# Format files (.ps1xml) to be loaded when importing this module
# FormatsToProcess = @()
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()
# Modules to import as nested modules of the module specified in RootModule/ModuleToProcess
# NestedModules = @()
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = '*'
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = '*'
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
CmdletsToExport = '*'
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
CmdletsToExport = '*'
# Variables to export from this module
VariablesToExport = '*'
# Variables to export from this module
VariablesToExport = '*'
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
AliasesToExport = '*'
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
AliasesToExport = '*'
# DSC resources to export from this module
DscResourcesToExport = '*'
# DSC resources to export from this module
DscResourcesToExport = '*'
# List of all modules packaged with this module
# ModuleList = @()
# List of all modules packaged with this module
# ModuleList = @()
# List of all files packaged with this module
# FileList = @()
# List of all files packaged with this module
# FileList = @()
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{
PSData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
# Tags = @()
# Tags applied to this module. These help with module discovery in online galleries.
# Tags = @()
# A URL to the license for this module.
# LicenseUri = ''
# A URL to the license for this module.
# LicenseUri = ''
# A URL to the main website for this project.
# ProjectUri = ''
# A URL to the main website for this project.
# ProjectUri = ''
# A URL to an icon representing this module.
# IconUri = ''
# A URL to an icon representing this module.
# IconUri = ''
# ReleaseNotes of this module
# ReleaseNotes = ''
# ReleaseNotes of this module
# ReleaseNotes = ''
} # End of PSData hashtable
} # End of PSData hashtable
} # End of PrivateData hashtable
} # End of PrivateData hashtable
# HelpInfo URI of this module
# HelpInfoURI = ''
# HelpInfo URI of this module
# HelpInfoURI = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''
}
}

Просмотреть файл

@ -255,7 +255,7 @@ function vDCBUI {
</StackPanel>
<StackPanel Visibility="Hidden" Name="panel5" HorizontalAlignment="Left" Height="522.101" VerticalAlignment="Top" Margin="169.149,0,0,0" Width="615.137">
<Label Content="Data Center Bridging" FontSize="18" Margin="10,0"/>
<TextBlock Margin="14,0" TextWrapping="WrapWithOverflow"><Hyperlink Name="uri3" NavigateUri="https://docs.microsoft.com/en-us/windows-server/networking/technologies/dcb/dcb-top"><Run Text="Data Center Bridging (DCB)"/></Hyperlink><Run Text=" "/><Run Text="enables converged fabrics in the data center where compute and storage run on the same network (e.g. HCI) by providing hardware-based bandwidth allocation (ETS) to a specific type of traffic, and enhances Ethernet transport reliability with the use of priority-based flow control (PFC)."/><LineBreak/><LineBreak/><Run Text="If you have chosen iWARP (recommended), or are not using RDMA, DCB is optional. If you have selected RDMA over Converged Ethernet (RoCE), Data Center Bridging "/><Run FontWeight="Bold" Text="is required "/><Run Text="for network reliability on all NICs and switchports."/></TextBlock>
<TextBlock Margin="14,0" TextWrapping="WrapWithOverflow"><Hyperlink Name="uri3" NavigateUri="https://docs.microsoft.com/en-us/windows-server/networking/technologies/dcb/dcb-top"><Run Text="Data Center Bridging (DCB)"/></Hyperlink><Run Text=" "/><Run Text="enables converged fabrics in the data center where compute and storage run on the same network (e.g. HCI) by providing hardware-based bandwidth allocation (ETS) to a specific type of traffic, and enhances Ethernet transport reliability with the use of priority-based flow control (PFC)."/><LineBreak/><LineBreak/><Run Text="If you have chosen iWARP (recommended), or are no using RDMA, DCB is optional. If you have selected RDMA over Converged Ethernet (RoCE), Data Center Bridging "/><Run FontWeight="Bold" Text="is required "/><Run Text="network reliability on all NICs and switchports."/></TextBlock>
<Grid Margin="0,10"/>
<Separator/>
<StackPanel Orientation="Horizontal" Margin="0,2">
@ -1649,4 +1649,4 @@ function vDCBUI {
#TODO: Panel4 Check then uncheck vSwitch should set vNIC and VLAN back to default template
#TODO: Panel5 Integrate Live Migration Bandwidth Limitation
#TODO: Import configuration on Panel2
#TODO: If you go back to the intro page, Next is not enabled
#TODO: If you go back to the intro page, Next is not enabled

Просмотреть файл

@ -1,202 +0,0 @@
<#
.SYNOPSIS
Validate-DCB validates RDMA and DCB best practice configuration to assist in troubleshooting or verifying configuration
.DESCRIPTION
Validate-DCB allows you to:
- Validate the expected configuration on one to N number of systems or clusters
- Validate the configuration meets best practices
Additional benefits include:
- The configuration doubles as DCB documentation for the expected configuration of your systems.
- Answer the question "What Changed?" when faced with an operational issue
This tool does not modify your system. As such, you can re-validate the configuration as many times as desired.
.PARAMETER LaunchUI
Use to launch a user interface to help create a configuration file. Use the following values to specify one of the example files.
Optionally allows you to deploy the configuration using Azure Automation at the end.
.PARAMETER ExampleConfig
Use to specify one of the example configuration files. Use the following values to specify one of the example files
| Value | Location |
| ------- |------------------------------------------|
| NDKm1 | .\Examples\NDKm1-examples.DCB.config.ps1 |
| NDKm2 | .\Examples\NDKm2-examples.DCB.config.ps1 |
Possible options include NDKm1 or NDKm2. This option cannot be used with the $ConfigFilePath parameter
.PARAMETER ConfigFilePath
Specifies the literal or relative paths to a custom configuration file.
This option cannot be used with the $ExampleConfig parameter
.PARAMETER ContinueOnFailure
By default, Validate-DCB will exit at the end of a describe block if at least one test has failed.
The intent is to give you an opportunity to correct the issue prior to moving on. This could have an impact
on the ability of future tests to run successfully.
Use this to attempt all tests even if a test failure is detected.
.PARAMETER Deploy
Deploy the configuration specified in the config file to the nodes.
By default, Validate-DCB validates the configuration. With this option, it will modify your system.
Please note: Due to the nature of declarative PowerShell (DSC) this could be destructive. For example,
if your config file specify's that a vSwitch's IovEnabled property is $true and it is not actually
configured properly on the system DSC will attempt to destroy the vSwitch and recreate it with
the correct settings. Since this option can only be configured at vSwitch creation time, there is only one option.
.PARAMETER TestScope
Determines the describe block to be run. You can use this to only run certain describe blocks.
By default, Global and Modal (currently all) describe blocks are run.
.EXAMPLE
.\Initiate.ps1 -ExampleConfig NDKm2
.EXAMPLE
.\Initiate.ps1 -ConfigFilePath c:\temp\ClusterA.ps1
.EXAMPLE
.\Initiate.ps1 -TestScope Global
.EXAMPLE
.\Initiate.ps1 -TestScope Modal
.NOTES
Author: Windows Core Networking team @ Microsoft
Please file issues on GitHub @ GitHub.com/Microsoft/Validate-DCB
.LINK
More projects : https://github.com/microsoft/sdn
Windows Networking Blog : https://blogs.technet.microsoft.com/networking/
RDMA Configuration Guidance : https://aka.ms/ConvergedNIC
#>
[CmdletBinding(DefaultParameterSetName = 'Create Config')]
param (
[Parameter(ParameterSetName = 'DefaultConfig')]
[ValidateSet('NDKm1', 'NDKm2')]
[string] $ExampleConfig,
[Parameter(ParameterSetName = 'CustomConfig')]
[string] $ConfigFilePath,
[Parameter(ParameterSetName = 'Create Config')]
[switch] $LaunchUI = $true,
[Parameter(Mandatory = $false)]
[switch] $ContinueOnFailure = $false,
[Parameter(Mandatory = $false)]
[ValidateSet('All', 'Global', 'Modal')]
[string] $TestScope = 'All' ,
[Parameter(ParameterSetName = 'DefaultConfig')]
[Parameter(ParameterSetName = 'CustomConfig')]
[switch] $Deploy = $false
)
Clear-Host
If ($PSCmdlet.ParameterSetName -ne 'Create Config') { $LaunchUI = $false }
# TODO: Once converted to module, just add pester to required modules
If (-not (Get-Module -Name Pester -ListAvailable)) {
Write-Output 'Pester is an inbox PowerShell Module included in Windows 10, Windows Server 2016, and later'
Throw 'Catastrophic Failure :: PowerShell Module Pester was not found'
}
$here = Split-Path -Parent $MyInvocation.MyCommand.Path
$startTime = Get-Date -format:'yyyyMMdd-HHmmss'
New-Item -Name 'Results' -Path $here -ItemType Directory -Force
If ($global:deploy -eq $true -or $LaunchUI -eq $true) {
$testFile = Join-Path -Path $here -ChildPath "tests\unit\global.unit.tests.ps1"
$launch_deploy = Invoke-Pester -Script $testFile -Tag 'Launch_Deploy' -PassThru
$launch_deploy | Select-Object -Property TagFilter, Time, TotalCount, PassedCount, FailedCount, SkippedCount, PendingCount | Format-Table -AutoSize
If ($launch_deploy.FailedCount -ne 0) {
Write-Error -Message "One or more of the required modules was not available on the system."
Break
}
Else {
Import-Module "$here\helpers\NetworkConfig\NetworkConfig.psd1" -Force
Import-Module "$here\helpers\UI\vDCBUI.psm1" -Force
}
}
#region Getting helpers & data...
If ($LaunchUI) {
Write-Output 'Launching Configuration and Deployment UI'
vDCBUI
$ConfigFile = $global:ConfigPath
Write-Output "Configuration from the UI will be used"
If ($configFile -eq $null) {
Write-Error "Configuration file was not successfully saved"
break
}
Else {
Write-Output "The configuration is located at $ConfigFile"
}
}
ElseIf ($PSBoundParameters.ContainsKey('ExampleConfig')) {
$ConfigFile = $(Join-Path $Here -ChildPath "Examples\$ExampleConfig-examples.DCB.config.ps1")
$fullPath = (Get-ChildItem -Path $configFile).FullName
Write-Output "Example Configuration Mode ($ExampleConfig) was specified"
Write-Output "The default configuration located at $fullPath will be used"
}
ElseIf ($PSBoundParameters.ContainsKey('ConfigFilePath')) {
$fullPath = (Get-ChildItem -Path $ConfigFilePath).FullName
Write-Output "The Config File at $fullPath will be used"
$ConfigFile = $ConfigFilePath
}
If (Test-Path $ConfigFile) { & $ConfigFile }
Else {
Throw "Catastrophic Failure :: Configuration File was not found at $ConfigFile"
}
Remove-Variable -Name configData -ErrorAction SilentlyContinue
Import-Module "$here\helpers\helpers.psd1" -Force
$configData += Import-PowerShellDataFile -Path .\helpers\drivers\drivers.psd1
#endregion
Switch ($TestScope) {
'Global' {
$testFile = Join-Path -Path $here -ChildPath "tests\unit\global.unit.tests.ps1"
$GlobalResults = Invoke-Pester -Script $testFile -Tag 'Global' -OutputFile "$here\Results\$startTime-Global-unit.xml" -OutputFormat NUnitXml -PassThru
$GlobalResults | Select-Object -Property TagFilter, Time, TotalCount, PassedCount, FailedCount, SkippedCount, PendingCount | Format-Table -AutoSize
}
'Modal' {
If ($global:deploy) { Publish-Automation }
$testFile = Join-Path -Path $here -ChildPath "tests\unit\modal.unit.tests.ps1"
$ModalResults = Invoke-Pester -Script $testFile -Tag 'Modal' -OutputFile "$here\Results\$startTime-Modal-unit.xml" -OutputFormat NUnitXml -PassThru
$ModalResults | Select-Object -Property TagFilter, Time, TotalCount, PassedCount, FailedCount, SkippedCount, PendingCount | Format-Table -AutoSize
}
Default {
$testFile = Join-Path -Path $here -ChildPath "tests\unit\global.unit.tests.ps1"
$GlobalResults = Invoke-Pester -Script $testFile -Tag 'Global' -OutputFile "$here\Results\$startTime-Global-unit.xml" -OutputFormat NUnitXml -PassThru
$GlobalResults | Select-Object -Property TagFilter, Time, TotalCount, PassedCount, FailedCount, SkippedCount, PendingCount | Format-Table -AutoSize
If ($global:deploy) { Publish-Automation }
If ($GlobalResults.FailedCount -ne 0) {
Write-Host 'Failures in Global exist. Please resolve failures prior to moving on'
Break
}
$testFile = Join-Path -Path $here -ChildPath "tests\unit\modal.unit.tests.ps1"
$ModalResults = Invoke-Pester -Script $testFile -Tag 'Modal' -OutputFile "$here\Results\$startTime-Modal-unit.xml" -OutputFormat NUnitXml -PassThru
$ModalResults | Select-Object -Property TagFilter, Time, TotalCount, PassedCount, FailedCount, SkippedCount, PendingCount | Format-Table -AutoSize
}
}