Warning: Undefined variable $file in /customers/a/e/3/tunecom.be/httpd.www/stg_ba12f/wp-content/plugins/fix-my-feed-rss-repair/rss-feed-fixr.php on line 14
Warning: Cannot modify header information - headers already sent by (output started at /customers/a/e/3/tunecom.be/httpd.www/stg_ba12f/wp-content/plugins/fix-my-feed-rss-repair/rss-feed-fixr.php:14) in /customers/a/e/3/tunecom.be/httpd.www/stg_ba12f/wp-content/plugins/onecom-vcache/vcaching.php on line 549
Warning: Cannot modify header information - headers already sent by (output started at /customers/a/e/3/tunecom.be/httpd.www/stg_ba12f/wp-content/plugins/fix-my-feed-rss-repair/rss-feed-fixr.php:14) in /customers/a/e/3/tunecom.be/httpd.www/stg_ba12f/wp-content/plugins/onecom-vcache/vcaching.php on line 557
Warning: Cannot modify header information - headers already sent by (output started at /customers/a/e/3/tunecom.be/httpd.www/stg_ba12f/wp-content/plugins/fix-my-feed-rss-repair/rss-feed-fixr.php:14) in /customers/a/e/3/tunecom.be/httpd.www/stg_ba12f/wp-includes/feed-rss2.php on line 8
The post How to use SNAT (Source Network Address Translation) for outbound Windows Virtual Desktop connections appeared first on Tunecom.
]]>Since there is no physical network hardware layer you can troubleshoot, one of the rather obvious cases which are often overlooked is SNAT (Source Network Address Translation). In a traditional on-premises environment you would have a reverse proxy or other networking equipment in place that would translate all of your internal workspace IP Addresses to a single public IP address.
Windows Virtual Desktop is an Azure Native solution built on IaaS. Virtual Machines running on Azure have direct internet connectivity by using the Azure backplane. Just like Microsoft 365 a wide range of public IP addresses and ports is used to connect to online services.
This wide range of public IP addresses might just be the reason for the previously mentioned issues.
What is SNAT? The following Microsoft Docs site explains more in detail all of the possible options & configurations for SNAT.
In our use case, we want to use SNAT to masquerade our back-end WVD Host IP Addresses to a single Public IP address.
What is required? We need a Standard Public Azure Loadbalancer configured on top of our WVD hosts and a SNAT rule configured to allow outbound connections.
Let’s get started with deploying the new load balancer and assigning the SNAT rules to the WVD hosts.
You can run the powershell script provided below or review it on my GitHub Repo.
#region clear variables & in memory parameters $slb = $null $vm = $null $NI = $null $natrules = $null $NIConfig = $null $ELBPurpose = $null $ELBlocation = $null $SKU = $null #endregion #region input variables $ELBPurpose = "enter the purpose of your loadbalancer (ex. wvd)" $ELBlocation = "enter the location of your loadbalancer (ex. westeurope)" $SKU = "enter the SKU of your loadbalancer (ex. standard)" $ELBResourceGroup = "enter the resource group name of your loadbalancer (ex. prd-network-rg)" #endregion #region naming convention $ELBconvention = "-elb" $PIPconvention = "-pip" $FrontEndConvention = "-fep" $BackEndConvention = "-bep" $OutboundRuleConvention = "-obr" $ELBname = $ELBPurpose + $ELBconvention $ELBpip = $ELBname + $PIPconvention $ELBFrontEndName = $ELBname + $FrontEndConvention $ELDBackEndPoolName = $ELBname + $BackEndConvention $ELBOutboundRulename = $ELBname + $OutboundRuleConvention #endregion #region loadbalancer deployment # Step 1: Create a new static public IP address $publicip = New-AzPublicIpAddress -ResourceGroupName $ELBResourceGroup -name $ELBpip -Location $ELBlocation -AllocationMethod Static -Sku $SKU # Step 2: Create a new front end pool configuration and assign the public IP $frontend = New-AzLoadBalancerFrontendIpConfig -Name $ELBFrontEndName -PublicIpAddress $publicip # Step 3: Create a new back end pool configuration $backendAddressPool = New-AzLoadBalancerBackendAddressPoolConfig -Name $ELDBackEndPoolName # Step 4: Create the actual load balancer $slb = New-AzLoadBalancer -Name $ELBname -ResourceGroupName $ELBResourceGroup -Location $ELBlocation -FrontendIpConfiguration $frontend -BackendAddressPool $backendAddressPool -Sku $SKU # Step 5: Assign the back end VMs to the loadbalancer $VMs = Get-AzVM | Out-GridView -PassThru -Title "Select your WVD hosts" foreach ($vm in $VMs) { $NI = Get-AzNetworkInterface | Where-Object { $_.name -like "*$($VM.name)*" } $NI.IpConfigurations[0].Subnet.Id $bep = Get-AzLoadBalancerBackendAddressPoolConfig -Name $ELDBackEndPoolName -LoadBalancer $slb $NI.IpConfigurations[0].LoadBalancerBackendAddressPools = $bep $NI | Set-AzNetworkInterface } # Step 6: Assign the outbound SNAT rules $myelb = Get-AzLoadBalancer -Name $slb.Name $myelb | Add-AzLoadBalancerOutboundRuleConfig -Name $ELBOutboundRulename -FrontendIpConfiguration $frontend -BackendAddressPool $backendAddressPool -Protocol "All" # Step 7: Configure the loadbalancer $myelb | Set-AzLoadBalancer #endregion
The end result will look similar to below screenshots.
The scripts are provided as-is, please be very careful and test run the scripts on a “test” environment or an environment that allows you to perform some quick checks and tests. Adding a standard load balancer with no SNAT rules can cause internet connectivity loss for Windows Virtual Desktop users.
Thank you for reading through this blog post, I hope I have been able to assist in adding SNAT rules to WVD.
If you encounter any new insights, feel free to drop me a comment or contact me via mail or other social media channels
The post How to use SNAT (Source Network Address Translation) for outbound Windows Virtual Desktop connections appeared first on Tunecom.
]]>The post How to retrieve lingering FSLogix profiles on Windows Virtual Desktop, mounted from an Azure File share appeared first on Tunecom.
]]>In some very particular cases it happens that when a user logs off its session from a WVD (Windows Virtual Desktop) host, the corresponding FSLogix profile is not dismounted from the host.
When the user tries to login again to the environment, this results in the following error.
Status : 0x0000000B : Cannot open virtual disk
Reason : 0x00000000 : The container is attached
Error code : 0x00000020 : The process cannot access the file because it is being used by another process
During normal behavior of the login and log off process to Windows Virtual Desktop in combination with an FSLogix profile, the profile is mounted from the underlying storage provider and correctly dismounted upon successful log off of the Windows Virtual Desktop host.
The root cause of why the profile container is not dismounted from the host is hard to find, in most cases, an update of the FSLogix components is required, please make sure to read through the latest FSLogix release notes.
During the days that we had our profile shares/data hosted on a traditional IaaS fileserver, we would just open up an MMC console and look for any open files or sessions.
Since our profiles are now being hosted on an Azure File share, this process is slightly different. I’ve written a small PowerShell script for you to use and/or alter to your needs.
The input variables are pretty straightforward :
Note: The script is currently “designed” to query only one storage account/file share, and only one host pool per run. You could of course alter this to check all host pools and related storage accounts.
The script loops through your active Windows Virtual Desktop sessions and active storage handles.
It then checks each storage handle, whether or not it has a corresponding active WVD session. If not you are presented with the virtual machine name where the FSLogix container is mounted.
Save this PowerShell script as “Clean-LingeringFSLogixProfiles.ps1” Read through the blog post to retrieve the InVM script. The scripts can be download from my GitRepo as well.
<# .SYNOPSIS Dismount lingering FSLogix VHD(X) profiles. .DESCRIPTION Dismount lingering FSLogix VHD(X) profiles. .PARAMETER Mode Provide the execution mode of the script. Alerting : Generates an alert whenever a lingering FSLogix VHDX profile is found React : Tries to dismount the lingering FSLogix Profile on the host where it is attached .PARAMETER ProfileStorageAccount Provide the storage account where the FSLogix profiles are located .PARAMETER ProfileStorageAccount Provide the fileshare where the FSLogix profiles are located .PARAMETER StorageAccountResourceGroupName Provide the resource group name of your storage account .PARAMETER OverrideErrorActionPreference Provide the ErrorActionPreference setting, as descibed in about_preference_variables. (https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_preference_variables?view=powershell-7#erroractionpreference). When running locally we should use "Break" mode, which breaks in to the debugger when an error is thrown. .EXAMPLE PS C:\> .\Clean-LingeringFSLogixProfiles.ps1 -Mode "Alerting" -ProfileStorageAccount "storageaccountname" -ProfileShare "profileshare" -StorageAccountResourceGroupName "resourcegroupname" #> [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateSet('alerting', 'react')] [string] $Mode, [Parameter(Mandatory = $true)] [string] $ProfileStorageAccount, [Parameter(Mandatory = $true)] [string] $ProfileShare, [Parameter(Mandatory = $true)] [string] $StorageAccountResourceGroupName, [Parameter(Mandatory = $false)] [string] $OverrideErrorActionPreference = "Break" ) $ErrorActionPreference = $OverrideErrorActionPreference # The following cmd retrieves your storage account details and puts it in a context variable $context = Get-AzStorageAccount -ResourceGroupName $StorageAccountResourceGroupName -Name $ProfileStorageAccount #region retrieve details per hostpool # Retrieves the hostpools => Alter the script here to check for additional host pools $hostpools = get-azwvdhostpool foreach ($hostpool in $hostpools) { $wvdrg = Get-AzResource -ResourceId $hostpools.Id # This is tricky, so if you only need 1 host pool remove the foreach loop completely and comment the line below $hostpools = $hostpool #region gather all open files & sessions $OpenFiles = Get-AzStorageFileHandle -Context $Context.Context -ShareName $ProfileShare -Recursive $UserSessions = Get-AzWvdUserSession -HostPoolName $hostpools.Name -ResourceGroupName $wvdrg.ResourceGroupName | Select-Object ActiveDirectoryUserName, ApplicationType, SessionState, UserPrincipalName, name #endregion #region fill Open Files array $pathusers = @() foreach ($openfile in $OpenFiles) { If ($openfile.path) { #Write-host $openfile.Path $FilePath = $openfile.Path.Split("/")[0] $pathusers += $FilePath } } $pathusers = $pathusers | Select-Object -Unique #endregion #region fill Open Sessions array $sessionusers = @() foreach ($usersession in $UserSessions) { If ($usersession) { #Write-host $usersession $Username = $UserSession.ActiveDirectoryUserName.Split("\")[1] $sessionusers += $Username } } $sessionusers = $sessionusers | Select-Object -Unique #endregion #region loop through every open file and find a corresponding user session foreach ($pathuser in $pathusers) { If ($sessionusers -contains $pathuser) { Write-host -ForegroundColor green "Active session user: " $pathuser } else { If ($mode -eq "alerting") { $OpenFilesDetails = Get-AzStorageFileHandle -Context $Context.Context -ShareName $ProfileShare -Recursive | Where-Object { $_.Path -like "*$($pathuser)*" } # the following retrieves the virtual machine name of the lingering VHDX file $IPNic = ((Get-AzNetworkInterface | Where-Object { $_.IpConfigurations.PrivateIpAddress -eq $($OpenFilesDetails.ClientIp.IPAddressToString[0]) }).virtualmachine).Id $vmname = ($IPNic -split '/') | Select-Object -Last 1 $VM = Get-AzVm -Name $vmname Write-host -ForegroundColor red "Inactive session user: $pathuser has a FSLogix mounted on the following virtual machine $vmname" } Else { $OpenFilesDetails = Get-AzStorageFileHandle -Context $Context.Context -ShareName $ProfileShare -Recursive | Where-Object { $_.Path -like "*$($pathuser)*" } # the following retrieves the virtual machine name of the lingering VHDX file $IPNic = ((Get-AzNetworkInterface | Where-Object { $_.IpConfigurations.PrivateIpAddress -eq $($OpenFilesDetails.ClientIp.IPAddressToString[0]) }).virtualmachine).Id $vmname = ($IPNic -split '/') | Select-Object -Last 1 $VM = Get-AzVm -Name $vmname Write-host -ForegroundColor red "Inactive session user: $pathuser has a FSLogix mounted on the following virtual machine $vmname" # double check whether or not you want to dismount the profile $YesNo = Read-Host "Are you sure you want to dismount the user profile off $pathuser on the following server $vmname: Yes/No" If ($YesNo -eq "Yes") { $domainupn = Read-Host "Please enter your domain admin username:" $domainpwd = Read-Host "Please enter your domain admin password:" $runDismount = Invoke-AzVMRunCommand -ResourceGroupName $VM.ResourceGroupName -Name $VM.Name -CommandId 'RunPowerShellScript' -ScriptPath "scripts\AzVMRunCommands\Clean-InVMLingeringFSLogixProfiles.ps1" -Parameter @{"Upn" = "$domainupn"; "Pass" = "$domainpwd";"pathuser" = $pathuser } If ($runDismount.Status -Ne "Succeeded") { Write-Error "Run failed" } else { Write-Host "FSLogix profile has been dismounted for $($pathuser) on $($vmname)" } } else { # Exit script Write-Host "We are now exiting the script, you've entered the wrong option: Yes/No is required" Exit } } } } #endregion } #endregion
Before launching the script above, make sure to save the script that needs to be run within the virtual machine.
Save the PowerShell script below as “InVMLingeringFSLogixProfiles.ps1” and alter the script path in the script above. The scripts can be download from my GitRepo as well.
param ( [Parameter(Mandatory = $true)] [string] $pathuser, [Parameter(Mandatory = $true)] [string] $upn, [Parameter(Mandatory = $true)] [string] $pass, [Parameter(Mandatory = $false)] [string] $OverrideErrorActionPreference = "Break" ) #This script is run within the virtual machine $ziptargetfolder = "c:\troubleshooting\" $innerscriptlocation = $ziptargetfolder + "Dismount-VHD.ps1" If (!(Test-Path $ziptargetfolder)) { mkdir $ziptargetfolder } @" `$ProfileNamingConvention = "Profile-" + "$pathuser" `$Volume = Get-Volume | Where-Object { `$_.filesystemlabel -eq `$ProfileNamingConvention } | % { Get-DiskImage -DevicePath `$(`$_.Path -replace "\\`$") } Dismount-DiskImage -ImagePath `$Volume.ImagePath "@ | Out-File -FilePath $innerscriptlocation $taskName = "Dismount-FSLogixProfile" $Action = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-NoProfile -NoLogo -NonInteractive -ExecutionPolicy Unrestricted -File $innerscriptlocation" -WorkingDirectory $ziptargetfolder $Settings = New-ScheduledTaskSettingsSet -Compatibility Win8 $TaskPath = "\CustomTasks" Register-ScheduledTask -TaskName $taskName -User $upn -Password $pass -RunLevel Highest -Action $Action -Settings $Settings Start-ScheduledTask -TaskName $taskName -TaskPath $TaskPath while ((Get-ScheduledTask -TaskName $taskName).State -ne 'Ready') { Start-Sleep -Seconds 2 } Unregister-ScheduledTask -TaskName $taskName -Confirm:$False Remove-Item -Path $innerscriptlocation -Recurse -Force
The scripts are provided as-is, please be very careful and test run the scripts on a “test” environment or an environment that allows you to perform some quick checks and tests. Dismounting VHD(X) files can cause unwanted effects when performed against an Active user.
Thank you for reading through this blog post, I hope I have been able to assist in troubleshooting FSLogix profile mounting issues.
If you encounter any new insights, feel free to drop me a comment or contact me via mail or other social media channels
The post How to retrieve lingering FSLogix profiles on Windows Virtual Desktop, mounted from an Azure File share appeared first on Tunecom.
]]>The post How to resolve WVD-Agent service is being stopped: NAME_ALREADY_REGISTERED, This VM needs to be properly registered in order to participate in the deployment appeared first on Tunecom.
]]>The following picture shows our host which is unavailable.
Logged on to the host, we can see that the RDAgentBootloader has stopped.
Looking at the event log of the specific host, you’ll see an error entry each time you try to restart the RDAgentBootLoader service.
Error message: How to resolve WVD-Agent service is being stopped: NAME_ALREADY_REGISTERED, This VM needs to be properly registered in order to participate in the deployment
Navigate to the host pool section, select your host. When you click on the settings icon, you can remove the host from the host pool.
If you have just installed the RDAgent & RDAgentBootloader, please skip step 2 and go to step 3.1. If you are not sure whether the RDAgent install went fine and you’ve entered a registration key before. Continue here.
Navigate to your host pool and select “Registration key”.
Select “Generate new key”.
Enter an expiration date and time for this specific key and select “OK”.
You can now copy or download the registration key.
Continue to step 3.2
Restart the RDAgentBootloader service or restart the entire virtual machine if you feel more comfortable in doing so.
On your WVD host download the latest version of the following software:
RDAgent: link to Microsoft Docs
RDAgentbootloader: link to Microsoft Docs
If you have previously installed the RDAgent & RDAgentBootLoader, make sure to remove it first.
During the installation process of the RDAgent, you will be prompted to enter the registration key. Fill in the key that you have copied or downloaded.
After having installed the RDAgent, please install the RDAgentBootLoader.
Reboot the WVD host and verify if the host is available in the pool again.
Thank you for reading through this blog post, I hope I have been able to assist in resolving this issue.
If you encounter any new insights, feel free to drop me a comment or contact me via mail or other social media channels
The post How to resolve WVD-Agent service is being stopped: NAME_ALREADY_REGISTERED, This VM needs to be properly registered in order to participate in the deployment appeared first on Tunecom.
]]>The post How to fix RD Client iOS error code 0x3000015 for Windows Virtual Desktop appeared first on Tunecom.
]]>0x3000015, a screen smasher for sure!
To avoid hitting the repair shop for a new screen, let me walk you through a couple of steps to fix this issue.
Starting with the screenshots below, I already have a workspace configured which points to 2 of my Windows Virtual Desktop tenants.
For the purpose of this demo and blog, I would like to setup a new workspace, so I can connect to another series of virtual desktops.
When pressing the “Edit” button, select “delete”
Press “delete” again in order to confirm and permanently delete that workspace.
Great so far, no workspaces to show:
Now let’s hit the “+” sign
And select “Add Workspace”
Enter the Windows Virtual Desktop webfeed url : “https://rdweb.wvd.microsoft.com” and enter next
You’re then prompted to authenticate against your Azure Active Directory Tenant , so use your e-mail address or UPN (User Principal Name) that has access to a Windows Virtual Desktop workspace to login.
Awesome, here is my new workspace, and as you can see I have a session desktop available to launch.
Now, you would expect that if you select your session desktop, you’ll end up in your Windows 10 environment..
Guess again! 0x3000015, “we couldn’t connect to the remote desktop gatexway because of an internal error. If this keeps happening contact your network administrator for assistance.”
Now, let me be that network administrator for you today!
In order to resolve this issue, follow the steps below!
To start of with a clean sheet, close all open apps on your iOS device and navigate to the settings pane.
Scroll down through your apps until you reach the RD Client app.
Select the RD Client app.
And scroll down to the “WVD Security Tokens” setting. Slide this slider to the right and make sure it’s green and selected.
Enable “Delete on App Launch” in the “WVD Security Tokens” settings
Now let’s navigate back to our Remote Desktop Client app.
And launch your previously added desktop
Enter your username and password
Woohoo! Here we have our rich Windows 10 experience on iOS provided by Windows Virtual Desktop.
Thank you for reading through this blog post, I hope I have saved you some time on researching the 0x3000015 error message.
If you encounter any new insights, feel free to drop me a comment or contact me via mail or other social media channels
The post How to fix RD Client iOS error code 0x3000015 for Windows Virtual Desktop appeared first on Tunecom.
]]>The post Teams on Windows Virtual Desktop (TeamsOnWVD Powershell Module) appeared first on Tunecom.
]]>Let me first set the stage and the reason why I’ve written this small powershell module.
When browsing the web for best practices on installing Microsoft Teams on Windows Virtual Desktop, I often encountered colleagues struggling with getting the Microsoft Teams (Machine-Wide) installer up and running. And a lot of questions have been raised as well with regards to un-installing teams completely.
With this powershell module, I hope to provide an added value to installing and un-installing Teams in just minutes.
Below you can find a step by step guide on how to use the powershell module, and see it’s effects on your systems.
Below screenshot is a view on my Windows Virtual Desktop Host, as you can see in the start menu, I don’t have any entries so far for Microsoft Teams.
And if I take a look at my App & Features, nothing to show here as well.
An important step, before you install Teams on your Windows Virtual Desktop host, is the Teams regkey, that indicates that it is a WVD environment:
@Christaan Brinkhoff has a summarizing blogpost on all WVD recommendations. Check here for more details.
This is the regkey we will be needing:
[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Teams\IsWVDEnvironment] Type: REG_DWORD Value: 0x1
As you can see in the screenshot below, that registry key is missing.
Now, let’s go to our TeamsOnWVD module, follow the steps in the screenshot below to install and import the module.
Install-Module TeamsOnWVD Import-Module TeamsOnWVD Get-Module -Name TeamsOnWVD
After having imported the TeamsOnWVD module, run the install-teams64bit command.
Install-Teams64bit
And this is where the magic happened, we’ve made sure that the registry key is added, and downloaded the latest version of the Teams msi file and installed it with the right set of parameters.
After running the cmdlet, Teams has been published on our desktop and is ready to be launched.
Below screenshot shows that our registry key is available now.
So, we’ve installed Microsoft Teams, let’s make sure that everything works for our end-users.
The screenshot below allows me to connect to one of my session desktops.
After have connected to my desktop, Microsoft Teams is auto-launching in my session.
And here we go, we have a fully functioning Microsoft Teams client on Windows Virtual Desktop, which is available to all my users.
If we want to un-install Microsoft Teams on our WVD hosts, we have a couple of things to check.
First of let us check which versions of Teams are available, below screenshot only indicates the “Machine Wide” installer, but User installed Teams versions might be here as well.
The registry key that we needed earlier is still there, so we might want to clean that one up.
To quickly uninstall all versions on Teams on your WVD hosts, run the Remove-Teams64bit cmdlet. This will check for any versions installed on your system and will cleanup all end-user repositories and the registry key.
Remove-Teams64bit
During the removal process, you will see that the Teams Icon is removed from my desktop.
And the registry key has been removed.
My Apps & Features have been cleaned up as well.
And last but not least, no more entries when searching in Windows Search.
Thank you al for reading and discovering my recent blog-post, if you encounter any issues while downloading and using the TeamsOnWVD powershell module. Reach out to me, so I can make the necessary improvements and help you out as soon as possible.
The post Teams on Windows Virtual Desktop (TeamsOnWVD Powershell Module) appeared first on Tunecom.
]]>