We had a requirement to migrated 8000+ Citrix User UPM profiles across globe to FSLogix Profiles (.VHDX) as customer wanted to move from Citrix to AVD. This was a very challenging requirement due to new experience
Post Virtual Machine Deletion in Azure, few resources like Disk,NICs,NSG,Public IP etc.. will remain exists so use below script to cleanup all these orphaned resources
## Gather orphaned resources details using below link and use below script to delete all orphaned resources
https://github.com/scautomation/AzureResourceGraph-Examples/blob/master/resourceQueries/Orphaned%20Resources/OrphanedResource.MD
##########################DeleteOrphanedDisk##########################
$csv = Import-Csv "disk.csv" #name of csv file
$filetim = (Get-Date).tostring("dd-MM-yyyy-hh-mm")
$Logfile = "log-deletedisk-$filetim.log"
Function LogWrite
{
Param ([string]$logstring)
Add-content $Logfile -value $logstring
}
Start-Transcript -Path $Logfile
Stop-Transcript
LogWrite " "
LogWrite " "
LogWrite "***** LogFile *****"
LogWrite " "
LogWrite " "
$csv | ForEach-Object {
$diskname = $_.NAME
$state = $_.DISKSTATE
$resourcegroup = $_.RESOURCEGROUP
$location = $_.LOCATION
if($state -like "Unattached")
{
$tim = (Get-Date).tostring("dd-MM-yyyy-hh:mm:ss")
LogWrite "$tim - Deleting disk $diskname in $resourcegroup of Location - $location"
Write-Host -ForegroundColor Cyan "Deleting Disk $diskname in $resourcegroup of Location - $location"
Remove-AzDisk -ResourceGroupName $resourcegroup -DiskName $diskname -Force
}
else
{
Write-Host -ForegroundColor Red "Failed to delete the disk $diskname in $resourcegroup of Location - $location since it is Attached"
$tim = (Get-Date).tostring("dd-MM-yyyy-hh:mm:ss")
LogWrite "$tim - Failed to delete the disk $diskname in $resourcegroup of Location - $location since it is Attached"
}
}
#####################################################################
##########################DeleteOrphanedNICs##########################
$csv = Import-Csv "nic.csv" #name of csv file
$filetim = (Get-Date).tostring("dd-MM-yyyy-hh-mm")
$Logfile = "log-$filetim.log"
Function LogWrite
{
Param ([string]$logstring)
Add-content $Logfile -value $logstring
}
Start-Transcript -Path $Logfile
Stop-Transcript
LogWrite " "
LogWrite " "
LogWrite "***** LogFile *****"
LogWrite " "
LogWrite " "
$csv | ForEach-Object {
$nicname = $_.NAME
$resourcegroup = $_.RESOURCEGROUP
$location = $_.LOCATION
$tim = (Get-Date).tostring("dd-MM-yyyy-hh:mm:ss")
LogWrite "$tim - Deleting NIC $nicname in $resourcegroup of Location - $location"
Write-Host -ForegroundColor Cyan "Deleting NIC $nicname in $resourcegroup of Location - $location"
Remove-AzNetworkInterface -Name $nicname -ResourceGroup $resourcegroup -Force
}
#####################################################################
##########################DeleteOrphanedNSGs#########################
$csv = Import-Csv "nsg.csv" #name of csv file
$filetim = (Get-Date).tostring("dd-MM-yyyy-hh-mm")
$Logfile = "log-deleteNSG-$filetim.log"
Function LogWrite
{
Param ([string]$logstring)
Add-content $Logfile -value $logstring
}
Start-Transcript -Path $Logfile
Stop-Transcript
LogWrite " "
LogWrite " "
LogWrite "***** LogFile *****"
LogWrite " "
LogWrite " "
$csv | ForEach-Object {
$nsgname = $_.RESOURCE
$resourcegroup = $_.RESOURCEGROUP
$location = $_.LOCATION
$tim = (Get-Date).tostring("dd-MM-yyyy-hh:mm:ss")
LogWrite "$tim - Deleting NSG $nsgname in $resourcegroup of Location - $location"
Write-Host -ForegroundColor Cyan "Deleting NSG $nsgname in $resourcegroup of Location - $location"
Remove-AzNetworkSecurityGroup -Name $nsgname -ResourceGroup $resourcegroup -Force
}
#####################################################################
##########################DeleteOrphanedPiP##########################
$csv = Import-Csv "pip.csv" #name of csv file
$filetim = (Get-Date).tostring("dd-MM-yyyy-hh-mm")
$Logfile = "log-deletePIP-$filetim.log"
Function LogWrite
{
Param ([string]$logstring)
Add-content $Logfile -value $logstring
}
Start-Transcript -Path $Logfile
Stop-Transcript
LogWrite " "
LogWrite " "
LogWrite "***** LogFile *****"
LogWrite " "
LogWrite " "
$csv | ForEach-Object {
$pipname = $_.NAME
$resourcegroup = $_.RESOURCEGROUP
$location = $_.LOCATION
$tim = (Get-Date).tostring("dd-MM-yyyy-hh:mm:ss")
LogWrite "$tim - Deleting Public IP $pipname in $resourcegroup of Location - $location"
Write-Host -ForegroundColor Cyan "Deleting Public IP $pipname in $resourcegroup of Location - $location"
Remove-AzPublicIpAddress -Name $pipname -ResourceGroupName $resourcegroup -Force
}
#####################################################################
We need to install the Azure PowerShellGet module. The problem is that we are unable to install NuGet provider and a couple of errors are showing. Warning unable to download from URI, unable to download the list of available providers. After the errors, it did not install. In this article, you will learn why this is happening and the solution for installing NuGet provider for PowerShell.
Install-Module Az.Accounts
Based on above error, tried below commands to install NuGet Provider for Powershell
Run PowerShell as administrator. Run the command Install-Module PowershellGet -Force. When asked to install NuGet provider, press Y and follow with Enter.
After pressing Y and follow with Enter, the output is giving us the following warnings.
WARNING: Unable to download from URI.
WARNING: Unable to download the list of available providers. Check your internet connection.
Unable to find package provider ‘NuGet’. It may not be imported yet.
OR , you will not able t
Why are we getting this error and what is the solution for unable to install and download NuGet provider?
Find PowerShell version
Find the PowerShell version that is running on the system. We are going to use the Get-Host cmdlet in Windows Server 2016.
Check Transport Layer Security protocols
PowerShell 5.1 enables SSL 3.0 and TLS 1.0 for secure HTTP connections by default. Let’s confirm that with the next step.
Check the supported security protocols on the system.
As we can see, the security protocols defined in the system are SSL 3.0 and TLS 1.0. Both of the security protocols are deprecated.
Follow below steps to resolve the above error
First, check the SSL version with below command
Solution for unable to install NuGet provider for PowerShell
Now that we gathered all the information, we are going to enable TLS 1.2 on the system. Run both cmdlets to set .NET Framework strong cryptography registry keys. After that, restart PowerShell and check if the security protocol TLS 1.2 is added
The first cmdlet is to set strong cryptography on 64 bit .Net Framework (version 4 and above).
Restart Powershell and check for supported security protocols.
Run again Install-Module Az.Accounts
Post installation, Import Modules ( Installed Modules can be seen in C:\Program Files\WindowsPowerShell\Modules)
Similarly do for Azure storage modules
Conclusion:
In this article, we learned why we are unable to install Azure &NuGet provider for PowerShell. The solution to this problem is configuring TLS1.2 or higher on the system. After that, you can install NuGet & Azure Modules for PowerShell
Azure Files offers fully managed file shares in the cloud that are accessible via the industry standard Server Message Block (SMB) protocol or Network File System (NFS) protocol. Azure Files file shares can be mounted concurrently by cloud or on-premises deployments. SMB Azure file shares are accessible from Windows, Linux, and macOS clients. NFS Azure Files shares are accessible from Linux or macOS clients. Additionally, SMB Azure file shares can be cached on Windows Servers with Azure File Sync for fast access near where the data is being used
Why would I use an Azure file share versus Azure Blob storage for my data?
Azure Files and Azure Blob storage both offer ways to store large amounts of data in the cloud, but they are useful for slightly different purposes. Azure Blob storage is useful for massive-scale, cloud-native applications that need to store unstructured data. To maximize performance and scale, Azure Blob storage is a simpler storage abstraction than a true file system. You can access Azure Blob storage only through REST-based client libraries (or directly through the REST-based protocol).
Azure Files is specifically a file system. Azure Files has all the file abstracts that you know and love from years of working with on-premises operating systems. Like Azure Blob storage, Azure Files offers a REST interface and REST-based client libraries. Unlike Azure Blob storage, Azure Files offers SMB or NFS access to Azure file shares. File shares can be mounted directly on Windows, Linux, or macOS, either on-premises or in cloud VMs, without writing any code or attaching any special drivers to the file system. You also can cache Azure SMB file shares on on-premises file servers by using Azure File Sync for quick access, close to where the data is used.
For a more in-depth description on the differences between Azure Files and Azure Blob storage, see Introduction to the core Azure Storage services. To learn more about Azure Blob storage, see Introduction to Blob storage.
Azure Files Connectivity options
We have some different connectivity options available to us depending on whether we’re accessing our file shares either internally or externally. In this context, accessing it internally or externally implies the Azure region where our storage account exists, where the file share exists.
• Internal connectivity: This implies that the clients accessing the file share are within the Azure cloud itself. Here we have the ability to use REST, SMB 2.1 and SMB 3.0.
• External connectivity: In this scenario, the client machines accessing the file shares are located in a different cloud environment or could also reside on premises. We only have the option of using REST and SMB 3.0 in this case because SMB 2.1 doesn’t provide the encryption which is required for connecting externally to ensure the safety of the data.
In terms of security, data encrypted at rest by default within our storage accounts and we have access to secure data transfer over HTTPS for data that is in transit. This allows us to protect our data, whether it’s at rest or in transit inside of our Azure Files.
Creating an Azure File Share Prerequisites
Create a storage account
Traditional AD environment synchronized to Azure AD with Azure AD Connect
Account credentials to perform the steps below to create a computer account in an existing Active Directory environment to connect with Azure Files.
Permissions to create the storage account
Before you can work with an Azure file share, you have to create an Azure storage account. A general-purpose v2 storage account provides access to all of the Azure Storage services: blobs, files, queues, and tables.
As I have a requirement for Premium, below screenshots are provided with Premium Type and note that options may vary based on selection of storage account type.
Storage Accounts ->Create New
In above screenshot, I selected Performance Type as “Standard”. In case, if you have a requirement for Premium file Type then options will be displayed as below
Click Next (Default options)
Under Networking ->Create Private Endpoint (best practice)
Click Next (Default Options)
Click Next and validate to create
Enable AD DS authentication & Authorization for your Azure file shares -> Onpremises AD DS Authentication
Azure Files supports identity-based authentication over Server Message Block (SMB) through two types of Domain Services: on-premises Active Directory Domain Services (AD DS) and Azure Active Directory Domain Services (Azure AD DS). We strongly recommend you to review the How it works section to select the right domain service for authentication. The setup is different depending on the domain service you choose.
Supported scenarios and restrictions
• AD DS Identities used for Azure Files on-premises AD DS authentication must be synced to Azure AD. Password hash synchronization is optional. • Supports Azure file shares managed by Azure File Sync. • Supports Kerberos authentication with AD with RC4-HMAC and AES 256 encryption. AES 256 encryption support is currently limited to storage accounts with names <= 15 characters in length. AES 128 Kerberos encryption is not yet supported. • Supports single sign-on experience. • Only supported on clients running on OS versions newer than Windows 7 or Windows Server 2008 R2. • Only supported against the AD forest that the storage account is registered to. You can only access Azure file shares with the AD DS credentials from a single forest by default. If you need to access your Azure file share from a different forest, make sure that you have the proper forest trust configured, see the FAQ for details. • Does not support authentication against computer accounts created in AD DS. • Does not support authentication against Network File System (NFS) file shares.
When you enable AD DS for Azure file shares over SMB, your AD DS-joined machines can mount Azure file shares using your existing AD DS credentials. This capability can be enabled with an AD DS environment hosted either in on-prem machines or hosted in Azure.
Prerequisites Before you enable AD DS authentication for Azure file shares, make sure you have completed the following prerequisites:
• Select or create your AD DS environment and sync it to Azure AD with Azure AD Connect.
You can enable the feature on a new or existing on-premises AD DS environment. Identities used for access must be synced to Azure AD. The Azure AD tenant and the file share that you are accessing must be associated with the same subscription.
• Domain-join an on-premises machine or an Azure VM to on-premises AD DS. For information about how to domain-join, refer to Join a Computer to a Domain.
Part one: Enable AD DS authentication for your Azure file shares
Option 1 (recommended): Use AzFilesHybrid PowerShell module
1.1.1 Download AzFilesHybrid module
• If you don’t have .NET Framework 4.7.2 installed, install it now. It is required for the module to import successfully. • Download and unzip the AzFilesHybrid module (GA module: v0.2.0+) Note that AES 256 kerberos encryption is supported on v0.2.2 or above. If you have enabled the feature with a AzFilesHybrid version below v0.2.2 and want to update to support AES 256 Kerberos encryption, please refer to this article. • Install and execute the module in a device that is domain joined to on-premises AD DS with AD DS credentials that have permissions to create a service logon account or a computer account in the target AD. • Run the script using an on-premises AD DS credential that is synced to your Azure AD. The on-premises AD DS credential must have either Owner or Contributor Azure role on the storage account.
The Join-AzStorageAccountForAuth cmdlet performs the equivalent of an offline domain join on behalf of the specified storage account. The script uses the cmdlet to create a computer account in your AD domain. If for whatever reason you cannot use a computer account, you can alter the script to create a service logon account instead. If you choose to run the command manually, you should select the account best suited for your environment.
The AD DS account created by the cmdlet represents the storage account. If the AD DS account is created under an organizational unit (OU) that enforces password expiration, you must update the password before the maximum password age. Failing to update the account password before that date results in authentication failures when accessing Azure file shares. To learn how to update the password,
Execute below are the steps if Azure Powershell & Azure storage modules not available at client system where you are trying to execute the Join-AzStorageAccountForAuth PowerShell commands
Install-Module Az.Accounts
The problem is that we are unable to install NuGet provider and a couple of errors are showing. Warning unable to download from URI, unable to download the list of available providers. After the errors, it did not install. In this article, you will learn why this is happening and the solution for installing NuGet provider for PowerShell.,
Follow below steps to resolve the above error
First, check the SSL version with below command
Solution for unable to install NuGet provider for PowerShell
Now that we gathered all the information, we are going to enable TLS 1.2 on the system. Run both cmdlets to set .NET Framework strong cryptography registry keys. After that, restart PowerShell and check if the security protocol TLS 1.2 is added
The first cmdlet is to set strong cryptography on 64 bit .Net Framework (version 4 and above).
Steps: .\CopyToPSPath.ps1 Connect-AzAccount (Note: connect the Azure with required credentials ( i.e, account should have permission to access storage and create computer account in domain) Import-Module AzFilesHybrid
Note: Add OrganizationalUnitDistinguishedName if computer account need to join in specific OU
Post execution ->verify from below tools
Or through PowerShell
Note: Update the password of your storage account identity in AD DS
If you registered the Active Directory Domain Services (AD DS) identity/account that represents your storage account in an organizational unit or domain that enforces password expiration time, you must change the password before the maximum password age. Your organization may run automated cleanup scripts that delete accounts once their password expires. Because of this, if you do not change your password before it expires, your account could be deleted, which will cause you to lose access to your Azure file shares.
To trigger password rotation, you can run the Update-
Part 2: Assign share-level permissions to an identity
Once you’ve enabled Active Directory Domain Services (AD DS) authentication on your storage account, you must configure share-level permissions in order to get access to your file shares. There are two ways you can assign share-level permissions. You can assign them to specific Azure AD users/user groups and you can assign them to all authenticated identities as a default share level permission. Share-level permissions for specific Azure AD users or groups Share-level permissions must be assigned to the Azure AD identity representing the same user or group in your AD DS to support AD DS authentication to your Azure file share. Authentication and authorization against identities that only exist in Azure AD, such as Azure Managed Identities (MSIs), are not supported with AD DS authentication.
You can use the Azure portal, Azure PowerShell module, or Azure CLI to assign the built-in roles to the Azure AD identity of a user for granting share-level permissions.
Note: The share level permissions will take upto 3 hours to take effect once completed. Please wait for the permissions to sync before connecting to your file share using your credentials
Share-level permissions for all authenticated identities
You can add a default share-level permission on your storage account, instead of configuring share-level permissions for Azure AD users or groups. A default share-level permission assigned to your storage account applies to all file shares contained in the storage account. When you set a default share-level permission, all authenticated users and groups will have the same permission. Authenticated users or groups are identified as the identity can be authenticated against the on-premises AD DS the storage account is associated with. The default share level permission is set to None at initialization, implying that no access is allowed to files & directories in Azure file share.
Note: You cannot currently assign permissions to the storage account with the Azure portal. Use either the Azure PowerShell module or the Azure CLI, instead.
Mounting prerequisites Before you can mount the file share, make sure you’ve gone through the following pre-requisites:
• If you are mounting the file share from a client that has previously mounted the file share using your storage account key, make sure that you have disconnected the share, removed the persistent credentials of the storage account key, and are currently using AD DS credentials for authentication. For instructions to clear the mounted share with storage account key, refer to FAQ page. • Your client must have line of sight to your AD DS. If your machine or VM is out of the network managed by your AD DS, you will need to enable VPN to reach AD DS for authentication. Replace the placeholder values with your own values, then use the following command to mount the Azure file share. You always need to mount using the path shown below. Using CNAME for file mount is not supported for identity based authentication (AD DS or Azure AD DS).