diff --git a/Scenarios/AzSHCI and Cloud Based Deployment/Scenario.ps1 b/Scenarios/AzSHCI and Cloud Based Deployment/Scenario.ps1 index 879af2e3..fbbf0a7d 100644 --- a/Scenarios/AzSHCI and Cloud Based Deployment/Scenario.ps1 +++ b/Scenarios/AzSHCI and Cloud Based Deployment/Scenario.ps1 @@ -284,71 +284,11 @@ Install-Module -Name az.accounts -Force } -Credential $Credentials - #region Create AzADServicePrincipal for Arc Onboarding with custom permissions (jaromirk note: "Microsoft.Authorization/roleAssignments/write" needs to go away, however this is something that will as it's preview) - #Create Azure Stack HCI ARC Onboarding role https://learn.microsoft.com/en-us/azure-stack/hci/deploy/register-with-azure#assign-permissions-from-azure-portal - #https://learn.microsoft.com/en-us/azure/role-based-access-control/built-in-roles#azure-connected-machine-onboarding - if (-not (Get-AzRoleDefinition -Name "Azure Stack HCI ARC Onboarding - Custom" -ErrorAction Ignore)){ - $Content=@" -{ - "Name": "Azure Stack HCI ARC Onboarding - Custom", - "Id": null, - "IsCustom": true, - "Description": "Custom Azure role to allow onboard Azure Stack HCI with azshci.arcinstaller", - "Actions": [ - "Microsoft.HybridCompute/machines/read", - "Microsoft.HybridCompute/machines/write", - "Microsoft.HybridCompute/privateLinkScopes/read", - "Microsoft.GuestConfiguration/guestConfigurationAssignments/read", - "Microsoft.HybridCompute/machines/extensions/write", - "Microsoft.Authorization/roleAssignments/write" - ], - "NotActions": [ - ], - "AssignableScopes": [ - "/subscriptions/$SubscriptionID" - ] - } -"@ - $Content | Out-File "$env:USERPROFILE\Downloads\customHCIRole.json" - New-AzRoleDefinition -InputFile "$env:USERPROFILE\Downloads\customHCIRole.json" - } - - #Create AzADServicePrincipal for Azure Stack HCI registration (if it does not exist) - $SP=Get-AZADServicePrincipal -DisplayName $ServicePrincipalName - if (-not $SP){ - $SP=New-AzADServicePrincipal -DisplayName $ServicePrincipalName -Role "Azure Stack HCI ARC Onboarding - Custom" - #remove default cred - Remove-AzADAppCredential -ApplicationId $SP.AppId - } - - #Create new SPN password - $credential = New-Object -TypeName "Microsoft.Azure.PowerShell.Cmdlets.Resources.MSGraph.Models.ApiV10.MicrosoftGraphPasswordCredential" -Property @{ - "KeyID" = (new-guid).Guid ; - "EndDateTime" = [DateTime]::UtcNow.AddYears(1) - } - $Creds=New-AzADAppCredential -PasswordCredentials $credential -ApplicationID $SP.AppID - $SPNSecret=$Creds.SecretText - $SPAppID=$SP.AppID - $SecuredPassword = ConvertTo-SecureString $SPNSecret -AsPlainText -Force - $SPNCredentials= New-Object System.Management.Automation.PSCredential ($SPAppID,$SecuredPassword) - #endregion - - #deploy ARC Agent (It's failing, cant figure out why) + #deploy ARC Agent with device authentication + $ARMtoken = (Get-AzAccessToken).Token + $id = (Get-AzContext).Account.Id Invoke-Command -ComputerName $Servers -ScriptBlock { - Invoke-AzStackHciArcInitialization -SubscriptionID $using:SubscriptionID -ResourceGroup $using:ResourceGroupName -TenantID $using:TenantID -Cloud $using:Cloud -Region $Using:Location -SpnCredential $Using:SPNCredentials - } -Credential $Credentials - - #let's onboard ARC agent "manually" - Invoke-Command -ComputerName $Servers -ScriptBlock { - $machineName = [System.Net.Dns]::GetHostName() - $SPNCredentials=$using:SPNCredentials - $SPNpassword=$SPNCredentials.GetNetworkCredential().Password - & "$env:ProgramW6432\AzureConnectedMachineAgent\azcmagent.exe" connect --service-principal-id $using:SpnCredentials.UserName --service-principal-secret $SPNpassword --resource-group $using:ResourceGroupName --resource-name "$machineName" --tenant-id $using:TenantID --location $Using:Location --subscription-id $using:SubscriptionID --cloud $using:Cloud - } -Credential $Credentials - - #and let's run deployment again - Invoke-Command -ComputerName $Servers -ScriptBlock { - Invoke-AzStackHciArcInitialization -SubscriptionID $using:SubscriptionID -ResourceGroup $using:ResourceGroupName -TenantID $using:TenantID -Cloud $using:Cloud -Region $Using:Location -SpnCredential $Using:SPNCredentials + Invoke-AzStackHciArcInitialization -SubscriptionID $using:SubscriptionID -ResourceGroup $using:ResourceGroupName -TenantID $using:TenantID -Cloud $using:Cloud -Region $Using:Location -ArmAccessToken $using:ARMtoken -AccountID $using:id } -Credential $Credentials #endregion @@ -495,15 +435,8 @@ #make sure there is only one management NIC with IP address (setup is complaining about multiple gateways) Invoke-Command -ComputerName $servers -ScriptBlock { - $adapter=Get-NetIPConfiguration | Where-Object IPV4defaultGateway | Get-NetAdapter | Sort-Object Name | Select-Object -Skip 1 - #disable netbios (otherwise the apipa might be resolved instead of 10.x address) - $query="select * From Win32_NetworkAdapterConfiguration where Description = `'$($Adapter.Interfacedescription)`'" - $arguments = @{'TcpipNetbiosOptions' = [UInt32](2) } - Invoke-CimMethod -Query $query -Namespace Root/CIMV2 -MethodName SetTcpipNetbios -Arguments $arguments - #disable receiving address from dhcp - $adapter | Set-NetIPInterface -Dhcp Disabled + Get-NetIPConfiguration | Where-Object IPV4defaultGateway | Get-NetAdapter | Sort-Object Name | Select-Object -Skip 1 | Set-NetIPInterface -Dhcp Disabled } -Credential $Credentials - Clear-DnsClientCache #add key vault admin of current user to Resource Group $objectId = (Get-AzADUser -SignedIn).Id @@ -514,7 +447,6 @@ Set-LocalUser -Name Administrator -AccountNeverExpires -Password (ConvertTo-SecureString "LS1setup!LS1setup!" -AsPlainText -Force) } -Credential $Credentials - #endregion #region do the magic in azure portal diff --git a/Scripts/1_Prereq.ps1 b/Scripts/1_Prereq.ps1 index d2276b69..eada06ad 100644 --- a/Scripts/1_Prereq.ps1 +++ b/Scripts/1_Prereq.ps1 @@ -195,7 +195,7 @@ function Get-WindowsBuildNumber { #region Downloading required Posh Modules # Downloading modules into Temp folder if needed. - $modules=("xActiveDirectory","3.0.0.0"),("xDHCpServer","2.0.0.0"),("xDNSServer","1.15.0.0"),("NetworkingDSC","7.4.0.0"),("xPSDesiredStateConfiguration","8.10.0.0") + $modules=("ActiveDirectoryDsc","6.3.0"),("xDHCPServer","3.1.1"),("DnsServerDsc","3.0.0"),("NetworkingDSC","9.0.0"),("xPSDesiredStateConfiguration","9.1.0") foreach ($module in $modules){ WriteInfoHighlighted "Testing if modules are present" $modulename=$module[0] diff --git a/Scripts/2_CreateParentDisks.ps1 b/Scripts/2_CreateParentDisks.ps1 index d37352f0..50436dc5 100644 --- a/Scripts/2_CreateParentDisks.ps1 +++ b/Scripts/2_CreateParentDisks.ps1 @@ -1,12 +1,12 @@ -# Verify Running as Admin +# Verify Running as Admin $isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator") If (-not $isAdmin) { Write-Host "-- Restarting as Administrator" -ForegroundColor Cyan ; Start-Sleep -Seconds 1 if($PSVersionTable.PSEdition -eq "Core") { - Start-Process pwsh.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs + Start-Process pwsh.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs } else { - Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs + Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs } exit @@ -15,7 +15,7 @@ If (-not $isAdmin) { #region Functions . $PSScriptRoot\0_Shared.ps1 # [!build-include-inline] - #Create Unattend for VHD + #Create Unattend for VHD Function CreateUnattendFileVHD{ param ( [parameter(Mandatory=$true)] @@ -72,8 +72,8 @@ If (-not $isAdmin) { true - true - true + true + true $TimeZone @@ -85,7 +85,7 @@ If (-not $isAdmin) { Set-Content -path $unattendFile -value $fileContent #return the file object - Return $unattendFile + Return $unattendFile } #endregion @@ -142,7 +142,7 @@ If (-not $isAdmin) { $LabConfig.DomainName.Split(".") | ForEach-Object { $DN+="DC=$_," } - + $LabConfig.DN=$DN.TrimEnd(",") $AdminPassword=$LabConfig.AdminPassword @@ -158,7 +158,7 @@ If (-not $isAdmin) { #DCHP scope $DHCPscope = $LabConfig.DHCPscope $ReverseDNSrecord = $DHCPscope -replace '^(\d+)\.(\d+)\.\d+\.(\d+)$','$3.$2.$1.in-addr.arpa' - $DHCPscope = $DHCPscope.Substring(0,$DHCPscope.Length-1) + $DHCPscope = $DHCPscope.Substring(0,$DHCPscope.Length-1) #endregion @@ -191,7 +191,7 @@ If (-not $isAdmin) { if(!(Test-Path -Path "$PSScriptRoot\$_")){ WriteErrorAndExit "file $_ needed for SCVMM install not found. Exitting" } - } + } } if ($LabConfig.InstallSCVMM -eq "Prereqs"){ @@ -199,16 +199,16 @@ If (-not $isAdmin) { if(!(Test-Path -Path "$PSScriptRoot\$_")){ WriteErrorAndExit "file $_ needed for SCVMM Prereqs install not found. Exitting" } - } + } } - + if ($LabConfig.InstallSCVMM -eq "SQL"){ "Temp\ToolsVHD\SCVMM\ADK\ADKsetup.exe","Temp\ToolsVHD\SCVMM\SQL\setup.exe" | ForEach-Object { if(!(Test-Path -Path "$PSScriptRoot\$_")){ WriteErrorAndExit "file $_ needed for SQL install not found. Exitting" } } - } + } if ($LabConfig.InstallSCVMM -eq "ADK"){ "Temp\ToolsVHD\SCVMM\ADK\ADKsetup.exe" | ForEach-Object { @@ -221,7 +221,7 @@ If (-not $isAdmin) { #check if parent images already exist (this is useful if you have parent disks from another lab and you want to rebuild for example scvmm) WriteInfoHighlighted "Testing if some parent disk already exists and can be used" - + #grab all files in parentdisks folder $ParentDisksNames=(Get-ChildItem -Path "$PSScriptRoot\ParentDisks" -ErrorAction SilentlyContinue).Name @@ -245,7 +245,7 @@ If (-not $isAdmin) { WriteInfoHighlighted "Checking if volume filesystem is NTFS or ReFS" $driveletter=$PSScriptRoot -split ":" | Select-Object -First 1 if ($PSScriptRoot -like "c:\ClusterStorage*"){ - WriteSuccess "`t Volume Cluster Shared Volume. Mountdir will be $env:Temp\MSLabMountdir" + WriteSuccess "`t Volume Cluster Shared Volume. Mountdir will be $env:Temp\MSLabMountdir" $mountdir="$env:Temp\MSLabMountdir" $VolumeFileSystem="CSVFS" }else{ @@ -279,10 +279,10 @@ If (-not $isAdmin) { $openFile = New-Object System.Windows.Forms.OpenFileDialog -Property @{ Title="Please select ISO image with Windows Server 2016, 2019, 2022 or Server Insider" } - $openFile.Filter = "iso files (*.iso)|*.iso|All files (*.*)|*.*" + $openFile.Filter = "iso files (*.iso)|*.iso|All files (*.*)|*.*" If($openFile.ShowDialog() -eq "OK"){ WriteInfo "File $($openfile.FileName) selected" - } + } if (!$openFile.FileName){ WriteErrorAndExit "Iso was not selected... Exitting" } @@ -332,7 +332,7 @@ If (-not $isAdmin) { Multiselect = $true; Title = "Please select Windows Server Updates (*.msu). Click Cancel if you don't want any." } - $msupackages.Filter = "msu files (*.msu)|*.msu|All files (*.*)|*.*" + $msupackages.Filter = "msu files (*.msu)|*.msu|All files (*.*)|*.*" If($msupackages.ShowDialog() -eq "OK"){ WriteInfoHighlighted "Following patches selected:" WriteInfo "`t $($msupackages.filenames)" @@ -352,13 +352,13 @@ If (-not $isAdmin) { #Windows Server 2016 $ServerVHDs += @{ Kind = "Full" - Edition="4" + Edition="4" VHDName="Win2016_G2.vhdx" Size=127GB } $ServerVHDs += @{ Kind = "Core" - Edition="3" + Edition="3" VHDName="Win2016Core_G2.vhdx" Size=127GB } @@ -374,13 +374,13 @@ If (-not $isAdmin) { #Windows Server 2019 $ServerVHDs += @{ Kind = "Full" - Edition="4" + Edition="4" VHDName="Win2019_G2.vhdx" Size=127GB } $ServerVHDs += @{ Kind = "Core" - Edition="3" + Edition="3" VHDName="Win2019Core_G2.vhdx" Size=127GB } @@ -388,20 +388,20 @@ If (-not $isAdmin) { #Windows Server 2022 $ServerVHDs += @{ Kind = "Full" - Edition="4" + Edition="4" VHDName="Win2022_G2.vhdx" Size=127GB } $ServerVHDs += @{ Kind = "Core" - Edition="3" + Edition="3" VHDName="Win2022Core_G2.vhdx" Size=127GB } }elseif ($BuildNumber -gt 20348 -and $SAC){ $ServerVHDs += @{ Kind = "Core" - Edition="2" + Edition="2" VHDName="WinSrvInsiderCore_$BuildNumber.vhdx" Size=127GB } @@ -413,13 +413,13 @@ If (-not $isAdmin) { #Windows Sever Insider $ServerVHDs += @{ Kind = "Full" - Edition="4" + Edition="4" VHDName="WinSrvInsider_$BuildNumber.vhdx" Size=127GB } $ServerVHDs += @{ Kind = "Core" - Edition="3" + Edition="3" VHDName="WinSrvInsiderCore_$BuildNumber.vhdx" Size=127GB } @@ -450,7 +450,7 @@ If (-not $isAdmin) { 'ParentDisks','Temp','Temp\mountdir' | ForEach-Object { if (!( Test-Path "$PSScriptRoot\$_" )) { WriteInfoHighlighted "Creating Directory $_" - New-Item -Type Directory -Path "$PSScriptRoot\$_" + New-Item -Type Directory -Path "$PSScriptRoot\$_" } } @@ -528,8 +528,8 @@ If (-not $isAdmin) { $toolsVHD=New-VHD -Path "$PSScriptRoot\ParentDisks\tools.vhdx" -SizeBytes 300GB -Dynamic #mount and format VHD $VHDMount = Mount-VHD $toolsVHD.Path -Passthru - $vhddisk = $VHDMount| get-disk - $vhddiskpart = $vhddisk | Initialize-Disk -PartitionStyle GPT -PassThru | New-Partition -UseMaximumSize -AssignDriveLetter |Format-Volume -FileSystem NTFS -AllocationUnitSize 8kb -NewFileSystemLabel ToolsDisk + $vhddisk = $VHDMount| get-disk + $vhddiskpart = $vhddisk | Initialize-Disk -PartitionStyle GPT -PassThru | New-Partition -UseMaximumSize -AssignDriveLetter |Format-Volume -FileSystem NTFS -AllocationUnitSize 8kb -NewFileSystemLabel ToolsDisk $VHDPathTest=Test-Path -Path "$PSScriptRoot\Temp\ToolsVHD\" if (!$VHDPathTest){ @@ -539,7 +539,7 @@ If (-not $isAdmin) { WriteInfo "Found $PSScriptRoot\Temp\ToolsVHD\*, copying files into VHDX" Copy-Item -Path "$PSScriptRoot\Temp\ToolsVHD\*" -Destination "$($vhddiskpart.DriveLetter):\" -Recurse -Force }else{ - WriteInfo "Files not found" + WriteInfo "Files not found" WriteInfoHighlighted "Add required tools into $PSScriptRoot\Temp\ToolsVHD and Press any key to continue..." $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | OUT-NULL Copy-Item -Path "$PSScriptRoot\Temp\ToolsVHD\*" -Destination ($vhddiskpart.DriveLetter+':\') -Recurse -Force @@ -632,7 +632,7 @@ If (-not $isAdmin) { New-item -type directory -Path $mountdir -force [System.Version]$VMVersion=(Get-WindowsImage -ImagePath $VHDPath -Index 1).Version Mount-WindowsImage -Path $mountdir -ImagePath $VHDPath -Index 1 - Use-WindowsUnattend -Path $mountdir -UnattendPath $unattendFile + Use-WindowsUnattend -Path $mountdir -UnattendPath $unattendFile #&"$PSScriptRoot\Temp\dism\dism" /mount-image /imagefile:$vhdpath /index:1 /MountDir:$mountdir #&"$PSScriptRoot\Temp\dism\dism" /image:$mountdir /Apply-Unattend:$unattendfile New-item -type directory -Path "$mountdir\Windows\Panther" -force @@ -650,12 +650,12 @@ If (-not $isAdmin) { #Create DSC configuration configuration DCHydration { - param - ( - [Parameter(Mandatory)] - [pscredential]$safemodeAdministratorCred, - - [Parameter(Mandatory)] + param + ( + [Parameter(Mandatory)] + [pscredential]$safemodeAdministratorCred, + + [Parameter(Mandatory)] [pscredential]$domainCred, [Parameter(Mandatory)] @@ -663,19 +663,20 @@ If (-not $isAdmin) { ) - Import-DscResource -ModuleName xActiveDirectory -ModuleVersion "3.0.0.0" - Import-DscResource -ModuleName xDNSServer -ModuleVersion "1.15.0.0" - Import-DSCResource -ModuleName NetworkingDSC -ModuleVersion "7.4.0.0" - Import-DSCResource -ModuleName xDHCPServer -ModuleVersion "2.0.0.0" - Import-DSCResource -ModuleName xPSDesiredStateConfiguration -ModuleVersion "8.10.0.0" + Import-DscResource -ModuleName ActiveDirectoryDsc -ModuleVersion "6.3.0" + Import-DscResource -ModuleName DnsServerDsc -ModuleVersion "3.0.0" + Import-DSCResource -ModuleName NetworkingDSC -ModuleVersion "9.0.0" + Import-DSCResource -ModuleName xDHCPServer -ModuleVersion "3.1.1" + Import-DSCResource -ModuleName xPSDesiredStateConfiguration -ModuleVersion "9.1.0" Import-DscResource -ModuleName PSDesiredStateConfiguration - Node $AllNodes.Where{$_.Role -eq "Parent DC"}.Nodename + + Node $AllNodes.Where{$_.Role -eq "Parent DC"}.Nodename { - WindowsFeature ADDSInstall - { - Ensure = "Present" + WindowsFeature ADDSInstall + { + Ensure = "Present" Name = "AD-Domain-Services" } @@ -691,138 +692,136 @@ If (-not $isAdmin) { Ensure = "Present" Name = "RSAT-AD-PowerShell" DependsOn = "[WindowsFeature]ADDSInstall" - } + } WindowsFeature FeatureADAdminCenter { Ensure = "Present" Name = "RSAT-AD-AdminCenter" DependsOn = "[WindowsFeature]ADDSInstall" - } + } WindowsFeature FeatureADDSTools { Ensure = "Present" Name = "RSAT-ADDS-Tools" DependsOn = "[WindowsFeature]ADDSInstall" - } + } WindowsFeature FeatureDNSTools { Ensure = "Present" Name = "RSAT-DNS-Server" DependsOn = "[WindowsFeature]ADDSInstall" - } - - xADDomain FirstDS - { - DomainName = $Node.DomainName - DomainAdministratorCredential = $domainCred + } + + ADDomain FirstDS + { + DomainName = $Node.DomainName + Credential = $domainCred SafemodeAdministratorPassword = $safemodeAdministratorCred DomainNetbiosName = $node.DomainNetbiosName DependsOn = "[WindowsFeature]ADDSInstall" } - - xWaitForADDomain DscForestWait - { - DomainName = $Node.DomainName - DomainUserCredential = $domainCred - RetryCount = $Node.RetryCount - RetryIntervalSec = $Node.RetryIntervalSec - DependsOn = "[xADDomain]FirstDS" + + WaitForADDomain DscForestWait + { + DomainName = $Node.DomainName + Credential = $domainCred + DependsOn = "[ADDomain]FirstDS" } - - xADOrganizationalUnit DefaultOU + + ADOrganizationalUnit DefaultOU { Name = $Node.DefaultOUName Path = $Node.DomainDN ProtectedFromAccidentalDeletion = $true Description = 'Default OU for all user and computer accounts' Ensure = 'Present' - DependsOn = "[xADDomain]FirstDS" + DependsOn = "[ADDomain]FirstDS" } - xADUser SQL_SA + ADUser SQL_SA { DomainName = $Node.DomainName - DomainAdministratorCredential = $domainCred + Credential = $domainCred UserName = "SQL_SA" Password = $NewADUserCred Ensure = "Present" - DependsOn = "[xADOrganizationalUnit]DefaultOU" + DependsOn = "[ADOrganizationalUnit]DefaultOU" Description = "SQL Service Account" Path = "OU=$($Node.DefaultOUName),$($Node.DomainDN)" PasswordNeverExpires = $true } - xADUser SQL_Agent + ADUser SQL_Agent { DomainName = $Node.DomainName - DomainAdministratorCredential = $domainCred + Credential = $domainCred UserName = "SQL_Agent" Password = $NewADUserCred Ensure = "Present" - DependsOn = "[xADOrganizationalUnit]DefaultOU" + DependsOn = "[ADOrganizationalUnit]DefaultOU" Description = "SQL Agent Account" Path = "OU=$($Node.DefaultOUName),$($Node.DomainDN)" PasswordNeverExpires = $true } - xADUser Domain_Admin + ADUser Domain_Admin { DomainName = $Node.DomainName - DomainAdministratorCredential = $domainCred + Credential = $domainCred UserName = $Node.DomainAdminName Password = $NewADUserCred Ensure = "Present" - DependsOn = "[xADOrganizationalUnit]DefaultOU" + DependsOn = "[ADOrganizationalUnit]DefaultOU" Description = "DomainAdmin" Path = "OU=$($Node.DefaultOUName),$($Node.DomainDN)" PasswordNeverExpires = $true } - xADUser VMM_SA + ADUser VMM_SA { DomainName = $Node.DomainName - DomainAdministratorCredential = $domainCred + Credential = $domainCred UserName = "VMM_SA" Password = $NewADUserCred Ensure = "Present" - DependsOn = "[xADUser]Domain_Admin" + DependsOn = "[ADUser]Domain_Admin" Description = "VMM Service Account" Path = "OU=$($Node.DefaultOUName),$($Node.DomainDN)" PasswordNeverExpires = $true } - xADGroup DomainAdmins + ADGroup DomainAdmins { GroupName = "Domain Admins" - DependsOn = "[xADUser]VMM_SA" + DependsOn = "[ADUser]VMM_SA" MembersToInclude = "VMM_SA",$Node.DomainAdminName } - xADGroup SchemaAdmins + ADGroup SchemaAdmins { GroupName = "Schema Admins" GroupScope = "Universal" - DependsOn = "[xADUser]VMM_SA" + DependsOn = "[ADUser]VMM_SA" MembersToInclude = $Node.DomainAdminName } - xADGroup EntAdmins + ADGroup EntAdmins { GroupName = "Enterprise Admins" GroupScope = "Universal" - DependsOn = "[xADUser]VMM_SA" + DependsOn = "[ADUser]VMM_SA" MembersToInclude = $Node.DomainAdminName } - xADUser AdministratorNeverExpires + ADUser AdministratorNeverExpires { DomainName = $Node.DomainName UserName = "Administrator" Ensure = "Present" - DependsOn = "[xADDomain]FirstDS" + DependsOn = "[ADDomain]FirstDS" PasswordNeverExpires = $true } @@ -836,7 +835,7 @@ If (-not $isAdmin) { { Ensure = "Present" Name = "DHCP" - DependsOn = "[xADDomain]FirstDS" + DependsOn = "[ADDomain]FirstDS" } Service DHCPServer #since insider 17035 dhcpserver was not starting for some reason @@ -851,7 +850,7 @@ If (-not $isAdmin) { Ensure = "Present" Name = "RSAT-DHCP" DependsOn = "[WindowsFeature]DHCPServer" - } + } xDhcpServerScope ManagementScope @@ -868,19 +867,45 @@ If (-not $isAdmin) { DependsOn = "[Service]DHCPServer" } - xDhcpServerOption MgmtScopeRouterOption + # Setting scope gateway + DhcpScopeOptionValue 'ScopeOptionGateway' { - Ensure = 'Present' - ScopeID = ($DHCPscope+"0") - DnsDomain = $Node.DomainName - DnsServerIPAddress = ($DHCPscope+"1") + OptionId = 3 + Value = ($DHCPscope+"1") + ScopeId = ($DHCPscope+"0") + VendorClass = '' + UserClass = '' AddressFamily = 'IPv4' - Router = ($DHCPscope+"1") - DependsOn = "[Service]DHCPServer" + DependsOn = "[xDhcpServerScope]ManagementScope" } + # Setting scope DNS servers + DhcpScopeOptionValue 'ScopeOptionDNS' + { + OptionId = 6 + Value = ($DHCPscope+"1") + ScopeId = ($DHCPscope+"0") + VendorClass = '' + UserClass = '' + AddressFamily = 'IPv4' + DependsOn = "[xDhcpServerScope]ManagementScope" + } + + # Setting scope DNS domain name + DhcpScopeOptionValue 'ScopeOptionDNSDomainName' + { + OptionId = 15 + Value = $Node.DomainName + ScopeId = ($DHCPscope+"0") + VendorClass = '' + UserClass = '' + AddressFamily = 'IPv4' + DependsOn = "[xDhcpServerScope]ManagementScope" + } + xDhcpServerAuthorization LocalServerActivation { + IsSingleInstance = 'Yes' Ensure = 'Present' } @@ -890,13 +915,13 @@ If (-not $isAdmin) { Name = "DSC-Service" } - xDnsServerADZone addReverseADZone + DnsServerADZone addReverseADZone { Name = $ReverseDNSrecord DynamicUpdate = "Secure" ReplicationScope = "Forest" Ensure = "Present" - DependsOn = "[xDhcpServerOption]MgmtScopeRouterOption" + DependsOn = "[DhcpScopeOptionValue]ScopeOptionGateway" } If ($LabConfig.PullServerDC){ @@ -913,7 +938,7 @@ If (-not $isAdmin) { State = "Started" DependsOn = "[WindowsFeature]DSCServiceFeature" } - + File RegistrationKeyFile { Ensure = 'Present' @@ -925,12 +950,12 @@ If (-not $isAdmin) { } } - $ConfigData = @{ - - AllNodes = @( - @{ - Nodename = $DCName - Role = "Parent DC" + $ConfigData = @{ + + AllNodes = @( + @{ + Nodename = $DCName + Role = "Parent DC" DomainAdminName=$LabConfig.DomainAdminName DomainName = $LabConfig.DomainName DomainNetbiosName = $LabConfig.DomainNetbiosName @@ -938,15 +963,15 @@ If (-not $isAdmin) { DefaultOUName=$LabConfig.DefaultOUName RegistrationKey='14fc8e72-5036-4e79-9f89-5382160053aa' PSDscAllowPlainTextPassword = $true - PsDscAllowDomainUser= $true - RetryCount = 50 - RetryIntervalSec = 30 - } - ) - } + PsDscAllowDomainUser= $true + RetryCount = 50 + RetryIntervalSec = 30 + } + ) + } #create LCM config - [DSCLocalConfigurationManager()] + [DSCLocalConfigurationManager()] configuration LCMConfig { Node DC @@ -954,7 +979,7 @@ If (-not $isAdmin) { Settings { RebootNodeIfNeeded = $true - ActionAfterReboot = 'ContinueConfiguration' + ActionAfterReboot = 'ContinueConfiguration' } } } @@ -963,7 +988,7 @@ If (-not $isAdmin) { WriteInfoHighlighted "`t Creating DSC Configs for DC" LCMConfig -OutputPath "$PSScriptRoot\Temp\config" -ConfigurationData $ConfigData DCHydration -OutputPath "$PSScriptRoot\Temp\config" -ConfigurationData $ConfigData -safemodeAdministratorCred $cred -domainCred $cred -NewADUserCred $cred - + #copy DSC MOF files to DC WriteInfoHighlighted "`t Copying DSC configurations (pending.mof and metaconfig.mof)" New-item -type directory -Path "$PSScriptRoot\Temp\config" -ErrorAction Ignore @@ -979,7 +1004,7 @@ If (-not $isAdmin) { WriteInfoHighlighted "`t Starting DC" $DC | Start-VM - $VMStartupTime = 250 + $VMStartupTime = 250 WriteInfoHighlighted "`t Configuring DC using DSC takes a while." WriteInfo "`t `t Initial configuration in progress. Sleeping $VMStartupTime seconds" Start-Sleep $VMStartupTime @@ -991,7 +1016,7 @@ If (-not $isAdmin) { Start-Sleep 10 }elseif ($test.status -ne "Success" -and $i -eq 1) { WriteInfo "`t `t Current DSC state: $($test.status), ResourncesNotInDesiredState: $($test.resourcesNotInDesiredState.count), ResourncesInDesiredState: $($test.resourcesInDesiredState.count)." - WriteInfoHighlighted "`t `t Invoking DSC Configuration again" + WriteInfoHighlighted "`t `t Invoking DSC Configuration again" Invoke-Command -VMGuid $DC.id -ScriptBlock {Start-DscConfiguration -UseExisting} -Credential $cred $i++ }elseif ($test.status -ne "Success" -and $i -gt 1) { @@ -1000,7 +1025,7 @@ If (-not $isAdmin) { Invoke-Command -VMGuid $DC.id -ScriptBlock {Restart-Computer} -Credential $cred }elseif ($test.status -eq "Success" ) { WriteInfo "`t `t Current DSC state: $($test.status), ResourncesNotInDesiredState: $($test.resourcesNotInDesiredState.count), ResourncesInDesiredState: $($test.resourcesInDesiredState.count)." - WriteInfoHighlighted "`t `t DSC Configured DC Successfully" + WriteInfoHighlighted "`t `t DSC Configured DC Successfully" } }until ($test.Status -eq 'Success' -and $test.rebootrequested -eq $false) $test @@ -1010,7 +1035,7 @@ If (-not $isAdmin) { Param($LabConfig); redircmp "OU=$($LabConfig.DefaultOUName),$($LabConfig.DN)" Add-DnsServerPrimaryZone -NetworkID ($DHCPscope+"/24") -ReplicationScope "Forest" - } + } #install SCVMM or its prereqs if specified so if (($LabConfig.InstallSCVMM -eq "Yes") -or ($LabConfig.InstallSCVMM -eq "SQL") -or ($LabConfig.InstallSCVMM -eq "ADK") -or ($LabConfig.InstallSCVMM -eq "Prereqs")){ $DC | Add-VMHardDiskDrive -Path $toolsVHD.Path @@ -1043,7 +1068,7 @@ If (-not $isAdmin) { Start-Sleep 30 #Wait as sometimes VMM failed to install without this. Invoke-Command -VMGuid $DC.id -Credential $cred -ScriptBlock { Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process -Force - d:\scvmm\3_SCVMM_Install.ps1 + d:\scvmm\3_SCVMM_Install.ps1 } } @@ -1051,7 +1076,7 @@ If (-not $isAdmin) { WriteInfoHighlighted "Installing SQL" Invoke-Command -VMGuid $DC.id -Credential $cred -ScriptBlock { Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process -Force - d:\scvmm\1_SQL_Install.ps1 + d:\scvmm\1_SQL_Install.ps1 } } @@ -1084,7 +1109,7 @@ If (-not $isAdmin) { #cleanup DC if (-not $DCFilesExists){ WriteInfoHighlighted "Backup DC and cleanup" - #shutdown DC + #shutdown DC WriteInfo "`t Disconnecting VMNetwork Adapter from DC" $DC | Get-VMNetworkAdapter | Disconnect-VMNetworkAdapter WriteInfo "`t Shutting down DC" @@ -1120,7 +1145,7 @@ If (-not $isAdmin) { <# 0 #> New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Cleanup .\Temp\ 1_Prereq.ps1 2_CreateParentDisks.ps1 and rename 3_deploy.ps1 to just deploy.ps1" <# 1 #> New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Keep files (in case DC was not created sucessfully)" ) - + If (!$LabConfig.AutoCleanUp) { $response = $host.UI.PromptForChoice("Unnecessary files cleanup","Do you want to cleanup unnecessary files and folders?", $options, 0 <#default option#>) } @@ -1134,11 +1159,11 @@ If (-not $isAdmin) { }else{ $renamed = $true WriteInfo "`t `t Cleaning unnecessary items" - Remove-Item -Path "$PSScriptRoot\temp" -Force -Recurse + Remove-Item -Path "$PSScriptRoot\temp" -Force -Recurse "$PSScriptRoot\Temp","$PSScriptRoot\1_Prereq.ps1","$PSScriptRoot\2_CreateParentDisks.ps1" | ForEach-Object { WriteInfo "`t `t `t Removing $_" Remove-Item -Path $_ -Force -Recurse -ErrorAction SilentlyContinue - } + } WriteInfo "`t `t `t Renaming $PSScriptRoot\3_Deploy.ps1 to Deploy.ps1" Rename-Item -Path "$PSScriptRoot\3_Deploy.ps1" -NewName "Deploy.ps1" -ErrorAction SilentlyContinue } @@ -1198,13 +1223,13 @@ If (-not $isAdmin) { $vhdProperties['vhd.os.language'] = $OSLanguage } } - $events += Initialize-TelemetryEvent -Event "CreateParentDisks.Vhd" -Metrics $vhdMetrics -Properties $vhdProperties -NickName $LabConfig.TelemetryNickName + $events += New-TelemetryEvent -Event "CreateParentDisks.Vhd" -Metrics $vhdMetrics -Properties $vhdProperties -NickName $LabConfig.TelemetryNickName } # and one overall - $events += Initialize-TelemetryEvent -Event "CreateParentDisks.End" -Metrics $metrics -Properties $properties -NickName $LabConfig.TelemetryNickName + $events += New-TelemetryEvent -Event "CreateParentDisks.End" -Metrics $metrics -Properties $properties -NickName $LabConfig.TelemetryNickName - Send-TelemetryEvent -Events $events | Out-Null + Send-TelemetryEvents -Events $events | Out-Null } Stop-Transcript