SCCM Task Sequence Windows 10 Language Pack’s Install

On a recent project there was a requirement to install different language pack’s and configure regional / keyboard settings. I was having issue getting this working so I though I would do a post on how I ended up getting it working correctly.

First problem I had was trying to find the language packs I ended up downloading the language pack ISO from the Microsoft visual studio site.

lp

Once downloaded I need to mount the ISO and copy the required lp3

Once all the required language packs where copied. Create a new packages for each packlp4lp5lp6lp7lp8

The next step is to configure the XML file’s that will be used to configure the regional and keyboard settings for each language pack. I used this support how to as a refrence for the XML:

https://support.microsoft.com/en-ie/help/2764405/how-to-automate-regional-and-language-settings-in-windows-vista-window

Below is the XML file that was used for the German language pack:

lp11

I used the below sites to get the GEO ID & the Input Locales

GEO ID : https://docs.microsoft.com/en-ie/windows/desktop/Intl/table-of-geographical-locations

Input Locales: https://docs.microsoft.com/en-us/windows-hardware/manufacture/desktop/default-input-locales-for-windows-language-packs

Once we have all the language packs completed create a single package with all the XML’s file’slp15

Next step is to add the steps to the Windows 10 task sequence

Add a run command line task, use the command below and replace with the required language pack .cab file. Select the corresponding package.

Below is for the german .cab

dism.exe /norestart /online /add-package /packagepath:.\Microsoft-Windows-Client-Language-Pack_x64_de-de(German).cablp10

After this step add a restart task lp12

Next step is to apply the XML file’s to set the regional / Keyboard settings. Below is the command line I used

rundll32.exe shell32,Control_RunDLL intl.cpl,,/f:”.\German.xml”

When copying the command above check that the double quotes are in the correct format or the command could fail to apply the xml fileLP13

After this step do another restart, the last step I did was to configure time zone for each region. I used the below site to get the time zone values

Time Zone Values: https://support.microsoft.com/en-us/help/973627/microsoft-time-zone-index-values

Below is the command line to set the time zones

cmd.exe /c tzutil.exe /s “W. Europe Standard Time”lp14

Below is the finished task sequence with all languages addedlp17

Last step was to set a condition to apply each package. I used host name as the condition to apply the language packs as each country has its own naming convention this was the easiest way for melp16

Once this is competed I tested and all packages were applied without error.

lp1lp2

SUP Migration WUHandler Error CWuaHandler::SetCategoriesForStateReportingExclusion

Just want to put this up in case anyone else run in to this issue. I had to test migrated WSUS and SUP role from my Primary site server to its own standalone server, so I could complete the same task in production.

After the migration all updates showed as unknown for all devices. I check the update deployment log and WUAHandler.log under c:\Windows\CCM and the update scan started but just sat at  the below log output

Assignment({968F78AA-AE13-495C-83D9-74920944C702}) already in progress state (AssignmentStateDetecting). No need to evaluate

sup2

When I checked the WUAHandler log I could see the below but the site never registered the new WSUS server.

CWuaHandler::SetCategoriesForStateReportingExclusion called with {GUDI } for bundles

I checked the general bits like the site status, component status and wsyncmgr.log all where green and working correctly. I then checked a few post online and most pointed to a Content version / MinSourceVersion miss match issue from the WSUS DB.

I checked this and my content version was the same as in MinSourceVersion so that was not the issue.  I then had a look at the Window update registry key on the clients to see if the new WSUS was registered. HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate

It wasn’t 😦

Finally had a look boundary (Should have done this first ) and turns out I was a bit forgetful and didn’t add the new site server to the boundary group’s so no client’s where able to see the new SUP server.

Once I added to all boundary groups and did an update scan cycle all updates started to show a few hours later and the WUAHanlder log now showed the WSUS connection.

sup3

yay it’s all fixed 🙂

Point to take away, always add new site servers to boundary groups first 🙂

 

Removing WSUS on SCCM Server Causes HTTP Error 500.19

Recently I was migrating my WSUS deployment off my SCCM server to a new standalone server so that I could enable Windows 10 and Windows Server 2016 updates.

After removing the role I started getting critical alerts for the management Point, Clients couldn’t be installed and I was getting 500.19 error from the SCCM IIS site.

SCCM MP Errorsccmerror2

IIS Errorsccmerror

I had a quick search and found a blog post by Jörgen Nilsson that had the reason for the error.

https://ccmexec.com/2014/03/uninstalling-wsus-on-primary-site-server-causing-http-error-500/

When removing the WSUS role there are configuration settings that are written to the Applicationhost.config that reference a .dll file used by WSUS that is removed during the WSUS role removal. The Applicationhost.config is located under C:\Windows\System32\inetsrv\config

If we check the Applicationhost.config there should be an entry the same as below:

<scheme name=”xpress” doStaticCompression=”false” doDynamicCompression=”true” 
dll=”C:\Windows\system32\inetsrv\suscomp.dll” staticCompressionLevel=”10″ 
dynamicCompressionLevel=”0″ />

Running the following command will remove the references of .dll that is installed by WSUS

%windir%\system32\inetsrv\appcmd.exe set config -section:system.webServer/httpCompression /-[name=’xpress’]sccmerror3

After running the above command the management point is back working and I can now access all SCCM URL’ssccmerror4

Remote Desktop Services 2012 R2 Deployment Part 3

In the last post we setup the RD connection broker HA to add additional resilience to the RDS deployment. In this post we are going to create and configure RDS collection.

To create a collection go to

Server Manager > Remote Desktop Services > Collections

Click on tasks and Create Session Collectionrdsc3

rdsc2

Give the collection and Namerdsc4

Select the required session hosts that will be used for this collectionrdsc5

Add user group that will have access I have left as domain users but this can be change to any security group to restrict accessrdsc6

In this setup we wont be using server profile disk but if this is required just enable and select a network location to save the VHDX user disks for the users profilesrdsc7

Click next and confirm all setting are correct continue with the deploymentrdsc8

Once this is completed we can now see the collection

Next step is to configure the session collection settings.

Select the collection and go to task Edit Propertiesrdsc16

First tab is just for changing the Name, adding a description and showing the session collection in RD web accessrdsc17

Second tab is for user / groups that will have access to the specific collectionrdsc18

Security allow you to change the security layer and encryption level. The default is negotiate (This will use the most secure layer that is supported by the client. ) and client compatible (This encrypt’s to the max strength that the client supports.)

rdsc19

To change session time out go to session. I am going to end disconnected sessions after 3 hours, never disconnect active sessions and set idle session limit to 3 hoursrdsc9

Load Balancing can be changed to session limits or prioritize one server over another by change Relative weight value or Session Limit value. In this case we will leave the defaultsrdsc10

Allow or deny redirction of local resource to the RDS session host ie Audio devices, local disk, printer .etcrdsc20

The last tab is to enable or disable user profile disk and specify network location and setting to be save to the profile disk. rdsc21

Once the collection is created and all setting are configured, we should now see the collection show in the RD web page.

RDSc12.png

click on the collection to launch the session and you should see the connection broker HA DNS address show as the connection address on the RDP session

rdsc13

In part 4, we will look at customizing the RDS web page and deploying the RDS licencing role.

 

 

 

Remote Desktop Services 2012 R2 Deployment Part 2

In the last post we setup the two RDS server that will be used for RD web access, connection broker and sessions hosts. In this post we will go through setting up RD connection broker HA to give more resilience to the RDS deployment.

To add connection broker HA we need to have server with SQL 2008 R2 or above and have a load balancer or DNS round robin to redirect traffic. I am using SQL 2014 with just the database engine and management tools selected. I have used a separate SQL server / RDS licensing for this as I don’t want the database on either of the current RDS servers.

I am going to use DNS round robin for redirecting traffic to both brokers as I don’t have a load balancer setup so I setup the below 4 DNS records on my internal DNS serverrdsbrokerha12

Once the database server is setup we need to create a security group and add the two RDS server that will be used as connection brokers. rdsbrokerha20

Once this group has been created we can set up the SQL permissions. Open SQL management studio on the database server and create a new login for the group

rdsbrokerhardsbrokerha1

Give dbcreator access as this will be required when setting up the HA deploymentrdsbrokerha2

To connect to the database SQL Server Native client is require on both the RD connection brokers. The latest version of this client is from SQL 2012 and can be downloaded from Microsoft : https://www.microsoft.com/en-us/download/details.aspx?id=50402

Once the client is installed go to Control Panel\All Control Panel Items\Administrative Tools and go to ODBC Data Sources (64-bit). Click Add and select SQL Server Native Client 11.0rdsbrokerha3

Enter in a Name, Description and SQL server that the permission where setup for the security group aboverdsbrokerha4

Leave as integrated windows authenticationrdsbrokerha5

Make sure that the application intent is readwrite the rest of the setting can be left as defaultrdsbrokerha6rdsbrokerha7

Once completed run a test to make sure that the database can be accessedrdsbrokerha8rdsbrokerha9

Once this is completed on both RD connection brokers we can start to set up the HA deployment.

Go back to the RDS deployment page and right-click on RD connection broker and click Configure High Availabilityrdsbrokerha10

Database connection string: (We need to put in SQL server name & the database name that will be created during the deployment.)

DRIVER=SQL Server Native Client 11.0;SERVER=<name of SQL server>;Trusted_Connection=Yes;APP=Remote Desktop Services Connection Broker;DATABASE=<name of database>

Folder to store database files: (I used the default SQL location)

Add in DNS Name: HARDSBroker.Lab.local

rdsbrokerha13

Next page is just to confirm all the settings are correctrdsbrokerha14rdsbrokerha15

Once HA has been configure we can now add the additional connection broker. Right click on RD connection broker and click Add RD Connection Broker Serverrdsbrokerha16

Select the required serverrdsbrokerha17

Click Add rdsbrokerha18

Once completed both server should now show the RD Connection Broker role as installed.rdsbrokerha19

In part 3, we will go over creating  and configure RDS collections

 

 

Remote Desktop Services 2012 R2 Deployment Part 1

I recently had a request to build a new Windows Server 2012 R2 RDS farm as the existing single Windows server 2012 RDS deployment as it was crashing and users where getting a bit angry. So I decided to build out the deployment on my test domain to make sure it would work out as expected.

I will be using three servers for this deployment as I want to co-locate some roles as to keep the number of servers to a minimum as this is a small 20 users setup.

I have two servers that will be RDS session host, connection brokers and RDS web access and one that will be used later as the licensing and SQL server for RDS broker HA setup.

To start we need add all servers to server manager on one of the RDS servers. rds1rds3

Once all servers are added to server manager and showing as online we can start to install the RDS roles.

Go to mange on the top right of server manager and click add roles and features

On the Installation type select Remote Desktops Services installation. rds4

Next select standard deployment rds5

Select session-based desktop deploymentrds6

Only one RD connection broker can be select during initial setup HA will be setup after intial setuprds7

Select Install the RD web access role on RD connection broker. We can add the RD web access to the second server afterrds8

Select both servers that will be used for sessions hosts. rds9

Next confirm if all servers have been selected for the correct roles and deployrds10

The deployment progress screen should then show it can take a while for this to complete rds13

Once the deployment has completed there will be the RDS icon on server manager. All servers need to be added to server manager or you be able to mange the deploymentrds14

To finish the current deployment I will add the second RD web access server to do this click on task above deployment servers and add RD Web Access Servers and select second server that will have the role addedrds18rdsc19

Last step I want to do was to use a wild card cert that I have from my internal CA so that I don’t get any cert errors when access the RD web access URL.

I wont go through generating the cert here but once you have the cert you can go to Deployment overview and click on edit deployment properties. rds15

Go to certificates. Select the roles you want to assign the cert to in my case it was the two RD connection broker and RD web access. click select existing certificate and select the cert that will be used. You can also create a new certificate on this windows aswell. rds16

Once cert is applied and all status say ok you should no longer get a cert error when access the RD web access URLrds17

We will use DNS round robin to load balance between the two RD web access servers and this will create a single URL for users to access.

rds19

We can now access the RDS web page using: HTTPS://RDS.Lab.Local/RDWeb

Instead of having to go to each individual serversrdsc11

In part 2, we will go through setting up a second connection broker for high availability deployment.

Azure Network Security Groups (NSG) to Restrict Management Access

For security reasons it is good practice to lock down access to Azure resources and not leave management ports open to the internet.

One way to restrict access to remote access protocols like RDS / SSH is to create a Network Security Groups (NSG) and apply this to either virtual machines or virtual network subnets.

To create a NSG

Logon on to the Azure portal: https://portal.azure.com

Once logged on go to All Services > Network security groups

If you have created VM’s or other resources there might already be some pre-existing NSG’s.NSG1

To create a new NSG click on Add

Give the NSG a name, assign subscription, resource group and locationNSG2

Once the deployment has completed, click on the NSG this will bring up the configuration page.

First part is to configure the inbound security rules. NSG4

Go to settings > Inbound security rules

Once in Inbound security rules. To add a rule click add.

I want to restrict access to a specific Public IP for RDP access. Set the source as IP Addresses and add in the IP that will be allowed this can be a full range or a single IP depending on network subnet bit. I am only going to add one address so I used /32 below is an example 10.10.10.92/32.

I left source port ranges and destination as default as I don’t want to restrict these.  Choose the required port in this case its 3389, set protocol to Any if you require both TCP/UDP I only need TCP.  Set action to allow, set priority value and last step is give the port a name / description. NSG5

Below is the updated rule I have marked out my public IPNSG6

The outbound rule is set to allow any/any by default so if there is a requirement to lock down certain ports then create a new rule here to block the required ports.

Last step once all rule have been configured is to apply the NSG against resources. I am going to apply the policy to both my subnet and NIC’s assigned to both my test VM’s.

The policy should only need to be applied to either the subnet or VM’s,  I just want to show how to apply to both. If you apply a rule to both VM and subnet they need to match or any port that is not allowed on both wont be work.

To assign to subnet: go to settings > SubnetsNSG7

Select virtual network and subnet. NSG8NSG9

To apply to each VM Nic: Go to settings > network interfaces

As I already had NSG’s associated from the VM deployments I need to re-associate to the new NSG.

Select the NSG of the VM you want to move and go to network interfacesNSG10NSG11

Chose the required NSG

NSG12

Once applied I can now only access the VM’s from my own network.

 

 

 

 

Azure VM Backup using Azure Recovery Service Vault

In this post I am going to go through setting up a weekly backup for VM’s using Azure Recovery Service Vault.

Recovery Services vaults protect:

  • Azure Resource Manager-deployed VMs
  • Classic VMs
  • Standard storage VMs
  • Premium storage VMs
  • VMs running on Managed Disks
  • VMs encrypted using Azure Disk Encryption
  • Application consistent backup of Windows VMs using VSS and Linux VMs using custom pre-snapshot and post-snapshot scripts

To backup a single VM we can click on the VM and go to backup and configure the Recovery Vault. I want to add all my servers at one time so I will create Recovery Vault first.

Logon on to the Azure portal: https://portal.azure.com

Once logged on go to All Services > Recovery Services vaults

Once in Recovery Services vaults click createRSV1

Give the Recovery Vault a Name, assign a subscription, resource group and location.

RSV2

Once the deployment has finished,  click on the newly create object. RSV3

First thing I am going to set the backup configuration to locally-redundant as this is just for my Lab VM’s and it will save on cost.

Go to Manage > Backup Infrastructure and set to Locally-redundant.RSV4-1

I am going to create a custom policy as I only want to backup my test VM’s once a week. go to Manage > Backup policies and click Add.RSV3-2

Once in the new backup policy configure settings as required. I have set frequency to every sunday at 22:00 and set retention to 4 weeks backups. Click create once all settings are configured. RSV3-1

The policy should now be available to assign to backup jobs. Next step is to setup the backup. Go to Getting started > backup

Select where the work load is running (Azure or on prem), I only want to backup my Azure Lab VM so I selected Azure. Next select backup type

  • VM
  • Azure File Share (in preview at the time of the post)
  • SQL server in Azure VM (in preview at the time of the post)

Select the backup policy, I am using the policy created above. RSV5

Next select the VM’s that will be backed up. RSV6

Click enable backup to finish the config.

I will kick off a manual backup job to get an initial backup.

Click on backup Item > Azure Virtual Machine > Backup nowRSV8RSV9

To view backup jobs go to Monitoring > Backup JobsRSV7

Once the backup is complete, the option to run VM restore or file level recovery becomes available.RSV10

Azure Automation “Run Login-AzureAccount to login”

When I was creating my Azure Automation account and tried to run a runbook that needed to logon to Azure,  to start my VM’s I was getting an error:

Run Login-AzureAccount to login.AZAUError2

After looking on technet there where a few different recommendations but none worked.

In the end I just decided to try update the Azure modules. This fixed the issue.

Below is how to update the modules.

Go to Automation Accounts > select account > Modules

AZAUError1

There will be a prompt to update all Azure modules click yes to continue. AZAUError3

To view the progress click on below. AZAUError4

Click on all logs or output to view what is currently running. AZAUError5

Once completed the below will show. AZAUError6

After this I was successfully able to run my runbooks.

 

Azure Automation PowerShell Runbook

In this post I am going to go through setting up an Azure automation account and creating a runbook to PowerShell.

Azure Automation allows for process automation, configuration management, update management and PowerShell script execution on both Azure / Office 365. I like using Azure Automation as it allows me to save credentials in Azure for running task opposed to having them called in my script which is less secure.

I am going to setup a runbook to power on and off my LAB servers so that they only run during the day.

To start using Azure Automation

Go to All services > Automation Accounts

Once in Automation Accounts we need to create a new account.AZAU2

Give the Automation account a name, assign to a subscription, resource group and location.  Leave create as yes and click crate. 

AZAU3

Once the task has completed there will now be Automation account showing. AZAU10

Next step is to create a runbook to run the PowerShell command. Click on the Automation account and go to process automation and click on runbooks.AZAU4

Once in runbooks there will be some pre-configure runbooks that can be used as references. 

To create a new runbook click Add a runbookAZAU11

Once in the runbook give a name and select the runbook type in this case it will be PowerShell. Then click create. AZAU5

Click on edit to modify the PowerShell script. AZAU6

The connection commands is generic and is copied from AzureAutomationTutorialScript runbook.

$connectionName = “AzureRunAsConnection”
try
{
# Get the connection “AzureRunAsConnection “
$servicePrincipalConnection=Get-AutomationConnection -Name $connectionName

 

“Logging in to Azure…”
Add-AzureRmAccount -ServicePrincipal `
-TenantId $servicePrincipalConnection.TenantId `
-ApplicationId $servicePrincipalConnection.ApplicationId `
-CertificateThumbprint $servicePrincipalConnection.CertificateThumbprint
}
catch {
if (!$servicePrincipalConnection)
{
$ErrorMessage = “Connection $connectionName not found.”
throw$ErrorMessage
} else{
Write-Error -Message $_.Exception
throw$_.Exception
}
}
 

I have added the command I want to run at the bottom. Once finished, the runbook needs to be saved and published. 

AZAU7

To test if the script will work as expected there is a test pane icon 
AZAU12
 
Once in test click start and the script will be executed the output of the command will be returned to the console. 
AZAU13
 
Once the runbook is saved, the start icon will become available so the runbook can be executed. 
AZAU8
 
Last step is to schedule when the runbook will execute, click schedule.
 
Add a name, description, start time/date, time zone and if the task is a once of or a recurring task. 
 
AZAU14
 
Once the schedule has been created it will show under schedules. 
AZAU15