initial commit
This commit is contained in:
Коммит
a271090fe5
|
@ -0,0 +1,2 @@
|
|||
DSC/.files/
|
||||
scripts/ignore/
|
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 41 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 40 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 62 KiB |
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 55 KiB |
|
@ -0,0 +1,894 @@
|
|||
configuration AzureStackHCIHost
|
||||
{
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory)]
|
||||
[String]$DomainName,
|
||||
|
||||
[Parameter(Mandatory)]
|
||||
[System.Management.Automation.PSCredential]$Admincreds,
|
||||
|
||||
[Int]$RetryCount=20,
|
||||
|
||||
[Int]$RetryIntervalSec=30,
|
||||
|
||||
[String]$targetDrive = "V:",
|
||||
|
||||
[String]$sourcePath = "$targetDrive\source",
|
||||
|
||||
[String]$targetVMPath = "$targetDrive\VMs",
|
||||
|
||||
[String]$baseVHDFolderPath = "$targetVMPath\base",
|
||||
|
||||
[String]$azsHCIISOLocalPath = "$sourcePath\AzSHCI.iso",
|
||||
|
||||
[String]$wacLocalPath = "$sourcePath\WACLatest.msi",
|
||||
|
||||
[String]$azsHCIIsoUri = "https://aka.ms/2CNBagfhSZ8BM7jyEV8I",
|
||||
|
||||
[String]$azsHciVhdPath = "$baseVHDFolderPath\AzSHCI.vhdx",
|
||||
|
||||
[String]$ws2019IsoUri = "https://software-download.microsoft.com/download/pr/17763.737.190906-2324.rs5_release_svc_refresh_SERVER_EVAL_x64FRE_en-us_1.iso",
|
||||
|
||||
[String]$ws2019IsoLocalPath = "$sourcePath\ws2019.iso",
|
||||
|
||||
[String]$ws2019VhdPath = "$baseVHDFolderPath\ws2019.vhdx",
|
||||
|
||||
[String]$wacUri = "https://aka.ms/wacdownload",
|
||||
|
||||
[Int]$azsHostCount = 2,
|
||||
|
||||
[Int]$azsHostDataDiskCount = 3,
|
||||
|
||||
[Int64]$dataDiskSize = 500GB,
|
||||
|
||||
[string]$natPrefix = "AzSHCI",
|
||||
|
||||
[string]$vSwitchNameMgmt = "Management",
|
||||
|
||||
[string]$vSwitchNameConverged = "Default Switch",
|
||||
|
||||
[string]$HCIvmPrefix = "hpv",
|
||||
|
||||
[string]$wacVMName = "wac",
|
||||
|
||||
[int]$azsHCIHostMemory,
|
||||
|
||||
[string]$branch = "master",
|
||||
|
||||
[string]$aksHciScenario
|
||||
)
|
||||
|
||||
Import-DscResource -ModuleName 'xActiveDirectory'
|
||||
Import-DscResource -ModuleName 'xStorage'
|
||||
Import-DscResource -ModuleName 'NetworkingDSC'
|
||||
Import-DscResource -ModuleName 'PSDesiredStateConfiguration'
|
||||
Import-DscResource -ModuleName 'ComputerManagementDsc'
|
||||
Import-DscResource -ModuleName 'xHyper-v'
|
||||
Import-DscResource -ModuleName 'cHyper-v'
|
||||
Import-DscResource -ModuleName 'xPSDesiredStateConfiguration'
|
||||
Import-DscResource -ModuleName 'xDHCpServer'
|
||||
Import-DscResource -ModuleName 'cChoco'
|
||||
Import-DscResource -ModuleName 'DSCR_Shortcut'
|
||||
|
||||
$repoName = "AzureStackHCIonAzure"
|
||||
$repoBaseUrl = "https://github.com/yagmurs/$repoName"
|
||||
$branchFiles = "$repoBaseUrl/archive/$branch.zip"
|
||||
|
||||
if ($aksHciScenario -eq 'onAzureVMDirectly') {
|
||||
$labScript = "Deploy-AksHciOnAzureVM.ps1"
|
||||
}
|
||||
else
|
||||
{
|
||||
$labScript = "Deploy-AksHciOnNestedAzureAzureStackHCI.ps1"
|
||||
}
|
||||
|
||||
[System.Management.Automation.PSCredential]$DomainCreds = New-Object System.Management.Automation.PSCredential ("${DomainName}\$($Admincreds.UserName)", $Admincreds.Password)
|
||||
|
||||
$ipConfig = (Get-NetAdapter -Physical | Get-NetIPConfiguration | Where-Object IPv4DefaultGateway)
|
||||
$netAdapters = Get-NetAdapter -Name ($ipConfig.InterfaceAlias) | Select-Object -First 1
|
||||
$InterfaceAlias=$($netAdapters.Name)
|
||||
|
||||
Node localhost
|
||||
{
|
||||
LocalConfigurationManager {
|
||||
RebootNodeIfNeeded = $true
|
||||
ActionAfterReboot = 'ContinueConfiguration'
|
||||
ConfigurationMode = 'ApplyOnly'
|
||||
}
|
||||
|
||||
xWaitforDisk Disk1
|
||||
{
|
||||
DiskID = 1
|
||||
RetryIntervalSec =$RetryIntervalSec
|
||||
RetryCount = $RetryCount
|
||||
}
|
||||
|
||||
xDisk ADDataDisk
|
||||
{
|
||||
DiskID = 1
|
||||
DriveLetter = "F"
|
||||
DependsOn = "[xWaitForDisk]Disk1"
|
||||
}
|
||||
|
||||
xWaitforDisk Disk2
|
||||
{
|
||||
DiskID = 2
|
||||
RetryIntervalSec =$RetryIntervalSec
|
||||
RetryCount = $RetryCount
|
||||
}
|
||||
|
||||
xDisk hpvDataDisk
|
||||
{
|
||||
DiskID = 2
|
||||
DriveLetter = $targetDrive
|
||||
DependsOn = "[xWaitForDisk]Disk2"
|
||||
}
|
||||
|
||||
File "source"
|
||||
{
|
||||
DestinationPath = $sourcePath
|
||||
Type = 'Directory'
|
||||
Force = $true
|
||||
DependsOn = "[xDisk]hpvDataDisk"
|
||||
}
|
||||
|
||||
File "folder-vms"
|
||||
{
|
||||
Type = 'Directory'
|
||||
DestinationPath = $targetVMPath
|
||||
DependsOn = "[xDisk]hpvDataDisk"
|
||||
}
|
||||
|
||||
File "VM-base"
|
||||
{
|
||||
Type = 'Directory'
|
||||
DestinationPath = $baseVHDFolderPath
|
||||
DependsOn = "[File]folder-vms"
|
||||
}
|
||||
|
||||
Registry "Disable Internet Explorer ESC for Admin"
|
||||
{
|
||||
Key = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A7-37EF-4b3f-8CFC-4F3A74704073}"
|
||||
ValueName = "IsInstalled"
|
||||
ValueData = "0"
|
||||
ValueType = "Dword"
|
||||
}
|
||||
|
||||
Registry "Disable Internet Explorer ESC for User"
|
||||
{
|
||||
Key = "HKLM:\SOFTWARE\Microsoft\Active Setup\Installed Components\{A509B1A8-37EF-4b3f-8CFC-4F3A74704073}"
|
||||
ValueName = "IsInstalled"
|
||||
ValueData = "0"
|
||||
ValueType = "Dword"
|
||||
}
|
||||
|
||||
Registry "Add Wac to Intranet zone for SSO"
|
||||
{
|
||||
Key = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Internet Settings\ZoneMap\EscDomains\wac'
|
||||
ValueName = "https"
|
||||
ValueData = 1
|
||||
ValueType = 'Dword'
|
||||
}
|
||||
|
||||
ScheduledTask "Disable Server Manager at Startup"
|
||||
{
|
||||
TaskName = 'ServerManager'
|
||||
Enable = $false
|
||||
TaskPath = '\Microsoft\Windows\Server Manager'
|
||||
}
|
||||
|
||||
script "Download branch files for $branch"
|
||||
{
|
||||
GetScript = {
|
||||
$result = Test-Path -Path "$using:sourcePath\$using:branch.zip"
|
||||
return @{ 'Result' = $result }
|
||||
}
|
||||
|
||||
SetScript = {
|
||||
Invoke-WebRequest -Uri $using:branchFiles -OutFile "$using:sourcePath\$using:branch.zip"
|
||||
#Start-BitsTransfer -Source $using:branchFiles -Destination "$using:sourcePath\$using:branch.zip"
|
||||
}
|
||||
|
||||
TestScript = {
|
||||
# Create and invoke a scriptblock using the $GetScript automatic variable, which contains a string representation of the GetScript.
|
||||
$state = [scriptblock]::Create($GetScript).Invoke()
|
||||
return $state.Result
|
||||
}
|
||||
DependsOn = "[File]source"
|
||||
}
|
||||
|
||||
archive "Extract branch files"
|
||||
{
|
||||
Ensure = 'Present'
|
||||
Path = "$sourcePath\$branch.zip"
|
||||
Destination = "$sourcePath\branchData"
|
||||
Validate = $true
|
||||
Checksum = 'SHA-1'
|
||||
DependsOn = "[script]Download branch files for $branch"
|
||||
}
|
||||
|
||||
script "Download AzureStack HCI bits"
|
||||
{
|
||||
GetScript = {
|
||||
$result = Test-Path -Path $using:azsHCIISOLocalPath
|
||||
return @{ 'Result' = $result }
|
||||
}
|
||||
|
||||
SetScript = {
|
||||
Start-BitsTransfer -Source $using:azsHCIIsoUri -Destination $using:azsHCIISOLocalPath
|
||||
}
|
||||
|
||||
TestScript = {
|
||||
# Create and invoke a scriptblock using the $GetScript automatic variable, which contains a string representation of the GetScript.
|
||||
$state = [scriptblock]::Create($GetScript).Invoke()
|
||||
return $state.Result
|
||||
}
|
||||
DependsOn = "[File]source"
|
||||
}
|
||||
|
||||
WindowsFeature DNS
|
||||
{
|
||||
Ensure = "Present"
|
||||
Name = "DNS"
|
||||
}
|
||||
|
||||
WindowsFeature "Enable Deduplication"
|
||||
{
|
||||
Ensure = "Present"
|
||||
Name = "FS-Data-Deduplication"
|
||||
}
|
||||
|
||||
Script EnableDNSDiags
|
||||
{
|
||||
SetScript = {
|
||||
Set-DnsServerDiagnostics -All $true
|
||||
Write-Verbose -Verbose "Enabling DNS client diagnostics"
|
||||
}
|
||||
GetScript = { @{} }
|
||||
TestScript = { $false }
|
||||
DependsOn = "[WindowsFeature]DNS"
|
||||
}
|
||||
|
||||
WindowsFeature DnsTools
|
||||
{
|
||||
Ensure = "Present"
|
||||
Name = "RSAT-DNS-Server"
|
||||
DependsOn = "[WindowsFeature]DNS"
|
||||
}
|
||||
|
||||
DnsServerAddress "DnsServerAddress for $InterfaceAlias"
|
||||
{
|
||||
Address = '127.0.0.1'
|
||||
InterfaceAlias = $InterfaceAlias
|
||||
AddressFamily = 'IPv4'
|
||||
DependsOn = "[WindowsFeature]DNS"
|
||||
}
|
||||
|
||||
WindowsFeature ADDSInstall
|
||||
{
|
||||
Ensure = "Present"
|
||||
Name = "AD-Domain-Services"
|
||||
DependsOn="[WindowsFeature]DNS"
|
||||
}
|
||||
|
||||
WindowsFeature ADDSTools
|
||||
{
|
||||
Ensure = "Present"
|
||||
Name = "RSAT-ADDS-Tools"
|
||||
DependsOn = "[WindowsFeature]ADDSInstall"
|
||||
}
|
||||
|
||||
WindowsFeature ADAdminCenter
|
||||
{
|
||||
Ensure = "Present"
|
||||
Name = "RSAT-AD-AdminCenter"
|
||||
DependsOn = "[WindowsFeature]ADDSInstall"
|
||||
}
|
||||
|
||||
xADDomain FirstDS
|
||||
{
|
||||
DomainName = $DomainName
|
||||
DomainAdministratorCredential = $DomainCreds
|
||||
SafemodeAdministratorPassword = $DomainCreds
|
||||
DatabasePath = "F:\NTDS"
|
||||
LogPath = "F:\NTDS"
|
||||
SysvolPath = "F:\SYSVOL"
|
||||
DependsOn = @("[xDisk]ADDataDisk", "[WindowsFeature]ADDSInstall")
|
||||
}
|
||||
|
||||
WindowsFeature "Install DHCPServer"
|
||||
{
|
||||
Name = 'DHCP'
|
||||
Ensure = 'Present'
|
||||
}
|
||||
|
||||
WindowsFeature DHCPTools
|
||||
{
|
||||
Ensure = "Present"
|
||||
Name = "RSAT-DHCP"
|
||||
DependsOn = "[WindowsFeature]Install DHCPServer"
|
||||
}
|
||||
|
||||
WindowsFeature "Hyper-V"
|
||||
{
|
||||
Name = "Hyper-V"
|
||||
Ensure = "Present"
|
||||
}
|
||||
|
||||
WindowsFeature "RSAT-Hyper-V-Tools"
|
||||
{
|
||||
Name = "RSAT-Hyper-V-Tools"
|
||||
Ensure = "Present"
|
||||
DependsOn = "[WindowsFeature]Hyper-V"
|
||||
}
|
||||
|
||||
WindowsFeature "RSAT-Clustering"
|
||||
{
|
||||
Name = "RSAT-Clustering"
|
||||
Ensure = "Present"
|
||||
}
|
||||
|
||||
xVMHost "hpvHost"
|
||||
{
|
||||
IsSingleInstance = 'yes'
|
||||
EnableEnhancedSessionMode = $true
|
||||
VirtualHardDiskPath = $targetVMPath
|
||||
VirtualMachinePath = $targetVMPath
|
||||
DependsOn = "[WindowsFeature]Hyper-V"
|
||||
}
|
||||
|
||||
xVMSwitch "$vSwitchNameMgmt"
|
||||
{
|
||||
Name = $vSwitchNameMgmt
|
||||
Type = "Internal"
|
||||
DependsOn = "[WindowsFeature]Hyper-V"
|
||||
}
|
||||
|
||||
xVMSwitch "$vSwitchNameConverged"
|
||||
{
|
||||
Name = $vSwitchNameConverged
|
||||
Type = "Internal"
|
||||
DependsOn = "[WindowsFeature]Hyper-V"
|
||||
}
|
||||
|
||||
IPAddress "New IP for vEthernet $vSwitchNameMgmt"
|
||||
{
|
||||
InterfaceAlias = "vEthernet `($vSwitchNameMgmt`)"
|
||||
AddressFamily = 'IPv4'
|
||||
IPAddress = '192.168.0.1/24'
|
||||
DependsOn = "[xVMSwitch]$vSwitchNameMgmt"
|
||||
}
|
||||
|
||||
NetIPInterface "Enable IP forwarding on vEthernet $vSwitchNameMgmt"
|
||||
{
|
||||
AddressFamily = 'IPv4'
|
||||
InterfaceAlias = "vEthernet `($vSwitchNameMgmt`)"
|
||||
Forwarding = 'Enabled'
|
||||
DependsOn = "[IPAddress]New IP for vEthernet $vSwitchNameMgmt"
|
||||
}
|
||||
|
||||
NetAdapterRdma "Enable RDMA on vEthernet $vSwitchNameMgmt"
|
||||
{
|
||||
Name = "vEthernet `($vSwitchNameMgmt`)"
|
||||
Enabled = $true
|
||||
DependsOn = "[NetIPInterface]Enable IP forwarding on vEthernet $vSwitchNameMgmt"
|
||||
}
|
||||
|
||||
DnsServerAddress "DnsServerAddress for vEthernet $vSwitchNameMgmt"
|
||||
{
|
||||
Address = '127.0.0.1'
|
||||
InterfaceAlias = "vEthernet `($vSwitchNameMgmt`)"
|
||||
AddressFamily = 'IPv4'
|
||||
DependsOn = "[IPAddress]New IP for vEthernet $vSwitchNameMgmt"
|
||||
}
|
||||
|
||||
IPAddress "New IP for vEthernet $vSwitchNameConverged"
|
||||
{
|
||||
InterfaceAlias = "vEthernet `($vSwitchNameConverged`)"
|
||||
AddressFamily = 'IPv4'
|
||||
IPAddress = '192.168.100.1/24'
|
||||
DependsOn = "[xVMSwitch]$vSwitchNameConverged"
|
||||
}
|
||||
|
||||
NetIPInterface "Enable IP forwarding on vEthernet $vSwitchNameConverged"
|
||||
{
|
||||
AddressFamily = 'IPv4'
|
||||
InterfaceAlias = "vEthernet `($vSwitchNameConverged`)"
|
||||
Forwarding = 'Enabled'
|
||||
DependsOn = "[IPAddress]New IP for vEthernet $vSwitchNameConverged"
|
||||
}
|
||||
|
||||
NetAdapterRdma "Enable RDMA on vEthernet $vSwitchNameConverged"
|
||||
{
|
||||
Name = "vEthernet `($vSwitchNameConverged`)"
|
||||
Enabled = $true
|
||||
DependsOn = "[NetIPInterface]Enable IP forwarding on vEthernet $vSwitchNameConverged"
|
||||
}
|
||||
|
||||
DnsServerAddress "DnsServerAddress for vEthernet $vSwitchNameConverged"
|
||||
{
|
||||
Address = '127.0.0.1'
|
||||
InterfaceAlias = "vEthernet `($vSwitchNameConverged`)"
|
||||
AddressFamily = 'IPv4'
|
||||
DependsOn = "[IPAddress]New IP for vEthernet $vSwitchNameConverged"
|
||||
}
|
||||
|
||||
xDhcpServerAuthorization "Authorize DHCP"
|
||||
{
|
||||
Ensure = 'Present'
|
||||
DependsOn = @('[WindowsFeature]Install DHCPServer')
|
||||
DnsName = [System.Net.Dns]::GetHostByName($env:computerName).hostname
|
||||
IPAddress = '192.168.100.1'
|
||||
}
|
||||
|
||||
xDhcpServerScope "Scope 192.168.0.0"
|
||||
{
|
||||
Ensure = 'Present'
|
||||
IPStartRange = '192.168.0.150'
|
||||
IPEndRange = '192.168.0.240'
|
||||
ScopeId = '192.168.0.0'
|
||||
Name = 'Management Address Range for VMs on AzSHCI Cluster'
|
||||
SubnetMask = '255.255.255.0'
|
||||
LeaseDuration = '02.00:00:00'
|
||||
State = 'Active'
|
||||
AddressFamily = 'IPv4'
|
||||
DependsOn = @("[WindowsFeature]Install DHCPServer", "[IPAddress]New IP for vEthernet $vSwitchNameMgmt")
|
||||
}
|
||||
|
||||
xDhcpServerScope "Scope 192.168.100.0"
|
||||
{
|
||||
Ensure = 'Present'
|
||||
IPStartRange = '192.168.100.21'
|
||||
IPEndRange = '192.168.100.254'
|
||||
ScopeId = '192.168.100.0'
|
||||
Name = 'Client Address Range for Nested VMs on AzSHCI Cluster'
|
||||
SubnetMask = '255.255.255.0'
|
||||
LeaseDuration = '02.00:00:00'
|
||||
State = 'Active'
|
||||
AddressFamily = 'IPv4'
|
||||
DependsOn = @("[WindowsFeature]Install DHCPServer", "[IPAddress]New IP for vEthernet $vSwitchNameConverged")
|
||||
}
|
||||
|
||||
xDhcpServerOption "Option 192.168.0.0"
|
||||
{
|
||||
Ensure = 'Present'
|
||||
ScopeID = '192.168.0.0'
|
||||
DnsDomain = $DomainName
|
||||
DnsServerIPAddress = '192.168.0.1'
|
||||
AddressFamily = 'IPv4'
|
||||
Router = '192.168.0.1'
|
||||
DependsOn = @("[WindowsFeature]Install DHCPServer", "[IPAddress]New IP for vEthernet $vSwitchNameMgmt")
|
||||
}
|
||||
|
||||
xDhcpServerOption "Option 192.168.100.0"
|
||||
{
|
||||
Ensure = 'Present'
|
||||
ScopeID = '192.168.100.0'
|
||||
DnsDomain = $DomainName
|
||||
DnsServerIPAddress = '192.168.100.1'
|
||||
AddressFamily = 'IPv4'
|
||||
Router = '192.168.100.1'
|
||||
DependsOn = @("[WindowsFeature]Install DHCPServer", "[IPAddress]New IP for vEthernet $vSwitchNameConverged")
|
||||
}
|
||||
|
||||
script "New Nat rule for Management Network"
|
||||
{
|
||||
GetScript = {
|
||||
$nat = $($using:natPrefix + "-Management")
|
||||
$result = if (Get-NetNat -Name $nat -ErrorAction SilentlyContinue) {$true} else {$false}
|
||||
return @{ 'Result' = $result }
|
||||
}
|
||||
|
||||
SetScript = {
|
||||
$nat = $($using:natPrefix + "-Management")
|
||||
New-NetNat -Name $nat -InternalIPInterfaceAddressPrefix "192.168.0.0/24"
|
||||
}
|
||||
|
||||
TestScript = {
|
||||
# Create and invoke a scriptblock using the $GetScript automatic variable, which contains a string representation of the GetScript.
|
||||
$state = [scriptblock]::Create($GetScript).Invoke()
|
||||
return $state.Result
|
||||
}
|
||||
DependsOn = "[IPAddress]New IP for vEthernet $vSwitchNameMgmt"
|
||||
}
|
||||
|
||||
script "New Nat rule for Nested Network"
|
||||
{
|
||||
GetScript = {
|
||||
$nat = $($using:natPrefix + "-Nested")
|
||||
$result = if (Get-NetNat -Name $nat -ErrorAction SilentlyContinue) {$true} else {$false}
|
||||
return @{ 'Result' = $result }
|
||||
}
|
||||
|
||||
SetScript = {
|
||||
$nat = $($using:natPrefix + "-Nested")
|
||||
New-NetNat -Name $nat -InternalIPInterfaceAddressPrefix "192.168.100.0/24"
|
||||
}
|
||||
|
||||
TestScript = {
|
||||
# Create and invoke a scriptblock using the $GetScript automatic variable, which contains a string representation of the GetScript.
|
||||
$state = [scriptblock]::Create($GetScript).Invoke()
|
||||
return $state.Result
|
||||
}
|
||||
DependsOn = "[IPAddress]New IP for vEthernet $vSwitchNameConverged"
|
||||
}
|
||||
|
||||
script "prepareVHDX"
|
||||
{
|
||||
GetScript = {
|
||||
$result = Test-Path -Path $using:azsHciVhdPath
|
||||
return @{ 'Result' = $result }
|
||||
}
|
||||
|
||||
SetScript = {
|
||||
#Create Azure Stack HCI Host Image
|
||||
Convert-Wim2Vhd -DiskLayout UEFI -SourcePath $using:azsHCIISOLocalPath -Path $using:azsHciVhdPath -Size 100GB -Dynamic -Index 1 -ErrorAction SilentlyContinue
|
||||
#Enable Hyper-v role on the Azure Stack HCI Host Image
|
||||
Install-WindowsFeature -Vhd $using:azsHciVhdPath -Name Hyper-V
|
||||
}
|
||||
|
||||
TestScript = {
|
||||
# Create and invoke a scriptblock using the $GetScript automatic variable, which contains a string representation of the GetScript.
|
||||
$state = [scriptblock]::Create($GetScript).Invoke()
|
||||
return $state.Result
|
||||
}
|
||||
DependsOn = "[file]VM-Base", "[script]Download AzureStack HCI bits"
|
||||
}
|
||||
|
||||
if ($aksHciScenario -eq 'onNestedAzureStackHciClusteronAzureVM')
|
||||
{
|
||||
for ($i = 1; $i -lt $azsHostCount + 1; $i++)
|
||||
{
|
||||
$suffix = '{0:D2}' -f $i
|
||||
$vmname = $($HCIvmPrefix + $suffix)
|
||||
$memory = $azsHCIHostMemory * 1gb
|
||||
|
||||
file "VM-Folder-$vmname"
|
||||
{
|
||||
Ensure = 'Present'
|
||||
DestinationPath = "$targetVMPath\$vmname"
|
||||
Type = 'Directory'
|
||||
DependsOn = "[File]folder-vms"
|
||||
}
|
||||
|
||||
xVhd "NewOSDisk-$vmname"
|
||||
{
|
||||
Ensure = 'Present'
|
||||
Name = "$vmname-OSDisk.vhdx"
|
||||
Path = "$targetVMPath\$vmname"
|
||||
Generation = 'vhdx'
|
||||
ParentPath = $azsHciVhdPath
|
||||
Type = 'Differencing'
|
||||
DependsOn = "[xVMSwitch]$vSwitchNameMgmt", "[script]prepareVHDX", "[file]VM-Folder-$vmname"
|
||||
}
|
||||
|
||||
xVMHyperV "VM-$vmname"
|
||||
{
|
||||
Ensure = 'Present'
|
||||
Name = $vmname
|
||||
VhdPath = "$targetVMPath\$vmname\$vmname-OSDisk.vhdx"
|
||||
Path = $targetVMPath
|
||||
Generation = 2
|
||||
StartupMemory = $memory
|
||||
ProcessorCount = 4
|
||||
DependsOn = "[xVhd]NewOSDisk-$vmname"
|
||||
}
|
||||
|
||||
xVMProcessor "Enable NestedVirtualization-$vmname"
|
||||
{
|
||||
VMName = $vmname
|
||||
ExposeVirtualizationExtensions = $true
|
||||
DependsOn = "[xVMHyperV]VM-$vmname"
|
||||
}
|
||||
|
||||
script "remove default Network Adapter on VM-$vmname"
|
||||
{
|
||||
GetScript = {
|
||||
$VMNetworkAdapter = Get-VMNetworkAdapter -VMName $using:vmname -Name 'Network Adapter' -ErrorAction SilentlyContinue
|
||||
$result = if ($VMNetworkAdapter) {$false} else {$true}
|
||||
return @{
|
||||
VMName = $VMNetworkAdapter.VMName
|
||||
Name = $VMNetworkAdapter.Name
|
||||
Result = $result
|
||||
}
|
||||
}
|
||||
|
||||
SetScript = {
|
||||
$state = [scriptblock]::Create($GetScript).Invoke()
|
||||
Remove-VMNetworkAdapter -VMName $state.VMName -Name $state.Name
|
||||
}
|
||||
|
||||
TestScript = {
|
||||
# Create and invoke a scriptblock using the $GetScript automatic variable, which contains a string representation of the GetScript.
|
||||
$state = [scriptblock]::Create($GetScript).Invoke()
|
||||
return $state.Result
|
||||
}
|
||||
DependsOn = "[xVMHyperV]VM-$vmname"
|
||||
}
|
||||
|
||||
for ($k = 1; $k -le 2; $k++)
|
||||
{
|
||||
$mgmtNicName = "$vmname-Management$k"
|
||||
xVMNetworkAdapter "New Network Adapter $mgmtNicName $vmname DHCP"
|
||||
{
|
||||
Id = $mgmtNicName
|
||||
Name = $mgmtNicName
|
||||
SwitchName = $vSwitchNameMgmt
|
||||
VMName = $vmname
|
||||
Ensure = 'Present'
|
||||
DependsOn = "[xVMHyperV]VM-$vmname"
|
||||
}
|
||||
|
||||
cVMNetworkAdapterSettings "Enable $vmname $mgmtNicName Mac address spoofing and Teaming"
|
||||
{
|
||||
Id = $mgmtNicName
|
||||
Name = $mgmtNicName
|
||||
SwitchName = $vSwitchNameMgmt
|
||||
VMName = $vmname
|
||||
AllowTeaming = 'on'
|
||||
MacAddressSpoofing = 'on'
|
||||
DependsOn = "[xVMNetworkAdapter]New Network Adapter $mgmtNicName $vmname DHCP"
|
||||
}
|
||||
}
|
||||
|
||||
for ($l = 1; $l -le 4; $l++)
|
||||
{
|
||||
$ipAddress = $('192.168.25' + $l + '.1' + $suffix)
|
||||
$nicName = "$vmname-Converged-Nic$l"
|
||||
|
||||
xVMNetworkAdapter "New Network Adapter Converged $vmname $nicName $ipAddress"
|
||||
{
|
||||
Id = $nicName
|
||||
Name = $nicName
|
||||
SwitchName = $vSwitchNameConverged
|
||||
VMName = $vmname
|
||||
NetworkSetting = xNetworkSettings {
|
||||
IpAddress = $ipAddress
|
||||
Subnet = "255.255.255.0"
|
||||
}
|
||||
Ensure = 'Present'
|
||||
DependsOn = "[xVMHyperV]VM-$vmname"
|
||||
}
|
||||
|
||||
cVMNetworkAdapterSettings "Enable $vmname $nicName Mac address spoofing and Teaming"
|
||||
{
|
||||
Id = $nicName
|
||||
Name = $nicName
|
||||
SwitchName = $vSwitchNameConverged
|
||||
VMName = $vmname
|
||||
AllowTeaming = 'on'
|
||||
MacAddressSpoofing = 'on'
|
||||
DependsOn = "[xVMNetworkAdapter]New Network Adapter Converged $vmname $nicName $ipAddress"
|
||||
}
|
||||
}
|
||||
|
||||
for ($j = 1; $j -lt $azsHostDataDiskCount + 1 ; $j++)
|
||||
{
|
||||
xvhd "$vmname-DataDisk$j"
|
||||
{
|
||||
Ensure = 'Present'
|
||||
Name = "$vmname-DataDisk$j.vhdx"
|
||||
Path = "$targetVMPath\$vmname"
|
||||
Generation = 'vhdx'
|
||||
Type = 'Dynamic'
|
||||
MaximumSizeBytes = $dataDiskSize
|
||||
DependsOn = "[xVMHyperV]VM-$vmname"
|
||||
}
|
||||
|
||||
xVMHardDiskDrive "$vmname-DataDisk$j"
|
||||
{
|
||||
VMName = $vmname
|
||||
ControllerType = 'SCSI'
|
||||
ControllerLocation = $j
|
||||
Path = "$targetVMPath\$vmname\$vmname-DataDisk$j.vhdx"
|
||||
Ensure = 'Present'
|
||||
DependsOn = "[xVMHyperV]VM-$vmname"
|
||||
}
|
||||
}
|
||||
|
||||
script "UnattendXML for $vmname"
|
||||
{
|
||||
GetScript = {
|
||||
$name = $using:VmName
|
||||
$result = Test-Path -Path "$using:targetVMPath\$name\Unattend.xml"
|
||||
return @{ 'Result' = $result }
|
||||
}
|
||||
|
||||
SetScript = {
|
||||
try
|
||||
{
|
||||
$name = $using:VmName
|
||||
$mount = Mount-VHD -Path "$using:targetVMPath\$name\$name-OSDisk.vhdx" -Passthru -ErrorAction Stop
|
||||
Start-Sleep -Seconds 2
|
||||
$driveLetter = $mount | Get-Disk | Get-Partition | Get-Volume | Where-Object DriveLetter | Select-Object -ExpandProperty DriveLetter
|
||||
|
||||
New-Item -Path $("$driveLetter" + ":" + "\Temp") -ItemType Directory -Force -ErrorAction Stop
|
||||
|
||||
Copy-Item -Path "$using:sourcePath\branchData\$using:repoName-$using:branch\helpers\Install-AzsRolesandFeatures.ps1" -Destination $("$driveLetter" + ":" + "\Temp") -Force -ErrorAction Stop
|
||||
|
||||
New-BasicUnattendXML -ComputerName $name -LocalAdministratorPassword $($using:Admincreds).Password -Domain $using:DomainName -Username $using:Admincreds.Username `
|
||||
-Password $($using:Admincreds).Password -JoinDomain $using:DomainName -AutoLogonCount 1 -OutputPath "$using:targetVMPath\$name" -Force `
|
||||
-PowerShellScriptFullPath 'c:\temp\Install-AzsRolesandFeatures.ps1' -ErrorAction Stop
|
||||
|
||||
Copy-Item -Path "$using:targetVMPath\$name\Unattend.xml" -Destination $("$driveLetter" + ":" + "\Windows\system32\SysPrep") -Force -ErrorAction Stop
|
||||
|
||||
Start-Sleep -Seconds 2
|
||||
}
|
||||
finally
|
||||
{
|
||||
DisMount-VHD -Path "$using:targetVMPath\$name\$name-OSDisk.vhdx"
|
||||
}
|
||||
|
||||
Start-VM -Name $name
|
||||
}
|
||||
|
||||
TestScript = {
|
||||
# Create and invoke a scriptblock using the $GetScript automatic variable, which contains a string representation of the GetScript.
|
||||
$state = [scriptblock]::Create($GetScript).Invoke()
|
||||
return $state.Result
|
||||
}
|
||||
DependsOn = "[xVhd]NewOSDisk-$vmname", "[archive]Extract branch files"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
file "VM-Folder-$wacVMName"
|
||||
{
|
||||
Ensure = 'Present'
|
||||
DestinationPath = "$targetVMPath\$wacVMName"
|
||||
Type = 'Directory'
|
||||
DependsOn = "[File]folder-vms"
|
||||
}
|
||||
|
||||
xVhd "NewOSDisk-$wacVMName"
|
||||
{
|
||||
Ensure = 'Present'
|
||||
Name = "$wacVMName-OSDisk.vhdx"
|
||||
Path = "$targetVMPath\$wacVMName"
|
||||
Generation = 'vhdx'
|
||||
ParentPath = $azsHciVhdPath
|
||||
Type = 'Differencing'
|
||||
DependsOn = "[xVMSwitch]$vSwitchNameMgmt", "[script]prepareVHDX", "[file]VM-Folder-$wacVMName"
|
||||
}
|
||||
|
||||
xVMHyperV "VM-$wacVMName"
|
||||
{
|
||||
Ensure = 'Present'
|
||||
Name = $wacVMName
|
||||
VhdPath = "$targetVMPath\$wacVMName\$wacVMName-OSDisk.vhdx"
|
||||
Path = $targetVMPath
|
||||
Generation = 2
|
||||
StartupMemory = 2GB
|
||||
MinimumMemory = 2GB
|
||||
MaximumMemory = 8GB
|
||||
ProcessorCount = 2
|
||||
DependsOn = "[xVhd]NewOSDisk-$wacVMName"
|
||||
}
|
||||
|
||||
xVMNetworkAdapter "remove default Network Adapter on VM-$wacVMName"
|
||||
{
|
||||
Ensure = 'Absent'
|
||||
Id = "Network Adapter"
|
||||
Name = "Network Adapter"
|
||||
SwitchName = $vSwitchNameMgmt
|
||||
VMName = $wacVMName
|
||||
DependsOn = "[xVMHyperV]VM-$wacVMName"
|
||||
}
|
||||
|
||||
xVMNetworkAdapter "New Network Adapter Management for VM-$wacVMName"
|
||||
{
|
||||
Id = "$wacVMName-Management"
|
||||
Name = "$wacVMName-Management"
|
||||
SwitchName = $vSwitchNameMgmt
|
||||
VMName = $wacVMName
|
||||
NetworkSetting = xNetworkSettings {
|
||||
IpAddress = "192.168.0.100"
|
||||
Subnet = "255.255.255.0"
|
||||
DefaultGateway = "192.168.0.1"
|
||||
DnsServer = "192.168.0.1"
|
||||
}
|
||||
Ensure = 'Present'
|
||||
DependsOn = "[xVMHyperV]VM-$wacVMName"
|
||||
}
|
||||
|
||||
Script "UnattendXML for $wacVMName"
|
||||
{
|
||||
GetScript = {
|
||||
$name = $using:wacVMName
|
||||
$result = Test-Path -Path "$using:targetVMPath\$name\Unattend.xml"
|
||||
return @{ 'Result' = $result }
|
||||
}
|
||||
|
||||
SetScript = {
|
||||
try
|
||||
{
|
||||
$name = $using:wacVMName
|
||||
$mount = Mount-VHD "$using:targetVMPath\$name\$name-OSDisk.vhdx" -Passthru -ErrorAction Stop
|
||||
Start-Sleep -Seconds 2
|
||||
$driveLetter = $mount | Get-Disk | Get-Partition | Get-Volume | Where-Object DriveLetter | Select-Object -ExpandProperty DriveLetter
|
||||
|
||||
New-Item -Path $("$driveLetter" + ":" + "\Temp") -ItemType Directory -Force -ErrorAction Stop
|
||||
Copy-Item -Path "$using:sourcePath\branchData\$using:repoName-$using:branch\helpers\Install-WacUsingChoco.ps1" -Destination $("$driveLetter" + ":" + "\Temp") -Force -ErrorAction Stop
|
||||
|
||||
New-BasicUnattendXML -ComputerName $name -LocalAdministratorPassword $($using:Admincreds).Password -Domain $using:DomainName -Username $using:Admincreds.Username `
|
||||
-Password $($using:Admincreds).Password -JoinDomain $using:DomainName -AutoLogonCount 1 -OutputPath "$using:targetVMPath\$name" -Force `
|
||||
-IpCidr "192.168.0.100/24" -DnsServer '192.168.0.1' -NicNameForIPandDNSAssignments 'Ethernet' -PowerShellScriptFullPath 'c:\temp\Install-WacUsingChoco.ps1' -ErrorAction Stop
|
||||
|
||||
Copy-Item -Path "$using:targetVMPath\$name\Unattend.xml" -Destination $("$driveLetter" + ":" + "\Windows\system32\SysPrep") -Force -ErrorAction Stop
|
||||
|
||||
Copy-Item -Path "C:\Program Files\WindowsPowerShell\Modules\cChoco" -Destination $("$driveLetter" + ":" + "\Program Files\WindowsPowerShell\Modules") -Recurse -Force -ErrorAction Stop
|
||||
Copy-Item -Path "C:\Program Files\WindowsPowerShell\Modules\ComputerManagementDsc" -Destination $("$driveLetter" + ":" + "\Program Files\WindowsPowerShell\Modules") -Recurse -Force -ErrorAction Stop
|
||||
|
||||
Start-Sleep -Seconds 2
|
||||
|
||||
}
|
||||
finally
|
||||
{
|
||||
DisMount-VHD "$using:targetVMPath\$name\$name-OSDisk.vhdx"
|
||||
}
|
||||
|
||||
Start-VM -Name $name
|
||||
}
|
||||
|
||||
TestScript = {
|
||||
# Create and invoke a scriptblock using the $GetScript automatic variable, which contains a string representation of the GetScript.
|
||||
$state = [scriptblock]::Create($GetScript).Invoke()
|
||||
return $state.Result
|
||||
}
|
||||
DependsOn = "[xVhd]NewOSDisk-$wacVMName", "[archive]Extract branch files"
|
||||
}
|
||||
|
||||
cChocoInstaller InstallChoco
|
||||
{
|
||||
InstallDir = "c:\choco"
|
||||
}
|
||||
|
||||
cChocoFeature allowGlobalConfirmation
|
||||
{
|
||||
|
||||
FeatureName = "allowGlobalConfirmation"
|
||||
Ensure = 'Present'
|
||||
DependsOn = '[cChocoInstaller]installChoco'
|
||||
}
|
||||
|
||||
cChocoFeature useRememberedArgumentsForUpgrades
|
||||
{
|
||||
|
||||
FeatureName = "useRememberedArgumentsForUpgrades"
|
||||
Ensure = 'Present'
|
||||
DependsOn = '[cChocoInstaller]installChoco'
|
||||
}
|
||||
|
||||
cChocoPackageInstaller "Install Chromium Edge"
|
||||
{
|
||||
Name = 'microsoft-edge'
|
||||
Ensure = 'Present'
|
||||
AutoUpgrade = $true
|
||||
DependsOn = '[cChocoInstaller]installChoco'
|
||||
}
|
||||
|
||||
cShortcut "Wac Shortcut"
|
||||
{
|
||||
Path = 'C:\Users\Public\Desktop\Windows Admin Center.lnk'
|
||||
Target = 'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'
|
||||
Arguments = 'https://wac'
|
||||
Icon = 'shell32.dll,34'
|
||||
}
|
||||
|
||||
cShortcut "Document Shortcut"
|
||||
{
|
||||
Path = 'C:\Users\Public\Desktop\Poc Guide.lnk'
|
||||
Target = 'C:\Program Files (x86)\Microsoft\Edge\Application\msedge.exe'
|
||||
Arguments = "https://yagmurs.github.io/$repoName"
|
||||
Icon = 'shell32.dll,74'
|
||||
}
|
||||
|
||||
cShortcut "Lab Guide Shortcut"
|
||||
{
|
||||
Path = 'C:\Users\Public\Desktop\Lab Script.lnk'
|
||||
Target = 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell_ise.exe'
|
||||
Arguments = "$sourcePath\branchData\$repoName-$branch\scripts\$labScript"
|
||||
}
|
||||
}
|
||||
}
|
Двоичный файл не отображается.
|
@ -0,0 +1,618 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"adminUsername": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The name of the administrator account of nested VMs and domain"
|
||||
}
|
||||
},
|
||||
"adminPassword": {
|
||||
"type": "securestring",
|
||||
"metadata": {
|
||||
"description": "The password for the administrator account of nested VMs and domain"
|
||||
}
|
||||
},
|
||||
"domainName": {
|
||||
"type": "string",
|
||||
"defaultValue": "corp.contoso.com",
|
||||
"metadata": {
|
||||
"description": "The FQDN of the Active Directory Domain to be created"
|
||||
|
||||
}
|
||||
},
|
||||
"dnsPrefix": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The DNS prefix for the public IP address used by the Load Balancer"
|
||||
}
|
||||
},
|
||||
"vmSize": {
|
||||
"type": "string",
|
||||
"defaultValue": "Standard_E16s_v4",
|
||||
"allowedValues": [
|
||||
"Standard_E8s_v4",
|
||||
"Standard_E8ds_v4",
|
||||
"Standard_E16s_v4",
|
||||
"Standard_E16ds_v4",
|
||||
"Standard_E20s_v4",
|
||||
"Standard_E20ds_v4",
|
||||
"Standard_E32s_v4",
|
||||
"Standard_E32ds_v4",
|
||||
"Standard_E48s_v4",
|
||||
"Standard_E48ds_v4",
|
||||
"Standard_E64s_v4",
|
||||
"Standard_E64ds_v4",
|
||||
"Standard_E8s_v3",
|
||||
"Standard_E16s_v3",
|
||||
"Standard_E20s_v3",
|
||||
"Standard_E32s_v3",
|
||||
"Standard_E48s_v3",
|
||||
"Standard_E64s_v3",
|
||||
"Standard_D16s_v4",
|
||||
"Standard_D16ds_v4",
|
||||
"Standard_D32s_v4",
|
||||
"Standard_D32ds_v4",
|
||||
"Standard_D48s_v4",
|
||||
"Standard_D48ds_v4",
|
||||
"Standard_D64s_v4",
|
||||
"Standard_D64ds_v4",
|
||||
"Standard_D16s_v3",
|
||||
"Standard_D32s_v3",
|
||||
"Standard_D48s_v3",
|
||||
"Standard_D64s_v3"
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Size of the VM that supports Nested virtualization"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"type": "string",
|
||||
"defaultValue": "[resourceGroup().location]",
|
||||
"metadata": {
|
||||
"description": "Location for all resources."
|
||||
}
|
||||
},
|
||||
"virtualMachineName": {
|
||||
"type": "string",
|
||||
"defaultValue": "dcVM",
|
||||
"metadata": {
|
||||
"description": "Virtual machine name."
|
||||
}
|
||||
},
|
||||
"privateIPAddress": {
|
||||
"type": "string",
|
||||
"defaultValue": "10.0.0.4",
|
||||
"metadata": {
|
||||
"description": "Private IP address for Azure VM, will be used as DNS address for vNet."
|
||||
}
|
||||
},
|
||||
"virtualNetworkAddressRange": {
|
||||
"type": "string",
|
||||
"defaultValue": "10.0.0.0/16",
|
||||
"metadata": {
|
||||
"description": "Virtual network address range."
|
||||
}
|
||||
},
|
||||
"subnetRange": {
|
||||
"type": "string",
|
||||
"defaultValue": "10.0.0.0/24",
|
||||
"metadata": {
|
||||
"description": "Subnet IP range."
|
||||
}
|
||||
},
|
||||
"vmStoreDiskSize": {
|
||||
"type": "int",
|
||||
"defaultValue": 512,
|
||||
"metadata": {
|
||||
"description": "Azure VM additional disk size for hosting Azure Stack HCI VMs amount in GB"
|
||||
}
|
||||
},
|
||||
"aksHciScenario": {
|
||||
"type": "string",
|
||||
"defaultValue": "onAzureVMDirectly",
|
||||
"allowedValues": [
|
||||
"onAzureVMDirectly",
|
||||
"onNestedAzureStackHciClusteronAzureVM"
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Select the scenario if Aks Hci will be deployed on a nested cluster or on top of Azure VM"
|
||||
}
|
||||
},
|
||||
"azsHCIHostCount": {
|
||||
"type": "int",
|
||||
"defaultValue": 3,
|
||||
"metadata": {
|
||||
"description": "How many Azure Stack HCI nested hosts to be created within the Azure VM."
|
||||
}
|
||||
},
|
||||
"azsHCIHostMemory": {
|
||||
"type": "int",
|
||||
"defaultValue": 32,
|
||||
"metadata": {
|
||||
"description": "Azure Stack HCI memory amount in GB"
|
||||
}
|
||||
},
|
||||
"autoShutdown": {
|
||||
"type": "string",
|
||||
"defaultValue": "Enabled",
|
||||
"allowedValues": [
|
||||
"Enabled",
|
||||
"Disabled"
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Configure Auto shutdown state"
|
||||
}
|
||||
},
|
||||
"autoShutdownTime": {
|
||||
"type": "string",
|
||||
"defaultValue": "0200",
|
||||
"minLength": 4,
|
||||
"maxLength": 4,
|
||||
"metadata": {
|
||||
"description": "The time at which VMs will be automatically shutdown (24h HHmm format)."
|
||||
}
|
||||
},
|
||||
"autoShutdownTimeZone": {
|
||||
"type": "string",
|
||||
"defaultValue": "UTC",
|
||||
"allowedValues": [
|
||||
"Dateline Standard Time",
|
||||
"UTC-11",
|
||||
"Aleutian Standard Time",
|
||||
"Hawaiian Standard Time",
|
||||
"Marquesas Standard Time",
|
||||
"Alaskan Standard Time",
|
||||
"UTC-09",
|
||||
"Pacific Standard Time (Mexico)",
|
||||
"UTC-08",
|
||||
"Pacific Standard Time",
|
||||
"US Mountain Standard Time",
|
||||
"Mountain Standard Time (Mexico)",
|
||||
"Mountain Standard Time",
|
||||
"Central America Standard Time",
|
||||
"Central Standard Time",
|
||||
"Easter Island Standard Time",
|
||||
"Central Standard Time (Mexico)",
|
||||
"Canada Central Standard Time",
|
||||
"SA Pacific Standard Time",
|
||||
"Eastern Standard Time (Mexico)",
|
||||
"Eastern Standard Time",
|
||||
"Haiti Standard Time",
|
||||
"Cuba Standard Time",
|
||||
"US Eastern Standard Time",
|
||||
"Turks And Caicos Standard Time",
|
||||
"Paraguay Standard Time",
|
||||
"Atlantic Standard Time",
|
||||
"Venezuela Standard Time",
|
||||
"Central Brazilian Standard Time",
|
||||
"SA Western Standard Time",
|
||||
"Pacific SA Standard Time",
|
||||
"Newfoundland Standard Time",
|
||||
"Tocantins Standard Time",
|
||||
"E. South America Standard Time",
|
||||
"SA Eastern Standard Time",
|
||||
"Argentina Standard Time",
|
||||
"Greenland Standard Time",
|
||||
"Montevideo Standard Time",
|
||||
"Magallanes Standard Time",
|
||||
"Saint Pierre Standard Time",
|
||||
"Bahia Standard Time",
|
||||
"UTC-02",
|
||||
"Mid-Atlantic Standard Time",
|
||||
"Azores Standard Time",
|
||||
"Cape Verde Standard Time",
|
||||
"UTC",
|
||||
"GMT Standard Time",
|
||||
"Greenwich Standard Time",
|
||||
"Sao Tome Standard Time",
|
||||
"Morocco Standard Time",
|
||||
"W. Europe Standard Time",
|
||||
"Central Europe Standard Time",
|
||||
"Romance Standard Time",
|
||||
"Central European Standard Time",
|
||||
"W. Central Africa Standard Time",
|
||||
"Jordan Standard Time",
|
||||
"GTB Standard Time",
|
||||
"Middle East Standard Time",
|
||||
"Egypt Standard Time",
|
||||
"E. Europe Standard Time",
|
||||
"Syria Standard Time",
|
||||
"West Bank Standard Time",
|
||||
"South Africa Standard Time",
|
||||
"FLE Standard Time",
|
||||
"Israel Standard Time",
|
||||
"Kaliningrad Standard Time",
|
||||
"Sudan Standard Time",
|
||||
"Libya Standard Time",
|
||||
"Namibia Standard Time",
|
||||
"Arabic Standard Time",
|
||||
"Turkey Standard Time",
|
||||
"Arab Standard Time",
|
||||
"Belarus Standard Time",
|
||||
"Russian Standard Time",
|
||||
"E. Africa Standard Time",
|
||||
"Iran Standard Time",
|
||||
"Arabian Standard Time",
|
||||
"Astrakhan Standard Time",
|
||||
"Azerbaijan Standard Time",
|
||||
"Russia Time Zone 3",
|
||||
"Mauritius Standard Time",
|
||||
"Saratov Standard Time",
|
||||
"Georgian Standard Time",
|
||||
"Volgograd Standard Time",
|
||||
"Caucasus Standard Time",
|
||||
"Afghanistan Standard Time",
|
||||
"West Asia Standard Time",
|
||||
"Ekaterinburg Standard Time",
|
||||
"Pakistan Standard Time",
|
||||
"Qyzylorda Standard Time",
|
||||
"India Standard Time",
|
||||
"Sri Lanka Standard Time",
|
||||
"Nepal Standard Time",
|
||||
"Central Asia Standard Time",
|
||||
"Bangladesh Standard Time",
|
||||
"Omsk Standard Time",
|
||||
"Myanmar Standard Time",
|
||||
"SE Asia Standard Time",
|
||||
"Altai Standard Time",
|
||||
"W. Mongolia Standard Time",
|
||||
"North Asia Standard Time",
|
||||
"N. Central Asia Standard Time",
|
||||
"Tomsk Standard Time",
|
||||
"China Standard Time",
|
||||
"North Asia East Standard Time",
|
||||
"Singapore Standard Time",
|
||||
"W. Australia Standard Time",
|
||||
"Taipei Standard Time",
|
||||
"Ulaanbaatar Standard Time",
|
||||
"Aus Central W. Standard Time",
|
||||
"Transbaikal Standard Time",
|
||||
"Tokyo Standard Time",
|
||||
"North Korea Standard Time",
|
||||
"Korea Standard Time",
|
||||
"Yakutsk Standard Time",
|
||||
"Cen. Australia Standard Time",
|
||||
"AUS Central Standard Time",
|
||||
"E. Australia Standard Time",
|
||||
"AUS Eastern Standard Time",
|
||||
"West Pacific Standard Time",
|
||||
"Tasmania Standard Time",
|
||||
"Vladivostok Standard Time",
|
||||
"Lord Howe Standard Time",
|
||||
"Bougainville Standard Time",
|
||||
"Russia Time Zone 10",
|
||||
"Magadan Standard Time",
|
||||
"Norfolk Standard Time",
|
||||
"Sakhalin Standard Time",
|
||||
"Central Pacific Standard Time",
|
||||
"Russia Time Zone 11",
|
||||
"New Zealand Standard Time",
|
||||
"UTC+12",
|
||||
"Fiji Standard Time",
|
||||
"Kamchatka Standard Time",
|
||||
"Chatham Islands Standard Time",
|
||||
"UTC+13",
|
||||
"Tonga Standard Time",
|
||||
"Samoa Standard Time",
|
||||
"Line Islands Standard Time"
|
||||
],
|
||||
"minLength": 2,
|
||||
"metadata": {
|
||||
"description": "Time zone of the virtual machines. Type \"[TimeZoneInfo]::GetSystemTimeZones().Id\" in PowerShell to get the list."
|
||||
}
|
||||
},
|
||||
"enableHybridBenefitServerLicenses": {
|
||||
"type": "string",
|
||||
"allowedValues": [
|
||||
"Yes",
|
||||
"No"
|
||||
],
|
||||
"defaultValue": "No",
|
||||
"metadata": {
|
||||
"description": "Enable Azure Hybrid Benefit to use your on-premises Windows Server licenses and reduce cost. See https://docs.microsoft.com/en-us/azure/virtual-machines/windows/hybrid-use-benefit-licensing for more information."
|
||||
}
|
||||
},
|
||||
"branch": {
|
||||
"type": "string",
|
||||
"defaultValue": "master",
|
||||
"metadata": {
|
||||
"description": "for branch selection leave master if you are not the contributor and developing the ARM template"
|
||||
}
|
||||
}
|
||||
},
|
||||
"variables": {
|
||||
"dscUri": "[concat('https://github.com/Azure/AksHcionAzureVM/raw/', parameters('branch'), '/DSC/AzureStackHCIHost.zip')]",
|
||||
"_artifactsLocation": "[concat('https://raw.githubusercontent.com/', 'Azure/AksHcionAzureVM/', parameters('branch'), '/')]",
|
||||
"networkSecurityGroupName": "[concat(parameters('virtualMachineName'),'-nsg')]",
|
||||
"publicIpAddressName": "[concat(parameters('virtualMachineName'),'-pip')]",
|
||||
"virtualNetworkName": "[concat(parameters('virtualMachineName'),'-vnet')]",
|
||||
"networkInterfaceName": "[concat(parameters('virtualMachineName'),'-nic')]",
|
||||
"subnetName": "[concat(parameters('virtualMachineName'),'-subnet')]"
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Network/publicIPAddresses",
|
||||
"apiVersion": "2020-05-01",
|
||||
"name": "[variables('publicIPAddressName')]",
|
||||
"location": "[parameters('location')]",
|
||||
"properties": {
|
||||
"publicIPAllocationMethod": "Dynamic",
|
||||
"dnsSettings": {
|
||||
"domainNameLabel": "[parameters('dnsPrefix')]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Resources/deployments",
|
||||
"apiVersion": "2020-06-01",
|
||||
"name": "VNet",
|
||||
"properties": {
|
||||
"mode": "Incremental",
|
||||
"templateLink": {
|
||||
"uri": "[uri(variables('_artifactsLocation'), concat('nestedtemplates/vnet.json'))]",
|
||||
"contentVersion": "1.0.0.0"
|
||||
},
|
||||
"parameters": {
|
||||
"virtualNetworkName": {
|
||||
"value": "[variables('virtualNetworkName')]"
|
||||
},
|
||||
"virtualNetworkAddressRange": {
|
||||
"value": "[parameters('virtualNetworkAddressRange')]"
|
||||
},
|
||||
"subnetName": {
|
||||
"value": "[variables('subnetName')]"
|
||||
},
|
||||
"subnetRange": {
|
||||
"value": "[parameters('subnetRange')]"
|
||||
},
|
||||
"location": {
|
||||
"value": "[parameters('location')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/networkInterfaces",
|
||||
"apiVersion": "2020-05-01",
|
||||
"name": "[variables('networkInterfaceName')]",
|
||||
"location": "[parameters('location')]",
|
||||
"dependsOn": [
|
||||
"VNet",
|
||||
"[concat('Microsoft.Network/publicIpAddresses/', variables('publicIpAddressName'))]",
|
||||
"[concat('Microsoft.Network/networkSecurityGroups/', variables('networkSecurityGroupName'))]"
|
||||
],
|
||||
"properties": {
|
||||
"ipConfigurations": [
|
||||
{
|
||||
"name": "ipconfig1",
|
||||
"properties": {
|
||||
"privateIPAllocationMethod": "Static",
|
||||
"privateIPAddress": "[parameters('privateIPAddress')]",
|
||||
"subnet": {
|
||||
"id": "[resourceId('Microsoft.Network/virtualNetworks/subnets', variables('virtualNetworkName'), variables('subnetName'))]"
|
||||
},
|
||||
"publicIPAddress": {
|
||||
"id": "[resourceId(resourceGroup().name,'Microsoft.Network/publicIpAddresses', variables('publicIpAddressName'))]"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"networkSecurityGroup": {
|
||||
"id": "[resourceId(resourceGroup().name, 'Microsoft.Network/networkSecurityGroups', variables('networkSecurityGroupName'))]"
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Network/networkSecurityGroups",
|
||||
"name": "[variables('networkSecurityGroupName')]",
|
||||
"apiVersion": "2020-05-01",
|
||||
"location": "[parameters('location')]",
|
||||
"properties": {
|
||||
"securityRules": [
|
||||
{
|
||||
"name": "default-allow-rdp",
|
||||
"properties": {
|
||||
"priority": 1000,
|
||||
"sourceAddressPrefix": "*",
|
||||
"protocol": "Tcp",
|
||||
"destinationPortRange": "3389",
|
||||
"access": "Allow",
|
||||
"direction": "Inbound",
|
||||
"sourcePortRange": "*",
|
||||
"destinationAddressPrefix": "*"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Compute/virtualMachines",
|
||||
"apiVersion": "2020-06-01",
|
||||
"name": "[parameters('virtualMachineName')]",
|
||||
"location": "[parameters('location')]",
|
||||
"dependsOn": [
|
||||
"[variables('networkInterfaceName')]"
|
||||
],
|
||||
"properties": {
|
||||
"licenseType": "[if(equals(parameters('enableHybridBenefitServerLicenses'), 'Yes'), 'Windows_Server', json('null'))]",
|
||||
"hardwareProfile": {
|
||||
"vmSize": "[parameters('vmSize')]"
|
||||
},
|
||||
"osProfile": {
|
||||
"computerName": "[parameters('virtualMachineName')]",
|
||||
"adminUsername": "[parameters('adminUsername')]",
|
||||
"adminPassword": "[parameters('adminPassword')]"
|
||||
},
|
||||
"storageProfile": {
|
||||
"imageReference": {
|
||||
"publisher": "MicrosoftWindowsServer",
|
||||
"offer": "WindowsServer",
|
||||
"sku": "2019-Datacenter",
|
||||
"version": "latest"
|
||||
},
|
||||
"osDisk": {
|
||||
"name": "[concat(parameters('virtualMachineName'),'-OSDisk')]",
|
||||
"caching": "ReadOnly",
|
||||
"createOption": "FromImage",
|
||||
"managedDisk": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
}
|
||||
},
|
||||
"dataDisks": [
|
||||
{
|
||||
"name": "[concat(parameters('virtualMachineName'), '-DataDisk1')]",
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "Empty",
|
||||
"diskSizeGB": 20,
|
||||
"managedDisk": {
|
||||
"storageAccountType": "Standard_LRS"
|
||||
},
|
||||
"lun": 0
|
||||
},
|
||||
{
|
||||
"name": "[concat(parameters('virtualMachineName'), '-DataDisk2')]",
|
||||
"caching": "ReadWrite",
|
||||
"createOption": "Empty",
|
||||
"diskSizeGB": "[parameters('vmStoreDiskSize')]",
|
||||
"managedDisk": {
|
||||
"storageAccountType": "Premium_LRS"
|
||||
},
|
||||
"lun": 1
|
||||
}
|
||||
]
|
||||
},
|
||||
"networkProfile": {
|
||||
"networkInterfaces": [
|
||||
{
|
||||
"id": "[resourceId('Microsoft.Network/networkInterfaces', variables('networkInterfaceName'))]"
|
||||
}
|
||||
]
|
||||
},
|
||||
"diagnosticsProfile": {
|
||||
"bootDiagnostics": {
|
||||
"enabled": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"name": "AzureStackHCIHost",
|
||||
"type": "extensions",
|
||||
"apiVersion": "2019-07-01",
|
||||
"location": "[parameters('location')]",
|
||||
"dependsOn": [
|
||||
"[parameters('virtualMachineName')]"
|
||||
],
|
||||
"properties": {
|
||||
"publisher": "Microsoft.Powershell",
|
||||
"type": "DSC",
|
||||
"typeHandlerVersion": "2.19",
|
||||
"autoUpgradeMinorVersion": true,
|
||||
"settings": {
|
||||
"ModulesUrl": "[variables('dscUri')]",
|
||||
"ConfigurationFunction": "AzureStackHCIHost.ps1\\AzureStackHCIHost",
|
||||
"Properties": {
|
||||
"DomainName": "[parameters('domainName')]",
|
||||
"AdminCreds": {
|
||||
"UserName": "[parameters('adminUsername')]",
|
||||
"Password": "PrivateSettingsRef:AdminPassword"
|
||||
},
|
||||
"azsHostCount": "[parameters('azsHCIHostCount')]",
|
||||
"azsHCIHostMemory": "[parameters('azsHCIHostMemory')]",
|
||||
"branch": "[parameters('branch')]",
|
||||
"aksHciScenario": "[parameters('aksHciScenario')]"
|
||||
}
|
||||
},
|
||||
"protectedSettings": {
|
||||
"Items": {
|
||||
"AdminPassword": "[parameters('adminPassword')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"condition": "[equals(parameters('autoShutdown'), 'Enabled')]",
|
||||
"name": "autoshutdown",
|
||||
"type": "Microsoft.Resources/deployments",
|
||||
"apiVersion": "2020-06-01",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), 'AzureStackHCIHost')]"
|
||||
],
|
||||
"properties": {
|
||||
"mode": "Incremental",
|
||||
"templateLink": {
|
||||
"uri": "[uri(variables('_artifactsLocation'), 'nestedtemplates/autoshutdown.json')]",
|
||||
"contentVersion": "1.0.0.0"
|
||||
},
|
||||
"parameters": {
|
||||
"location": {
|
||||
"value": "[parameters('location')]"
|
||||
},
|
||||
"virtualMachineName": {
|
||||
"value": "[parameters('virtualMachineName')]"
|
||||
},
|
||||
"autoShutdown": {
|
||||
"value": "[parameters('autoShutdown')]"
|
||||
},
|
||||
"autoShutdownTime": {
|
||||
"value": "[parameters('autoShutdownTime')]"
|
||||
},
|
||||
"autoShutdownTimeZone": {
|
||||
"value": "[parameters('autoShutdownTimeZone')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "Microsoft.Resources/deployments",
|
||||
"apiVersion": "2020-06-01",
|
||||
"name": "UpdateVNetDNS",
|
||||
"dependsOn": [
|
||||
"[resourceId('Microsoft.Compute/virtualMachines/extensions', parameters('virtualMachineName'), 'AzureStackHCIHost')]"
|
||||
],
|
||||
"properties": {
|
||||
"mode": "Incremental",
|
||||
"templateLink": {
|
||||
"uri": "[uri(variables('_artifactsLocation'), concat('nestedtemplates/vnet-with-dns-server.json'))]",
|
||||
"contentVersion": "1.0.0.0"
|
||||
},
|
||||
"parameters": {
|
||||
"virtualNetworkName": {
|
||||
"value": "[variables('virtualNetworkName')]"
|
||||
},
|
||||
"virtualNetworkAddressRange": {
|
||||
"value": "[parameters('virtualNetworkAddressRange')]"
|
||||
},
|
||||
"subnetName": {
|
||||
"value": "[variables('subnetName')]"
|
||||
},
|
||||
"subnetRange": {
|
||||
"value": "[parameters('subnetRange')]"
|
||||
},
|
||||
"DNSServerAddress": {
|
||||
"value": [
|
||||
"[parameters('privateIPAddress')]"
|
||||
]
|
||||
},
|
||||
"location": {
|
||||
"value": "[parameters('location')]"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": {
|
||||
"dscUri": {
|
||||
"type": "string",
|
||||
"value": "[variables('dscUri')]"
|
||||
},
|
||||
"branch": {
|
||||
"type": "string",
|
||||
"value": "[parameters('branch')]"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2015-01-01/deploymentParameters.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"adminUsername": {
|
||||
"value": "adm01"
|
||||
},
|
||||
"domainName": {
|
||||
"value": "corp.msft.fun"
|
||||
},
|
||||
"dnsPrefix": {
|
||||
"value": "msftfundc"
|
||||
},
|
||||
"vmSize": {
|
||||
"value": "Standard_E8s_v4"
|
||||
},
|
||||
"location": {
|
||||
"value": "germanywestcentral"
|
||||
},
|
||||
"virtualMachineName": {
|
||||
"value": "dc01"
|
||||
},
|
||||
"azsHCIHostCount": {
|
||||
"value": 2
|
||||
},
|
||||
"virtualNetworkAddressRange": {
|
||||
"value": "172.31.0.0/16"
|
||||
},
|
||||
"privateIPAddress": {
|
||||
"value": "172.31.1.4"
|
||||
},
|
||||
"subnetRange": {
|
||||
"value": "172.31.1.0/24"
|
||||
},
|
||||
"branch": {
|
||||
"value": "master"
|
||||
},
|
||||
"azsHCIHostMemory": {
|
||||
"value": 22
|
||||
},
|
||||
"vmStoreDiskSize": {
|
||||
"value": 512
|
||||
},
|
||||
"enableHybridBenefitServerLicenses": {
|
||||
"value": "Yes"
|
||||
},
|
||||
"autoShutdown": {
|
||||
"value": "Enabled"
|
||||
},
|
||||
"autoShutdownTime": {
|
||||
"value": "0200"
|
||||
},
|
||||
"autoShutdownTimeZone": {
|
||||
"value": "UTC"
|
||||
},
|
||||
"aksHciScenario": {
|
||||
"value": "onAzureVMDirectly"
|
||||
}
|
||||
}
|
||||
}
|
Двоичный файл не отображается.
|
@ -0,0 +1,992 @@
|
|||
function Cleanup-VMs
|
||||
{
|
||||
[CmdletBinding(
|
||||
DefaultParameterSetName = 'default',
|
||||
SupportsShouldProcess,
|
||||
ConfirmImpact = 'High'
|
||||
)]
|
||||
Param
|
||||
(
|
||||
[Parameter(ParameterSetName = 'default')]
|
||||
[Parameter(Mandatory=$false)]
|
||||
[Switch]
|
||||
$AzureStackHciHostVMs,
|
||||
|
||||
[Parameter(ParameterSetName = 'default')]
|
||||
[Parameter(Mandatory=$false)]
|
||||
[Switch]
|
||||
$WindowsAdminCenterVM,
|
||||
|
||||
[Parameter(ParameterSetName = 'default')]
|
||||
[Parameter(Mandatory=$false)]
|
||||
[Switch]
|
||||
$DoNotRedeploy,
|
||||
|
||||
[Parameter(ParameterSetName = 'default')]
|
||||
[Parameter(Mandatory=$false)]
|
||||
[Switch]
|
||||
$RemoveAllSourceFiles
|
||||
)
|
||||
|
||||
Begin
|
||||
{
|
||||
#initializing variables
|
||||
$domainName = (Get-ADDomain).DnsRoot
|
||||
$dhcpScopeString = '192.168.0.0'
|
||||
$sleep = 300
|
||||
|
||||
}
|
||||
Process
|
||||
{
|
||||
if ($AzureStackHciHostVMs)
|
||||
{
|
||||
$AzureStackHCIClusterName = 'hci01'
|
||||
$AzureStackHCIHosts = Get-VM "hpv*" -ErrorAction SilentlyContinue
|
||||
$ouName = $AzureStackHCIClusterName
|
||||
$servers = $AzureStackHCIHosts.Name + $AzureStackHCIClusterName
|
||||
|
||||
if ($AzureStackHCIHosts)
|
||||
{
|
||||
if ($PSCmdlet.ShouldProcess($AzureStackHCIHosts,'Turn off and Remove'))
|
||||
{
|
||||
Write-Verbose "[Cleanup-VMs]: Removing Azure Stack HCI hosts, cluster and related DHCP, DNS records and computer accounts"
|
||||
#remove Azure Stack HCI hosts
|
||||
$AzureStackHCIHosts | Stop-VM -TurnOff -Passthru | Remove-VM -Force
|
||||
Remove-Item -Path $AzureStackHCIHosts.ConfigurationLocation -Recurse -Force
|
||||
|
||||
#remove Azure Stack HCI hosts DNS records, DHCP leases and Disable Computer Accounts
|
||||
Write-Verbose "[Cleanup-VMs]: Removing Dns Records for $($AzureStackHCIHosts.Name + "." + "$domainname")"
|
||||
$AzureStackHCIHosts.Name | ForEach-Object {Get-DnsServerResourceRecord -ZoneName $domainName -Name $_ -ErrorAction SilentlyContinue | Remove-DnsServerResourceRecord -ZoneName $domainName -Force}
|
||||
|
||||
Write-Verbose "[Cleanup-VMs]: Removing Dhcp lease for $($AzureStackHCIHosts.Name)"
|
||||
$AzureStackHCIHosts.Name | ForEach-Object {Get-DhcpServerv4Lease -ScopeId $dhcpScopeString -ErrorAction SilentlyContinue | Where-Object hostname -like $_* | Remove-DhcpServerv4Lease}
|
||||
|
||||
Write-Verbose "[Cleanup-VMs]: Removing Dns Records for $($AzureStackHCIClusterName + "." + "$domainname")"
|
||||
$AzureStackHCIClusterName | ForEach-Object {Get-DnsServerResourceRecord -ZoneName $domainName -Name $_ -ErrorAction SilentlyContinue | Remove-DnsServerResourceRecord -ZoneName $domainName -Force}
|
||||
|
||||
Write-Verbose "[Cleanup-VMs]: Removing Dhcp lease for $AzureStackHCIClusterName"
|
||||
$AzureStackHCIClusterName | ForEach-Object {Get-DhcpServerv4Lease -ScopeId $dhcpScopeString -ErrorAction SilentlyContinue | Where-Object hostname -like $_* | Remove-DhcpServerv4Lease}
|
||||
|
||||
Write-Verbose "[Cleanup-VMs]: Removing AD Computer for $servers"
|
||||
$servers | Get-ADComputer -ErrorAction SilentlyContinue | Remove-ADObject -Recursive -Confirm:$false
|
||||
|
||||
Write-Verbose "[Cleanup-VMs]: Removing the OU: $ouName"
|
||||
Get-ADOrganizationalUnit -Filter * | where-object name -eq $ouName | Set-ADOrganizationalUnit -ProtectedFromAccidentalDeletion $false -PassThru | Remove-ADOrganizationalUnit -Recursive -Confirm:$false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($WindowsAdminCenterVM)
|
||||
{
|
||||
$wac = Get-VM wac -ErrorAction SilentlyContinue
|
||||
if ($wac)
|
||||
{
|
||||
if ($PSCmdlet.ShouldProcess($wac,'Turn off and Remove'))
|
||||
{
|
||||
Write-Verbose "[Cleanup-VMs]: Removing Windows Center VM and related DHCP, DNS records and computer account"
|
||||
#remove Windows Admin Center host
|
||||
$wac | Stop-VM -TurnOff -Passthru | Remove-VM -Force
|
||||
Remove-Item -Path $wac.ConfigurationLocation -Recurse -Force
|
||||
|
||||
#remove Windows Admin Center host DNS record, DHCP lease
|
||||
Write-Verbose "[Cleanup-VMs]: Removing Dns Records for $($wac.Name + "." + "$domainname")"
|
||||
Get-DnsServerResourceRecord -ZoneName $domainName -Name $wac.Name -ErrorAction SilentlyContinue | Remove-DnsServerResourceRecord -ZoneName $domainName -Force
|
||||
Write-Verbose "[Cleanup-VMs]: Removing Dhcp lease for $($wac.Name)"
|
||||
Get-DhcpServerv4Lease -ScopeId $dhcpScopeString -ErrorAction SilentlyContinue | Where-Object hostname -like $wac.Name | Remove-DhcpServerv4Lease
|
||||
Write-Verbose "[Cleanup-VMs]: Removing AD Computer for $($wac.Name)"
|
||||
$wac.name | Get-ADComputer | Remove-ADObject -Recursive -Confirm:$false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($RemoveAllSourceFiles) {
|
||||
if ($PSCmdlet.ShouldProcess('PoC Source files','Remove'))
|
||||
{
|
||||
Remove-Item v:\ -Recurse -Force
|
||||
}
|
||||
}
|
||||
|
||||
if (-not ($DoNotRedeploy))
|
||||
{
|
||||
if ($PSCmdlet.ShouldProcess('Re-Apply DSC configuration to restore VMs','Apply'))
|
||||
{
|
||||
|
||||
Write-Verbose "[Cleanup-VMs]: Recalling DSC config to restore default state."
|
||||
Start-DscConfiguration -UseExisting -Wait -Force
|
||||
Write-Verbose "[Cleanup-VMs]: DSC config re-applied, check for any error!"
|
||||
if ($AzureStackHciHostVMs -or $WindowsAdminCenterVM)
|
||||
{
|
||||
Write-Verbose "[Cleanup-VMs]: Sleeping for $sleep seconds to make sure Azure Stack HCI hosts are reachable"
|
||||
Start-Sleep -Seconds $sleep
|
||||
Clear-DnsClientCache
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Verbose "[Prepare AD]: Creating computer accounts in AD if not exist and configuring delegations for Windows Admin Center"
|
||||
Prepare-AdforAzsHciDeployment
|
||||
|
||||
}
|
||||
End
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
function Prepare-AzsHciPackage
|
||||
{
|
||||
[CmdletBinding()]
|
||||
Param
|
||||
(
|
||||
)
|
||||
|
||||
Begin
|
||||
{
|
||||
#variables
|
||||
$targetDrive = "V:"
|
||||
$sourcePath = "$targetDrive\source"
|
||||
$aksSource = "$sourcePath\aksHciSource"
|
||||
}
|
||||
Process
|
||||
{
|
||||
#create source folder for AKS bits
|
||||
New-Item -Path $aksSource -ItemType Directory -Force
|
||||
|
||||
#Download AKS on Azure Stack HCI tools if no exist
|
||||
if (-not (Test-Path -Path "$aksSource\aks-hci-tools.zip" -ErrorAction SilentlyContinue))
|
||||
{
|
||||
Write-Verbose "[Prepare-AzsHciPackage]: Downloading AKS on Azure Stack HCI tools from https://aka.ms/aks-hci-download"
|
||||
Start-BitsTransfer -Source https://aka.ms/aks-hci-download -Destination "$aksSource\aks-hci-tools.zip" -Confirm:$false
|
||||
}
|
||||
|
||||
#unblock download file
|
||||
Unblock-File -Path "$aksSource\aks-hci-tools.zip"
|
||||
|
||||
#Unzip download file if not unzipped
|
||||
if (-not (Test-Path -Path "$aksSource\aks-hci-tools" -ErrorAction SilentlyContinue))
|
||||
{
|
||||
Write-Verbose "[Prepare-AzsHciPackage]: Unzip downloaded file: aks-hci-tools.zip"
|
||||
Expand-Archive -Path "$aksSource\aks-hci-tools.zip" -DestinationPath "$aksSource\aks-hci-tools" -Force
|
||||
}
|
||||
|
||||
#Unzip Powershell modules if not unzipped
|
||||
if (-not (Test-Path -Path "$aksSource\aks-hci-tools\Powershell\Modules" -ErrorAction SilentlyContinue))
|
||||
{
|
||||
Write-Verbose "[Prepare-AzsHciPackage]: Unzip Aks Hci PowerShell module"
|
||||
Expand-Archive -Path "$aksSource\aks-hci-tools\AksHci.Powershell.zip" -DestinationPath "$aksSource\aks-hci-tools\Powershell\Modules" -Force
|
||||
}
|
||||
}
|
||||
End
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
function Prepare-AzureVMforAksHciDeployment
|
||||
{
|
||||
[CmdletBinding()]
|
||||
Param
|
||||
(
|
||||
)
|
||||
|
||||
Begin
|
||||
{
|
||||
#variables
|
||||
$targetDrive = "V:"
|
||||
$sourcePath = "$targetDrive\source"
|
||||
$aksSource = "$sourcePath\aksHciSource"
|
||||
$aksHCITargetPath = "$targetDrive\AksHciMain"
|
||||
}
|
||||
|
||||
Process
|
||||
{
|
||||
Prepare-AzsHciPackage
|
||||
|
||||
#Copy AksHCI modules to Azure Stack HCI hosts
|
||||
$AzureStackHCIHosts.Name | ForEach-Object {Copy-Item "$aksSource\aks-hci-tools\Powershell\Modules" "c:\Program Files\WindowsPowershell\" -Recurse -Force}
|
||||
|
||||
New-Item -Path $aksHCITargetPath -ItemType Directory -Force
|
||||
}
|
||||
|
||||
End
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
function Prepare-AdforAzsHciDeployment
|
||||
{
|
||||
[CmdletBinding()]
|
||||
Param
|
||||
(
|
||||
|
||||
)
|
||||
|
||||
Begin
|
||||
{
|
||||
#variables
|
||||
$wac = "wac"
|
||||
$AzureStackHCIHosts = Get-VM hpv*
|
||||
$AzureStackHCIClusterName = "hci01"
|
||||
$ouName = "hci01"
|
||||
}
|
||||
Process
|
||||
{
|
||||
#New organizational Unit for cluster
|
||||
$dn = Get-ADOrganizationalUnit -Filter * | Where-Object name -eq $ouName
|
||||
if (-not ($dn))
|
||||
{
|
||||
$dn = New-ADOrganizationalUnit -Name $ouName -PassThru
|
||||
}
|
||||
|
||||
#Get Wac Computer Object
|
||||
$wacObject = Get-ADComputer -Filter * | Where-Object name -eq wac
|
||||
if (-not ($wacObject))
|
||||
{
|
||||
$wacObject = New-ADComputer -Name $wac -Enabled $false -PassThru
|
||||
}
|
||||
|
||||
#Creates Azure Stack HCI hosts if not exist
|
||||
if ($AzureStackHCIHosts.Name)
|
||||
{
|
||||
$AzureStackHCIHosts.Name | ForEach-Object {
|
||||
$comp = Get-ADComputer -Filter * | Where-Object name -eq $_
|
||||
if (-not ($comp))
|
||||
{
|
||||
New-ADComputer -Name $_ -Enabled $false -Path $dn -PrincipalsAllowedToDelegateToAccount $wacObject
|
||||
}
|
||||
else
|
||||
{
|
||||
$comp | Set-ADComputer -PrincipalsAllowedToDelegateToAccount $wacObject
|
||||
$comp | Move-AdObject -TargetPath $dn
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#Creates Azure Stack HCI Cluster CNO if not exist
|
||||
$AzureStackHCIClusterObject = Get-ADComputer -Filter * | Where-Object name -eq $AzureStackHCIClusterName
|
||||
if (-not ($AzureStackHCIClusterObject))
|
||||
{
|
||||
$AzureStackHCIClusterObject = New-ADComputer -Name $AzureStackHCIClusterName -Enabled $false -Path $dn -PrincipalsAllowedToDelegateToAccount $wacObject -PassThru
|
||||
}
|
||||
else
|
||||
{
|
||||
$AzureStackHCIClusterObject | Set-ADComputer -PrincipalsAllowedToDelegateToAccount $wacObject
|
||||
$AzureStackHCIClusterObject | Move-AdObject -TargetPath $dn
|
||||
}
|
||||
|
||||
#read OU DACL
|
||||
$acl = Get-Acl -Path "AD:\$dn"
|
||||
|
||||
# Set properties to allow Cluster CNO to Full Control on the new OU
|
||||
$principal = New-Object System.Security.Principal.SecurityIdentifier ($AzureStackHCIClusterObject).SID
|
||||
$ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule($principal, [System.DirectoryServices.ActiveDirectoryRights]::GenericAll, [System.Security.AccessControl.AccessControlType]::Allow, [DirectoryServices.ActiveDirectorySecurityInheritance]::All)
|
||||
|
||||
#modify DACL
|
||||
$acl.AddAccessRule($ace)
|
||||
|
||||
#Re-apply the modified DACL to the OU
|
||||
Set-ACL -ACLObject $acl -Path "AD:\$dn"
|
||||
}
|
||||
End
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
Function Configure-AzsHciClusterRoles
|
||||
{
|
||||
[CmdletBinding()]
|
||||
|
||||
Param
|
||||
(
|
||||
)
|
||||
|
||||
begin
|
||||
{
|
||||
#initializing variables
|
||||
$AzureStackHCIHosts = Get-VM hpv*
|
||||
|
||||
#Enable Roles
|
||||
$rolesToEnable = @("File-Services", "FS-FileServer", "FS-Data-Deduplication", "BitLocker", "Data-Center-Bridging", "EnhancedStorage", "Failover-Clustering", "RSAT", "RSAT-Feature-Tools", "RSAT-DataCenterBridging-LLDP-Tools", "RSAT-Clustering", "RSAT-Clustering-PowerShell", "RSAT-Role-Tools", "RSAT-AD-Tools", "RSAT-AD-PowerShell", "RSAT-Hyper-V-Tools", "Hyper-V-PowerShell")
|
||||
$rolesToDisable = @("telnet-client")
|
||||
|
||||
#new PsSession to
|
||||
$psSession = New-PSSession -ComputerName $AzureStackHCIHosts.Name
|
||||
}
|
||||
|
||||
process
|
||||
{
|
||||
Write-Verbose "Enabling/Disabling Roles and Features required on Azure Stack HCI Hosts"
|
||||
Invoke-Command -Session $psSession -ScriptBlock {
|
||||
$VerbosePreference=$using:VerbosePreference
|
||||
if ($using:rolesToEnable.Count -gt 0)
|
||||
{
|
||||
Write-Verbose "Installing following required roles/features to Azure Stack HCI hosts"
|
||||
$using:rolesToEnable | Write-Verbose
|
||||
Install-WindowsFeature -Name $using:rolesToEnable
|
||||
}
|
||||
|
||||
if ($using:rolesToDisable.Count -gt 0)
|
||||
{
|
||||
Write-Verbose "Removing following unnecessary roles/features from Azure Stack HCI hosts"
|
||||
$using:rolesToDisable | Write-Verbose
|
||||
Remove-WindowsFeature -Name $using:rolesToDisable
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
end
|
||||
{
|
||||
Remove-PSSession -Session $psSession
|
||||
Remove-Variable -Name psSession
|
||||
}
|
||||
}
|
||||
|
||||
Function Configure-AzsHciClusterNetwork
|
||||
{
|
||||
|
||||
[CmdletBinding(DefaultParameterSetName='Configure', SupportsShouldProcess=$true)]
|
||||
param (
|
||||
|
||||
[Parameter(ParameterSetName='Configure')]
|
||||
[Parameter(Mandatory=$false)]
|
||||
[ValidateSet("HighAvailable","SingleAdapter","Dummy")]
|
||||
[string]
|
||||
$ManagementInterfaceConfig = "HighAvailable",
|
||||
|
||||
[Parameter(ParameterSetName='Configure')]
|
||||
[Parameter(Mandatory=$false)]
|
||||
[ValidateSet("OneVirtualSwitchforAllTraffic","OneVirtualSwitchforComputeOnly","TwoVirtualSwitches","Dummy")]
|
||||
[string]
|
||||
$ComputeAndStorageInterfaceConfig = "OneVirtualSwitchforAllTraffic",
|
||||
|
||||
[Parameter(ParameterSetName='Cleanup')]
|
||||
[Parameter(Mandatory=$false)]
|
||||
[switch]
|
||||
$CleanupConfiguration,
|
||||
|
||||
[Parameter(ParameterSetName='Configure')]
|
||||
[Parameter(Mandatory=$false)]
|
||||
[switch]
|
||||
$ForceCleanup
|
||||
)
|
||||
|
||||
begin
|
||||
{
|
||||
#initializing variables
|
||||
$AzureStackHCIHosts = Get-VM hpv*
|
||||
$vSwitchNameMgmt = 'Management'
|
||||
$vSwitchNameConverged = "Default Switch"
|
||||
$vSwitchNameCompute = "Default Switch"
|
||||
$vSwitchNameStorage = "StorageSwitch"
|
||||
|
||||
#Enable Roles
|
||||
$rolesToEnable = @("File-Services", "FS-FileServer", "FS-Data-Deduplication", "BitLocker", "Data-Center-Bridging", "EnhancedStorage", "Failover-Clustering", "RSAT", "RSAT-Feature-Tools", "RSAT-DataCenterBridging-LLDP-Tools", "RSAT-Clustering", "RSAT-Clustering-PowerShell", "RSAT-Role-Tools", "RSAT-AD-Tools", "RSAT-AD-PowerShell", "RSAT-Hyper-V-Tools", "Hyper-V-PowerShell")
|
||||
$rolesToDisable = @()
|
||||
|
||||
Clear-DnsClientCache
|
||||
|
||||
#Disable DHCP Scope to prevent IP address from DHCP
|
||||
Set-DhcpServerv4Scope -ScopeId 192.168.100.0 -State InActive
|
||||
|
||||
#new PsSession to
|
||||
$psSession = New-PSSession -ComputerName $AzureStackHCIHosts.Name
|
||||
}
|
||||
|
||||
process
|
||||
{
|
||||
if ($cleanupConfiguration)
|
||||
{
|
||||
Write-Verbose "[Cleanup]: Current network configuration"
|
||||
Invoke-Command -Session $psSession -ScriptBlock {
|
||||
$vSwitch = Get-VMSwitch
|
||||
$VerbosePreference=$using:VerbosePreference
|
||||
Write-Verbose "[Cleanup]: Following vSwitch/es will be removed from Azure Stack HCI hosts"
|
||||
|
||||
if ($vSwitch)
|
||||
{
|
||||
$vSwitch.Name | Write-Verbose
|
||||
}
|
||||
|
||||
if ($vSwitch.Name -contains $using:vSwitchNameMgmt)
|
||||
{
|
||||
Write-Warning -Message "[Cleanup]: $env:COMPUTERNAME Network connection will be interupted for couple of minutes, be patient!!"
|
||||
|
||||
}
|
||||
$vSwitch | Remove-VMSwitch -Force
|
||||
}
|
||||
|
||||
Clear-DnsClientCache
|
||||
|
||||
Write-Verbose "[Cleanup]: Scramble Nic names to prevent name conflict"
|
||||
Invoke-Command -Session $psSession -ScriptBlock {
|
||||
$i = get-random -Minimum 100000 -max 999999
|
||||
Get-NetAdapter | foreach {Rename-NetAdapter -Name $_.Name -NewName $i; $i++}
|
||||
}
|
||||
|
||||
Invoke-Command -Session $psSession -ScriptBlock {
|
||||
$adapter = Get-NetAdapter | Where-Object status -eq "disabled"
|
||||
$VerbosePreference=$using:VerbosePreference
|
||||
if ($adapter)
|
||||
{
|
||||
Write-Verbose "[Cleanup]: Following adapters will be enabled on Azure Stack HCI hosts"
|
||||
$adapter.Name | Write-Verbose
|
||||
$adapter | Enable-NetAdapter -Confirm:$false -Passthru
|
||||
}
|
||||
}
|
||||
|
||||
Write-Verbose "[Cleanup]: Recalling DSC config to restore default state"
|
||||
|
||||
Start-DscConfiguration -UseExisting -Wait -Verbose:$false
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
$state = Invoke-Command -Session $psSession -ScriptBlock {
|
||||
Get-NetAdapter -Name Management*
|
||||
}
|
||||
if ($ForceCleanup)
|
||||
{
|
||||
Write-Warning "Current configuration detected! ForceCleanup switch Enabled. Cleaning up"
|
||||
Configure-AzsHciClusterNetwork -CleanupConfiguration
|
||||
}
|
||||
elseif ($state)
|
||||
{
|
||||
Write-Warning "Current configuration detected! Cleanup required"
|
||||
|
||||
Write-Host "Continue cleanup ? Continue without cleanup, recommended though 'n'o!!! Default action is cleanup. : " -Foregroundcolor Yellow -Nonewline
|
||||
$continue = Read-Host
|
||||
if ($continue -ne 'n' )
|
||||
{
|
||||
Configure-AzsHciClusterNetwork -CleanupConfiguration
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Warning "Current configuration detected however no Cleanup option is selected. You may face some errors"
|
||||
Write-Warning "Sleep for 10 seconds to make sure it is not accidentialy entered. You can break execution using 'Crtl + C' to cancel configuration"
|
||||
Start-Sleep 10
|
||||
}
|
||||
}
|
||||
|
||||
#Configure Management Network adapters
|
||||
|
||||
switch ($ManagementInterfaceConfig) {
|
||||
"HighAvailable" {
|
||||
Write-Verbose "[Configure ManagementInterfaceConfig]: HighAvailable - Configuring Management Interface"
|
||||
Write-Warning -Message "[Configure ManagementInterfaceConfig]: Network connection will be interupted for couple of minutes, be patient!!"
|
||||
Invoke-Command -Session $psSession -ScriptBlock {
|
||||
$ipConfig = (
|
||||
Get-NetAdapter -Physical | Get-NetAdapterBinding | Where-Object {$_.enabled -eq $true -and $_.DisplayName -eq 'Internet Protocol Version 4 (TCP/IPv4)'} |
|
||||
Get-NetIPConfiguration | Where-Object IPv4DefaultGateway | Sort-Object IPv4Address
|
||||
)
|
||||
$netAdapters = Get-NetAdapter -Name ($ipConfig.InterfaceAlias)
|
||||
$VerbosePreference=$using:VerbosePreference
|
||||
|
||||
$newAdapterNames = @()
|
||||
for ($i = 1; $i -lt $netAdapters.count + 1; $i++)
|
||||
{
|
||||
$netAdapterName = $netAdapters[$i - 1].Name
|
||||
|
||||
if ($netAdapterName -ne $($using:vSwitchNameMgmt + " $i"))
|
||||
{
|
||||
$newAdapterNames += $($using:vSwitchNameMgmt + " $i")
|
||||
Rename-NetAdapter -Name $netAdapterName -NewName $($using:vSwitchNameMgmt + " $i")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#try to suppress error message
|
||||
New-VMSwitch -Name $using:vSwitchNameMgmt -AllowManagementOS $true -NetAdapterName $newAdapterNames -EnableEmbeddedTeaming $true
|
||||
Rename-NetAdapter -Name "vEthernet `($using:vSwitchNameMgmt`)" -NewName $using:vSwitchNameMgmt
|
||||
}
|
||||
$mgmtSwitchName = $vSwitchNameMgmt
|
||||
}
|
||||
"SingleAdapter" {
|
||||
Write-Verbose "[Configure ManagementInterfaceConfig]: SingleAdapter - Configuring Management Interface"
|
||||
Invoke-Command -Session $psSession -ScriptBlock {
|
||||
$ipConfig = (
|
||||
Get-NetAdapter -Physical | Get-NetAdapterBinding | Where-Object {$_.enabled -eq $true -and $_.DisplayName -eq 'Internet Protocol Version 4 (TCP/IPv4)'} |
|
||||
Get-NetIPConfiguration | Where-Object IPv4DefaultGateway | Sort-Object IPv4Address
|
||||
)
|
||||
$netAdapters = Get-NetAdapter -Name ($ipConfig.InterfaceAlias)
|
||||
$VerbosePreference=$using:VerbosePreference
|
||||
Rename-NetAdapter -Name "$($netAdapters[0].Name)" -NewName $($using:vSwitchNameMgmt + " 1")
|
||||
Rename-NetAdapter -Name "$($netAdapters[1].Name)" -NewName $($using:vSwitchNameMgmt + " 2")
|
||||
Disable-NetAdapter -Name $($using:vSwitchNameMgmt + " 2") -Confirm:$false
|
||||
}
|
||||
$mgmtSwitchName = $null
|
||||
}
|
||||
}
|
||||
|
||||
#Configure Compute And Storage Network adapters
|
||||
|
||||
switch ($ComputeAndStorageInterfaceConfig) {
|
||||
"OneVirtualSwitchforAllTraffic" {
|
||||
Write-Verbose "[Configure ComputeAndStorageInterfaces]: OneVirtualSwitchforAllTraffic - Configuring ComputeAndStorageInterfaces"
|
||||
Invoke-Command -Session $psSession -ScriptBlock {
|
||||
$ipConfig = (
|
||||
Get-NetAdapter -Physical | Where-Object status -ne disabled | Get-NetAdapterBinding | Where-Object {$_.enabled -eq $true -and $_.DisplayName -eq 'Internet Protocol Version 4 (TCP/IPv4)'} |
|
||||
Get-NetIPConfiguration | Where-Object {$_.IPv4DefaultGateway -eq $null -and $_.IPv4Address.Ipaddress -like "192.168.25*"} | Sort-Object IPv4Address
|
||||
)
|
||||
$netAdapters = Get-NetAdapter -Name ($ipConfig.InterfaceAlias)
|
||||
$VerbosePreference=$using:VerbosePreference
|
||||
|
||||
New-VMSwitch -Name $using:vSwitchNameConverged -NetAdapterName $netAdapters.Name -EnableEmbeddedTeaming $true -AllowManagementOS $false
|
||||
|
||||
for ($i = 1; $i -lt $netAdapters.Count + 1; $i++)
|
||||
{
|
||||
$adapterName = "smb " + $i
|
||||
Add-VMNetworkAdapter -ManagementOS -SwitchName $using:vSwitchNameConverged -Name $adapterName
|
||||
$vNic = Rename-NetAdapter -Name "vEthernet `($adapterName`)" -NewName $adapterName -PassThru
|
||||
$pNic = Rename-NetAdapter -Name $netAdapters[$i - 1].Name -NewName $($using:vSwitchNameConverged + " $i") -PassThru
|
||||
New-NetIPAddress -IPAddress $ipconfig[$i - 1].ipv4Address.Ipaddress -InterfaceAlias $vNic.Name -AddressFamily IPv4 -PrefixLength $ipconfig[$i - 1].ipv4Address.prefixlength | Out-Null
|
||||
$sleep = 5
|
||||
do
|
||||
{
|
||||
Write-Verbose "Waiting for NICs $($vNic.Name) and $($pNic.Name) to come 'up' for $sleep seconds"
|
||||
Start-Sleep -Seconds $sleep
|
||||
}
|
||||
|
||||
until ((Get-NetAdapter -Name $vNic.Name | Where-Object status -eq "up") -and (Get-NetAdapter -Name $pNic.Name | Where-Object status -eq "up"))
|
||||
Write-Verbose "Setting up $($vNic.Name) and $($pNic.Name) for VMNetworkAdapterTeamMapping"
|
||||
Set-VMNetworkAdapterTeamMapping -ManagementOS -VMNetworkAdapterName $vnic.Name -PhysicalNetAdapterName $pNic.Name
|
||||
|
||||
}
|
||||
}
|
||||
$computeSwitchName = $vSwitchNameConverged
|
||||
}
|
||||
"OneVirtualSwitchforComputeOnly" {
|
||||
Write-Verbose "[Configure ComputeAndStorageInterfaces]: OneVirtualSwitchforComputeOnly - Configuring ComputeAndStorageInterfaces"
|
||||
Invoke-Command -Session $psSession -ScriptBlock {
|
||||
|
||||
$ipConfigCompute = (
|
||||
Get-NetAdapter -Physical | Where-Object status -ne disabled | Get-NetAdapterBinding | ? {$_.enabled -eq $true -and $_.DisplayName -eq 'Internet Protocol Version 4 (TCP/IPv4)'} |
|
||||
Get-NetIPConfiguration | Where-Object {($_.IPv4DefaultGateway -eq $null) -and ($_.IPv4Address.Ipaddress -like "192.168.251.*" -or $_.IPv4Address.Ipaddress -like "192.168.252.*")} |
|
||||
Sort-Object IPv4Address
|
||||
)
|
||||
$netAdaptersCompute = Get-NetAdapter -Name ($ipConfigCompute.InterfaceAlias)
|
||||
|
||||
$ipConfigStorage = (
|
||||
Get-NetAdapter -Physical | Where-Object status -ne disabled | Get-NetAdapterBinding | ? {$_.enabled -eq $true -and $_.DisplayName -eq 'Internet Protocol Version 4 (TCP/IPv4)'} |
|
||||
Get-NetIPConfiguration | Where-Object {($_.IPv4DefaultGateway -eq $null) -and ($_.IPv4Address.Ipaddress -like "192.168.253.*" -or $_.IPv4Address.Ipaddress -like "192.168.254.*")} |
|
||||
Sort-Object IPv4Address
|
||||
)
|
||||
#$ipConfigStorage = (Get-NetAdapter -Physical | Where-Object status -ne disabled | Get-NetIPConfiguration | Where-Object {($_.IPv4DefaultGateway -eq $null) -and ($_.IPv4Address.Ipaddress -like "192.168.253.*" -or $_.IPv4Address.Ipaddress -like "192.168.254.*")})
|
||||
$netAdaptersStorage = Get-NetAdapter -Name ($ipConfigStorage.InterfaceAlias)
|
||||
|
||||
$VerbosePreference=$using:VerbosePreference
|
||||
|
||||
Write-Verbose "[New SET switch]: $($using:vSwitchNameCompute) with following members"
|
||||
Write-Verbose "$($netAdaptersCompute.Name)"
|
||||
|
||||
New-VMSwitch -Name $using:vSwitchNameCompute -NetAdapterName $netAdaptersCompute.Name -EnableEmbeddedTeaming $true -AllowManagementOS $false
|
||||
|
||||
for ($i = 1; $i -lt $netAdaptersCompute.Count + 1; $i++){
|
||||
Write-Verbose "[Rename NIC]: $($netAdaptersCompute[$i - 1].Name) to $($using:vSwitchNameCompute + " $i")"
|
||||
$pNic = Rename-NetAdapter -Name $netAdaptersCompute[$i - 1].Name -NewName $($using:vSwitchNameCompute + " $i") -PassThru
|
||||
|
||||
}
|
||||
|
||||
for ($i = 1; $i -lt $netAdaptersStorage.Count + 1; $i++)
|
||||
{
|
||||
$adapterName = "smb " + $i
|
||||
Write-Verbose "[Rename NIC]: $($netAdaptersStorage[$i - 1].Name) to $adapterName"
|
||||
$pNic = Rename-NetAdapter -Name $netAdaptersStorage[$i - 1].Name -NewName $adapterName -PassThru
|
||||
|
||||
}
|
||||
}
|
||||
$computeSwitchName = $vSwitchNameCompute
|
||||
}
|
||||
"TwoVirtualSwitches" {
|
||||
Write-Verbose "[Configure ComputeAndStorageInterfaces]: TwoVirtualSwitches - Configuring ComputeAndStorageInterfaces"
|
||||
Invoke-Command -Session $psSession -ScriptBlock {
|
||||
|
||||
$ipConfigCompute = (
|
||||
Get-NetAdapter -Physical | Where-Object status -ne disabled | Get-NetAdapterBinding | Where-Object {$_.enabled -eq $true -and $_.DisplayName -eq 'Internet Protocol Version 4 (TCP/IPv4)'} |
|
||||
Get-NetIPConfiguration | Where-Object {($_.IPv4DefaultGateway -eq $null) -and ($_.IPv4Address.Ipaddress -like "192.168.251.*" -or $_.IPv4Address.Ipaddress -like "192.168.252.*")} |
|
||||
Sort-Object IPv4Address
|
||||
)
|
||||
$netAdaptersCompute = Get-NetAdapter -Name ($ipConfigCompute.InterfaceAlias)
|
||||
|
||||
$ipConfigStorage = (
|
||||
Get-NetAdapter -Physical | Where-Object status -ne disabled | Get-NetAdapterBinding | ? {$_.enabled -eq $true -and $_.DisplayName -eq 'Internet Protocol Version 4 (TCP/IPv4)'} |
|
||||
Get-NetIPConfiguration | Where-Object {($_.IPv4DefaultGateway -eq $null) -and ($_.IPv4Address.Ipaddress -like "192.168.253.*" -or $_.IPv4Address.Ipaddress -like "192.168.254.*")} |
|
||||
Sort-Object IPv4Address
|
||||
)
|
||||
$netAdaptersStorage = Get-NetAdapter -Name ($ipConfigStorage.InterfaceAlias)
|
||||
|
||||
$VerbosePreference=$using:VerbosePreference
|
||||
|
||||
Write-Verbose "[New SET switch]: $($using:vSwitchNameCompute) with following members"
|
||||
|
||||
New-VMSwitch -Name $using:vSwitchNameCompute -NetAdapterName $netAdaptersCompute.Name -EnableEmbeddedTeaming $true -AllowManagementOS $false
|
||||
|
||||
for ($i = 1; $i -lt $netAdaptersCompute.Count + 1; $i++)
|
||||
{
|
||||
Write-Verbose "[Rename NIC]: $($netAdaptersCompute[$i - 1].Name) to $adapterName"
|
||||
$pNic = Rename-NetAdapter -Name $netAdaptersCompute[$i - 1].Name -NewName $($using:vSwitchNameCompute + " $i") -PassThru
|
||||
}
|
||||
|
||||
Write-Verbose "[New SET switch]: $($using:vSwitchNameStorage) with following members"
|
||||
|
||||
New-VMSwitch -Name $using:vSwitchNameStorage -NetAdapterName $netAdaptersStorage.Name -EnableEmbeddedTeaming $true -AllowManagementOS $false
|
||||
|
||||
for ($i = 1; $i -lt $netAdaptersStorage.Count + 1; $i++)
|
||||
{
|
||||
$adapterName = "smb " + $i
|
||||
Add-VMNetworkAdapter -ManagementOS -SwitchName $using:vSwitchNameStorage -Name $adapterName
|
||||
#Start-Sleep 4
|
||||
|
||||
Write-Verbose "[Rename NIC]: $($netAdaptersStorage[$i - 1].Name) to $adapterName"
|
||||
|
||||
$vNic = Rename-NetAdapter -Name "vEthernet `($adapterName`)" -NewName $adapterName -PassThru
|
||||
$pNic = Rename-NetAdapter -Name $netAdaptersStorage[$i - 1].Name -NewName $($using:vSwitchNameStorage + " $i") -PassThru
|
||||
New-NetIPAddress -IPAddress $ipConfigStorage[$i - 1].ipv4Address.Ipaddress -InterfaceAlias $vNic.Name -AddressFamily IPv4 -PrefixLength $ipConfigStorage[$i - 1].ipv4Address.prefixlength | Out-Null
|
||||
$sleep = 5
|
||||
do
|
||||
{
|
||||
Write-Verbose "Waiting for NICs $($vNic.Name) and $($pNic.Name) to come 'up' for $sleep seconds"
|
||||
Start-Sleep -Seconds $sleep
|
||||
}
|
||||
until ((Get-NetAdapter -Name $vNic.Name | Where-Object status -eq "up") -and (Get-NetAdapter -Name $pNic.Name | Where-Object status -eq "up"))
|
||||
Write-Verbose "Setting up vNIC: $($vNic.Name) and pNIC: $($pNic.Name) for VMNetworkAdapterTeamMapping"
|
||||
Set-VMNetworkAdapterTeamMapping -ManagementOS -VMNetworkAdapterName $vnic.Name -PhysicalNetAdapterName $pNic.Name
|
||||
|
||||
}
|
||||
}
|
||||
$computeSwitchName = $vSwitchNameCompute
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
end
|
||||
{
|
||||
#Re-Enable DHCP Scope
|
||||
|
||||
Set-DhcpServerv4Scope -ScopeId 192.168.100.0 -State Active
|
||||
Remove-PSSession -Session $psSession
|
||||
Remove-Variable -Name psSession
|
||||
@{
|
||||
ManagementSwitch = $mgmtSwitchName
|
||||
ComputeSwitch = $computeSwitchName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Erase-AzsHciClusterDisks
|
||||
{
|
||||
[CmdletBinding()]
|
||||
|
||||
Param
|
||||
(
|
||||
)
|
||||
|
||||
Begin
|
||||
{
|
||||
#initializing variables
|
||||
$AzureStackHCIHosts = Get-VM hpv*
|
||||
|
||||
$psSession = New-PSSession -ComputerName $AzureStackHCIHosts.Name
|
||||
}
|
||||
|
||||
Process
|
||||
{
|
||||
Write-Verbose "Cleaning up previously configured S2D Disks"
|
||||
Invoke-Command -Session $psSession -ScriptBlock {
|
||||
Update-StorageProviderCache
|
||||
Get-StoragePool | Where-Object IsPrimordial -eq $false | Set-StoragePool -IsReadOnly:$false -ErrorAction SilentlyContinue
|
||||
Get-StoragePool | Where-Object IsPrimordial -eq $false | Get-VirtualDisk | Remove-VirtualDisk -Confirm:$false -ErrorAction SilentlyContinue
|
||||
Get-StoragePool | Where-Object IsPrimordial -eq $false | Remove-StoragePool -Confirm:$false -ErrorAction SilentlyContinue
|
||||
Get-PhysicalDisk | Reset-PhysicalDisk -ErrorAction SilentlyContinue
|
||||
Get-Disk | Where-Object Number -ne $null | Where-Object IsBoot -ne $true | Where-Object IsSystem -ne $true | Where-Object PartitionStyle -ne RAW | Foreach-Object {
|
||||
$_ | Set-Disk -isoffline:$false
|
||||
$_ | Set-Disk -isreadonly:$false
|
||||
$_ | Clear-Disk -RemoveData -RemoveOEM -Confirm:$false
|
||||
$_ | Set-Disk -isreadonly:$true
|
||||
$_ | Set-Disk -isoffline:$true
|
||||
}
|
||||
Get-Disk | Where-Object Number -Ne $Null | Where-Object IsBoot -Ne $True | Where-Object IsSystem -Ne $True | Where-Object PartitionStyle -Eq RAW | Group -NoElement -Property FriendlyName
|
||||
} | Sort-Object -Property PsComputerName, Count
|
||||
}
|
||||
|
||||
End
|
||||
{
|
||||
Remove-PSSession -Session $psSession
|
||||
Remove-Variable -Name psSession
|
||||
}
|
||||
}
|
||||
|
||||
function Configure-AzsHciCluster
|
||||
{
|
||||
[CmdletBinding()]
|
||||
Param
|
||||
(
|
||||
# Param1 help description
|
||||
[Parameter(Mandatory=$true)]
|
||||
$ClusterName
|
||||
)
|
||||
|
||||
Begin
|
||||
{
|
||||
#initializing variables
|
||||
$AzureStackHCIHosts = Get-VM hpv*
|
||||
|
||||
$cimSession = New-CimSession -ComputerName $AzureStackHCIHosts[0].Name
|
||||
|
||||
}
|
||||
|
||||
Process
|
||||
{
|
||||
Write-Verbose "Enabling Cluster: $ClusterName"
|
||||
New-Cluster -Name $ClusterName -Node $AzureStackHCIHosts.Name -NoStorage -Force
|
||||
Write-Verbose "Enabling Storage Spaces Direct on Cluster: $ClusterName"
|
||||
Enable-ClusterStorageSpacesDirect -PoolFriendlyName "Cluster Storage Pool" -CimSession $cimSession -Confirm:$false -SkipEligibilityChecks -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
End
|
||||
{
|
||||
#clean up variables
|
||||
Remove-CimSession -CimSession $cimSession
|
||||
Remove-Variable -Name cimSession
|
||||
}
|
||||
}
|
||||
|
||||
function Prepare-AzsHciClusterforAksHciDeployment
|
||||
{
|
||||
[CmdletBinding()]
|
||||
Param
|
||||
(
|
||||
)
|
||||
|
||||
Begin
|
||||
{
|
||||
#variables
|
||||
$targetDrive = "V:"
|
||||
$sourcePath = "$targetDrive\source"
|
||||
$aksSource = "$sourcePath\aksHciSource"
|
||||
$AzureStackHCIHosts = Get-VM hpv*
|
||||
$AzureStackHCIClusterName = 'Hci01'
|
||||
$azSHCICSV = "AksHCIMain"
|
||||
$azSHCICSVPath = "c:\ClusterStorage\$azSHCICSV"
|
||||
}
|
||||
Process
|
||||
{
|
||||
Prepare-AzsHciPackage
|
||||
|
||||
#Update NuGet Package provider on AzsHci Host
|
||||
Invoke-Command -ComputerName $AzureStackHCIHosts.Name -ScriptBlock {
|
||||
Install-PackageProvider -Name NuGet -Force
|
||||
Install-Module -Name PowershellGet -Force -Confirm:$false -SkipPublisherCheck
|
||||
}
|
||||
|
||||
#Copy AksHCI modules to Azure Stack HCI hosts
|
||||
$AzureStackHCIHosts.Name | ForEach-Object {Copy-Item "$aksSource\aks-hci-tools\Powershell\Modules" "\\$_\c$\Program Files\WindowsPowershell\" -Recurse -Force}
|
||||
|
||||
#create Cluster Shared Volume for AksHCI and Enable Deduplication
|
||||
#New-Volume -CimSession "$($AzureStackHCIHosts[0].Name)" -FriendlyName $azSHCICSV -FileSystem CSVFS_ReFS -StoragePoolFriendlyName S2D* -Size 1.3TB
|
||||
New-Volume -CimSession $AzureStackHCIClusterName -FriendlyName $azSHCICSV -FileSystem CSVFS_ReFS -StoragePoolFriendlyName cluster* -Size 1.3TB
|
||||
Enable-DedupVolume -CimSession $AzureStackHCIClusterName -Volume $azSHCICSVPath
|
||||
Enable-DedupVolume -CimSession $AzureStackHCIClusterName -Volume $azSHCICSVPath -UsageType HyperV -DataAccess
|
||||
|
||||
}
|
||||
End
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
function Start-AksHciPoC
|
||||
{
|
||||
param (
|
||||
)
|
||||
|
||||
begin
|
||||
{
|
||||
|
||||
#Initialize variables
|
||||
$AzureStackHCIHosts = Get-VM -Name hpv*
|
||||
$sleep = 20
|
||||
|
||||
}
|
||||
|
||||
process
|
||||
{
|
||||
|
||||
$CleanupVMsSelection = Show-Menu -Items @(
|
||||
'Do NOT Cleanup ( !!Default selection!! )',
|
||||
'Yes, Cleanup Azure Stack HCI host VMs and Wac VMs',
|
||||
'Yes, Cleanup Windows Admin Center VM Only!',
|
||||
'Yes, Cleanup Azure Stack HCI host VMs Only!',
|
||||
'Yes, Cleanup All VMs for both HCI host VMs, Aks Hci VMs!'
|
||||
) -Title 'Cleanup VMs option to start from scratch?' -Description 'This option will destroy All VMs or selected VMs.'
|
||||
|
||||
$RolesConfigurationProfileSelection = Show-Menu -Items @(
|
||||
'Do NOT install any Roles ( !!Default selection!! )',
|
||||
'Install required roles to Azure Stack HCI Hosts'
|
||||
) -Title 'Azure Stack HCI Roles and Features Installation optionssndklajsdkljasdjasjdljasd' -Description 'Roles are installed by default. (Optional)'
|
||||
|
||||
$NetworkConfigurationProfileSelection = Show-Menu -Items @(
|
||||
'High-available Management & One Virtual Switch for All Traffic ( !!Default selection!! )',
|
||||
'High-available networks for Management & One Virtual Switch for Compute Only',
|
||||
'High-available networks for Managament & Two Virtual Switches',
|
||||
'Single Network Adapter for Management & One Virtual Switch for All Traffic',
|
||||
'Single Network Adapter for Management & One Virtual Switch for Compute Only',
|
||||
'Single Network Adapter for Management & Two Virtual Switches for Compute and Storage',
|
||||
'High-available networks for Management & One Virtual Switch for All Traffic ( !!Also reset network config!! )',
|
||||
'Single Network Adapter for Management & One Virtual Switch for Compute Only ( !!Also reset network config!! )',
|
||||
'High-available networks for Managament & Two Virtual Switches ( !!Also reset network config!! )',
|
||||
'Do NOT configure networks'
|
||||
) -Title 'Azure Stack HCI Network Adapter Configuration options (SET Switch)' -Description ""
|
||||
|
||||
$DisksConfigurationProfileSelection = Show-Menu -Items @(
|
||||
'Do NOT erase and cleanup ( !!Default selection!! )',
|
||||
'Erase all drives'
|
||||
) -Title 'Azure Stack HCI Disks cleanup options' -Description 'Please do so, if this is NOT first installation on top of clean environment. (Optional)'
|
||||
|
||||
$ClusterConfigurationProfileSelection = Show-Menu -Items @(
|
||||
'Enable Cluster using default Name (Cluster Name: hci01) ( !!Default selection!! )',
|
||||
'Do NOT Create Cluster yet.'
|
||||
) -Title 'Azure Stack HCI Cluster options' -Description 'Install cluster using default name to prevent any misconfigurations'
|
||||
|
||||
$AksHciConfigurationProfileSelection = Show-Menu -Items @(
|
||||
'Prepare for Aks Hci Deployment ( !!Default selection!! )',
|
||||
'Do NOT Prepare for Aks Hci Deployment yet.'
|
||||
) -Title 'Azure Stack HCI Cluster Aks Hci preparation options' -Description 'Prepare Azure Stack HCI Cluster with Aks Hci pre-requisites'
|
||||
|
||||
switch ($CleanupVMsSelection)
|
||||
{
|
||||
1 {Cleanup-VMs -AzureStackHciHostVMs -WindowsAdminCenterVM -Verbose; Prepare-AdforAzsHciDeployment}
|
||||
2 {Cleanup-VMs -WindowsAdminCenterVM -Verbose}
|
||||
3 {Cleanup-VMs -AzureStackHciHostVMs -Verbose; Prepare-AdforAzsHciDeployment}
|
||||
4 {if ((Get-Vm * | Where-Object name -ne 'wac').count -gt 0){Uninstall-AksHci}; Cleanup-VMs -AzureStackHciHostVMs -Verbose; Prepare-AdforAzsHciDeployment}
|
||||
Default {Write-Warning "[Cleanup-VMs]: No Cleanup selected."}
|
||||
}
|
||||
|
||||
$cimSession = New-CimSession -ComputerName $AzureStackHCIHosts.name
|
||||
|
||||
do
|
||||
{
|
||||
Clear-DnsClientCache
|
||||
Write-Verbose "Waiting for Azure Stack HCI hosts to finish initial DSC configuration for $sleep seconds" -Verbose
|
||||
Start-Sleep -Seconds $sleep
|
||||
}
|
||||
while (((Get-DscLocalConfigurationManager -CimSession $cimSession -ErrorAction SilentlyContinue | Select-Object -ExpandProperty lcmstate) -contains "busy" -or (Get-DscLocalConfigurationManager -CimSession $cimSession -ErrorAction SilentlyContinue | Select-Object -ExpandProperty lcmstate) -contains "PendingConfiguration"))
|
||||
|
||||
switch ($RolesConfigurationProfileSelection)
|
||||
{
|
||||
1 {Configure-AzsHciClusterRoles -Verbose}
|
||||
Default {Write-Warning "[Configure-AzsHciClusterRoles]: Not installing Roles and Features, assuming All Roles and Features required are already installed. Subsequent process may rely on Roles and Features Installation."}
|
||||
}
|
||||
|
||||
switch ($NetworkConfigurationProfileSelection)
|
||||
{
|
||||
1 {Configure-AzsHciClusterNetwork -ManagementInterfaceConfig HighAvailable -Verbose -ComputeAndStorageInterfaceConfig OneVirtualSwitchforComputeOnly}
|
||||
2 {Configure-AzsHciClusterNetwork -ManagementInterfaceConfig HighAvailable -Verbose -ComputeAndStorageInterfaceConfig TwoVirtualSwitches}
|
||||
3 {Configure-AzsHciClusterNetwork -ManagementInterfaceConfig SingleAdapter -Verbose -ComputeAndStorageInterfaceConfig OneVirtualSwitchforAllTraffic}
|
||||
4 {Configure-AzsHciClusterNetwork -ManagementInterfaceConfig SingleAdapter -Verbose -ComputeAndStorageInterfaceConfig OneVirtualSwitchforComputeOnly}
|
||||
5 {Configure-AzsHciClusterNetwork -ManagementInterfaceConfig SingleAdapter -Verbose -ComputeAndStorageInterfaceConfig TwoVirtualSwitches}
|
||||
6 {Configure-AzsHciClusterNetwork -ManagementInterfaceConfig HighAvailable -Verbose -ComputeAndStorageInterfaceConfig OneVirtualSwitchforAllTraffic -ForceCleanup}
|
||||
7 {Configure-AzsHciClusterNetwork -ManagementInterfaceConfig SingleAdapter -Verbose -ComputeAndStorageInterfaceConfig OneVirtualSwitchforComputeOnly -ForceCleanup}
|
||||
8 {Configure-AzsHciClusterNetwork -ManagementInterfaceConfig HighAvailable -Verbose -ComputeAndStorageInterfaceConfig TwoVirtualSwitches -ForceCleanup}
|
||||
9 {Write-Warning "[Configure-AzsHciClusterNetwork]: Assuming Networks are already configured!"}
|
||||
Default {Configure-AzsHciClusterNetwork -ManagementInterfaceConfig HighAvailable -Verbose -ComputeAndStorageInterfaceConfig OneVirtualSwitchforAllTraffic}
|
||||
}
|
||||
|
||||
switch ($DisksConfigurationProfileSelection)
|
||||
{
|
||||
1 {Erase-AzsHciClusterDisks -Verbose}
|
||||
default {Write-Warning "[Erase-AzsHciClusterDisks]: Assuming this is first installation on top of clean environment. Otherwise subsequent process may fail."}
|
||||
}
|
||||
|
||||
switch ($ClusterConfigurationProfileSelection)
|
||||
{
|
||||
1 {Write-Warning "You may need to configure cluster manually!"}
|
||||
Default {Configure-AzsHciCluster -ClusterName hci01 -Verbose}
|
||||
}
|
||||
|
||||
switch ($AksHciConfigurationProfileSelection)
|
||||
{
|
||||
1 {Write-Warning "You may need to prepare Azure Stack HCI cluster for Aks Hci pre-requisites manually!"}
|
||||
Default {Prepare-AzsHciClusterforAksHciDeployment -Verbose}
|
||||
}
|
||||
}
|
||||
|
||||
end
|
||||
{
|
||||
|
||||
Remove-CimSession $cimSession
|
||||
Remove-variable cimsession
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
function Show-Menu
|
||||
{
|
||||
[CmdletBinding()]
|
||||
[OutputType([string])]
|
||||
Param
|
||||
(
|
||||
[parameter(Mandatory=$true)]
|
||||
[string[]]
|
||||
$Items,
|
||||
|
||||
[parameter(Mandatory=$true)]
|
||||
[string]
|
||||
$Title,
|
||||
|
||||
[string]
|
||||
$Description,
|
||||
|
||||
[int]
|
||||
[ValidateRange(4,10)]
|
||||
$MenuIndent = 4,
|
||||
|
||||
[System.ConsoleColor]
|
||||
$ColorTitle = 'Green',
|
||||
|
||||
[System.ConsoleColor]
|
||||
$ColorDescription = 'Yellow'
|
||||
)
|
||||
|
||||
Begin
|
||||
{
|
||||
$titleLength = [math]::Round($Title.Length / 2)
|
||||
$longest = [math]::Round(($items | ForEach-Object {$_.length} | Sort-Object -Descending | Select-Object -First 1) / 2)
|
||||
if ($longest -lt $titleLength)
|
||||
{
|
||||
$longest = $titleLength
|
||||
}
|
||||
|
||||
}
|
||||
Process
|
||||
{
|
||||
Clear-Host
|
||||
Write-Host $('=' * $(($longest + $MenuIndent) - $titleLength) + " " + "$Title" + " " + '=' * $(($longest + $MenuIndent) - $titleLength) ) -ForegroundColor Green
|
||||
Write-Host ""
|
||||
|
||||
if ($Description)
|
||||
{
|
||||
Write-Host $(" " * $($MenuIndent - 2) + $Description) -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
for ($i = 0; $i -lt $items.count; $i++)
|
||||
{
|
||||
Write-Host "$(" " * $MenuIndent + "$i" + '. ' + $items[$i])"
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Selection: " -ForegroundColor Green -NoNewline
|
||||
|
||||
$selection = Read-Host
|
||||
|
||||
if ([string]::IsNullOrEmpty($selection))
|
||||
{
|
||||
$selection = 0
|
||||
}
|
||||
return $selection
|
||||
}
|
||||
End
|
||||
{
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
configuration AzSHciHost
|
||||
{
|
||||
Import-DscResource -ModuleName 'PSDesiredStateConfiguration'
|
||||
|
||||
node localhost
|
||||
{
|
||||
LocalConfigurationManager {
|
||||
RebootNodeIfNeeded = $true
|
||||
ActionAfterReboot = 'ContinueConfiguration'
|
||||
ConfigurationMode = 'ApplyAndAutoCorrect'
|
||||
ConfigurationModeFrequencyMins = 1440
|
||||
}
|
||||
|
||||
WindowsFeatureSet "AzsHci Required Roles"
|
||||
{
|
||||
Ensure = 'Present'
|
||||
Name = @("File-Services", "FS-FileServer", "FS-Data-Deduplication", "BitLocker", "Data-Center-Bridging", "EnhancedStorage", "Failover-Clustering", "RSAT", "RSAT-Feature-Tools", "RSAT-DataCenterBridging-LLDP-Tools", "RSAT-Clustering", "RSAT-Clustering-PowerShell", "RSAT-Role-Tools", "RSAT-AD-Tools", "RSAT-AD-PowerShell", "RSAT-Hyper-V-Tools", "Hyper-V-PowerShell")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$date = get-date -f yyyy-MM-dd
|
||||
$logFile = Join-Path -Path "C:\temp" -ChildPath $('AzSHciHost-Transcipt-' + $date + '.log')
|
||||
$DscConfigLocation = "c:\temp\AzSHciHost"
|
||||
|
||||
Start-Transcript -Path $logFile
|
||||
|
||||
Remove-DscConfigurationDocument -Stage Current, Previous, Pending -Force
|
||||
|
||||
AzSHciHost -OutputPath $DscConfigLocation
|
||||
|
||||
Set-DscLocalConfigurationManager -Path $DscConfigLocation -Verbose
|
||||
|
||||
Start-DscConfiguration -Path $DscConfigLocation -Wait -Verbose
|
||||
|
||||
Stop-Transcript
|
||||
|
||||
Logoff
|
|
@ -0,0 +1,134 @@
|
|||
configuration WindowsAdminCenter
|
||||
{
|
||||
Import-DscResource -ModuleName 'cChoco'
|
||||
Import-DscResource -ModuleName 'ComputerManagementDsc'
|
||||
|
||||
node localhost
|
||||
{
|
||||
LocalConfigurationManager {
|
||||
RebootNodeIfNeeded = $true
|
||||
ActionAfterReboot = 'ContinueConfiguration'
|
||||
ConfigurationMode = 'ApplyAndAutoCorrect'
|
||||
ConfigurationModeFrequencyMins = 1440
|
||||
}
|
||||
|
||||
cChocoInstaller InstallChoco
|
||||
{
|
||||
InstallDir = "c:\choco"
|
||||
}
|
||||
|
||||
cChocoFeature allowGlobalConfirmation
|
||||
{
|
||||
|
||||
FeatureName = "allowGlobalConfirmation"
|
||||
Ensure = 'Present'
|
||||
DependsOn = '[cChocoInstaller]installChoco'
|
||||
}
|
||||
|
||||
cChocoFeature useRememberedArgumentsForUpgrades
|
||||
{
|
||||
|
||||
FeatureName = "useRememberedArgumentsForUpgrades"
|
||||
Ensure = 'Present'
|
||||
DependsOn = '[cChocoInstaller]installChoco'
|
||||
}
|
||||
|
||||
cChocoPackageInstaller "Install Windows Admin Center on 443"
|
||||
{
|
||||
Name = 'windows-admin-center'
|
||||
Ensure = 'Present'
|
||||
AutoUpgrade = $true
|
||||
DependsOn = '[cChocoInstaller]installChoco'
|
||||
Params = "'/Port:443'"
|
||||
}
|
||||
|
||||
PendingReboot "reboot"
|
||||
{
|
||||
Name = 'reboot'
|
||||
}
|
||||
|
||||
Script "Fake reboot"
|
||||
{
|
||||
TestScript = {
|
||||
return (Test-Path HKLM:\SOFTWARE\RebootKey)
|
||||
}
|
||||
SetScript = {
|
||||
New-Item -Path HKLM:\SOFTWARE\RebootKey -Force
|
||||
$global:DSCMachineStatus = 1
|
||||
}
|
||||
GetScript = {
|
||||
return @{result = 'result'}
|
||||
}
|
||||
DependsOn = "[cChocoPackageInstaller]Install Windows Admin Center on 443"
|
||||
}
|
||||
|
||||
script "Windows Admin Center updater"
|
||||
{
|
||||
GetScript = {
|
||||
|
||||
# Specify the WAC gateway
|
||||
$wac = "https://$env:COMPUTERNAME"
|
||||
|
||||
# Add the module to the current session
|
||||
$module = "$env:ProgramFiles\Windows Admin Center\PowerShell\Modules\ExtensionTools\ExtensionTools.psm1"
|
||||
|
||||
Import-Module -Name $module -Verbose -Force
|
||||
|
||||
# List the WAC extensions
|
||||
$extensions = Get-Extension $wac | Where-Object {$_.isLatestVersion -like 'False'}
|
||||
|
||||
$result = if ($extensions.count -gt 0) {$false} else {$true}
|
||||
|
||||
return @{
|
||||
Wac = $WAC
|
||||
extensions = $extensions
|
||||
result = $result
|
||||
}
|
||||
}
|
||||
TestScript = {
|
||||
# Create and invoke a scriptblock using the $GetScript automatic variable, which contains a string representation of the GetScript.
|
||||
$state = [scriptblock]::Create($GetScript).Invoke()
|
||||
return $state.Result
|
||||
}
|
||||
SetScript = {
|
||||
$state = [scriptblock]::Create($GetScript).Invoke()
|
||||
|
||||
$date = get-date -f yyyy-MM-dd
|
||||
|
||||
$logFile = Join-Path -Path "C:\Users\Public" -ChildPath $('WACUpdateLog-' + $date + '.log')
|
||||
|
||||
New-Item -Path $logFile -ItemType File -Force
|
||||
|
||||
ForEach($extension in $state.extensions)
|
||||
{
|
||||
Update-Extension $state.wac -ExtensionId $extension.Id -Verbose | Out-File -Append -FilePath $logFile -Force
|
||||
}
|
||||
|
||||
# Delete log files older than 30 days
|
||||
Get-ChildItem -Path "C:\Users\Public\WACUpdateLog*" -Recurse -Include @("*.log") | Where-Object { $_.CreationTime -lt (Get-Date).AddDays(-30)} | Remove-Item
|
||||
}
|
||||
DependsOn = "[Script]Fake reboot"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
$date = get-date -f yyyy-MM-dd
|
||||
$logFile = Join-Path -Path "C:\temp" -ChildPath $('WindowsAdminCenter-Transcipt-' + $date + '.log')
|
||||
$DscConfigLocation = "c:\temp\WindowsAdminCenter"
|
||||
|
||||
Start-Transcript -Path $logFile
|
||||
|
||||
Remove-DscConfigurationDocument -Stage Current, Previous, Pending -Force
|
||||
|
||||
WindowsAdminCenter -OutputPath $DscConfigLocation
|
||||
|
||||
Set-DscLocalConfigurationManager -Path $DscConfigLocation -Verbose
|
||||
|
||||
Start-DscConfiguration -Path $DscConfigLocation -Wait -Verbose
|
||||
|
||||
Start-DscConfiguration -UseExisting -Wait -Verbose -Force
|
||||
|
||||
Stop-Transcript
|
||||
|
||||
Logoff
|
Двоичный файл не отображается.
|
@ -0,0 +1,371 @@
|
|||
function New-BasicUnattendXML
|
||||
{
|
||||
|
||||
[CmdletBinding(DefaultParameterSetName='basic')]
|
||||
|
||||
Param (
|
||||
|
||||
[Parameter(Mandatory=$true, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$true, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$true, ParameterSetName='Join Domain')]
|
||||
[String]$ComputerName,
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$true, ParameterSetName='Join Domain')]
|
||||
[String]$Domain,
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$true, ParameterSetName='Join Domain')]
|
||||
[String]$Username,
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$true, ParameterSetName='Join Domain')]
|
||||
[SecureString]$Password,
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$true, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$true, ParameterSetName='Join Domain')]
|
||||
[SecureString]$LocalAdministratorPassword,
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$true, ParameterSetName='Join Domain')]
|
||||
[String]$JoinDomain,
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='Join Domain')]
|
||||
[validatescript({(([system.net.ipaddress]($_ -split '/' | Select-Object -First 1)).AddressFamily -match 'InterNetwork') -and (0..32 -contains ([int]($_ -split '/' | Select-Object -Last 1) )) })]
|
||||
[String]$IpCidr,
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='Join Domain')]
|
||||
[String]$DefaultGateway,
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='Join Domain')]
|
||||
[String]$DnsServer,
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='Join Domain')]
|
||||
[String]$NicNameForIPandDNSAssignments,
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$true, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$true, ParameterSetName='Join Domain')]
|
||||
[String]$OutputPath,
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='Join Domain')]
|
||||
[Switch]$Force,
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='Join Domain')]
|
||||
[System.Globalization.CultureInfo]$InputLocale = 'en-us',
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='Join Domain')]
|
||||
[System.Globalization.CultureInfo]$SystemLocale = 'en-us',
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='Join Domain')]
|
||||
[System.Globalization.CultureInfo]$UILanguage = 'en-us',
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='Join Domain')]
|
||||
[System.Globalization.CultureInfo]$UserLocale = 'en-us',
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='Join Domain')]
|
||||
[bool]$HideEULAPage = $true,
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='Join Domain')]
|
||||
[ValidateScript({$_ -in (Get-TimeZone -ListAvailable | Select-Object -ExpandProperty standardname)})]
|
||||
[String]$TimeZone = 'GMT Standard Time',
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='Join Domain')]
|
||||
[ValidateRange(0,100)]
|
||||
[int]$AutoLogonCount = 0,
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='Join Domain')]
|
||||
[String]$RegisteredOrganization = 'Azure Stack HCI on Azure VM',
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='Join Domain')]
|
||||
[String]$RegisteredOwner = 'Azure Stack HCI on Azure VM',
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='Join Domain')]
|
||||
[String]$PowerShellScriptFullPath,
|
||||
|
||||
[Parameter(Mandatory=$false, ParameterSetName='print')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='basic')]
|
||||
[Parameter(Mandatory=$false, ParameterSetName='Join Domain')]
|
||||
[Switch]$PrintScreenOnly
|
||||
)
|
||||
|
||||
$localAdministratorCreds = New-Object pscredential -ArgumentList Administrator, $LocalAdministratorPassword
|
||||
$domainAdministratorCreds = New-Object pscredential -ArgumentList $Username, $Password
|
||||
$LocalAdministratorPasswordClearText = $localAdministratorCreds.GetNetworkCredential().password
|
||||
$domainAdministratorPasswordClearText = $domainAdministratorCreds.GetNetworkCredential().password
|
||||
$encodedAdministratorPassword = [System.Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes(('{0}AdministratorPassword' -f $LocalAdministratorPasswordClearText)))
|
||||
|
||||
if ($JoinDomain)
|
||||
{
|
||||
$domainJoinerCreds = New-Object pscredential -ArgumentList Administrator, $LocalAdministratorPassword
|
||||
$domainJoinerPasswordClearText = $domainJoinerCreds.GetNetworkCredential().password
|
||||
$domainJoinXMLString = @"
|
||||
|
||||
<component name="Microsoft-Windows-UnattendedJoin" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<Identification>
|
||||
<Credentials>
|
||||
<Domain>$Domain</Domain>
|
||||
<Password>$domainJoinerPasswordClearText</Password>
|
||||
<Username>$username</Username>
|
||||
</Credentials>
|
||||
<JoinDomain>$joinDomain</JoinDomain>
|
||||
</Identification>
|
||||
</component>
|
||||
"@
|
||||
}
|
||||
else
|
||||
{
|
||||
$domainJoinXMLString = $null
|
||||
}
|
||||
|
||||
$PowerShellStartupCmd = "%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe -NoProfile -ExecutionPolicy Bypass -File $PowerShellScriptFullPath"
|
||||
|
||||
if ($AutoLogonCount -gt 0)
|
||||
{
|
||||
Write-Warning -Message '-AutoLogonCount places the password in plain txt'
|
||||
if ($JoinDomain)
|
||||
{
|
||||
$autoLogonXMLString = @"
|
||||
|
||||
<AutoLogon>
|
||||
<Password>
|
||||
<Value>$domainAdministratorPasswordClearText</Value>
|
||||
</Password>
|
||||
<Domain>$JoinDomain</Domain>
|
||||
<LogonCount>$AutoLogonCount</LogonCount>
|
||||
<Username>$Username</Username>
|
||||
<Enabled>true</Enabled>
|
||||
</AutoLogon>
|
||||
"@
|
||||
}
|
||||
else
|
||||
{
|
||||
$autoLogonXMLString = @"
|
||||
|
||||
<AutoLogon>
|
||||
<Password>
|
||||
<Value>$LocalAdministratorPasswordClearText</Value>
|
||||
</Password>
|
||||
<LogonCount>$AutoLogonCount</LogonCount>
|
||||
<Username>Administrator</Username>
|
||||
<Enabled>true</Enabled>
|
||||
</AutoLogon>
|
||||
"@
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$autoLogonXMLString = $null
|
||||
}
|
||||
if ($IpCidr){
|
||||
$IPAddressXMLString = @"
|
||||
|
||||
<component name="Microsoft-Windows-TCPIP" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<Interfaces>
|
||||
<Interface wcm:action="add">
|
||||
<Identifier>$NicNameForIPandDNSAssignments</Identifier>
|
||||
<UnicastIPAddresses>
|
||||
<IpAddress wcm:action="add" wcm:keyValue="1">$IpCidr</IpAddress>
|
||||
</UnicastIPAddresses>
|
||||
<Routes>
|
||||
<Route wcm:action="add">
|
||||
<Identifier>1</Identifier>
|
||||
<Prefix>0.0.0.0/0</Prefix>
|
||||
<Metric>10</Metric>
|
||||
<NextHopAddress>$DefaultGateway</NextHopAddress>
|
||||
</Route>
|
||||
</Routes>
|
||||
<IPv4Settings>
|
||||
<DhcpEnabled>false</DhcpEnabled>
|
||||
</IPv4Settings>
|
||||
</Interface>
|
||||
</Interfaces>
|
||||
</component>
|
||||
"@
|
||||
}
|
||||
else
|
||||
{
|
||||
$IPAddressXMLString = $null
|
||||
}
|
||||
if ($DnsServer)
|
||||
{
|
||||
$DnsAddressXMLString = @"
|
||||
|
||||
<component name="Microsoft-Windows-DNS-Client" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<Interfaces>
|
||||
<Interface wcm:action="add">
|
||||
<Identifier>$NicNameForIPandDNSAssignments</Identifier>
|
||||
<DNSServerSearchOrder>
|
||||
<IpAddress wcm:action="add" wcm:keyValue="1">$DnsServer</IpAddress>
|
||||
</DNSServerSearchOrder>
|
||||
<EnableAdapterDomainNameRegistration>true</EnableAdapterDomainNameRegistration>
|
||||
<DisableDynamicUpdate>false</DisableDynamicUpdate>
|
||||
</Interface>
|
||||
</Interfaces>
|
||||
</component>
|
||||
"@
|
||||
}
|
||||
else
|
||||
{
|
||||
$DnsAddressXMLString = $null
|
||||
}
|
||||
|
||||
if ($PowerShellScriptFullPath)
|
||||
{
|
||||
$logonScriptXMLString = @"
|
||||
|
||||
<FirstLogonCommands>
|
||||
<SynchronousCommand wcm:action="add">
|
||||
<Description>PowerShell First logon script</Description>
|
||||
<Order>1</Order>
|
||||
<CommandLine>$PowerShellStartupCmd</CommandLine>
|
||||
<RequiresUserInput>false</RequiresUserInput>
|
||||
</SynchronousCommand>
|
||||
</FirstLogonCommands>
|
||||
"@
|
||||
}
|
||||
else
|
||||
{
|
||||
$logonScriptXMLString = $null
|
||||
}
|
||||
|
||||
$unattend = @"
|
||||
|
||||
<unattend xmlns="urn:schemas-microsoft-com:unattend">
|
||||
<settings pass="specialize">
|
||||
<component name="Microsoft-Windows-Deployment" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
</component>
|
||||
<component name="Microsoft-Windows-Deployment" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
</component>
|
||||
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<ComputerName>$computerName</ComputerName>
|
||||
</component>
|
||||
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<ComputerName>$computerName</ComputerName>
|
||||
</component>$IPAddressXMLString$DnsAddressXMLString$domainJoinXMLString
|
||||
</settings>
|
||||
<settings pass="oobeSystem">
|
||||
<component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<InputLocale>$InputLocale</InputLocale>
|
||||
<SystemLocale>$SystemLocale</SystemLocale>
|
||||
<UILanguage>$UILanguage</UILanguage>
|
||||
<UserLocale>$UserLocale</UserLocale>
|
||||
</component>
|
||||
<component name="Microsoft-Windows-International-Core" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<InputLocale>$InputLocale</InputLocale>
|
||||
<SystemLocale>$SystemLocale</SystemLocale>
|
||||
<UILanguage>$UILanguage</UILanguage>
|
||||
<UserLocale>$UserLocale</UserLocale>
|
||||
</component>
|
||||
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<OOBE>
|
||||
<HideEULAPage>$HideEULAPage</HideEULAPage>
|
||||
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
|
||||
<NetworkLocation>Work</NetworkLocation>
|
||||
<ProtectYourPC>1</ProtectYourPC>
|
||||
<SkipUserOOBE>true</SkipUserOOBE>
|
||||
<SkipMachineOOBE>true</SkipMachineOOBE>
|
||||
</OOBE>
|
||||
<TimeZone>$TimeZone</TimeZone>
|
||||
<UserAccounts>
|
||||
<AdministratorPassword>
|
||||
<Value>$encodedAdministratorPassword</Value>
|
||||
<PlainText>false</PlainText>
|
||||
</AdministratorPassword>
|
||||
</UserAccounts>
|
||||
<RegisteredOrganization>$RegisteredOrganization</RegisteredOrganization>
|
||||
<RegisteredOwner>$RegisteredOrganization</RegisteredOwner>$autoLogonXMLString$logonScriptXMLString
|
||||
</component>
|
||||
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="x86" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||
<OOBE>
|
||||
<HideEULAPage>$HideEULAPage</HideEULAPage>
|
||||
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
|
||||
<NetworkLocation>Work</NetworkLocation>
|
||||
<ProtectYourPC>1</ProtectYourPC>
|
||||
<SkipUserOOBE>true</SkipUserOOBE>
|
||||
<SkipMachineOOBE>true</SkipMachineOOBE>
|
||||
</OOBE>
|
||||
<TimeZone>$TimeZone</TimeZone>
|
||||
<UserAccounts>
|
||||
<AdministratorPassword>
|
||||
<Value>$encodedAdministratorPassword</Value>
|
||||
<PlainText>false</PlainText>
|
||||
</AdministratorPassword>
|
||||
</UserAccounts>
|
||||
<RegisteredOrganization>$RegisteredOrganization</RegisteredOrganization>
|
||||
<RegisteredOwner>$RegisteredOrganization</RegisteredOwner>$autoLogonXMLString$logonScriptXMLString
|
||||
</component>
|
||||
</settings>
|
||||
</unattend>
|
||||
"@
|
||||
|
||||
|
||||
try
|
||||
{
|
||||
$path = Resolve-Path -Path $OutputPath -ErrorAction Stop
|
||||
$file = (Join-Path -Path $path -ChildPath 'Unattend.xml')
|
||||
|
||||
$fileExist = Test-Path -Path $file
|
||||
if ($fileExist -and $Force)
|
||||
{
|
||||
Write-Verbose -Message "Overwriting $file, Force switch was enabled."
|
||||
$confirm = $false
|
||||
$operation = 'Overridden'
|
||||
}
|
||||
elseif ($fileExist)
|
||||
{
|
||||
Write-Verbose -Message "$file deletion will be prompted."
|
||||
$confirm = $true
|
||||
$operation = 'Overridden'
|
||||
}
|
||||
else
|
||||
{
|
||||
Write-Verbose -Message "Creating Unattend.xml file in $OutputPath"
|
||||
$confirm = $false
|
||||
$operation = 'created'
|
||||
}
|
||||
if ($PrintScreenOnly)
|
||||
{
|
||||
return $unattend
|
||||
}
|
||||
Remove-Item -Path $file -Confirm:$confirm -ErrorAction SilentlyContinue
|
||||
Set-Content -Path $file -Value $unattend
|
||||
Write-Output "File $($operation): $file"
|
||||
}
|
||||
finally
|
||||
{
|
||||
Remove-Variable -Name unattend, LocalAdministratorPasswordClearText, encodedAdministratorPassword, domainJoinerPasswordClearText -ErrorAction SilentlyContinue
|
||||
}
|
||||
|
||||
}
|
||||
Export-ModuleMember -Function New-BasicUnattendXML
|
|
@ -0,0 +1,212 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"location": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Location for all resources."
|
||||
}
|
||||
},
|
||||
"virtualMachineName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Virtual machine name."
|
||||
}
|
||||
},
|
||||
"autoShutdown": {
|
||||
"type": "string",
|
||||
"defaultValue": "Enabled",
|
||||
"allowedValues": [
|
||||
"Enabled",
|
||||
"Disabled"
|
||||
],
|
||||
"metadata": {
|
||||
"description": "Configure Auto shutdown state"
|
||||
}
|
||||
},
|
||||
"autoShutdownTime": {
|
||||
"type": "string",
|
||||
"defaultValue": "0200",
|
||||
"minLength": 4,
|
||||
"maxLength": 4,
|
||||
"metadata": {
|
||||
"description": "The time at which VMs will be automatically shutdown (24h HHmm format)."
|
||||
}
|
||||
},
|
||||
"autoShutdownTimeZone": {
|
||||
"type": "string",
|
||||
"defaultValue": "UTC",
|
||||
"allowedValues": [
|
||||
"Dateline Standard Time",
|
||||
"UTC-11",
|
||||
"Aleutian Standard Time",
|
||||
"Hawaiian Standard Time",
|
||||
"Marquesas Standard Time",
|
||||
"Alaskan Standard Time",
|
||||
"UTC-09",
|
||||
"Pacific Standard Time (Mexico)",
|
||||
"UTC-08",
|
||||
"Pacific Standard Time",
|
||||
"US Mountain Standard Time",
|
||||
"Mountain Standard Time (Mexico)",
|
||||
"Mountain Standard Time",
|
||||
"Central America Standard Time",
|
||||
"Central Standard Time",
|
||||
"Easter Island Standard Time",
|
||||
"Central Standard Time (Mexico)",
|
||||
"Canada Central Standard Time",
|
||||
"SA Pacific Standard Time",
|
||||
"Eastern Standard Time (Mexico)",
|
||||
"Eastern Standard Time",
|
||||
"Haiti Standard Time",
|
||||
"Cuba Standard Time",
|
||||
"US Eastern Standard Time",
|
||||
"Turks And Caicos Standard Time",
|
||||
"Paraguay Standard Time",
|
||||
"Atlantic Standard Time",
|
||||
"Venezuela Standard Time",
|
||||
"Central Brazilian Standard Time",
|
||||
"SA Western Standard Time",
|
||||
"Pacific SA Standard Time",
|
||||
"Newfoundland Standard Time",
|
||||
"Tocantins Standard Time",
|
||||
"E. South America Standard Time",
|
||||
"SA Eastern Standard Time",
|
||||
"Argentina Standard Time",
|
||||
"Greenland Standard Time",
|
||||
"Montevideo Standard Time",
|
||||
"Magallanes Standard Time",
|
||||
"Saint Pierre Standard Time",
|
||||
"Bahia Standard Time",
|
||||
"UTC-02",
|
||||
"Mid-Atlantic Standard Time",
|
||||
"Azores Standard Time",
|
||||
"Cape Verde Standard Time",
|
||||
"UTC",
|
||||
"GMT Standard Time",
|
||||
"Greenwich Standard Time",
|
||||
"Sao Tome Standard Time",
|
||||
"Morocco Standard Time",
|
||||
"W. Europe Standard Time",
|
||||
"Central Europe Standard Time",
|
||||
"Romance Standard Time",
|
||||
"Central European Standard Time",
|
||||
"W. Central Africa Standard Time",
|
||||
"Jordan Standard Time",
|
||||
"GTB Standard Time",
|
||||
"Middle East Standard Time",
|
||||
"Egypt Standard Time",
|
||||
"E. Europe Standard Time",
|
||||
"Syria Standard Time",
|
||||
"West Bank Standard Time",
|
||||
"South Africa Standard Time",
|
||||
"FLE Standard Time",
|
||||
"Israel Standard Time",
|
||||
"Kaliningrad Standard Time",
|
||||
"Sudan Standard Time",
|
||||
"Libya Standard Time",
|
||||
"Namibia Standard Time",
|
||||
"Arabic Standard Time",
|
||||
"Turkey Standard Time",
|
||||
"Arab Standard Time",
|
||||
"Belarus Standard Time",
|
||||
"Russian Standard Time",
|
||||
"E. Africa Standard Time",
|
||||
"Iran Standard Time",
|
||||
"Arabian Standard Time",
|
||||
"Astrakhan Standard Time",
|
||||
"Azerbaijan Standard Time",
|
||||
"Russia Time Zone 3",
|
||||
"Mauritius Standard Time",
|
||||
"Saratov Standard Time",
|
||||
"Georgian Standard Time",
|
||||
"Volgograd Standard Time",
|
||||
"Caucasus Standard Time",
|
||||
"Afghanistan Standard Time",
|
||||
"West Asia Standard Time",
|
||||
"Ekaterinburg Standard Time",
|
||||
"Pakistan Standard Time",
|
||||
"Qyzylorda Standard Time",
|
||||
"India Standard Time",
|
||||
"Sri Lanka Standard Time",
|
||||
"Nepal Standard Time",
|
||||
"Central Asia Standard Time",
|
||||
"Bangladesh Standard Time",
|
||||
"Omsk Standard Time",
|
||||
"Myanmar Standard Time",
|
||||
"SE Asia Standard Time",
|
||||
"Altai Standard Time",
|
||||
"W. Mongolia Standard Time",
|
||||
"North Asia Standard Time",
|
||||
"N. Central Asia Standard Time",
|
||||
"Tomsk Standard Time",
|
||||
"China Standard Time",
|
||||
"North Asia East Standard Time",
|
||||
"Singapore Standard Time",
|
||||
"W. Australia Standard Time",
|
||||
"Taipei Standard Time",
|
||||
"Ulaanbaatar Standard Time",
|
||||
"Aus Central W. Standard Time",
|
||||
"Transbaikal Standard Time",
|
||||
"Tokyo Standard Time",
|
||||
"North Korea Standard Time",
|
||||
"Korea Standard Time",
|
||||
"Yakutsk Standard Time",
|
||||
"Cen. Australia Standard Time",
|
||||
"AUS Central Standard Time",
|
||||
"E. Australia Standard Time",
|
||||
"AUS Eastern Standard Time",
|
||||
"West Pacific Standard Time",
|
||||
"Tasmania Standard Time",
|
||||
"Vladivostok Standard Time",
|
||||
"Lord Howe Standard Time",
|
||||
"Bougainville Standard Time",
|
||||
"Russia Time Zone 10",
|
||||
"Magadan Standard Time",
|
||||
"Norfolk Standard Time",
|
||||
"Sakhalin Standard Time",
|
||||
"Central Pacific Standard Time",
|
||||
"Russia Time Zone 11",
|
||||
"New Zealand Standard Time",
|
||||
"UTC+12",
|
||||
"Fiji Standard Time",
|
||||
"Kamchatka Standard Time",
|
||||
"Chatham Islands Standard Time",
|
||||
"UTC+13",
|
||||
"Tonga Standard Time",
|
||||
"Samoa Standard Time",
|
||||
"Line Islands Standard Time"
|
||||
],
|
||||
"minLength": 2,
|
||||
"metadata": {
|
||||
"description": "Time zone of the virtual machines. Type \"[TimeZoneInfo]::GetSystemTimeZones().Id\" in PowerShell to get the list."
|
||||
}
|
||||
}
|
||||
},
|
||||
"functions": [],
|
||||
"variables": {},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.DevTestLab/schedules",
|
||||
"apiVersion": "2018-09-15",
|
||||
"location": "[parameters('location')]",
|
||||
"name": "[concat('shutdown-computevm-', parameters('virtualMachineName'))]",
|
||||
"properties": {
|
||||
"status": "[parameters('autoShutdown')]",
|
||||
"taskType": "ComputeVmShutdownTask",
|
||||
"dailyRecurrence": {
|
||||
"time": "[parameters('autoShutdownTime')]"
|
||||
},
|
||||
"timeZoneId": "[parameters('autoShutdownTimeZone')]",
|
||||
"notificationSettings": {
|
||||
"status": "Disabled",
|
||||
"timeInMinutes": 30,
|
||||
"notificationLocale": "en"
|
||||
},
|
||||
"targetResourceId": "[resourceId('Microsoft.Compute/virtualMachines', parameters('virtualMachineName'))]"
|
||||
}
|
||||
}
|
||||
],
|
||||
"outputs": {}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentParameters.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"location":{
|
||||
"value": "germanywestcentral"
|
||||
},
|
||||
"virtualMachineName": {
|
||||
"value": "dcVM"
|
||||
},
|
||||
"autoShutdown": {
|
||||
"value": "Enabled"
|
||||
},
|
||||
"autoShutdownTime": {
|
||||
"value": "0100"
|
||||
},
|
||||
"autoShutdownTimeZone": {
|
||||
"value": "UTC"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,68 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"virtualNetworkName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The name of the Virtual Network to Create"
|
||||
}
|
||||
},
|
||||
"virtualNetworkAddressRange": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The address range of the new VNET in CIDR format"
|
||||
}
|
||||
},
|
||||
"subnetName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The name of the subnet created in the new VNET"
|
||||
}
|
||||
},
|
||||
"subnetRange": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The address range of the subnet created in the new VNET"
|
||||
}
|
||||
},
|
||||
"DNSServerAddress": {
|
||||
"type": "array",
|
||||
"metadata": {
|
||||
"description": "The DNS address(es) of the DNS Server(s) used by the VNET"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Location for all resources."
|
||||
}
|
||||
}
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Network/virtualNetworks",
|
||||
"name": "[parameters('virtualNetworkName')]",
|
||||
"apiVersion": "2020-05-01",
|
||||
"location": "[parameters('location')]",
|
||||
"properties": {
|
||||
"addressSpace": {
|
||||
"addressPrefixes": [
|
||||
"[parameters('virtualNetworkAddressRange')]"
|
||||
]
|
||||
},
|
||||
"dhcpOptions": {
|
||||
"dnsServers": "[parameters('DNSServerAddress')]"
|
||||
},
|
||||
"subnets": [
|
||||
{
|
||||
"name": "[parameters('subnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "[parameters('subnetRange')]"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
{
|
||||
"$schema": "https://schema.management.azure.com/schemas/2019-04-01/deploymentTemplate.json#",
|
||||
"contentVersion": "1.0.0.0",
|
||||
"parameters": {
|
||||
"virtualNetworkName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The name of the Virtual Network to Create"
|
||||
}
|
||||
},
|
||||
"virtualNetworkAddressRange": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The address range of the new VNET in CIDR format"
|
||||
}
|
||||
},
|
||||
"subnetName": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The name of the subnet created in the new VNET"
|
||||
}
|
||||
},
|
||||
"subnetRange": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "The address range of the subnet created in the new VNET"
|
||||
}
|
||||
},
|
||||
"location": {
|
||||
"type": "string",
|
||||
"metadata": {
|
||||
"description": "Location for all resources."
|
||||
}
|
||||
}
|
||||
},
|
||||
"resources": [
|
||||
{
|
||||
"type": "Microsoft.Network/virtualNetworks",
|
||||
"name": "[parameters('virtualNetworkName')]",
|
||||
"apiVersion": "2020-05-01",
|
||||
"location": "[parameters('location')]",
|
||||
"properties": {
|
||||
"addressSpace": {
|
||||
"addressPrefixes": [
|
||||
"[parameters('virtualNetworkAddressRange')]"
|
||||
]
|
||||
},
|
||||
"subnets": [
|
||||
{
|
||||
"name": "[parameters('subnetName')]",
|
||||
"properties": {
|
||||
"addressPrefix": "[parameters('subnetRange')]"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,77 @@
|
|||
# Aks Hci on Azure VM project
|
||||
|
||||
This repository is designed to simplify Aks Hci demos in mind for people who are developers without domain knowledge or IT-Pros without Virtualization knowledge. There are two options to utilize the ARM template;
|
||||
|
||||
## Aks Hci on Azure VM
|
||||
|
||||
Only Windows Admin Center VM will be created once ARM template successfully deployed. Windows Admin center or PowerShell scripts (available to the desktop) may be utilized for completing Aks Hci deployment on top of Azure VM in couple of minutes.
|
||||
|
||||
### **Architecture of the deployment** (Aks Hci on Azure VM)
|
||||
|
||||
![AksHciOnAzureStackHci](./.images/AksHcionAzureVM.png)
|
||||
|
||||
## Aks Hci on Azure Stack HCI cluster
|
||||
|
||||
Azure Stack HCI host and Windows Admin Center VMs will be created once ARM template successfully deployed. Windows Admin center or PowerShell scripts (available to the desktop) may be utilized for completing Azure Stack HCI deployment in couple of minutes. Afterwards Aks Hci may be deployed on top of Azure Stack HCI clusters using provided scripts (available to the desktop).
|
||||
|
||||
**Note**: Due to nature of multiple layers of Nested virtualization, there are performance implications. However this is implemented to practice bits and pieces of the whole deployment to experience Aks Hci on top of Azure Stack HCI.
|
||||
|
||||
### **Architecture of the deployment** (Aks Hci on Azure Stack HCI cluster)
|
||||
|
||||
![AksHciOnAzureStackHci](./.images/AksHciOnAzureStackHci.png)
|
||||
|
||||
## Using ARM template to deploy Azure VM
|
||||
|
||||
Click the button below to deploy from the portal:
|
||||
|
||||
[![Deploy to Azure](https://aka.ms/deploytoazurebutton)](https://portal.azure.com/#create/Microsoft.Template/uri/https%3A%2F%2Fraw.githubusercontent.com%2Fyagmurs%2FAzureStackHCIonAzure%2Ftest%2Fazuredeploy.json)
|
||||
|
||||
[![Visualize](https://raw.githubusercontent.com/Azure/azure-quickstart-templates/master/1-CONTRIBUTION-GUIDE/images/visualizebutton.svg?sanitize=true)](http://armviz.io/#/?load=https%3A%2F%2Fraw.githubusercontent.com%2Fyagmurs%2FAzureStackHCIonAzure%2Ftest%2Fazuredeploy.json)
|
||||
|
||||
### High level deployment process and features
|
||||
|
||||
Deploy the ARM template (above buttons) by providing all the parameters required. Find details of **Aks Hci Scenario** options below. Most of the parameters have default values and sufficient for demostrate Aks Hci features and deployment procedures.
|
||||
During the ARM template deployment Azure VM DSC will create Windows Admin Center VM than Chocolatey which means will be updated once released in Chocolatey repository. All installed extensions are getting updated daily in the background.
|
||||
|
||||
Note that all VMs deployed within the Azure VM use **same password** that has been specified in the ARM template.
|
||||
|
||||
* Azure VM will be configured as Domain Controller, DHCP, DNS and Hyper-v host.
|
||||
* All Local accounts are named as **Administrator**.
|
||||
* The **Domain Administrator** username is the **Username specified in the ARM template**.
|
||||
|
||||
### Deployment Scenarios
|
||||
|
||||
#### **Aks Hci on Azure VM**
|
||||
|
||||
This is one of scenario if you are willing to understand how to deploy Aks Hci and understand options.
|
||||
|
||||
![ARM-akshcionAzureVM](./.images/ARM-akshcionAzureVM.png)
|
||||
|
||||
**Note**: Once **'onAzureVMDirectly'** option selected for **'Aks Hci Scenario'** the following two option will be disregarded in the DSC configuration. As a result on WAC (Windows Admin Center) VM will be deployed.
|
||||
|
||||
#### **Aks Hci on Azure Stack HCI cluster**
|
||||
|
||||
This is one of scenario if you are willing to understand how to deploy Aks Hci on Azure Stack HCI and understand options. This is also useful scenarion to test Azure Stack HCI only without deploying Aks Hci on top of Azure Stack Hci Cluster.
|
||||
|
||||
![ARM-akshcionAzureStackHCICluster](./.images/ARM-akshcionAzureStackHCICluster.png)
|
||||
|
||||
**Note**: Once **'onNestedAzureStackHciClusteronAzureVM'** option selected for **'Aks Hci Scenario'** Make sure the correlation between the deployment VM size and Azure Stack HCI host counts and Memory sizes are compatible. As a result a number of Azure Stack HCI VMs (specified in 'AzS Hci Host Count' with 'AzS Hci Host Memory') and WAC (Windows Admin Center) VM will be deployed on Azure VM.
|
||||
|
||||
## How to run PoC once Azure VM deployed
|
||||
|
||||
There are couple of shortcuts available on the desktop; can be utilized to demostraion or learning purposes to understand process and options
|
||||
|
||||
* Proof of concepts guide (which is this guide)
|
||||
* Step by step lab Script, the script includes;
|
||||
* Deployment of Azure Stack HCI cluster through a wizard. (Depends on the scenario selected)
|
||||
* Tools and prerequisites installations
|
||||
* Management and Target Aks clusters deployment
|
||||
* Azure Arc onboarding process
|
||||
* Enable Azure Arc montioring
|
||||
* Deploy demo application to Kubernetes cluster onboarded to Azure Arc
|
||||
* Scale up kubernetes cluster
|
||||
* Deployment of an older version of Kubernetes cluster than updating the cluster to newer version
|
||||
* Uninstall onboarding from Azure Arc
|
||||
* Destroy kubernetes cluster
|
||||
* Remove Aks Hci deployment
|
||||
|
|
@ -0,0 +1,248 @@
|
|||
#https://docs.microsoft.com/en-us/azure-stack/aks-hci/setup-powershell
|
||||
|
||||
#the following function downloads, extract and place required PowerShell Modules in PowerShell modules folder
|
||||
Prepare-AzureVMforAksHciDeployment
|
||||
|
||||
# variables used in the script, update them accordingly based on your environment before proceed further
|
||||
$targetDrive = "V:"
|
||||
$AksHciTargetFolder = "AksHCIMain"
|
||||
$AksHciTargetPath = "$targetDrive\$AksHciTargetFolder"
|
||||
$sourcePath = "$targetDrive\source"
|
||||
$targetClusterName = "target-cls1"
|
||||
$tenant = "xxxxxxxxxxx.onmicrosoft.com"
|
||||
$subscriptionID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
$rgName = "new-arc-rg"
|
||||
$location = "westeurope"
|
||||
|
||||
break
|
||||
|
||||
#region pre-requisites
|
||||
# Install Az modules to access Azure and Azure Arc Kubernetes resources
|
||||
Install-Module az
|
||||
Install-Module Az.ConnectedKubernetes
|
||||
|
||||
# Install Chocolatey if not installed already
|
||||
Set-ExecutionPolicy Bypass -Scope Process -Force
|
||||
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
|
||||
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
|
||||
|
||||
# supress choco installation prompt
|
||||
choco feature enable -n allowGlobalConfirmation --verbose
|
||||
|
||||
# Install Azure Cli using Chocolatey
|
||||
choco install azure-cli --verbose
|
||||
|
||||
# Install latest Helm using Chocolatey
|
||||
choco install kubernetes-helm --verbose
|
||||
|
||||
#update environment variable values after Azure Cli and Helm installation
|
||||
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine")
|
||||
|
||||
# Add and update Az Cli k8sconfiguration and connectedk8s extensions
|
||||
# https://docs.microsoft.com/en-us/azure/azure-arc/kubernetes/connect-cluster
|
||||
az extension add --name connectedk8s
|
||||
az extension add --name k8sconfiguration
|
||||
|
||||
# check if update available for extensions
|
||||
az extension update --name connectedk8s
|
||||
az extension update --name k8sconfiguration
|
||||
|
||||
#endregion pre-requisites
|
||||
|
||||
break
|
||||
|
||||
#region Enable AksHCI
|
||||
|
||||
#Deploy Management Cluster
|
||||
# https://docs.microsoft.com/en-us/azure-stack/aks-hci/create-kubernetes-cluster-powershell
|
||||
Import-Module AksHci
|
||||
Initialize-AksHciNode
|
||||
|
||||
$managementClusterParams = @{
|
||||
imageDir = "$AksHciTargetPath\Images"
|
||||
cloudConfigLocation = "$AksHciTargetPath\Config"
|
||||
workingDir = "$AksHciTargetPath\Working"
|
||||
vnetName = 'Default Switch'
|
||||
controlPlaneVmSize = 'default' # Get-AksHciVmSize
|
||||
loadBalancerVmSize = 'default' # Get-AksHciVmSize
|
||||
vnetType = 'ICS'
|
||||
}
|
||||
|
||||
Set-AksHciConfig @managementClusterParams
|
||||
|
||||
|
||||
Install-AksHci
|
||||
|
||||
#Deploy Target Cluster
|
||||
$targetClusterParams = @{
|
||||
clusterName = $targetClusterName
|
||||
kubernetesVersion = 'v1.18.8'
|
||||
controlPlaneNodeCount = 1
|
||||
linuxNodeCount = 1
|
||||
windowsNodeCount = 0
|
||||
controlPlaneVmSize = 'default' # Get-AksHciVmSize
|
||||
loadBalancerVmSize = 'default' # Get-AksHciVmSize
|
||||
linuxNodeVmSize = 'Standard_D4s_v3' # Get-AksHciVmSize
|
||||
windowsNodeVmSize = 'default' # Get-AksHciVmSize
|
||||
}
|
||||
|
||||
New-AksHciCluster @targetClusterParams
|
||||
|
||||
|
||||
#endregion Enable AksHCI
|
||||
|
||||
#region deploy and upgrade kubernetes cluster
|
||||
# https://docs.microsoft.com/en-us/azure-stack/aks-hci/create-kubernetes-cluster-powershell#step-3-upgrade-kubernetes-version
|
||||
|
||||
$demoClusterParams = @{
|
||||
clusterName = 'update-demo'
|
||||
kubernetesVersion = 'v1.16.10' # v1.16.15, v1.17.11, v1.18.8
|
||||
controlPlaneNodeCount = 1
|
||||
linuxNodeCount = 1
|
||||
windowsNodeCount = 0
|
||||
controlPlaneVmSize = 'default' # Get-AksHciSize
|
||||
loadBalancerVmSize = 'default' # Get-AksHciSize
|
||||
linuxNodeVmSize = 'default' # Get-AksHciSize
|
||||
windowsNodeVmSize = 'default' # Get-AksHciSize
|
||||
}
|
||||
|
||||
New-AksHciCluster @demoClusterParams
|
||||
|
||||
#List k8s clusters
|
||||
Get-AksHciCluster -clusterName update-demo
|
||||
|
||||
# scale up controller node count
|
||||
Set-AksHciClusterNodeCount -clusterName update-demo -controlPlaneNodeCount 3
|
||||
|
||||
# run update patch (1.16.x --> 1.16.y)
|
||||
Update-AksHciCluster -clusterName update-demo -patch
|
||||
|
||||
# run update without patching (1.16.x --> 1.17.y)
|
||||
Update-AksHciCluster -clusterName update-demo
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
break
|
||||
|
||||
#list Aks Hci cmdlets
|
||||
Get-Command -Module AksHci
|
||||
|
||||
#List k8s clusters
|
||||
Get-AksHciCluster
|
||||
|
||||
#Retreive AksHCI logs for Target Cluster deployment
|
||||
Get-AksHciCredential -clusterName $targetClusterName
|
||||
|
||||
#region onboarding
|
||||
|
||||
# login Azure
|
||||
Connect-AzAccount -Tenant $tenant
|
||||
|
||||
# Get current Azure context
|
||||
Get-AzContext
|
||||
|
||||
# list subscriptions
|
||||
Get-AzSubscription
|
||||
|
||||
# select subscription
|
||||
Select-AzSubscription -Subscription $subscriptionID
|
||||
|
||||
# Verify using correct subscription
|
||||
Get-AzContext
|
||||
$context = Get-AzContext
|
||||
|
||||
# Create new resource group to onboard Aks Hci to Azure Arc
|
||||
$rg = New-AzResourceGroup -Name $rgName -Location $location
|
||||
|
||||
#https://docs.microsoft.com/en-us/powershell/module/az.resources/new-azadserviceprincipal?view=azps-5.4.0
|
||||
# Create new Spn on azure and assing them contributor access on the Resource Group
|
||||
$sp = New-AzADServicePrincipal -Role Contributor -Scope "/subscriptions/$subscriptionID/resourceGroups/$($rg.ResourceGroupName)"
|
||||
[pscredential]$credObject = New-Object System.Management.Automation.PSCredential ($sp.ApplicationId, $sp.Secret)
|
||||
|
||||
#https://docs.microsoft.com/en-us/azure-stack/aks-hci/connect-to-arc
|
||||
# Onboard Aks Hci to Azure Arc using Powershell
|
||||
Install-AksHciArcOnboarding -clusterName $targetClusterName -resourcegroup $rg.ResourceGroupName -location $rg.location -subscriptionId $context.Subscription.Id -clientid $sp.ApplicationId -clientsecret $credObject.GetNetworkCredential().Password -tenantid $context.Tenant.Id
|
||||
|
||||
# get state of the onboarding process
|
||||
kubectl get pods -n azure-arc-onboarding
|
||||
|
||||
# list error information
|
||||
kubectl describe pod -n azure-arc-onboarding azure-arc-onboarding-<Name of the pod>
|
||||
kubectl logs -n azure-arc-onboarding azure-arc-onboarding-<Name of the pod>
|
||||
|
||||
#endregion onboarding
|
||||
|
||||
#region enable monitoring
|
||||
|
||||
# enable monitoring using Powershell
|
||||
# https://docs.microsoft.com/en-us/azure/azure-monitor/insights/container-insights-enable-arc-enabled-clusters
|
||||
Invoke-WebRequest https://aka.ms/enable-monitoring-powershell-script -OutFile enable-monitoring.ps1
|
||||
$azureArcClusterResourceId = "/subscriptions/$subscriptionID/resourceGroups/$($rg.ResourceGroupName)/providers/Microsoft.Kubernetes/connectedClusters/$targetClusterName"
|
||||
$kubeContext = kubectl.exe config current-context
|
||||
$logAnalyticsWorkspaceResourceId = "/subscriptions/$subscriptionID/resourceGroups/$($rg.ResourceGroupName)/providers/microsoft.operationalinsights/workspaces/yagmurslog"
|
||||
.\enable-monitoring.ps1 -clusterResourceId $azureArcClusterResourceId -kubeContext $kubeContext -workspaceResourceId $logAnalyticsWorkspaceResourceId
|
||||
|
||||
#endregion enable monitoring
|
||||
|
||||
#region deploy application
|
||||
|
||||
# the repository can be forked to run advanced scenarios. If you fork the repo please update the repo variable accordingly to be used in the following commands.
|
||||
$gitRepo = "https://github.com/Azure/arc-k8s-demo"
|
||||
|
||||
# deploy demo application from Azure Arc Enabled Kubernetes from Azure portal (UI)
|
||||
<#
|
||||
Go to Azure Portal --> Azure arc target kubernetes cluster --> select gitops and add, provide following information
|
||||
|
||||
Configuration name: cluster-config
|
||||
Operator instance name: cluster-config
|
||||
Operator namespace: cluster-config
|
||||
Repository URL: https://github.com/Azure/arc-k8s-demo.git
|
||||
Operator scope: Cluster
|
||||
add
|
||||
#>
|
||||
|
||||
# deploy demo application on Azure Arc Enabled Kubernetes using Azure Cli
|
||||
# https://docs.microsoft.com/en-us/azure/azure-arc/kubernetes/use-gitops-connected-cluster
|
||||
az login --tenant $tenant
|
||||
az k8sconfiguration create --name "cluster-config" --cluster-name $targetClusterName --resource-group $rg.ResourceGroupName --operator-instance-name "cluster-config" --operator-namespace 'cluster-config' --repository-url $gitRepo --scope "cluster" --cluster-type "connectedClusters" --operator-params "'--git-poll-interval 3s --git-readonly'"
|
||||
|
||||
# list all service config
|
||||
kubectl.exe get services
|
||||
|
||||
# list specific service config for azure vote application
|
||||
kubectl.exe get services azure-vote-front
|
||||
|
||||
#endregion deploy application
|
||||
|
||||
|
||||
#region scale up
|
||||
|
||||
# Scale up/down node count
|
||||
Set-AksHciClusterNodeCount -clusterName $targetClusterName -linuxNodeCount 1 -windowsNodeCount 0
|
||||
|
||||
# scale up azure vote application pod count
|
||||
|
||||
# scale up with devops from github vote application pod count
|
||||
|
||||
# verify scale up
|
||||
|
||||
#endregion
|
||||
|
||||
#region clean up
|
||||
|
||||
# uninstall / remove from Azure Arc
|
||||
Uninstall-AksHciArcOnboarding -clusterName $targetClusterName
|
||||
|
||||
#Retreive AksHCI logs for Target Cluster deployment
|
||||
Get-AksHciLogs
|
||||
|
||||
#List k8s clusters
|
||||
Get-AksHciCluster
|
||||
|
||||
#Remove Target cluster
|
||||
Remove-AksHciCluster -clusterName $targetClusterName
|
||||
|
||||
Uninstall-AksHci
|
||||
|
||||
#endregion
|
|
@ -0,0 +1,275 @@
|
|||
|
||||
Import-Module AzureStackHCIInstallerHelper
|
||||
|
||||
# The following function calls the wizard to setup Azure Stack Hci cluster then prepares hosts for Aks Hci Deployment
|
||||
Start-AksHciPoC -verbose
|
||||
|
||||
#register Azure Stack HCI cluster as Azure Arc resource (pre-requisites to deploy any vm on Azure Stack HCI)
|
||||
# https://docs.microsoft.com/en-us/azure-stack/hci/deploy/register-with-azure
|
||||
|
||||
# variables used in the script, update them accordingly based on your environment before proceed further
|
||||
$tenant = "xxxxxxxxxxx.onmicrosoft.com"
|
||||
$subscriptionID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
$rgName = "new-arc-hci-rg"
|
||||
$location = "westeurope"
|
||||
$hciHostName = "hpv01"
|
||||
$hciClusterName = "hci01"
|
||||
|
||||
Install-Module az
|
||||
Install-Module AzureAD
|
||||
Install-Module -Name Az.StackHCI
|
||||
Connect-AzAccount -Tenant $tenant
|
||||
Select-AzSubscription -Subscription $subscriptionID
|
||||
$rg = New-AzResourceGroup -Name $rgName -Location $location
|
||||
Register-AzStackHCI -SubscriptionId $subscriptionID -ComputerName $hciHostName -ResourceName $hciClusterName -ResourceGroupName $rg.ResourceGroupName -Region $rg.location
|
||||
|
||||
break
|
||||
|
||||
#############################################################
|
||||
# #
|
||||
# Run the following code on one of the Azure Stack HCI host #
|
||||
# #
|
||||
#############################################################
|
||||
|
||||
#Enable AksHCI on Azure Stack HCI cluster
|
||||
# variables used in the script, update them accordingly based on your environment before proceed further
|
||||
$targetDrive = "C:\ClusterStorage"
|
||||
$AksHciTargetFolder = "AksHCIMain"
|
||||
$AksHciTargetPath = "$targetDrive\$AksHciTargetFolder"
|
||||
$sourcePath = "$AksHciTargetPath\source"
|
||||
$targetClusterName = "target-cls1-on-hci" #must be lower case
|
||||
$tenant = "xxxxxxxxxxx.onmicrosoft.com"
|
||||
$subscriptionID = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
|
||||
$rgName = "new-arc-rg"
|
||||
$location = "westeurope"
|
||||
|
||||
break
|
||||
|
||||
#region pre-requisites
|
||||
# Install Az modules to access Azure and Azure Arc Kubernetes resources
|
||||
Install-Module az
|
||||
Install-Module Az.ConnectedKubernetes
|
||||
|
||||
# Install Chocolatey if not installed already
|
||||
Set-ExecutionPolicy Bypass -Scope Process -Force
|
||||
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072
|
||||
Invoke-Expression ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))
|
||||
|
||||
# supress choco installation prompt
|
||||
choco feature enable -n allowGlobalConfirmation
|
||||
|
||||
# Install Azure Cli using Chocolatey
|
||||
choco install azure-cli
|
||||
|
||||
# Install latest Helm using Chocolatey
|
||||
choco install kubernetes-helm
|
||||
|
||||
#update environment variable values after Azure Cli and Helm installation
|
||||
$env:Path = [System.Environment]::GetEnvironmentVariable("Path", "Machine")
|
||||
|
||||
# Add and update Az Cli k8sconfiguration and connectedk8s extensions
|
||||
# https://docs.microsoft.com/en-us/azure/azure-arc/kubernetes/connect-cluster
|
||||
az extension add --name connectedk8s
|
||||
az extension add --name k8sconfiguration
|
||||
|
||||
# check if update available for extensions
|
||||
az extension update --name connectedk8s
|
||||
az extension update --name k8sconfiguration
|
||||
|
||||
#endregion pre-requisites
|
||||
|
||||
break
|
||||
|
||||
#region Enable AksHCI
|
||||
|
||||
#Deploy Management Cluster
|
||||
# https://docs.microsoft.com/en-us/azure-stack/aks-hci/create-kubernetes-cluster-powershell
|
||||
Import-Module AksHci
|
||||
Initialize-AksHciNode
|
||||
|
||||
$managementClusterParams = @{
|
||||
imageDir = "$AksHciTargetPath\Images"
|
||||
cloudConfigLocation = "$AksHciTargetPath\Config"
|
||||
workingDir = "$AksHciTargetPath\Working"
|
||||
vnetName = 'Default Switch'
|
||||
controlPlaneVmSize = 'default' # Get-AksHciVmSize
|
||||
loadBalancerVmSize = 'default' # Get-AksHciVmSize
|
||||
}
|
||||
|
||||
Set-AksHciConfig @managementClusterParams
|
||||
|
||||
Install-AksHci
|
||||
|
||||
#Deploy Target Cluster
|
||||
|
||||
$targetClusterParams = @{
|
||||
clusterName = $targetClusterName
|
||||
kubernetesVersion = 'v1.18.8'
|
||||
controlPlaneNodeCount = 1
|
||||
linuxNodeCount = 1
|
||||
windowsNodeCount = 0
|
||||
controlPlaneVmSize = 'default' # Get-AksHciVmSize
|
||||
loadBalancerVmSize = 'default' # Get-AksHciVmSize
|
||||
linuxNodeVmSize = 'default' # Get-AksHciVmSize
|
||||
windowsNodeVmSize = 'default' # Get-AksHciVmSize
|
||||
}
|
||||
|
||||
New-AksHciCluster @targetClusterParams
|
||||
|
||||
#endregion Enable AksHCI
|
||||
|
||||
#region deploy and upgrade kubernetes cluster
|
||||
# https://docs.microsoft.com/en-us/azure-stack/aks-hci/create-kubernetes-cluster-powershell#step-3-upgrade-kubernetes-version
|
||||
|
||||
$demoClusterParams = @{
|
||||
clusterName = 'update-demo'
|
||||
kubernetesVersion = 'v1.16.10' # v1.16.15, v1.17.11, v1.18.8
|
||||
controlPlaneNodeCount = 1
|
||||
linuxNodeCount = 1
|
||||
windowsNodeCount = 0
|
||||
controlPlaneVmSize = 'default' # Get-AksHciSize
|
||||
loadBalancerVmSize = 'default' # Get-AksHciSize
|
||||
linuxNodeVmSize = 'default' # Get-AksHciSize
|
||||
windowsNodeVmSize = 'default' # Get-AksHciSize
|
||||
}
|
||||
|
||||
New-AksHciCluster @demoClusterParams
|
||||
|
||||
#List k8s clusters
|
||||
Get-AksHciCluster -clusterName update-demo
|
||||
|
||||
# scale up controller node count
|
||||
Set-AksHciClusterNodeCount -clusterName update-demo -controlPlaneNodeCount 3
|
||||
|
||||
# run update patch (1.16.x --> 1.16.y)
|
||||
Update-AksHciCluster -clusterName update-demo -patch
|
||||
|
||||
# run update without patching (1.16.x --> 1.17.y)
|
||||
Update-AksHciCluster -clusterName update-demo
|
||||
|
||||
|
||||
#endregion
|
||||
|
||||
break
|
||||
|
||||
#list Aks Hci cmdlets
|
||||
Get-Command -Module AksHci
|
||||
|
||||
#List k8s clusters
|
||||
Get-AksHciCluster
|
||||
|
||||
#Retreive AksHCI logs for Target Cluster deployment
|
||||
Get-AksHciCredential -clusterName $targetClusterName
|
||||
|
||||
#region onboarding
|
||||
|
||||
# login Azure
|
||||
Connect-AzAccount -Tenant $tenant
|
||||
|
||||
# Get current Azure context
|
||||
Get-AzContext
|
||||
|
||||
# list subscriptions
|
||||
Get-AzSubscription
|
||||
|
||||
# select subscription
|
||||
Select-AzSubscription -Subscription $subscriptionID
|
||||
|
||||
# Verify using correct subscription
|
||||
Get-AzContext
|
||||
$context = Get-AzContext
|
||||
|
||||
# Create new resource group to onboard Aks Hci to Azure Arc
|
||||
$rg = New-AzResourceGroup -Name $rgName -Location $location
|
||||
|
||||
#https://docs.microsoft.com/en-us/powershell/module/az.resources/new-azadserviceprincipal?view=azps-5.4.0
|
||||
# Create new Spn on azure and assing them contributor access on the Resource Group
|
||||
$sp = New-AzADServicePrincipal -Role Contributor -Scope "/subscriptions/$subscriptionID/resourceGroups/$($rg.ResourceGroupName)"
|
||||
[pscredential]$credObject = New-Object System.Management.Automation.PSCredential ($sp.ApplicationId, $sp.Secret)
|
||||
|
||||
#https://docs.microsoft.com/en-us/azure-stack/aks-hci/connect-to-arc
|
||||
# Onboard Aks Hci to Azure Arc using Powershell
|
||||
Install-AksHciArcOnboarding -clusterName $targetClusterName -resourcegroup $rg.ResourceGroupName -location $rg.location -subscriptionId $context.Subscription.Id -clientid $sp.ApplicationId -clientsecret $credObject.GetNetworkCredential().Password -tenantid $context.Tenant.Id
|
||||
|
||||
# get state of the onboarding process
|
||||
kubectl get pods -n azure-arc-onboarding
|
||||
|
||||
# list error information
|
||||
kubectl describe pod -n azure-arc-onboarding azure-arc-onboarding-<Name of the pod>
|
||||
kubectl logs -n azure-arc-onboarding azure-arc-onboarding-<Name of the pod>
|
||||
|
||||
#endregion onboarding
|
||||
|
||||
#region enable monitoring
|
||||
|
||||
# enable monitoring using Powershell
|
||||
# https://docs.microsoft.com/en-us/azure/azure-monitor/insights/container-insights-enable-arc-enabled-clusters
|
||||
Invoke-WebRequest https://aka.ms/enable-monitoring-powershell-script -OutFile enable-monitoring.ps1
|
||||
$azureArcClusterResourceId = "/subscriptions/$subscriptionID/resourceGroups/$($rg.ResourceGroupName)/providers/Microsoft.Kubernetes/connectedClusters/$targetClusterName"
|
||||
$kubeContext = kubectl.exe config current-context
|
||||
$logAnalyticsWorkspaceResourceId = "/subscriptions/$subscriptionID/resourceGroups/$($rg.ResourceGroupName)/providers/microsoft.operationalinsights/workspaces/yagmurslog"
|
||||
.\enable-monitoring.ps1 -clusterResourceId $azureArcClusterResourceId -kubeContext $kubeContext -workspaceResourceId $logAnalyticsWorkspaceResourceId
|
||||
|
||||
#endregion enable monitoring
|
||||
|
||||
#region deploy application
|
||||
|
||||
# the repository can be forked to run advanced scenarios. If you fork the repo please update the repo variable accordingly to be used in the following commands.
|
||||
$gitRepo = "https://github.com/Azure/arc-k8s-demo"
|
||||
|
||||
# deploy demo application from Azure Arc Enabled Kubernetes from Azure portal (UI)
|
||||
<#
|
||||
Go to Azure Portal --> Azure arc target kubernetes cluster --> select gitops and add, provide following information
|
||||
|
||||
Configuration name: cluster-config
|
||||
Operator instance name: cluster-config
|
||||
Operator namespace: cluster-config
|
||||
Repository URL: https://github.com/Azure/arc-k8s-demo.git
|
||||
Operator scope: Cluster
|
||||
add
|
||||
#>
|
||||
|
||||
# deploy demo application on Azure Arc Enabled Kubernetes using Azure Cli
|
||||
# https://docs.microsoft.com/en-us/azure/azure-arc/kubernetes/use-gitops-connected-cluster
|
||||
az login --tenant $tenant
|
||||
az k8sconfiguration create --name "cluster-config" --cluster-name $targetClusterName --resource-group $rg.ResourceGroupName --operator-instance-name "cluster-config" --operator-namespace 'cluster-config' --repository-url $gitRepo --scope "cluster" --cluster-type "connectedClusters" --operator-params "'--git-poll-interval 3s --git-readonly'"
|
||||
|
||||
# list all service config
|
||||
kubectl.exe get services
|
||||
|
||||
# list specific service config for azure vote application
|
||||
kubectl.exe get services azure-vote-front
|
||||
|
||||
#endregion deploy application
|
||||
|
||||
|
||||
#region scale up
|
||||
|
||||
# Scale up/down node count
|
||||
Set-AksHciClusterNodeCount -clusterName $targetClusterName -linuxNodeCount 1 -windowsNodeCount 0
|
||||
|
||||
# scale up azure vote application pod count
|
||||
|
||||
# scale up with devops from github vote application pod count
|
||||
|
||||
# verify scale up
|
||||
|
||||
#endregion
|
||||
|
||||
#region clean up
|
||||
|
||||
# uninstall / remove from Azure Arc
|
||||
Uninstall-AksHciArcOnboarding -clusterName $targetClusterName
|
||||
|
||||
#Retreive AksHCI logs for Target Cluster deployment
|
||||
Get-AksHciLogs
|
||||
|
||||
#List k8s clusters
|
||||
Get-AksHciCluster
|
||||
|
||||
#Remove Target cluster
|
||||
Remove-AksHciCluster -clusterName $targetClusterName
|
||||
|
||||
Uninstall-AksHci
|
||||
|
||||
#endregion
|
|
@ -0,0 +1,85 @@
|
|||
$rgPrefix = 'yagmurs-azurestack'
|
||||
$location = 'germanywestcentral'
|
||||
$branch = 'test'
|
||||
$subs = Get-Content .\scripts\ignore\subscription.txt
|
||||
if (-not (Get-AzAccessToken))
|
||||
{
|
||||
Connect-AzAccount -UseDeviceAuthentication
|
||||
}
|
||||
|
||||
if (-not ($sub))
|
||||
{
|
||||
$subs | Out-GridView -PassThru | ForEach-Object {$sub = $_}
|
||||
}
|
||||
Write-Verbose -Message "Subscription: $sub will be used" -Verbose
|
||||
|
||||
if ((Get-AzContext | Select-Object -ExpandProperty name) -notlike "$sub*")
|
||||
{
|
||||
Get-AzSubscription | Out-GridView -PassThru | Select-AzSubscription
|
||||
}
|
||||
|
||||
$paramUri = "https://raw.githubusercontent.com/yagmurs/AzureStackHCIonAzure/test/azuredeploy.parameters.json"
|
||||
$paramFileAsHash = ((Invoke-WebRequest -UseBasicParsing -Uri $paramUri).content | ConvertFrom-Json -AsHashtable)
|
||||
if (-not ($clearTextPassword))
|
||||
{
|
||||
$clearTextPassword = Read-Host -Prompt "Enter password for the VM" -MaskInput
|
||||
}
|
||||
|
||||
$encryptedPass = $clearTextPassword | ConvertTo-SecureString -AsPlainText -Force
|
||||
$templateParameterObject = @{}
|
||||
$paramFileAsHash.parameters.keys | ForEach-Object {$templateParameterObject[$_] = $paramFileAsHash.parameters.$_.value}
|
||||
$templateParameterObject.add("AdminPassword", $encryptedPass)
|
||||
$templateParameterObject.location = $location
|
||||
$templateParameterObject.branch = $branch
|
||||
#$templateParameterObject.aksHciScenario = 'onNestedAzureStackHciClusteronAzureVM'
|
||||
#$templateParameterObject
|
||||
|
||||
do {
|
||||
Write-Host "'N'ew or 'D'SC only deployment?" -Nonewline -ForegroundColor DarkYellow -BackgroundColor Blue
|
||||
$dtype = read-host
|
||||
} until ($dtype -eq "N" -or $dtype -eq "D")
|
||||
|
||||
if ($dtype -eq "n")
|
||||
{
|
||||
if ([string]::IsNullOrEmpty($rgPrefix))
|
||||
{
|
||||
Write-Error "`$rgPrefix is empty" -ErrorAction Stop
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
$r = get-random -Minimum 1 -Maximum 3
|
||||
} while (Get-AzResourceGroup -Name "$rgPrefix$r" -ErrorAction SilentlyContinue)
|
||||
|
||||
$rgName = "$rgPrefix$r"
|
||||
|
||||
$rgObject = @($("$rgPrefix" + 0), $("$rgPrefix" + 1), $("$rgPrefix" + 2), $("$rgPrefix" + 3)) | ForEach-Object {Get-AzResourceGroup -Name $_ -ErrorAction SilentlyContinue}
|
||||
|
||||
if ($rgObject)
|
||||
{
|
||||
Write-Verbose -Message "Resource Group: $($rgObject.ResourceGroupName) will be deleted" -Verbose
|
||||
$rgObject | Remove-AzResourceGroup -confirm:$true
|
||||
#$rgObject | Remove-AzResourceGroup -Force -AsJob
|
||||
}
|
||||
|
||||
$templateParameterObject.dnsPrefix = $templateParameterObject.dnsPrefix.Insert($templateParameterObject.dnsPrefix.Length, $r)
|
||||
|
||||
New-AzResourceGroup -Name $rgName -Location $templateParameterObject.location
|
||||
New-AzResourceGroupDeployment -ResourceGroupName $rgName `
|
||||
-Name "azshcihost" -TemplateUri "https://raw.githubusercontent.com/yagmurs/AzureStackHCIonAzure/$branch/azuredeploy.json" `
|
||||
-TemplateParameterObject $templateParameterObject
|
||||
}
|
||||
elseif ($dtype -eq "d")
|
||||
{
|
||||
$rg = (Get-AzResourceGroup -ResourceGroupName $rgPrefix*).ResourceGroupName
|
||||
$r = $rg[-1]
|
||||
Write-Verbose "Removing DSC Extension for VM on $rg Resource Group" -Verbose
|
||||
Get-AzVMExtension -ResourceGroupName $rg -VMName dc01 | Where-Object ExtensionType -eq DSC | Remove-AzVMExtension -Force -Verbose
|
||||
|
||||
$templateParameterObject.dnsPrefix = $templateParameterObject.dnsPrefix.Insert($templateParameterObject.dnsPrefix.Length, $r)
|
||||
|
||||
Write-Verbose "Redeploying ARM template for VM on $rg Resource Group" -Verbose
|
||||
New-AzResourceGroupDeployment -ResourceGroupName $rg `
|
||||
-Name "azshcihost" -TemplateUri "https://raw.githubusercontent.com/yagmurs/AzureStackHCIonAzure/$branch/azuredeploy.json" `
|
||||
-TemplateParameterObject $templateParameterObject -Force -Verbose
|
||||
}
|
Загрузка…
Ссылка в новой задаче