Andy T
Andy T

Reputation: 9881

Issues mounting Azure Files using VM Custom Extensions

I am trying to mount an Azure File share when I provision a VM using Powershell.

I am using net use with the values that are provided in the portal when I click on "Connect" in the file share. I've also persisted the storage account credentials using cmdkey.

The share does show up, but is "disconnected" because the username or password is incorrect.

If I RDP into the server and run the script myself, the file share mounts without a problem.

I've added whoami in my script to see what context the script is running under when the VM is being provisioned, and it shows as "nt authority\system"

Upvotes: 2

Views: 938

Answers (2)

WitoldW
WitoldW

Reputation: 898

After a lot of time of searching and trying, here is what I ended up doing :

Powershell script

This script is run by the VM Extension. It adds credentials for the fileshare and mounts the drive.

Caveat: it has to be run by the user using the script. By default a VM extension is run as system. See solution below.

param(
    [Parameter(Mandatory=$true)]
    [string]$FileShare,

    [Parameter(Mandatory=$true)]
    [string]$StorageAccountAccessKey,
    
    [Parameter(Mandatory=$true)]
    [string]$StorageAccount
)

# Save the password so the drive will persist on reboot
cmd.exe /C "cmdkey /add:`"${StorageAccount}.file.core.windows.net`" /user:`"localhost\${StorageAccount}`" /pass:`"${StorageAccountAccessKey}`""
# Mount the drive
net use "Z:" "\\${StorageAccount}.file.core.windows.net\${FileShare}" /persistent:yes

Execute script as another user : psexec

I ended up using psexec to execute my script above as the user who is going to use the VM and need the mounted drive. It is not available out of the box so you will need to download it when running the script (see below). PsExec is part of the PsTools suite.

VM Extension definition

To run the script when creating the VM, I used a bicep template to define the VM Extension. The template references two files in fileUris : the first one is a link to download the powerhsell script, and the second one is a link to a exe of psexec. I used github to host both files. They will be downloaded automatically and will be available by the commandToExecute command. Some variables are defined : accountName and accountPassword are the credentials of the user who is going to use the drive.

resource vmMountDriveExtension 'extensions@2022-08-01' = {
    name: 'mountDriveExtension'
    location: location
    properties: {
      settings: any({
        fileUris: [
          'https://URL_TO_POWERSHELL_SCRIPT/mountDrive.ps1'
          'https://URL_TO_SELF_HOSTED_PSEXEC/PsExec.exe'
        ]
      })
      protectedSettings: any({
        commandToExecute: 'powershell -Command "Enable-PSRemoting -Force" ;.\\psexec -u ${accountName} -p ${accountPassword} -accepteula -h -i "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" -File \${pwd}\\mountDrive.ps1 -FileShare ${fileShareName} -StorageAccountAccessKey ${storageAccount.listKeys().keys[0].value} -StorageAccount ${storageAccount.name}'
      })
      publisher: 'Microsoft.Compute'
      type: 'CustomScriptExtension'
      typeHandlerVersion: '1.10'
    }
  }
}

Upvotes: 1

Shui shengbao
Shui shengbao

Reputation: 19195

Based on my knowledge, it is not possible. In order for you to access the mapped drive in this scenario you would need to store the credentials (i.e. the storage account name and key) in the Credential Manager store of the user account you are using to log on to the VM.

Please refer to this similar question.

Upvotes: -2

Related Questions