From 50c14256818f1ea58e689868ae0b1e21afbb5578 Mon Sep 17 00:00:00 2001 From: JaromirK Date: Tue, 21 Nov 2023 15:14:24 +0100 Subject: [PATCH 1/2] simplified arc deployment --- .../Scenario.ps1 | 78 ++----------------- 1 file changed, 5 insertions(+), 73 deletions(-) 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 From bb6120a37cb1d8e109efe75ecd98db4d946d5be0 Mon Sep 17 00:00:00 2001 From: JaromirK Date: Fri, 12 Jan 2024 10:37:00 +0100 Subject: [PATCH 2/2] updated DSC modules --- Scripts/1_Prereq.ps1 | 2 +- Scripts/2_CreateParentDisks.ps1 | 113 +++++++++++++++++++------------- 2 files changed, 70 insertions(+), 45 deletions(-) diff --git a/Scripts/1_Prereq.ps1 b/Scripts/1_Prereq.ps1 index 2d12aa26..a04140b1 100644 --- a/Scripts/1_Prereq.ps1 +++ b/Scripts/1_Prereq.ps1 @@ -171,7 +171,7 @@ If ( Test-Path -Path "$PSScriptRoot\Temp\Convert-WindowsImage.ps1" ) { #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 fe4c1d05..a1a55deb 100644 --- a/Scripts/2_CreateParentDisks.ps1 +++ b/Scripts/2_CreateParentDisks.ps1 @@ -663,13 +663,14 @@ 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 { @@ -714,115 +715,113 @@ If (-not $isAdmin) { DependsOn = "[WindowsFeature]ADDSInstall" } - xADDomain FirstDS + ADDomain FirstDS { DomainName = $Node.DomainName - DomainAdministratorCredential = $domainCred + Credential = $domainCred SafemodeAdministratorPassword = $safemodeAdministratorCred DomainNetbiosName = $node.DomainNetbiosName DependsOn = "[WindowsFeature]ADDSInstall" } - xWaitForADDomain DscForestWait + WaitForADDomain DscForestWait { DomainName = $Node.DomainName - DomainUserCredential = $domainCred - RetryCount = $Node.RetryCount - RetryIntervalSec = $Node.RetryIntervalSec - DependsOn = "[xADDomain]FirstDS" + 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 @@ -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){