зеркало из https://github.com/microsoft/MSLab.git
Коммит
75a67c5698
|
@ -225,13 +225,18 @@
|
|||
#Device Guard
|
||||
#REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard" /v "Locked" /t REG_DWORD /d 1 /f
|
||||
REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard" /v "EnableVirtualizationBasedSecurity" /t REG_DWORD /d 1 /f
|
||||
REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard" /v "RequirePlatformSecurityFeatures" /t REG_DWORD /d 3 /f
|
||||
#there s different setting for VM and Bare metal
|
||||
if ((Get-CimInstance -ClassName win32_computersystem).Model -eq "Virtual Machine"){
|
||||
REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard" /v "RequirePlatformSecurityFeatures" /t REG_DWORD /d 1 /f
|
||||
}else{
|
||||
REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard" /v "RequirePlatformSecurityFeatures" /t REG_DWORD /d 3 /f
|
||||
}
|
||||
REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard" /v "RequireMicrosoftSignedBootChain" /t REG_DWORD /d 1 /f
|
||||
|
||||
#Cred Guard
|
||||
REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v "LsaCfgFlags" /t REG_DWORD /d 1 /f
|
||||
|
||||
#System Guard Secure Launch
|
||||
#System Guard Secure Launch (bare meta only)
|
||||
#https://docs.microsoft.com/en-us/windows/security/threat-protection/windows-defender-system-guard/system-guard-secure-launch-and-smm-protection
|
||||
REG ADD "HKLM\SYSTEM\CurrentControlSet\Control\DeviceGuard\Scenarios\SystemGuard" /v "Enabled" /t REG_DWORD /d 1 /f
|
||||
|
||||
|
@ -1074,9 +1079,14 @@ if ($numberofnodes -eq 16){
|
|||
}
|
||||
|
||||
#Register AzSHCI with prompting for creds
|
||||
#Register-AzStackHCI -Region $Region -SubscriptionID $subscriptionID -ComputerName $ClusterName -UseDeviceAuthentication
|
||||
if ($ResourceGroupName){
|
||||
Register-AzStackHCI -Region $Region -SubscriptionID $subscriptionID -ComputerName $ClusterName -UseDeviceAuthentication -ResourceGroupName $ResourceGroupName
|
||||
}else{
|
||||
Register-AzStackHCI -Region $Region -SubscriptionID $subscriptionID -ComputerName $ClusterName -UseDeviceAuthentication
|
||||
}
|
||||
|
||||
#Register AZSHCi without prompting for creds again
|
||||
<#
|
||||
$armTokenItemResource = "https://management.core.windows.net/"
|
||||
#$graphTokenItemResource = "https://graph.windows.net/"
|
||||
$azContext = Get-AzContext
|
||||
|
@ -1088,6 +1098,7 @@ if ($numberofnodes -eq 16){
|
|||
}else{
|
||||
Register-AzStackHCI -Region $Region -SubscriptionID $subscriptionID -ArmAccessToken $armToken -ComputerName $ClusterName -AccountId $id -ResourceName $ClusterName
|
||||
}
|
||||
#>
|
||||
|
||||
#validate registration status
|
||||
#grab available commands for registration
|
||||
|
@ -1161,6 +1172,55 @@ if ((Get-CimInstance -ClassName win32_computersystem -CimSession $Servers[0]).Ma
|
|||
}
|
||||
#endregion
|
||||
|
||||
#region (optional) install iDRAC Service Module (ism) https://www.dell.com/support/search/en-us#q=ism&sort=relevancy&f:langFacet=[en]
|
||||
#note: ismrfutil is installed anyway as part of managing AzSHCI With Windows Admin Center
|
||||
if ((Get-CimInstance -ClassName win32_computersystem -CimSession $Servers[0]).Manufacturer -like "*Dell*"){
|
||||
#download and extract latest catalog
|
||||
#Download catalog
|
||||
Start-BitsTransfer -Source "https://downloads.dell.com/catalog/ASHCI-Catalog.xml.gz" -Destination "$env:UserProfile\Downloads\ASHCI-Catalog.xml.gz"
|
||||
#unzip gzip to a folder https://scatteredcode.net/download-and-extract-gzip-tar-with-powershell/
|
||||
Function Expand-GZipArchive{
|
||||
Param(
|
||||
$infile,
|
||||
$outfile = ($infile -replace '\.gz$','')
|
||||
)
|
||||
$input = New-Object System.IO.FileStream $inFile, ([IO.FileMode]::Open), ([IO.FileAccess]::Read), ([IO.FileShare]::Read)
|
||||
$output = New-Object System.IO.FileStream $outFile, ([IO.FileMode]::Create), ([IO.FileAccess]::Write), ([IO.FileShare]::None)
|
||||
$gzipStream = New-Object System.IO.Compression.GzipStream $input, ([IO.Compression.CompressionMode]::Decompress)
|
||||
$buffer = New-Object byte[](1024)
|
||||
while($true){
|
||||
$read = $gzipstream.Read($buffer, 0, 1024)
|
||||
if ($read -le 0){break}
|
||||
$output.Write($buffer, 0, $read)
|
||||
}
|
||||
$gzipStream.Close()
|
||||
$output.Close()
|
||||
$input.Close()
|
||||
}
|
||||
Expand-GZipArchive "$env:UserProfile\Downloads\ASHCI-Catalog.xml.gz" "$env:UserProfile\Downloads\ASHCI-Catalog.xml"
|
||||
#find binary in catalog
|
||||
#load catalog
|
||||
[xml]$XML=Get-Content "$env:UserProfile\Downloads\ASHCI-Catalog.xml"
|
||||
$component=$xml.manifest.SoftwareComponent | Where-Object Path -Like *systems-management*
|
||||
#find binary
|
||||
$url="https://dl.dell.com/$($component.path)"
|
||||
$filename=$url | Split-Path -Leaf
|
||||
#download
|
||||
Start-BitsTransfer -Source $url -Destination $env:USERPROFILE\Downloads\$filename
|
||||
#extract
|
||||
& $env:USERPROFILE\Downloads\$filename /auto $env:USERPROFILE\Downloads
|
||||
#copy ism to nodes and install
|
||||
$Sessions=New-PSSession -ComputerName $Servers
|
||||
foreach ($session in $sessions){
|
||||
Copy-Item -Path $env:USERPROFILE\Downloads\$filename -Destination $env:USERPROFILE\Downloads\$filename -ToSession $Session
|
||||
}
|
||||
#install
|
||||
Invoke-Command -ComputerName $Servers -ScriptBlock {
|
||||
Start-Process -FilePath $env:USERPROFILE\Downloads\$using:FileName -ArgumentList "/s" -Wait
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region (optional) Install Windows Admin Center Gateway https://github.com/microsoft/WSLab/tree/master/Scenarios/Windows%20Admin%20Center%20and%20Enterprise%20CA#gw-mode-installation-with-self-signed-cert
|
||||
##Install Windows Admin Center Gateway
|
||||
$GatewayServerName="WACGW"
|
||||
|
|
|
@ -154,39 +154,6 @@ $ScanResult
|
|||
|
||||
#let's update do node by node (in case something goes wrong). It would be definitely faster if we would install both updates at once. But if something would go wrong on one node, it's easier to roll back
|
||||
foreach ($Node in $Nodes){
|
||||
#Install Dell updates https://dl.dell.com/content/manual36290092-dell-emc-system-update-version-1-9-3-0-user-s-guide.pdf?language=en-us&ps=true
|
||||
if (($ScanResult | Where-Object ComputerName -eq $node).DellUpdateRequired){
|
||||
Write-Output "$($Node): Installing Dell System Updates"
|
||||
Invoke-Command -ComputerName $Node -ScriptBlock {
|
||||
#install DSU updates
|
||||
Start-Process -FilePath "install.cmd" -Wait -WorkingDirectory $using:DSUPackageDownloadFolder
|
||||
#display result
|
||||
Get-Content "C:\ProgramData\Dell\DELL System Update\dell_dup\DSU_STATUS.json"
|
||||
}
|
||||
}else{
|
||||
Write-Output "$($Node): Dell System Updates not required"
|
||||
}
|
||||
|
||||
#install Microsoft updates
|
||||
if (($ScanResult | Where-Object ComputerName -eq $node).MicrosoftUpdateRequired){
|
||||
Write-Output "$($Node): Installing $Updates Microsoft Updates"
|
||||
$MSUpdateInstallResult=Invoke-Command -ComputerName $Node -ConfigurationName 'VirtualAccount' {
|
||||
$Searcher = New-Object -ComObject Microsoft.Update.Searcher
|
||||
$SearchResult = $Searcher.Search($using:SearchCriteriaAllUpdates).Updates
|
||||
$Session = New-Object -ComObject Microsoft.Update.Session
|
||||
$Downloader = $Session.CreateUpdateDownloader()
|
||||
$Downloader.Updates = $SearchResult
|
||||
$Downloader.Download()
|
||||
$Installer = New-Object -ComObject Microsoft.Update.Installer
|
||||
$Installer.Updates = $SearchResult
|
||||
$Result = $Installer.Install()
|
||||
$Result
|
||||
}
|
||||
}else{
|
||||
Write-Output "$($Node): Microsoft Updates not required"
|
||||
$MSUpdateInstallResult=$Null
|
||||
}
|
||||
|
||||
#Check if reboot is required
|
||||
if (($ScanResult | Where-Object ComputerName -eq $node).DellUpdateRequired -or $MSUpdateInstallResult.RebootRequired -or $ForceReboot){
|
||||
Write-Output "$($Node): Reboot is required"
|
||||
|
@ -223,6 +190,26 @@ $ScanResult
|
|||
do{Start-Sleep 5}while(Get-StorageFaultDomain -CimSession $ClusterName | Where-Object HealthStatus -ne "Healthy")
|
||||
}
|
||||
|
||||
#install Microsoft updates
|
||||
if (($ScanResult | Where-Object ComputerName -eq $node).MicrosoftUpdateRequired){
|
||||
Write-Output "$($Node): Installing $Updates Microsoft Updates"
|
||||
$MSUpdateInstallResult=Invoke-Command -ComputerName $Node -ConfigurationName 'VirtualAccount' {
|
||||
$Searcher = New-Object -ComObject Microsoft.Update.Searcher
|
||||
$SearchResult = $Searcher.Search($using:SearchCriteriaAllUpdates).Updates
|
||||
$Session = New-Object -ComObject Microsoft.Update.Session
|
||||
$Downloader = $Session.CreateUpdateDownloader()
|
||||
$Downloader.Updates = $SearchResult
|
||||
$Downloader.Download()
|
||||
$Installer = New-Object -ComObject Microsoft.Update.Installer
|
||||
$Installer.Updates = $SearchResult
|
||||
$Result = $Installer.Install()
|
||||
$Result
|
||||
}
|
||||
}else{
|
||||
Write-Output "$($Node): Microsoft Updates not required"
|
||||
$MSUpdateInstallResult=$Null
|
||||
}
|
||||
|
||||
#Suspend node
|
||||
Write-Output "$($Node): Suspending Cluster Node"
|
||||
Suspend-ClusterNode -Name "$Node" -Cluster $ClusterName -Drain -Wait | Out-Null
|
||||
|
@ -231,6 +218,19 @@ $ScanResult
|
|||
Write-Output "$($Node): Enabling Storage Maintenance mode"
|
||||
Get-StorageFaultDomain -CimSession $ClusterName -FriendlyName $Node | Enable-StorageMaintenanceMode -CimSession $ClusterName
|
||||
|
||||
#Install Dell updates https://dl.dell.com/content/manual36290092-dell-emc-system-update-version-1-9-3-0-user-s-guide.pdf?language=en-us&ps=true
|
||||
if (($ScanResult | Where-Object ComputerName -eq $node).DellUpdateRequired){
|
||||
Write-Output "$($Node): Installing Dell System Updates"
|
||||
Invoke-Command -ComputerName $Node -ScriptBlock {
|
||||
#install DSU updates
|
||||
Start-Process -FilePath "install.cmd" -Wait -WorkingDirectory $using:DSUPackageDownloadFolder
|
||||
#display result
|
||||
Get-Content "C:\ProgramData\Dell\DELL System Update\dell_dup\DSU_STATUS.json"
|
||||
}
|
||||
}else{
|
||||
Write-Output "$($Node): Dell System Updates not required"
|
||||
}
|
||||
|
||||
#restart node and wait for PowerShell to come up
|
||||
Write-Output "$($Node): Restarting Cluster Node"
|
||||
Restart-Computer -ComputerName $Node -Protocol WSMan -Wait -For PowerShell
|
||||
|
@ -246,7 +246,7 @@ $ScanResult
|
|||
#wait for machines to finish live migration
|
||||
Write-Output "$($Node): Waiting for Live migrations to finish"
|
||||
do {Start-Sleep 5}while(
|
||||
Invoke-Command -ComputerName $Nodes -ScriptBlock {Get-CimInstance -Namespace root\virtualization\v2 -ClassName Msvm_MigrationJob} | Where-Object StatusDescriptions -eq "Job is running"
|
||||
Get-CimInstance -CimSession $Nodes -Namespace root\virtualization\v2 -ClassName Msvm_MigrationJob | Where-Object StatusDescriptions -eq "Job is running"
|
||||
)
|
||||
}else{
|
||||
Write-Output "$($Node): Reboot is not required"
|
||||
|
|
|
@ -39,8 +39,6 @@
|
|||
get-disk -Number 1 | Set-Disk -IsReadOnly $false
|
||||
get-disk -Number 1 | Set-Disk -IsOffline $false
|
||||
}
|
||||
#set trusted hosts back to $Null
|
||||
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "" -force
|
||||
|
||||
#Download files
|
||||
$downloadfolder="D:"
|
||||
|
@ -92,10 +90,10 @@
|
|||
}
|
||||
|
||||
#Create Azure Stack HCI registration role https://learn.microsoft.com/en-us/azure-stack/hci/deploy/register-with-azure#assign-permissions-from-azure-portal
|
||||
if (-not (Get-AzRoleDefinition -Name "Azure Stack HCI registration role")){
|
||||
if (-not (Get-AzRoleDefinition -Name "Azure Stack HCI registration role - Custom")){
|
||||
$Content=@"
|
||||
{
|
||||
"Name": "Azure Stack HCI registration role",
|
||||
"Name": "Azure Stack HCI registration role - Custom",
|
||||
"Id": null,
|
||||
"IsCustom": true,
|
||||
"Description": "Custom Azure role to allow subscription-level access to register Azure Stack HCI",
|
||||
|
@ -125,7 +123,7 @@
|
|||
#Create AzADServicePrincipal for Azure Stack HCI registration
|
||||
$SP=Get-AZADServicePrincipal -DisplayName $ServicePrincipalName
|
||||
if (-not $SP){
|
||||
$SP=New-AzADServicePrincipal -DisplayName $ServicePrincipalName -Role "Azure Stack HCI registration role"
|
||||
$SP=New-AzADServicePrincipal -DisplayName $ServicePrincipalName -Role "Azure Stack HCI registration role - Custom"
|
||||
#remove default cred
|
||||
Remove-AzADAppCredential -ApplicationId $SP.AppId
|
||||
}
|
||||
|
@ -278,6 +276,9 @@
|
|||
"@
|
||||
$Content | Out-File -FilePath d:\config.json
|
||||
|
||||
#set trusted hosts back to $Null
|
||||
Set-Item WSMan:\localhost\Client\TrustedHosts -Value "" -force
|
||||
|
||||
#start deployment
|
||||
.\Invoke-CloudDeployment -JSONFilePath D:\config.json -DeploymentUserCredential $DeploymentUserCred -LocalAdminCredential $LocalAdminCred -RegistrationSPCredential $SPNCred -RegistrationCloudName $CloudName -RegistrationSubscriptionID $SubscriptionID
|
||||
|
||||
|
@ -287,6 +288,6 @@ $Content | Out-File -FilePath d:\config.json
|
|||
$SeedNode="ASNode1"
|
||||
|
||||
Invoke-Command -ComputerName $SeedNode -ScriptBlock {
|
||||
([xml](Get-Content C:\ecestore\efb61d70-47ed-8f44-5d63-bed6adc0fb0f\086a22e3-ef1a-7b3a-dc9d-f407953b0f84)) | Select-Xml -XPath "//Action/Steps/Step" | ForEach-Object { $_.Node } | Select-Object FullStepIndex, Status, Name, StartTimeUtc, EndTimeUtc, @{Name="Durration";Expression={new-timespan -Start $_.StartTimeUtc -End $_.EndTimeUtc } } | ft -AutoSize
|
||||
([xml](Get-Content C:\ecestore\efb61d70-47ed-8f44-5d63-bed6adc0fb0f\086a22e3-ef1a-7b3a-dc9d-f407953b0f84)) | Select-Xml -XPath "//Action/Steps/Step" | ForEach-Object { $_.Node } | Select-Object FullStepIndex, Status, Name, StartTimeUtc, EndTimeUtc, @{Name="Duration";Expression={new-timespan -Start $_.StartTimeUtc -End $_.EndTimeUtc } } | ft -AutoSize
|
||||
}
|
||||
#endregion
|
|
@ -0,0 +1,23 @@
|
|||
$LabConfig=@{AllowedVLANs="1-10,711-719" ; DomainAdminName='LabAdmin'; AdminPassword='LS1setup!'; <# Prefix = 'MSLab-';#> SwitchName = 'LabSwitch'; DCEdition='4'; AdditionalNetworksConfig=@(); VMs=@()}
|
||||
|
||||
#Azure Stack HCI 22h2 (without disks as we dont need it to play with network)
|
||||
#4VMProcessors are needed for NetATC to work in VMs (intent will fail to apply because of vRSS)
|
||||
$LabConfig.VMs += @{ VMName = '2NICs1' ; ParentVHD = 'AzSHCI22H2_G2.vhdx' ; VMProcessorCount=4 }
|
||||
$LabConfig.VMs += @{ VMName = '2NICs2' ; ParentVHD = 'AzSHCI22H2_G2.vhdx' ; VMProcessorCount=4 }
|
||||
$LabConfig.VMs += @{ VMName = '4NICs1' ; ParentVHD = 'AzSHCI22H2_G2.vhdx' ; VMProcessorCount=4 ; MGMTNICs=4 }
|
||||
$LabConfig.VMs += @{ VMName = '4NICs2' ; ParentVHD = 'AzSHCI22H2_G2.vhdx' ; VMProcessorCount=4 ; MGMTNICs=4 }
|
||||
$LabConfig.VMs += @{ VMName = '6NICs1' ; ParentVHD = 'AzSHCI22H2_G2.vhdx' ; VMProcessorCount=4 ; MGMTNICs=6 }
|
||||
$LabConfig.VMs += @{ VMName = '6NICs2' ; ParentVHD = 'AzSHCI22H2_G2.vhdx' ; VMProcessorCount=4 ; MGMTNICs=6 }
|
||||
$LabConfig.VMs += @{ VMName = 'Switchless1' ; ParentVHD = 'AzSHCI22H2_G2.vhdx' ; VMProcessorCount=4 ; MGMTNICs=4 }
|
||||
$LabConfig.VMs += @{ VMName = 'Switchless2' ; ParentVHD = 'AzSHCI22H2_G2.vhdx' ; VMProcessorCount=4 ; MGMTNICs=4 }
|
||||
$LabConfig.VMs += @{ VMName = 'Switchless3' ; ParentVHD = 'AzSHCI22H2_G2.vhdx' ; VMProcessorCount=4 ; MGMTNICs=4 }
|
||||
$LabConfig.VMs += @{ VMName = 'Site1Node1' ; ParentVHD = 'AzSHCI22H2_G2.vhdx' ; VMProcessorCount=4 ; MGMTNICs=4 }
|
||||
$LabConfig.VMs += @{ VMName = 'Site1Node2' ; ParentVHD = 'AzSHCI22H2_G2.vhdx' ; VMProcessorCount=4 ; MGMTNICs=4 }
|
||||
$LabConfig.VMs += @{ VMName = 'Site2Node1' ; ParentVHD = 'AzSHCI22H2_G2.vhdx' ; VMProcessorCount=4 ; MGMTNICs=4 }
|
||||
$LabConfig.VMs += @{ VMName = 'Site2Node2' ; ParentVHD = 'AzSHCI22H2_G2.vhdx' ; VMProcessorCount=4 ; MGMTNICs=4 }
|
||||
|
||||
#Management machine
|
||||
$LabConfig.VMs += @{ VMName = 'Management' ; ParentVHD = 'Win2022_G2.vhdx'; MGMTNICs=1}
|
||||
|
||||
#Optional Windows Admin Center in GW mode
|
||||
#$LabConfig.VMs += @{ VMName = 'WacGW' ; ParentVHD = 'Win2022Core_G2.vhdx'; MGMTNICs=1}
|
|
@ -0,0 +1,587 @@
|
|||
#source:
|
||||
#https://learn.microsoft.com/en-us/azure-stack/hci/deploy/network-atc?tabs=22H2
|
||||
#https://techcommunity.microsoft.com/t5/networking-blog/network-atc-common-preview-questions/ba-p/2780086
|
||||
|
||||
#region variables
|
||||
$Clusters=@()
|
||||
$Clusters+=@{Nodes="2NICs1","2NICs2" ; Name="2NICsCluster" ; IP="10.0.0.111" }
|
||||
$Clusters+=@{Nodes="4NICs1","4NICs2" ; Name="4NICsCluster" ; IP="10.0.0.112" }
|
||||
$Clusters+=@{Nodes="6NICs1","6NICs2" ; Name="6NICsCluster" ; IP="10.0.0.113" }
|
||||
$Clusters+=@{Nodes="Switchless1","Switchless2","Switchless3" ; Name="SLCluster" ; IP="10.0.0.114" }
|
||||
$Clusters+=@{Nodes="Site1Node1","Site1Node2","Site2Node1","Site2Node2" ; Name="StretchCluster" ; IP="10.0.0.115" }
|
||||
|
||||
$StretchClusterName="StretchCluster"
|
||||
$CredSSPUserName="corp\LabAdmin"
|
||||
$CredSSPPassword="LS1setup!"
|
||||
|
||||
#endregion
|
||||
|
||||
#region update all servers (there have been multiple fixes for NetATC. Updating servers is crucial)
|
||||
# Update servers with all updates (including preview)
|
||||
$Servers=$Clusters.Nodes
|
||||
Invoke-Command -ComputerName $servers -ScriptBlock {
|
||||
New-PSSessionConfigurationFile -RunAsVirtualAccount -Path $env:TEMP\VirtualAccount.pssc
|
||||
Register-PSSessionConfiguration -Name 'VirtualAccount' -Path $env:TEMP\VirtualAccount.pssc -Force
|
||||
} -ErrorAction Ignore
|
||||
#sleep a bit
|
||||
Start-Sleep 2
|
||||
# Run Windows Update via ComObject.
|
||||
Invoke-Command -ComputerName $servers -ConfigurationName 'VirtualAccount' {
|
||||
$Searcher = New-Object -ComObject Microsoft.Update.Searcher
|
||||
$SearchCriteriaAllUpdates = "IsInstalled=0 and DeploymentAction='Installation' or
|
||||
IsInstalled=0 and DeploymentAction='OptionalInstallation' or
|
||||
IsPresent=1 and DeploymentAction='Uninstallation' or
|
||||
IsInstalled=1 and DeploymentAction='Installation' and RebootRequired=1 or
|
||||
IsInstalled=0 and DeploymentAction='Uninstallation' and RebootRequired=1"
|
||||
$SearchResult = $Searcher.Search($SearchCriteriaAllUpdates).Updates
|
||||
if ($SearchResult.Count -gt 0){
|
||||
$Session = New-Object -ComObject Microsoft.Update.Session
|
||||
$Downloader = $Session.CreateUpdateDownloader()
|
||||
$Downloader.Updates = $SearchResult
|
||||
$Downloader.Download()
|
||||
$Installer = New-Object -ComObject Microsoft.Update.Installer
|
||||
$Installer.Updates = $SearchResult
|
||||
$Result = $Installer.Install()
|
||||
$Result
|
||||
}
|
||||
}
|
||||
#remove temporary PSsession config
|
||||
Invoke-Command -ComputerName $servers -ScriptBlock {
|
||||
Unregister-PSSessionConfiguration -Name 'VirtualAccount'
|
||||
Remove-Item -Path $env:TEMP\VirtualAccount.pssc
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Install features (Same as Azure Stack HCI 22H2 Scenario)
|
||||
#install features for management (assuming you are running these commands on Windows Server with GUI)
|
||||
Install-WindowsFeature -Name RSAT-Clustering,RSAT-Clustering-Mgmt,RSAT-Clustering-PowerShell,RSAT-Hyper-V-Tools,RSAT-Feature-Tools-BitLocker-BdeAducExt,RSAT-Storage-Replica
|
||||
|
||||
#install roles and features on servers
|
||||
$Servers=$Clusters.Nodes
|
||||
#install Hyper-V using DISM if Install-WindowsFeature fails (if nested virtualization is not enabled install-windowsfeature fails)
|
||||
Invoke-Command -ComputerName $servers -ScriptBlock {
|
||||
$Result=Install-WindowsFeature -Name "Hyper-V" -ErrorAction SilentlyContinue
|
||||
if ($result.ExitCode -eq "failed"){
|
||||
Enable-WindowsOptionalFeature -FeatureName Microsoft-Hyper-V -Online -NoRestart
|
||||
}
|
||||
}
|
||||
#define and install other features
|
||||
$features="Failover-Clustering","RSAT-Clustering-PowerShell","Hyper-V-PowerShell","NetworkATC","NetworkHUD","Data-Center-Bridging","RSAT-DataCenterBridging-LLDP-Tools","FS-SMBBW","Bitlocker","RSAT-Feature-Tools-BitLocker","Storage-Replica","RSAT-Storage-Replica","FS-Data-Deduplication","System-Insights","RSAT-System-Insights"
|
||||
Invoke-Command -ComputerName $servers -ScriptBlock {Install-WindowsFeature -Name $using:features}
|
||||
|
||||
#restart all servers
|
||||
Restart-Computer -ComputerName $servers -Protocol WSMan -Wait -For PowerShell
|
||||
|
||||
#check windows version
|
||||
$RegistryPath = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\'
|
||||
$ComputersInfo = Invoke-Command -ComputerName $servers -ScriptBlock {
|
||||
Get-ItemProperty -Path $using:RegistryPath
|
||||
}
|
||||
$ComputersInfo | Select-Object PSComputerName,ProductName,DisplayVersion,CurrentBuildNumber,UBR | Format-Table -AutoSize
|
||||
|
||||
#endregion
|
||||
|
||||
#region Explore NetATC commands
|
||||
$Servers=$Clusters.Nodes
|
||||
#make sure NetATC,FS-SMBBW and other required features are installed on servers
|
||||
#FS-SMBBW feature is used to configure SMB limits on Live Migration traffic using NetATC.
|
||||
Invoke-Command -ComputerName $Servers -ScriptBlock {
|
||||
Install-WindowsFeature -Name NetworkATC,Data-Center-Bridging,RSAT-Clustering-PowerShell,RSAT-Hyper-V-Tools,FS-SMBBW
|
||||
}
|
||||
|
||||
#since ATC is not available on management machine, copy PowerShell module over to management machine from cluster. However global intents will not be automatically added as in C:\Windows\System32\WindowsPowerShell\v1.0\Modules\NetworkATC\NetWorkATC.psm1 is being checked if NetATC feature is installed [FabricManager.FeatureStaging]::Feature_NetworkATC_IsEnabled()
|
||||
$session=New-PSSession -ComputerName $Servers[0]
|
||||
$items="C:\Windows\System32\WindowsPowerShell\v1.0\Modules\NetworkATC","C:\Windows\System32\NetworkAtc.Driver.dll","C:\Windows\System32\Newtonsoft.Json.dll","C:\Windows\System32\NetworkAtcFeatureStaging.dll"
|
||||
foreach ($item in $items){
|
||||
Copy-Item -FromSession $session -Path $item -Destination $item -Recurse -Force
|
||||
}
|
||||
|
||||
#Explore Commands available locally
|
||||
$Commands1=Get-Command -Module NetworkATC
|
||||
$Commands1
|
||||
|
||||
#Explore commands avalable on Servers
|
||||
$Commands2=Invoke-Command -ComputerName $Servers[0] -ScriptBlock {
|
||||
Get-Command -Module NetworkATC
|
||||
}
|
||||
$Commands2
|
||||
|
||||
#you will most likely see, that there are some commands present only on Servers
|
||||
Compare-Object $Commands1.Name $Commands2.Name
|
||||
<#
|
||||
InputObject SideIndicator
|
||||
----------- -------------
|
||||
New-NetIntentGlobalClusterOverrides =>
|
||||
New-NetIntentGlobalProxyOverrides =>
|
||||
New-NetIntentSiteOverrides =>
|
||||
New-NetIntentStorageOverrides =>
|
||||
#>
|
||||
#The reason is, that PowerShell module is wrongly (I guess design decision) detecting, if NetATC 22H2 is running locally.
|
||||
#endregion
|
||||
|
||||
#region Working with Network intent with server scope
|
||||
$Servers=$Clusters.Nodes
|
||||
#region apply intent and troubleshoot
|
||||
#You can configure Network intent on one server, or on entire cluster.
|
||||
#it might be useful to configure intent first on servers before cluster is created, as flapping network will make node isolated during intent application
|
||||
|
||||
#let's configure converged intent on first server (will fail - what???)
|
||||
Add-NetIntent -ComputerName $Servers[0] -Name compute_management_storage -Management -Compute -Storage -AdapterName "Ethernet","Ethernet 2"
|
||||
|
||||
#anyway, let's invoke it
|
||||
Invoke-Command -ComputerName $Servers[0] -ScriptBlock {
|
||||
Add-NetIntent -Name compute_management_storage -Management -Compute -Storage -AdapterName "Ethernet","Ethernet 2"
|
||||
}
|
||||
|
||||
#Converged intent will be submitted. Let's check status
|
||||
Get-NetIntentStatus -ComputerName $Servers[0]
|
||||
|
||||
#we can also wait until intent is finished (will take quite some time)
|
||||
Start-Sleep 20 #let intent propagate a bit
|
||||
Write-Output "applying intent"
|
||||
do {
|
||||
$status=Invoke-Command -ComputerName $Servers[0] -ScriptBlock {Get-NetIntentStatus}
|
||||
Write-Host "." -NoNewline
|
||||
Start-Sleep 5
|
||||
} while ($status.ConfigurationStatus -contains "Provisioning" -or $status.ConfigurationStatus -contains "Retrying")
|
||||
|
||||
#Intent will fail to apply, since we are in VMs. Let's troubleshoot
|
||||
Get-NetIntentStatus -ComputerName $Servers[0]
|
||||
|
||||
#check event logs
|
||||
$events=Invoke-Command -ComputerName $Servers[0] -ScriptBlock {
|
||||
Get-WinEvent -FilterHashtable @{"ProviderName"="Microsoft-Windows-Networking-NetworkATC"}
|
||||
}
|
||||
$events | Format-Table -AutoSize
|
||||
|
||||
#the problem is, that in VM you cannot configure DCB (because of hyper-v adapters), so let's create an override (Error:AdvancedPropertyNotSupported)
|
||||
#note: Name of the intent is case sensitive!!!
|
||||
|
||||
#let's remove intent first (it's faster than adjusting failing intent)
|
||||
Remove-NetIntent -ComputerName $Servers[0] -Name compute_management_storage
|
||||
|
||||
#and let's try to create intent again, but now with override
|
||||
Invoke-Command -ComputerName $Servers[0] -ScriptBlock {
|
||||
$AdapterOverride = New-NetIntentAdapterPropertyOverrides
|
||||
$AdapterOverride.NetworkDirect = 0
|
||||
Add-NetIntent -Name compute_management_storage -Management -Compute -Storage -AdapterName "Ethernet","Ethernet 2" -AdapterPropertyOverrides $AdapterOverride -Verbose
|
||||
}
|
||||
#wait for intent to be applied
|
||||
#wait a bit first
|
||||
Start-Sleep 20
|
||||
Write-Output "applying intent"
|
||||
do {
|
||||
$status=Invoke-Command -ComputerName $Servers[0] -ScriptBlock {Get-NetIntentStatus}
|
||||
Write-Host "." -NoNewline
|
||||
Start-Sleep 5
|
||||
} while ($status.ConfigurationStatus -contains "Provisioning" -or $status.ConfigurationStatus -contains "Retrying")
|
||||
|
||||
#Check intent status
|
||||
Get-NetIntentStatus -ComputerName $Servers[0]
|
||||
#endregion
|
||||
|
||||
#region explore what was configured
|
||||
#explore intent
|
||||
$Intent=Get-NetIntent -ComputerName $Servers[0]
|
||||
$Intent
|
||||
$Intent.AdapterAdvancedParametersOverride
|
||||
$Intent.RssConfigOverride
|
||||
$Intent.QosPolicyOverride
|
||||
$Intent.SwitchConfigOverride
|
||||
$Intent.IPOverride
|
||||
|
||||
#VMSwitch (notice IOVEnabled,BandwidthReservationMode,)
|
||||
Get-VMSwitch -CimSession $Servers[0] | Select-Object *
|
||||
|
||||
#validate vNICs to pNICs mapping
|
||||
Get-VMNetworkAdapterTeamMapping -CimSession $servers[0] -ManagementOS | Select-Object ComputerName,NetAdapterName,ParentAdapter
|
||||
#grab vNICs
|
||||
Get-VMNetworkAdapter -CimSession $Servers[0] -ManagementOS
|
||||
#grab IPAddresses
|
||||
Get-NetIPAddress -InterfaceAlias v* -AddressFamily IPv4 -CimSession $Servers[0]
|
||||
#validate JumboFrames setting (is default - disabled)
|
||||
Get-NetAdapterAdvancedProperty -CimSession $servers[0] -DisplayName "Jumbo Packet"
|
||||
#verify RDMA settings (disabled in VMs)
|
||||
Get-NetAdapterRdma -CimSession $servers[0] | Sort-Object -Property PSComputerName,Name
|
||||
#validate if VLANs were set
|
||||
Get-VMNetworkAdapterVlan -CimSession $Servers[0] -ManagementOS
|
||||
#VLANs in NetATC are set with VMNetworkAdapterIsolation
|
||||
Get-VMNetworkAdapterIsolation -CimSession $Servers[0] -ManagementOS
|
||||
#validate policy (no result since it's not available in VM)
|
||||
Invoke-Command -ComputerName $servers[0] -ScriptBlock {Get-NetAdapterQos | Where-Object enabled -eq true} | Sort-Object PSComputerName
|
||||
#Validate QOS Policies
|
||||
Get-NetQosPolicy -CimSession $servers[0] | Sort-Object PSComputerName,Name | Select-Object PSComputerName,NetDirectPort,PriorityValue
|
||||
#validate flow control setting
|
||||
Invoke-Command -ComputerName $servers[0] -ScriptBlock {Get-NetQosFlowControl} | Sort-Object -Property PSComputername,Priority | Select-Object PSComputerName,Priority,Enabled
|
||||
#validate QoS Traffic Classes (2 percent for cluster since in VMs are 10Gbps NICs)
|
||||
Invoke-Command -ComputerName $servers[0] -ScriptBlock {Get-NetQosTrafficClass} |Sort-Object PSComputerName,Name |Select-Object PSComputerName,Name,PriorityFriendly,Bandwidth
|
||||
#endregion
|
||||
|
||||
#region remove netintent from first server
|
||||
Remove-NetIntent -ComputerName $Servers[0] -Name compute_management_storage
|
||||
#remove VMSwitch
|
||||
Get-VMSwitch -CimSession $Servers[0] | Remove-VMSwitch -Force
|
||||
#endregion
|
||||
#endregion
|
||||
|
||||
#region working with network intents in clusters
|
||||
#region create clusters
|
||||
foreach ($Cluster in $Clusters){
|
||||
New-Cluster -Name $cluster.Name -Node $Cluster.Nodes -StaticAddress $cluster.IP
|
||||
Start-Sleep 5
|
||||
Clear-DNSClientCache
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region create fully converged cluster intent on 2NICsCluster
|
||||
$ClusterName=$Clusters[0].Name
|
||||
$Servers=$Clusters[0].Nodes
|
||||
|
||||
#make sure NetATC,FS-SMBBW and other required features are installed on servers
|
||||
Invoke-Command -ComputerName $Servers -ScriptBlock {
|
||||
Install-WindowsFeature -Name NetworkATC,Data-Center-Bridging,RSAT-Clustering-PowerShell,RSAT-Hyper-V-Tools,FS-SMBBW
|
||||
}
|
||||
|
||||
Import-Module NetworkATC
|
||||
$AdapterNames="Ethernet","Ethernet 2"
|
||||
Add-NetIntent -ClusterName $ClusterName -Name compute_management_storage -Management -Compute -Storage -AdapterName $AdapterNames -AdapterPropertyOverrides $AdapterOverride -Verbose #-StorageVlans 1,2
|
||||
|
||||
#in virtual environment it's needed to add override for RDMA config (you should skip this for physical servers)
|
||||
#virtual environment (skipping RDMA config)
|
||||
$AdapterOverride = New-NetIntentAdapterPropertyOverrides
|
||||
$AdapterOverride.NetworkDirect = 0
|
||||
Set-NetIntent -ClusterName $ClusterName -Name management -AdapterPropertyOverrides $AdapterOverride
|
||||
|
||||
#Add default global intent
|
||||
#since when configuring from Management machine there is a test [FabricManager.FeatureStaging]::Feature_NetworkATC_IsEnabled() to make global intents available, it will not be configured, so it has to be configured manually with invoke command
|
||||
Invoke-Command -ComputerName $servers[0] -ScriptBlock {
|
||||
Import-Module NetworkATC
|
||||
$overrides=New-NetIntentGlobalClusterOverrides
|
||||
#add empty intent
|
||||
Add-NetIntent -GlobalClusterOverrides $overrides
|
||||
}
|
||||
|
||||
#check
|
||||
Start-Sleep 20 #let intent propagate a bit
|
||||
Write-Output "applying intent"
|
||||
do {
|
||||
$status=Invoke-Command -ComputerName $ClusterName -ScriptBlock {Get-NetIntentStatus}
|
||||
Write-Host "." -NoNewline
|
||||
Start-Sleep 5
|
||||
} while ($status.ConfigurationStatus -contains "Provisioning" -or $status.ConfigurationStatus -contains "Retrying")
|
||||
|
||||
#remove if necessary
|
||||
<#
|
||||
Invoke-Command -ComputerName $servers[0] -ScriptBlock {
|
||||
$intents = Get-NetIntent
|
||||
foreach ($intent in $intents){
|
||||
Remove-NetIntent -Name $intent.IntentName
|
||||
}
|
||||
}
|
||||
#>
|
||||
|
||||
#if deploying in VMs, some nodes might fail (quarantined state) and even CNO can go to offline ... go to cluadmin and fix
|
||||
#Get-ClusterNode -Cluster $ClusterName | Where-Object State -eq down | Start-ClusterNode -ClearQuarantine
|
||||
#endregion
|
||||
|
||||
#region create Network Intent for cluster where are 2 NICs used for compute and management, and another 2 NICs for storage
|
||||
$ClusterName=$Clusters[1].Name
|
||||
$Servers=$Clusters[1].Nodes
|
||||
|
||||
#make sure NetATC,FS-SMBBW and other required features are installed on servers
|
||||
Invoke-Command -ComputerName $Servers -ScriptBlock {
|
||||
Install-WindowsFeature -Name NetworkATC,Data-Center-Bridging,RSAT-Clustering-PowerShell,RSAT-Hyper-V-Tools,FS-SMBBW
|
||||
}
|
||||
|
||||
Import-Module NetworkATC
|
||||
#add compute+management intent
|
||||
$AdapterNames="Ethernet","Ethernet 2"
|
||||
Add-NetIntent -ClusterName $ClusterName -Name compute_management -Management -Compute -AdapterName $AdapterNames -Verbose
|
||||
|
||||
#add storage intent
|
||||
$AdapterNames="Ethernet 3","Ethernet 4"
|
||||
Add-NetIntent -ClusterName $ClusterName -Name storage -Storage -AdapterName $AdapterNames -Verbose #-StorageVlans 1,2
|
||||
|
||||
#in virtual environment it's needed to add override for RDMA config (you should skip this for physical servers)
|
||||
#virtual environment (skipping RDMA config)
|
||||
$AdapterOverride = New-NetIntentAdapterPropertyOverrides
|
||||
$AdapterOverride.NetworkDirect = 0
|
||||
Set-NetIntent -ClusterName $ClusterName -Name compute_management -AdapterPropertyOverrides $AdapterOverride
|
||||
Set-NetIntent -ClusterName $ClusterName -Name storage -AdapterPropertyOverrides $AdapterOverride
|
||||
|
||||
#Add default global intent
|
||||
#since when configuring from Management machine there is a test [FabricManager.FeatureStaging]::Feature_NetworkATC_IsEnabled() to make global intents available, it will not be configured, so it has to be configured manually with invoke command
|
||||
Invoke-Command -ComputerName $servers[0] -ScriptBlock {
|
||||
Import-Module NetworkATC
|
||||
$overrides=New-NetIntentGlobalClusterOverrides
|
||||
#add empty intent
|
||||
Add-NetIntent -GlobalClusterOverrides $overrides
|
||||
}
|
||||
|
||||
#check
|
||||
Start-Sleep 20 #let intent propagate a bit
|
||||
Write-Output "applying intent"
|
||||
do {
|
||||
$status=Invoke-Command -ComputerName $ClusterName -ScriptBlock {Get-NetIntentStatus}
|
||||
Write-Host "." -NoNewline
|
||||
Start-Sleep 5
|
||||
} while ($status.ConfigurationStatus -contains "Provisioning" -or $status.ConfigurationStatus -contains "Retrying")
|
||||
|
||||
#remove if necessary
|
||||
<#
|
||||
Invoke-Command -ComputerName $servers[0] -ScriptBlock {
|
||||
$intents = Get-NetIntent
|
||||
foreach ($intent in $intents){
|
||||
Remove-NetIntent -Name $intent.IntentName
|
||||
}
|
||||
}
|
||||
#>
|
||||
|
||||
#if deploying in VMs, some nodes might fail (quarantined state) and even CNO can go to offline ... go to cluadmin and fix
|
||||
#Get-ClusterNode -Cluster $ClusterName | Where-Object State -eq down | Start-ClusterNode -ClearQuarantine
|
||||
#endregion
|
||||
|
||||
#region create Network Intent for cluster where are 2 NICs used for Management, 2NICs for VMs, and 2NICs for Storage
|
||||
$ClusterName=$Clusters[2].Name
|
||||
$Servers=$Clusters[2].Nodes
|
||||
|
||||
#make sure NetATC,FS-SMBBW and other required features are installed on servers
|
||||
Invoke-Command -ComputerName $Servers -ScriptBlock {
|
||||
Install-WindowsFeature -Name NetworkATC,Data-Center-Bridging,RSAT-Clustering-PowerShell,RSAT-Hyper-V-Tools,FS-SMBBW
|
||||
}
|
||||
|
||||
Import-Module NetworkATC
|
||||
#add Management intent
|
||||
$AdapterNames="Ethernet","Ethernet 2"
|
||||
Add-NetIntent -ClusterName $ClusterName -Name management -Management -AdapterName $AdapterNames -Verbose
|
||||
|
||||
#add Compute intent
|
||||
$AdapterNames="Ethernet 3","Ethernet 4"
|
||||
Add-NetIntent -ClusterName $ClusterName -Name compute -Compute -AdapterName $AdapterNames -Verbose
|
||||
|
||||
#add storage intent
|
||||
$AdapterNames="Ethernet 5","Ethernet 6"
|
||||
Add-NetIntent -ClusterName $ClusterName -Name storage -Storage -AdapterName $AdapterNames -Verbose #-StorageVlans 1,2
|
||||
|
||||
#in virtual environment it's needed to add override for RDMA config (you should skip this for physical servers)
|
||||
#virtual environment (skipping RDMA config)
|
||||
$AdapterOverride = New-NetIntentAdapterPropertyOverrides
|
||||
$AdapterOverride.NetworkDirect = 0
|
||||
Set-NetIntent -ClusterName $ClusterName -Name management -AdapterPropertyOverrides $AdapterOverride
|
||||
Set-NetIntent -ClusterName $ClusterName -Name compute -AdapterPropertyOverrides $AdapterOverride
|
||||
Set-NetIntent -ClusterName $ClusterName -Name storage -AdapterPropertyOverrides $AdapterOverride
|
||||
|
||||
#Add default global intent
|
||||
#since when configuring from Management machine there is a test [FabricManager.FeatureStaging]::Feature_NetworkATC_IsEnabled() to make global intents available, it will not be configured, so it has to be configured manually with invoke command
|
||||
Invoke-Command -ComputerName $servers[0] -ScriptBlock {
|
||||
Import-Module NetworkATC
|
||||
$overrides=New-NetIntentGlobalClusterOverrides
|
||||
#add empty intent
|
||||
Add-NetIntent -GlobalClusterOverrides $overrides
|
||||
}
|
||||
|
||||
#check
|
||||
Start-Sleep 20 #let intent propagate a bit
|
||||
Write-Output "applying intent"
|
||||
do {
|
||||
$status=Invoke-Command -ComputerName $ClusterName -ScriptBlock {Get-NetIntentStatus}
|
||||
Write-Host "." -NoNewline
|
||||
Start-Sleep 5
|
||||
} while ($status.ConfigurationStatus -contains "Provisioning" -or $status.ConfigurationStatus -contains "Retrying")
|
||||
|
||||
#remove if necessary
|
||||
<#
|
||||
Invoke-Command -ComputerName $servers[0] -ScriptBlock {
|
||||
$intents = Get-NetIntent
|
||||
foreach ($intent in $intents){
|
||||
Remove-NetIntent -Name $intent.IntentName
|
||||
}
|
||||
}
|
||||
#>
|
||||
|
||||
#if deploying in VMs, some nodes might fail (quarantined state) and even CNO can go to offline ... go to cluadmin and fix
|
||||
#Get-ClusterNode -Cluster $ClusterName | Where-Object State -eq down | Start-ClusterNode -ClearQuarantine
|
||||
#endregion
|
||||
|
||||
#region create Network Intent for switchless 3 node cluster
|
||||
$ClusterName=$Clusters[3].Name
|
||||
$Servers=$Clusters[3].Nodes
|
||||
|
||||
#make sure NetATC,FS-SMBBW and other required features are installed on servers
|
||||
Invoke-Command -ComputerName $Servers -ScriptBlock {
|
||||
Install-WindowsFeature -Name NetworkATC,Data-Center-Bridging,RSAT-Clustering-PowerShell,RSAT-Hyper-V-Tools,FS-SMBBW
|
||||
}
|
||||
|
||||
Import-Module NetworkATC
|
||||
#add Management intent
|
||||
$AdapterNames="Ethernet","Ethernet 2"
|
||||
Add-NetIntent -ClusterName $ClusterName -Name compute_management -Management -Compute -AdapterName $AdapterNames -Verbose
|
||||
|
||||
#add storage intent (notice just one VLAN for Storage - as per https://techcommunity.microsoft.com/t5/networking-blog/network-atc-common-preview-questions/ba-p/2780086)
|
||||
$AdapterNames="Ethernet 3","Ethernet 4"
|
||||
Add-NetIntent -ClusterName $ClusterName -Name storage -Storage -AdapterName $AdapterNames -Verbose -StorageVlans 711
|
||||
|
||||
#in virtual environment it's needed to add override for RDMA config (you should skip this for physical servers)
|
||||
#virtual environment (skipping RDMA config)
|
||||
$AdapterOverride = New-NetIntentAdapterPropertyOverrides
|
||||
$AdapterOverride.NetworkDirect = 0
|
||||
Set-NetIntent -ClusterName $ClusterName -Name compute_management -AdapterPropertyOverrides $AdapterOverride
|
||||
Set-NetIntent -ClusterName $ClusterName -Name storage -AdapterPropertyOverrides $AdapterOverride
|
||||
|
||||
#Add default global intent
|
||||
#since when configuring from Management machine there is a test [FabricManager.FeatureStaging]::Feature_NetworkATC_IsEnabled() to make global intents available, it will not be configured, so it has to be configured manually with invoke command
|
||||
Invoke-Command -ComputerName $servers[0] -ScriptBlock {
|
||||
Import-Module NetworkATC
|
||||
$overrides=New-NetIntentGlobalClusterOverrides
|
||||
#add empty intent
|
||||
Add-NetIntent -GlobalClusterOverrides $overrides
|
||||
}
|
||||
|
||||
#check
|
||||
Start-Sleep 20 #let intent propagate a bit
|
||||
Write-Output "applying intent"
|
||||
do {
|
||||
$status=Invoke-Command -ComputerName $ClusterName -ScriptBlock {Get-NetIntentStatus}
|
||||
Write-Host "." -NoNewline
|
||||
Start-Sleep 5
|
||||
} while ($status.ConfigurationStatus -contains "Provisioning" -or $status.ConfigurationStatus -contains "Retrying")
|
||||
|
||||
#remove if necessary
|
||||
<#
|
||||
Invoke-Command -ComputerName $servers[0] -ScriptBlock {
|
||||
$intents = Get-NetIntent
|
||||
foreach ($intent in $intents){
|
||||
Remove-NetIntent -Name $intent.IntentName
|
||||
}
|
||||
}
|
||||
#>
|
||||
|
||||
#if deploying in VMs, some nodes might fail (quarantined state) and even CNO can go to offline ... go to cluadmin and fix
|
||||
#Get-ClusterNode -Cluster $ClusterName | Where-Object State -eq down | Start-ClusterNode -ClearQuarantine
|
||||
#endregion
|
||||
|
||||
#region (WORK IN PROGRESS!!!) create Network Intent for stretch cluster https://learn.microsoft.com/en-us/azure-stack/hci/deploy/create-cluster-powershell#step-54-set-up-stretch-clustering-with-network-atc
|
||||
#configure sites in Stretch cluster first
|
||||
New-ClusterFaultDomain -Name "SEA-Rack01" -FaultDomainType Rack -Location "Contoso HQ, Room 4010, Aisle A, Rack 01" -CimSession $StretchClusterName
|
||||
New-ClusterFaultDomain -Name "RED-Rack01" -FaultDomainType Rack -Location "Contoso HQ, Room 1040, Aisle A, Rack 01" -CimSession $StretchClusterName
|
||||
New-ClusterFaultDomain -Name "SEA" -FaultDomainType Site -Location "Contoso HQ, 123 Example St, Room 4010, Seattle" -CimSession $StretchClusterName
|
||||
New-ClusterFaultDomain -Name "RED" -FaultDomainType Site -Location "Contoso HQ, 321 Example St, Room 1040, Redmond" -CimSession $StretchClusterName
|
||||
|
||||
Set-ClusterFaultDomain -Name "Site1Node1" -Parent "SEA-Rack01" -CimSession $StretchClusterName
|
||||
Set-ClusterFaultDomain -Name "Site1Node2" -Parent "SEA-Rack01" -CimSession $StretchClusterName
|
||||
Set-ClusterFaultDomain -Name "Site2Node1" -Parent "RED-Rack01" -CimSession $StretchClusterName
|
||||
Set-ClusterFaultDomain -Name "Site2Node2" -Parent "RED-Rack01" -CimSession $StretchClusterName
|
||||
|
||||
Set-ClusterFaultDomain -Name "SEA-Rack01" -Parent "SEA" -CimSession $StretchClusterName
|
||||
Set-ClusterFaultDomain -Name "RED-Rack01" -Parent "RED" -CimSession $StretchClusterName
|
||||
|
||||
#validate
|
||||
Get-ClusterFaultDomainXML -CimSession $StretchClusterName
|
||||
|
||||
$Servers=(Get-ClusterNode -Cluster $StretchClusterName).Name
|
||||
$ClusterName=$StretchClusterName
|
||||
|
||||
#make sure NetATC,FS-SMBBW and other required features are installed on servers
|
||||
Invoke-Command -ComputerName $Servers -ScriptBlock {
|
||||
Install-WindowsFeature -Name NetworkATC,Data-Center-Bridging,RSAT-Clustering-PowerShell,RSAT-Hyper-V-Tools,FS-SMBBW
|
||||
}
|
||||
|
||||
Import-Module NetworkATC
|
||||
#add stretch intent
|
||||
$AdapterNames="Ethernet","Ethernet 2"
|
||||
#it needs to be invoked with CredSSP as it contains check for netatc enabled - obviously not available in management machine that is WS2022
|
||||
|
||||
#Enable CredSSP
|
||||
# Temporarily enable CredSSP delegation to avoid double-hop issue
|
||||
foreach ($Server in $servers){
|
||||
Enable-WSManCredSSP -Role "Client" -DelegateComputer $Server -Force
|
||||
}
|
||||
Invoke-Command -ComputerName $servers -ScriptBlock { Enable-WSManCredSSP Server -Force }
|
||||
$password = ConvertTo-SecureString $CredSSPPassword -AsPlainText -Force
|
||||
$Credentials = New-Object System.Management.Automation.PSCredential ($CredSSPUserName, $password)
|
||||
|
||||
Invoke-Command -ComputerName $servers -Credential $Credentials -Authentication Credssp -ScriptBlock {
|
||||
Add-NetIntent -Name compute_management_storage_stretch -Compute -Management -Storage -Stretch -AdapterName $using:AdapterNames -Verbose
|
||||
}
|
||||
|
||||
# Disable CredSSP
|
||||
Disable-WSManCredSSP -Role Client
|
||||
Invoke-Command -ComputerName $servers -ScriptBlock { Disable-WSManCredSSP Server }
|
||||
|
||||
#in virtual environment it's needed to add override for RDMA config (you should skip this for physical servers)
|
||||
#virtual environment (skipping RDMA config)
|
||||
$AdapterOverride = New-NetIntentAdapterPropertyOverrides
|
||||
$AdapterOverride.NetworkDirect = 0
|
||||
Set-NetIntent -ClusterName $ClusterName -Name compute_management_storage_stretch -AdapterPropertyOverrides $AdapterOverride
|
||||
|
||||
#Add default global intent
|
||||
#since when configuring from Management machine there is a test [FabricManager.FeatureStaging]::Feature_NetworkATC_IsEnabled() to make global intents available, it will not be configured, so it has to be configured manually with invoke command
|
||||
Invoke-Command -ComputerName $servers[0] -ScriptBlock {
|
||||
Import-Module NetworkATC
|
||||
$overrides=New-NetIntentGlobalClusterOverrides
|
||||
#add empty intent
|
||||
Add-NetIntent -GlobalClusterOverrides $overrides
|
||||
}
|
||||
|
||||
#check
|
||||
Start-Sleep 20 #let intent propagate a bit
|
||||
Write-Output "applying intent"
|
||||
do {
|
||||
$status=Invoke-Command -ComputerName $ClusterName -ScriptBlock {Get-NetIntentStatus}
|
||||
Write-Host "." -NoNewline
|
||||
Start-Sleep 5
|
||||
} while ($status.ConfigurationStatus -contains "Provisioning" -or $status.ConfigurationStatus -contains "Retrying")
|
||||
|
||||
#remove if necessary
|
||||
<#
|
||||
Invoke-Command -ComputerName $servers[0] -ScriptBlock {
|
||||
$intents = Get-NetIntent
|
||||
foreach ($intent in $intents){
|
||||
Remove-NetIntent -Name $intent.IntentName
|
||||
}
|
||||
}
|
||||
#>
|
||||
|
||||
#if deploying in VMs, some nodes might fail (quarantined state) and even CNO can go to offline ... go to cluadmin and fix
|
||||
#Get-ClusterNode -Cluster $ClusterName | Where-Object State -eq down | Start-ClusterNode -ClearQuarantine
|
||||
#endregion
|
||||
|
||||
#endregion
|
||||
|
||||
#region install network HUD (NetATC)
|
||||
$Servers=$Clusters.Nodes
|
||||
#make sure NetworkHUD features are installed and network HUD is started on servers
|
||||
Invoke-Command -ComputerName $Servers -ScriptBlock {
|
||||
Install-WindowsFeature -Name "NetworkHUD","Hyper-V","Hyper-V-PowerShell","Data-Center-Bridging", "RSAT-DataCenterBridging-LLDP-Tools","NetworkATC","Failover-Clustering"
|
||||
#make sure service is started and running (it is)
|
||||
#Set-Service -Name NetworkHUD -StartupType Automatic
|
||||
#Start-Service -Name NetworkHUD
|
||||
}
|
||||
#install Network HUD modules (Test-NetStack and az.stackhci.networkhud) on nodes
|
||||
$Modules="Test-NetStack","az.stackhci.networkhud"
|
||||
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
|
||||
foreach ($Module in $Modules){
|
||||
#download module to management node
|
||||
Save-Module -Name $Module -Path $env:Userprofile\downloads\
|
||||
#copy it to servers
|
||||
foreach ($Server in $Servers){
|
||||
Copy-Item -Path "$env:Userprofile\downloads\$module" -Destination "\\$Server\C$\Program Files\WindowsPowerShell\Modules\" -Recurse -Force
|
||||
}
|
||||
}
|
||||
#restart NetworkHUD service to activate
|
||||
Invoke-Command -ComputerName $Servers -ScriptBlock {
|
||||
Restart-Service NetworkHUD
|
||||
}
|
||||
#wait a bit
|
||||
Start-Sleep 10
|
||||
|
||||
#check event logs (no successfull events found as there is some error in PCIE.ps1)
|
||||
$events=Invoke-Command -ComputerName $Servers -ScriptBlock {
|
||||
Get-WinEvent -FilterHashtable @{"ProviderName"="Microsoft-Windows-Networking-NetworkHUD";Id=105}
|
||||
}
|
||||
$events | Format-Table -AutoSize
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче