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 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 Moving your data to a serverless infrastructure with Azure Files and Active Directory Authentication (Preview) appeared first on Tunecom.
]]>Now it’s time to integrate this with our existing Windows Server Active Directory Infrastructure
We are now able to set NTFS permissions and ACLs based on our existing Windows Server AD on an Azure Fileshare. This blogpost takes you through the necessary steps to automate the process shown below.
Before we can activate all of this, we have a couple of prerequisites:
Background info: Change the initial variables to meet your environment needs, I have chosen France Central as a region to deploy our Storage Account.
Download the script here, or copy paste the scriptblock below. After running the script you’ll see that new or additional file shares have been created.
######################## # # Name: Azure Files Create Storage Account # Author: Yannick Dils # Version: v0.1 # ######################## Write-Host "Let's get started" -ForegroundColor Magenta Sleep 3 ######################## # # Install or import the required modules # ######################## start-process powershell –verb runAs -ArgumentList "Install-Module -Name Az.Accounts -RequiredVersion 1.6.4 -Force" -WindowStyle Hidden Import-Module Az.Accounts start-process powershell –verb runAs -ArgumentList "Install-Module -Name Az.Resources -RequiredVersion 1.11.0 -Force" -WindowStyle Hidden Import-Module Az.Resources start-process powershell –verb runAs -ArgumentList "Install-Module -Name Az.Storage -RequiredVersion 1.11.0 -Force" -WindowStyle Hidden Import-Module Az.Storage ######################## # # Create Naming Convention + Location and Name Variables # ######################## Write-Host "Step 1 : Let's define some variables and naming conventions`n" -ForegroundColor Cyan Write-Host "Enter a 3 letter word abbreviation for your customer or project (example: tuc, vdc) : " -ForegroundColor Yellow -NoNewline $Cus = Read-Host Write-Host "Enter a 3 letter word abbreviation for your environment (example: hub, prd, tst, dev, acc) : " -ForegroundColor Yellow -NoNewline $Env = Read-host $FullLocation = "France Central" $NamingConv = "st" + "lrs" + $Cus + "frc" + $Env + "file" $SAFILE = $NamingConv $RGDATA = $Cus + "-hub-storage-rg" Write-Host "Enter a name for your fileshare (example: fileserver, profiles,..) : " -ForegroundColor Yellow -NoNewline $FileShareName = Read-host Write-Host "`nStep 2 : Based on the naming convention provided in the script, the following has been identitfied:`n" -ForegroundColor Cyan Write-Host "Location : $FullLocation" -ForegroundColor Green Write-Host "Storage Account Name : $SAFILE" -ForegroundColor Green Write-Host "Fileshare Name : $FileShareName" -ForegroundColor Green Write-Host "Resource Group Name : $RGDATA" -ForegroundColor Green ######################## # # Login to Az Account # ######################## Write-Host "`nStep 3 : Before we continue, we need to log you into your Azure Account" -ForegroundColor Cyan Login-AzAccount ######################## # # Select the Azure Subscription where you want to create your storage account # ######################## $Subscriptions = Get-AzSubscription Write-Host "Step 4 : These are your available subscriptions`n" -ForegroundColor Cyan Write-host $Subscriptions.Name -ForegroundColor Cyan -BackgroundColor Black Write-Host "`nStep 5 : Enter the subscription name : " -ForegroundColor Yellow -NoNewline $SubscriptionName = Read-host Select-AzSubscription -Subscription $SubscriptionName ######################## # # Verify if an existing resource group exists with the name in variable $RGDATa, create a new one if not # ######################## $RG = Get-AzResourceGroup -Name $RGDATA -ErrorAction SilentlyContinue If ($RG) { Write-Host "Step 6 : A Resource Group already exists with the name $RGDATA, no need to create one" -ForegroundColor Cyan } Else { Write-Host "Step 6 : A Resource Group is created with the name $RGDATA" -ForegroundColor Cyan New-AzResourceGroup -Name $RGDATA -Location $FullLocation } ######################## # # Create a new Storage Account located in the $FullLocation region based on the input variables # ######################## $SA = Get-AzStorageAccount -ResourceGroupName $RGDATA -Name $SAFILE.ToLower() -ErrorAction SilentlyContinue $StorageShare = Get-AzStorageShare -Name $FileShareName -Context $sa.Context -ErrorAction SilentlyContinue If ($SA) { Write-Host "Step 7 : A Storage Account already exists with the name $SAFILE, no need to create one" -ForegroundColor Cyan If ($StorageShare) { Write-Host "Step 8 : A File Share already exists with the name $FileShareName, no need to create one" -ForegroundColor Cyan } Else { Write-Host "Step 8 : A File Share is created with the name $FileShareName" -ForegroundColor Cyan New-AzStorageShare -Name $FileShareName -Context $SA.Context } } Else { Write-Host "Step 7 : A Storage Account is created with the name $SAFILE" -ForegroundColor Cyan New-AzStorageAccount -ResourceGroupName $RGDATA -Name $SAFILE.ToLower() -Kind StorageV2 -SkuName Standard_LRS -Location $FullLocation -AccessTier Hot Write-Host "Step 8 : A File Share is created with the name $FileShareName" -ForegroundColor Cyan $ctx = Get-AzStorageAccount -ResourceGroupName $RGDATa -Name $SAFILE New-AzStorageShare -Name $FileShareName -Context $ctx.Context } Write-Host "End of script" -ForegroundColor Magenta ######################## # # End of script # ######################## SLeep 5
Since it’s still in public preview, you need to perform a couple of manual steps in order to join your Azure Storage account to your Windows Server Active Directory Domain. Looking at Azure AD Domain Services, this is an additional switch / parameters you need to provide in order to allow Azure AD DS authentication. I assume that the product team will try to provide the same type of deployment feature with regards to joining your traditional active directory domain.
The following link provides you a step by step guide in how to perform the required steps to join your domain. So feel free to read through it. But wait!
I’ve taken the opportunity to automate the necessary steps and put it in the following script. Note: Make sure to run it from a domain joined machine or directly on your domain controller.
Download the script here, or copy paste the scriptblock below. After running the script your Azure Storage Account will be joined to the domain, this is how it could look like.
######################## # # Name: Azure Files Domain Join Script # Author: Yannick Dils # Version: v0.1 # ######################## Write-Host "Let's get started" -ForegroundColor Cyan Sleep 3 ######################## # # Install or import the required modules # ######################## start-process powershell –verb runAs -ArgumentList "Install-Module -Name Az.Accounts -RequiredVersion 1.6.4 -Force" -WindowStyle Hidden Import-Module Az.Accounts start-process powershell –verb runAs -ArgumentList "Install-Module -Name Az.Resources -RequiredVersion 1.11.0 -Force" -WindowStyle Hidden Import-Module Az.Resources start-process powershell –verb runAs -ArgumentList "Install-Module -Name Az.Storage -RequiredVersion 1.11.0 -Force" -WindowStyle Hidden Import-Module Az.Storage start-process powershell –verb runAs -ArgumentList "Install-Module -Name ActiveDirectory -Force" -WindowStyle Hidden Import-Module ActiveDirectory ######################## # # Change the execution policy to unblock importing AzFilesHybrid.psm1 module # ######################## Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Currentuser -Force -ErrorAction SilentlyContinue ######################## # # Download The AzFilesHybird powershell modules # ######################## Write-Host "Step 1 : We will now download the Azure Files Hybrid powershell modules into a C:\Temp directory" -ForegroundColor Cyan $DownloadLink = "https://github.com/Azure-Samples/azure-files-samples/releases/download/AzFilesHybrid-0.1.0.0/AzFilesHybrid.zip" $TempDir = "C:\Temp" $Output = "C:\Temp\AzFilesHybrid.zip" $Path = Test-Path $TempDir If ($Path -eq $true) { Write-Host "Step 2 : The C:\Temp path already exists, no need to create one" -ForegroundColor Cyan } Else { Write-host "Step 2 : We are creating a temp directory C:\Temp" -ForegroundColor Cyan $DontShow = mkdir $TempDir } (New-Object System.Net.WebClient).DownloadFile($DownloadLink, $output) ######################## # # Navigate to where AzFilesHybrid is unzipped and stored and run to copy the files into your path # ######################## cd $TempDir Expand-Archive -LiteralPath $Output -DestinationPath $TempDir -Force .\CopyToPSPath.ps1 ######################## # # Import AzFilesHybrid module # ######################## Import-Module -name AzFilesHybrid ######################## # # Login with an Azure AD credential that has either storage account owner or contributer RBAC assignment # ######################## Write-Host "Step 3 : Let's connect to our Azure Subscriptions" -ForegroundColor Cyan Sleep 3 Connect-AzAccount ######################## # # Select the Azure Subscription where your Storage Account is located # ######################## $Subscriptions = Get-AzSubscription Write-Host "Step 4 : These are your available subscriptions" -ForegroundColor Cyan Write-host $Subscriptions.Name -ForegroundColor Cyan -BackgroundColor Black Write-Host "Step 5 : Enter the subscription name : " -ForegroundColor Yellow -NoNewline $SubscriptionName = Read-host Select-AzSubscription -Subscription $SubscriptionName ######################## # # Retrieve your current Windows Server Active Directory Domain Details # ######################## $domaindetails = Get-ADDomain #Register the target storage account with your active directory environment under the target OU $Domain = $domaindetails.DNSRoot ######################## # # Retrieve your Resource Groups and Storage Accounts located in your Azure Subscription # ######################## ############# # # Resource Groups # ############# $ResourceGroups = Get-AzResourceGroup | Select ResourceGroupName Write-Host "Step 6 : These are the available resource groups: " -ForegroundColor Cyan Foreach ($RG in $ResourceGroups) { Write-Host $RG.ResourceGroupName -ForegroundColor Cyan -BackgroundColor Black } Write-Host "Step 7 : Enter the resource group name, where your Azure Files storage account is located: " -ForegroundColor Yellow -NoNewline $ResourceGroup = Read-host ############# # # Storage Accounts # ############# $StorageAccounts = Get-AzStorageAccount -ResourceGroupName $ResourceGroup Write-Host "Step 8 : These are the available storage accounts : " -ForegroundColor Cyan Foreach ($SA in $StorageAccounts) { Write-Host $SA.StorageAccountName -ForegroundColor Cyan -BackgroundColor Black } Write-Host "Step 9 : Enter the storage account name, where your Azure Files share is located: " -ForegroundColor Yellow -NoNewline $StorageAccount = Read-host ######################## # # Create or use an Organizational Unit where our Azure Files storage account will be located # ######################## $AzureFilesOUName = "AzureFiles" Write-Host "Step 10 : We now want to join the Azure File Storage Accounts to the domain in an OU called $AzureFilesOUName" -ForegroundColor Cyan $OU = Get-ADOrganizationalUnit -Filter 'Name -like $AzureFilesOUName' If ($OU) {Write-Host "Step 11 : The AzureFiles OU Already Exists, no need to create one" -ForegroundColor Cyan} Else { Write-Host "Step 11 : The OU needs to be created, we will now create a new OU called $AzureFilesOUName" -ForegroundColor Cyan $AzureFilesOU = New-ADOrganizationalUnit -Name $AzureFilesOUName } ######################## # # Join the storage account into the domain, located in the required organizational unit # ######################## Join-AzStorageAccountForAuth -ResourceGroupName $ResourceGroup -StorageAccountName $StorageAccount -Domain $Domain -DomainAccountType ComputerAccount -OrganizationalUnitName "Servers" ######################## # # Verify Domain Join # ######################## $azurefiles = Get-AzStorageAccount -ResourceGroupName $ResourceGroup -Name $StorageAccount $ADService = $azurefiles.AzureFilesIdentityBasedAuth.DirectoryServiceOptions Write-Host "Step 12 : Let us now verify if the directory service is ok" -ForegroundColor Cyan Sleep 5 If ($ADService -eq "AD") { Write-host "Step 13 : All OK" -ForegroundColor Green } Else { Write-host "Step 13 : Something went wrong ;)" -ForegroundColor Red } Write-Host "Step 14 : Let us now verify if the directory authentication is ok" -ForegroundColor Cyan Sleep 5 $ADInfo = $azurefiles.AzureFilesIdentityBasedAuth.ActiveDirectoryProperties If ($ADInfo.DomainName -eq $Domain) { Write-host "Step 15 : All OK" -ForegroundColor Green } Else { Write-host "Step 15 : Something went wrong ;)" -ForegroundColor Red } Write-host "End of script" -ForegroundColor Cyan Sleep 5 ######################## # # End of script # ########################
Now that we have our storage account joined to the domain. We need to assign the right set of role based access controls on the Azure File Share level.
3 built-in roles can be identified to set access to the Azure File Share:
The following script can assist you in setting the right set of permissions for a certain security principal. Note: The security principal must be entered in a UPN format (username@corp.something)
Download the script here, or copy paste the scriptblock below. After running the script you will be able to mount the Azure File share in the context of the security principal.
######################## # # Name: Azure Files RBAC # Author: Yannick Dils # Version: v0.1 # ######################## Write-Host "Let's get started" -ForegroundColor Cyan Sleep 3 ######################## # # Set General Variables and Naming Conventions # ######################## Write-Host "Step 1 : Let's define some variables and naming conventions" -ForegroundColor Cyan Write-Host "Enter a 3 letter word abbreviation for your customer or project (example: tuc, vdc) : " -ForegroundColor Yellow -NoNewline $Cus = Read-Host Write-Host "Enter a 3 letter word abbreviation for your environment (example: hub, prd, tst, dev, acc) : " -ForegroundColor Yellow -NoNewline $Env = Read-host $FullLocation = "France Central" $NamingConv = "st" + "lrs" + $Cus + "frc" + $Env + "file" $SAFILE = $NamingConv $RGDATA = $Cus + "-hub-storage-rg" Write-Host "Enter a name for your fileshare (example: fileserver, profiles,..) : " -ForegroundColor Yellow -NoNewline $FileShareName = Read-host ######################## # # Set the names of the Azure Files Roles into Variables # ######################## Write-Host "Step 2 : Let's store the Azure File Storage Roles into variables for later use" -ForegroundColor Cyan $Reader = "Storage File Data SMB Share Reader" # R permissions $Contributor = "Storage File Data SMB Share Contributor" # R W D permissions $ElevatedContributor ="Storage File Data SMB Share Elevated Contributor" # R W D M permissions ######################## # # Enter the specific group in UPN format and store them into variables # ######################## Write-Host "Step 3 : Enter the security principal that needs to receive the required access controls (UPN format required):`n" -ForegroundColor Cyan Write-Host "Read Group = Storage File Data SMB Share Reader # R permissions" -ForegroundColor Green Write-Host "Contributor Group = Storage File Data SMB Share Contributor # R W D permissions" -ForegroundColor Green Write-Host "ElevatedContributor = Storage File Data SMB Share Elevated Contributor # R W D M permissions`n" -ForegroundColor green Write-Host "Enter the Reader Security Principal UPN Name : (Leave empty if not required) :" -ForegroundColor Yellow -NoNewline $ReadGroup = Read-Host Write-Host "Enter the Contributor Security Principal UPN name : (Leave empty if not required) :" -ForegroundColor Yellow -NoNewline $ContributorGroup = Read-Host Write-Host "Elevated Contributor Security Principal UPN name : (Leave empty if not required) :" -ForegroundColor Yellow -NoNewline $ElevatedContributorGroup = Read-host ######################## # # Set the scope onto our subscription and specific Azure File Share # ######################## Write-Host "`nStep 4 : Let's set our subscription scope`n" -ForegroundColor Cyan Login-AzAccount $Subscriptions = Get-AzSubscription Write-Host "Step 5 : These are your available subscriptions`n" -ForegroundColor Cyan Write-host $Subscriptions.Name -ForegroundColor Cyan -BackgroundColor Black Write-Host "`nStep 6 : Enter the subscription name : " -ForegroundColor Yellow -NoNewline $SubscriptionName = Read-host Select-AzSubscription -Subscription $SubscriptionName $Subscription = Get-AzSubscription -SubscriptionName $SubscriptionName $SubScriptionID = $Subscription.SubscriptionId $scope = "/subscriptions/$subscriptionID/resourceGroups/$RGDATA/providers/Microsoft.Storage/storageAccounts/$SAFILE/fileServices/default/fileshares/$fileShareName" ######################## # # Let's assign the role to the specified security principal and scope # ######################## ########## # # Reader Group # ########## If($ReadGroup -eq "") { Write-Host "You haven't entered any Reader Group, we will skip this role assignment for now" -ForegroundColor Yellow } else { Write-Host "We are now verifying the Reader Group role assignment for Security Principal $ReadGroup" -ForegroundColor Cyan $RoleAssignment = Get-AzRoleAssignment -SignInName $ReadGroup -RoleDefinitionName $Reader -Scope $scope -ErrorAction SilentlyContinue If ($RoleAssignment) { Write-host "The role assignment already exists, we don't need to add the specific assignment" -ForegroundColor Cyan } else { Write-Host "The role assignment is being created" -ForegroundColor Cyan New-AzRoleAssignment -SignInName $ReadGroup -RoleDefinitionName $Reader -Scope $scope } } ########## # # Contributor Group # ########## If($ContributorGroup -eq "") { Write-Host "You haven't entered any Contributor Group, we will skip this role assignment for now" -ForegroundColor Yellow } else { Write-Host "We are now verifying the Contributor Group role assignment for Security Principal $ContributorGroup" -ForegroundColor Cyan $RoleAssignment = Get-AzRoleAssignment -SignInName $ContributorGroup -RoleDefinitionName $Contributor -Scope $scope -ErrorAction SilentlyContinue If ($RoleAssignment) { Write-host "The role assignment already exists, we don't need to add the specific assignment" -ForegroundColor Cyan } else { Write-Host "The role assignment is being created" -ForegroundColor Cyan New-AzRoleAssignment -SignInName $ContributorGroup -RoleDefinitionName $Contributor -Scope $scope } } ########## # # Elevated Contributor Group # ########## If($ElevatedContributorGroup -eq "") { Write-Host "You haven't entered any Elevated Contributor Group, we will skip this role assignment for now" -ForegroundColor Yellow } else { Write-Host "We are now verifying the Elevated Contributor Group role assignment for Security Principal $ElevatedContributorGroup" -ForegroundColor Cyan $RoleAssignment = Get-AzRoleAssignment -SignInName $ElevatedContributorGroup -RoleDefinitionName $ElevatedContributor -Scope $scope -ErrorAction SilentlyContinue If ($RoleAssignment) { Write-host "The role assignment already exists, we don't need to add the specific assignment" -ForegroundColor Cyan } else { Write-Host "The role assignment is being created" -ForegroundColor Cyan New-AzRoleAssignment -SignInName $ElevatedContributorGroup -RoleDefinitionName $ElevatedContributor -Scope $scope } } #Get-AzRoleAssignment -scope $scope Write-Host "`nEnd of Script" -ForegroundColor Cyan Sleep 5
In the previous section we’ve set the share level permissions, as with traditional file server installations or implementations, we would set an additional layer of security, called NTFS permissions.
By mounting the Azure File share together with storage access key you we are elevating our privileges, allowing us to set fine grained ACLs.
The following script will automatically mount the drive-letter you choose based on the Access Keys of your storage account
Download the script here or copy the scriptblock below.
######################## # # Name: Mount Azure File Share # Author: Yannick Dils # Version: v0.1 # ######################## Write-Host "Let's get started" -ForegroundColor Cyan Sleep 3 ######################## # # Create Naming Convention + Location and Name Variables # ######################## Write-Host "Step 1 : Let's define some variables and naming conventions`n" -ForegroundColor Cyan Write-Host "Enter a 3 letter word abbreviation for your customer or project (example: tuc, vdc) : " -ForegroundColor Yellow -NoNewline $Cus = Read-Host Write-Host "Enter a 3 letter word abbreviation for your environment (example: hub, prd, tst, dev, acc) : " -ForegroundColor Yellow -NoNewline $Env = Read-host $FullLocation = "France Central" $NamingConv = "st" + "lrs" + $Cus + "frc" + $Env + "file" $SAFILE = $NamingConv $RGDATA = $Cus + "-hub-storage-rg" Write-Host "Enter a name for your fileshare (example: fileserver, profiles,..) : " -ForegroundColor Yellow -NoNewline $FileShareName = Read-host Write-Host "Enter a driveletter for your fileshare (example: F, G, P..) : " -ForegroundColor Yellow -NoNewline $DriveLetter = Read-Host ######################## # # Login with an Azure AD credential that has either storage account owner or contributer RBAC assignment # ######################## Write-Host "Step 2 : Let's connect to our Azure Subscriptions" -ForegroundColor Cyan Sleep 3 Connect-AzAccount ######################## # # Select the Azure Subscription where your Storage Account is located # ######################## $Subscriptions = Get-AzSubscription Write-Host "Step 3 : These are your available subscriptions" -ForegroundColor Cyan Write-host $Subscriptions.Name -ForegroundColor Cyan -BackgroundColor Black Write-Host "`nEnter the subscription name : " -ForegroundColor Yellow -NoNewline $SubscriptionName = Read-host Select-AzSubscription -Subscription $SubscriptionName ######################## # # Retrieve the Storage Account Details and Access Tokens # ######################## Write-Host "Step 4 : We are now retrieving the storage account details and access tokens" -ForegroundColor Cyan $storageAccount = Get-AzStorageAccount -ResourceGroupName $RGDATA -Name $SAFILE $storageAccountKeys = Get-AzStorageAccountKey -ResourceGroupName $RGDATA -Name $SAFILE ######################## # # Retrieve the FileShare Details # ######################## Write-Host "Step 5 : We are now retrieving the file share details" -ForegroundColor Cyan $fileShare = Get-AzStorageShare -Context $storageAccount.Context | Where-Object { $_.Name -eq $fileShareName -and $_.IsSnapshot -eq $false } if ($fileShare -eq $null) { throw [System.Exception]::new("Azure file share not found") } ######################## # # Mount the Azure File Storage # ######################## Write-Host "Step 6 : Your file share is being mounted" -ForegroundColor Cyan $password = ConvertTo-SecureString -String $storageAccountKeys[0].Value -AsPlainText -Force $credential = New-Object System.Management.Automation.PSCredential -ArgumentList "AZURE\$($storageAccount.StorageAccountName)", $password New-PSDrive -Name $DriveLetter -PSProvider FileSystem -Root "\\$($fileShare.StorageUri.PrimaryUri.Host)\$($fileShare.Name)" -Credential $credential -Persist Write-Host "Step 7 : Let's open up our file share in an explorer window" -ForegroundColor Cyan $path = $DriveLetter + ":\" Invoke-Item $path Write-Host "`nEnd of script" -ForegroundColor Cyan Sleep 5 ######################## # # End of script # ########################
Next steps could be defined as the following
Feel free to comment or provide additional insights on the scripts and documentation provided.
The post Moving your data to a serverless infrastructure with Azure Files and Active Directory Authentication (Preview) appeared first on Tunecom.
]]>The post Virtual Datacenter Concept | Introduction appeared first on Tunecom.
]]>The following series of posts is a direct reference to the Virtual Datacenter Concept provided by Microsoft as part of the Cloud Adoption Framework.
My intention is to provide you with a holistic overview, lessons learned and best practices over the last couple of years during the design and implementation phase of the Azure Virtual Datacenter.
VDC is a series of guidelines that can be interpreted in various ways, the main goal of the VDC is to be able to deploy and manage your Azure resources in a secure and proper fashion.
When looking at AzOps and AzSec we are striving to build an operational and security model that fits the customers needs and wishes, which can still provide the promised scalability, flexibility and cloud optimization benefits. AzOps and AzSec should play a supporting role in the application landscape
Taking into account the perspective of DevOps and DevSecOps the VDC should facilitate the application development team to perform CI/CD in a way that the entire IT infrastructure which is oriented around your Line-of-business applications closes the gap between the operations and deployment lifecycle.
Planning Cloud Adoption is key, we’ve often seen Cloud environments that have been setup with no clear vision of the future application and IT landscape, which ended up in consuming a lot of credits that could’ve been spent more wisely.
On your road to onboarding IaaS, PaaS and SaaS the Virtual Datacenter Concept is your hitchhikers guide to the galaxy. It’s often seen as a way to easily lift and shift your servers, when looking at the VDC from a broader perspective, it can be a good fit to start transitioning to PaaS and SaaS.
Below infographic shows a typical scenario where a DTAP (Development, Test, Acceptance, Production) environment has been setup and during deployment, key components have gone missing.
In order to fix the above situation, we’ve got a couple of options, either deploy additional equipment on Azure or consolidate and optimize to make the best use of all Azure Resources.
Below IaaS overview shows how we can consolidate the central shared services and make use of unique Azure techniques like vnet peering to tie everything together in a secure way.
In the above example we’ve seen a full blow DTAP environment located on Azure infrastructure. However Cloud Adoption isn’t about moving virtual machines to the Cloud. When moving to the cloud our goal is to provide our end-customers with tools and applications that are always on and can meet the necessary capacity demands.
As a start we would primordially get started with the Virtual Datacenter Basic setup. This allows you to extend your on-premises workloads to Azure with a minimum amount of resources.
The basic setup consists of :
Hope you liked the introduction, and sort of know where we are working towards in this blogpost series.
The following aspects of the virtual datacenter concept will be highlighted in the following upcoming posts:
The post Virtual Datacenter Concept | Introduction appeared first on Tunecom.
]]>